summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-10 22:42:11 +0200
committerTarja Sundqvist <tarja.sundqvist@qt.io>2022-11-10 22:42:11 +0200
commitc3c7e6ebc29cce466d954f72f340a257d76b5ec2 (patch)
treedc72395a1792572e9ddea04b1cfe2d8ce5503c78
parentfa7cb071928c9603bb0c5a0f1958dd4a7c045340 (diff)
parenta96a379a6aeac867413330026a78ff71c19d34dc (diff)
Merge remote-tracking branch 'origin/tqtc/lts-5.15.8' into tqtc/lts-5.15-opensourcev5.15.8-lts-lgpl
-rw-r--r--.gitmodules3
-rw-r--r--.qmake.conf2
-rw-r--r--config.tests/assimp/main.cpp4
-rw-r--r--src/3rdparty/assimp/LICENSE53
-rw-r--r--src/3rdparty/assimp/README1
-rw-r--r--src/3rdparty/assimp/Readme.md170
-rw-r--r--src/3rdparty/assimp/assimp.pri940
-rw-r--r--src/3rdparty/assimp/code/3DSConverter.cpp871
-rw-r--r--src/3rdparty/assimp/code/3DSExporter.cpp579
-rw-r--r--src/3rdparty/assimp/code/3DSExporter.h97
-rw-r--r--src/3rdparty/assimp/code/3DSHelper.h595
-rw-r--r--src/3rdparty/assimp/code/3DSLoader.cpp1433
-rw-r--r--src/3rdparty/assimp/code/3DSLoader.h283
-rw-r--r--src/3rdparty/assimp/code/3MFXmlTags.h89
-rw-r--r--src/3rdparty/assimp/code/ACLoader.cpp909
-rw-r--r--src/3rdparty/assimp/code/ACLoader.h275
-rw-r--r--src/3rdparty/assimp/code/AMFImporter.cpp704
-rw-r--r--src/3rdparty/assimp/code/AMFImporter.hpp563
-rw-r--r--src/3rdparty/assimp/code/AMFImporter_Geometry.cpp356
-rw-r--r--src/3rdparty/assimp/code/AMFImporter_Macro.hpp165
-rw-r--r--src/3rdparty/assimp/code/AMFImporter_Material.cpp310
-rw-r--r--src/3rdparty/assimp/code/AMFImporter_Node.hpp400
-rw-r--r--src/3rdparty/assimp/code/AMFImporter_Postprocess.cpp976
-rw-r--r--src/3rdparty/assimp/code/ASELoader.cpp1328
-rw-r--r--src/3rdparty/assimp/code/ASELoader.h207
-rw-r--r--src/3rdparty/assimp/code/ASEParser.cpp2157
-rw-r--r--src/3rdparty/assimp/code/ASEParser.h669
-rw-r--r--src/3rdparty/assimp/code/AssbinExporter.cpp822
-rw-r--r--src/3rdparty/assimp/code/AssbinExporter.h50
-rw-r--r--src/3rdparty/assimp/code/AssbinLoader.cpp740
-rw-r--r--src/3rdparty/assimp/code/AssbinLoader.h104
-rw-r--r--src/3rdparty/assimp/code/Assimp.cpp694
-rw-r--r--src/3rdparty/assimp/code/AssimpCExport.cpp156
-rw-r--r--src/3rdparty/assimp/code/AssxmlExporter.cpp648
-rw-r--r--src/3rdparty/assimp/code/AssxmlExporter.h50
-rw-r--r--src/3rdparty/assimp/code/B3DImporter.cpp719
-rw-r--r--src/3rdparty/assimp/code/B3DImporter.h132
-rw-r--r--src/3rdparty/assimp/code/BVHLoader.cpp545
-rw-r--r--src/3rdparty/assimp/code/BVHLoader.h172
-rw-r--r--src/3rdparty/assimp/code/BaseImporter.cpp601
-rw-r--r--src/3rdparty/assimp/code/BaseImporter.h361
-rw-r--r--src/3rdparty/assimp/code/BaseProcess.cpp106
-rw-r--r--src/3rdparty/assimp/code/BaseProcess.h293
-rw-r--r--src/3rdparty/assimp/code/Bitmap.cpp153
-rw-r--r--src/3rdparty/assimp/code/Bitmap.h123
-rw-r--r--src/3rdparty/assimp/code/BlenderBMesh.cpp206
-rw-r--r--src/3rdparty/assimp/code/BlenderBMesh.h94
-rw-r--r--src/3rdparty/assimp/code/BlenderDNA.cpp376
-rw-r--r--src/3rdparty/assimp/code/BlenderDNA.h810
-rw-r--r--src/3rdparty/assimp/code/BlenderDNA.inl755
-rw-r--r--src/3rdparty/assimp/code/BlenderIntermediate.h201
-rw-r--r--src/3rdparty/assimp/code/BlenderLoader.cpp1318
-rw-r--r--src/3rdparty/assimp/code/BlenderLoader.h239
-rw-r--r--src/3rdparty/assimp/code/BlenderModifier.cpp326
-rw-r--r--src/3rdparty/assimp/code/BlenderModifier.h157
-rw-r--r--src/3rdparty/assimp/code/BlenderScene.cpp828
-rw-r--r--src/3rdparty/assimp/code/BlenderScene.h900
-rw-r--r--src/3rdparty/assimp/code/BlenderSceneGen.h255
-rw-r--r--src/3rdparty/assimp/code/BlenderTessellator.cpp525
-rw-r--r--src/3rdparty/assimp/code/BlenderTessellator.h209
-rw-r--r--src/3rdparty/assimp/code/BlobIOSystem.h337
-rw-r--r--src/3rdparty/assimp/code/ByteSwapper.h287
-rw-r--r--src/3rdparty/assimp/code/C4DImporter.cpp650
-rw-r--r--src/3rdparty/assimp/code/C4DImporter.h123
-rw-r--r--src/3rdparty/assimp/code/CInterfaceIOWrapper.cpp135
-rw-r--r--src/3rdparty/assimp/code/CInterfaceIOWrapper.h98
-rw-r--r--src/3rdparty/assimp/code/CMakeLists.txt1012
-rw-r--r--src/3rdparty/assimp/code/COBLoader.cpp1300
-rw-r--r--src/3rdparty/assimp/code/COBLoader.h175
-rw-r--r--src/3rdparty/assimp/code/COBScene.h276
-rw-r--r--src/3rdparty/assimp/code/CSMLoader.cpp307
-rw-r--r--src/3rdparty/assimp/code/CSMLoader.h92
-rw-r--r--src/3rdparty/assimp/code/CalcTangentsProcess.cpp318
-rw-r--r--src/3rdparty/assimp/code/CalcTangentsProcess.h116
-rw-r--r--src/3rdparty/assimp/code/ColladaExporter.cpp1625
-rw-r--r--src/3rdparty/assimp/code/ColladaExporter.h222
-rw-r--r--src/3rdparty/assimp/code/ColladaHelper.h703
-rw-r--r--src/3rdparty/assimp/code/ColladaLoader.cpp1924
-rw-r--r--src/3rdparty/assimp/code/ColladaLoader.h257
-rw-r--r--src/3rdparty/assimp/code/ColladaParser.cpp3199
-rw-r--r--src/3rdparty/assimp/code/ColladaParser.h367
-rw-r--r--src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp505
-rw-r--r--src/3rdparty/assimp/code/ComputeUVMappingProcess.h147
-rw-r--r--src/3rdparty/assimp/code/ConvertToLHProcess.cpp332
-rw-r--r--src/3rdparty/assimp/code/ConvertToLHProcess.h169
-rw-r--r--src/3rdparty/assimp/code/CreateAnimMesh.cpp92
-rw-r--r--src/3rdparty/assimp/code/CreateAnimMesh.h57
-rw-r--r--src/3rdparty/assimp/code/D3MFExporter.cpp328
-rw-r--r--src/3rdparty/assimp/code/D3MFExporter.h103
-rw-r--r--src/3rdparty/assimp/code/D3MFImporter.cpp334
-rw-r--r--src/3rdparty/assimp/code/D3MFImporter.h64
-rw-r--r--src/3rdparty/assimp/code/D3MFOpcPackage.cpp520
-rw-r--r--src/3rdparty/assimp/code/D3MFOpcPackage.h81
-rw-r--r--src/3rdparty/assimp/code/DXFHelper.h236
-rw-r--r--src/3rdparty/assimp/code/DXFLoader.cpp919
-rw-r--r--src/3rdparty/assimp/code/DXFLoader.h154
-rw-r--r--src/3rdparty/assimp/code/DeboneProcess.cpp466
-rw-r--r--src/3rdparty/assimp/code/DeboneProcess.h133
-rw-r--r--src/3rdparty/assimp/code/DefaultIOStream.cpp152
-rw-r--r--src/3rdparty/assimp/code/DefaultIOSystem.cpp199
-rw-r--r--src/3rdparty/assimp/code/DefaultLogger.cpp429
-rw-r--r--src/3rdparty/assimp/code/DefaultProgressHandler.h66
-rw-r--r--src/3rdparty/assimp/code/Exceptional.h125
-rw-r--r--src/3rdparty/assimp/code/Exporter.cpp602
-rw-r--r--src/3rdparty/assimp/code/FBXAnimation.cpp304
-rw-r--r--src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp460
-rw-r--r--src/3rdparty/assimp/code/FBXCompileConfig.h69
-rw-r--r--src/3rdparty/assimp/code/FBXConverter.cpp3356
-rw-r--r--src/3rdparty/assimp/code/FBXConverter.h65
-rw-r--r--src/3rdparty/assimp/code/FBXDeformer.cpp165
-rw-r--r--src/3rdparty/assimp/code/FBXDocument.cpp713
-rw-r--r--src/3rdparty/assimp/code/FBXDocument.h1167
-rw-r--r--src/3rdparty/assimp/code/FBXDocumentUtil.cpp134
-rw-r--r--src/3rdparty/assimp/code/FBXDocumentUtil.h122
-rw-r--r--src/3rdparty/assimp/code/FBXImportSettings.h152
-rw-r--r--src/3rdparty/assimp/code/FBXImporter.cpp194
-rw-r--r--src/3rdparty/assimp/code/FBXImporter.h99
-rw-r--r--src/3rdparty/assimp/code/FBXMaterial.cpp344
-rw-r--r--src/3rdparty/assimp/code/FBXMeshGeometry.cpp639
-rw-r--r--src/3rdparty/assimp/code/FBXMeshGeometry.h181
-rw-r--r--src/3rdparty/assimp/code/FBXModel.cpp152
-rw-r--r--src/3rdparty/assimp/code/FBXNodeAttribute.cpp169
-rw-r--r--src/3rdparty/assimp/code/FBXParser.cpp1307
-rw-r--r--src/3rdparty/assimp/code/FBXParser.h235
-rw-r--r--src/3rdparty/assimp/code/FBXProperties.cpp237
-rw-r--r--src/3rdparty/assimp/code/FBXProperties.h172
-rw-r--r--src/3rdparty/assimp/code/FBXTokenizer.cpp249
-rw-r--r--src/3rdparty/assimp/code/FBXTokenizer.h186
-rw-r--r--src/3rdparty/assimp/code/FBXUtil.cpp119
-rw-r--r--src/3rdparty/assimp/code/FBXUtil.h104
-rw-r--r--src/3rdparty/assimp/code/FIReader.cpp1833
-rw-r--r--src/3rdparty/assimp/code/FIReader.hpp185
-rw-r--r--src/3rdparty/assimp/code/FileLogStream.h106
-rw-r--r--src/3rdparty/assimp/code/FileSystemFilter.h300
-rw-r--r--src/3rdparty/assimp/code/FindDegenerates.cpp258
-rw-r--r--src/3rdparty/assimp/code/FindDegenerates.h127
-rw-r--r--src/3rdparty/assimp/code/FindInstancesProcess.cpp278
-rw-r--r--src/3rdparty/assimp/code/FindInstancesProcess.h136
-rw-r--r--src/3rdparty/assimp/code/FindInvalidDataProcess.cpp429
-rw-r--r--src/3rdparty/assimp/code/FindInvalidDataProcess.h106
-rw-r--r--src/3rdparty/assimp/code/FixNormalsStep.cpp181
-rw-r--r--src/3rdparty/assimp/code/FixNormalsStep.h90
-rw-r--r--src/3rdparty/assimp/code/GenFaceNormalsProcess.cpp144
-rw-r--r--src/3rdparty/assimp/code/GenFaceNormalsProcess.h85
-rw-r--r--src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp236
-rw-r--r--src/3rdparty/assimp/code/GenVertexNormalsProcess.h113
-rw-r--r--src/3rdparty/assimp/code/GenericProperty.h126
-rw-r--r--src/3rdparty/assimp/code/HMPFileData.h136
-rw-r--r--src/3rdparty/assimp/code/HMPLoader.cpp519
-rw-r--r--src/3rdparty/assimp/code/HMPLoader.h151
-rw-r--r--src/3rdparty/assimp/code/HalfLifeFileData.h148
-rw-r--r--src/3rdparty/assimp/code/Hash.h117
-rw-r--r--src/3rdparty/assimp/code/IFCBoolean.cpp831
-rw-r--r--src/3rdparty/assimp/code/IFCCurve.cpp617
-rw-r--r--src/3rdparty/assimp/code/IFCGeometry.cpp885
-rw-r--r--src/3rdparty/assimp/code/IFCLoader.cpp982
-rw-r--r--src/3rdparty/assimp/code/IFCLoader.h133
-rw-r--r--src/3rdparty/assimp/code/IFCMaterial.cpp205
-rw-r--r--src/3rdparty/assimp/code/IFCOpenings.cpp1699
-rw-r--r--src/3rdparty/assimp/code/IFCProfile.cpp190
-rw-r--r--src/3rdparty/assimp/code/IFCReaderGen.h4368
-rw-r--r--src/3rdparty/assimp/code/IFCReaderGen1.cpp3168
-rw-r--r--src/3rdparty/assimp/code/IFCReaderGen2.cpp1917
-rw-r--r--src/3rdparty/assimp/code/IFCUtil.cpp707
-rw-r--r--src/3rdparty/assimp/code/IFCUtil.h429
-rw-r--r--src/3rdparty/assimp/code/IFF.h102
-rw-r--r--src/3rdparty/assimp/code/IOStreamBuffer.h350
-rw-r--r--src/3rdparty/assimp/code/IRRLoader.cpp1488
-rw-r--r--src/3rdparty/assimp/code/IRRLoader.h314
-rw-r--r--src/3rdparty/assimp/code/IRRMeshLoader.cpp535
-rw-r--r--src/3rdparty/assimp/code/IRRMeshLoader.h100
-rw-r--r--src/3rdparty/assimp/code/IRRShared.cpp505
-rw-r--r--src/3rdparty/assimp/code/IRRShared.h118
-rw-r--r--src/3rdparty/assimp/code/Importer.cpp1195
-rw-r--r--src/3rdparty/assimp/code/Importer.h228
-rw-r--r--src/3rdparty/assimp/code/ImporterRegistry.cpp364
-rw-r--r--src/3rdparty/assimp/code/ImproveCacheLocality.cpp388
-rw-r--r--src/3rdparty/assimp/code/ImproveCacheLocality.h99
-rw-r--r--src/3rdparty/assimp/code/JoinVerticesProcess.cpp417
-rw-r--r--src/3rdparty/assimp/code/JoinVerticesProcess.h98
-rw-r--r--src/3rdparty/assimp/code/LWOAnimation.cpp603
-rw-r--r--src/3rdparty/assimp/code/LWOAnimation.h346
-rw-r--r--src/3rdparty/assimp/code/LWOBLoader.cpp423
-rw-r--r--src/3rdparty/assimp/code/LWOFileData.h702
-rw-r--r--src/3rdparty/assimp/code/LWOLoader.cpp1480
-rw-r--r--src/3rdparty/assimp/code/LWOLoader.h489
-rw-r--r--src/3rdparty/assimp/code/LWOMaterial.cpp898
-rw-r--r--src/3rdparty/assimp/code/LWSLoader.cpp935
-rw-r--r--src/3rdparty/assimp/code/LWSLoader.h253
-rw-r--r--src/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp202
-rw-r--r--src/3rdparty/assimp/code/LimitBoneWeightsProcess.h143
-rw-r--r--src/3rdparty/assimp/code/LineSplitter.h243
-rw-r--r--src/3rdparty/assimp/code/LogAux.h133
-rw-r--r--src/3rdparty/assimp/code/MD2FileData.h163
-rw-r--r--src/3rdparty/assimp/code/MD2Loader.cpp458
-rw-r--r--src/3rdparty/assimp/code/MD2Loader.h123
-rw-r--r--src/3rdparty/assimp/code/MD2NormalTable.h218
-rw-r--r--src/3rdparty/assimp/code/MD3FileData.h313
-rw-r--r--src/3rdparty/assimp/code/MD3Loader.cpp1094
-rw-r--r--src/3rdparty/assimp/code/MD3Loader.h332
-rw-r--r--src/3rdparty/assimp/code/MD4FileData.h218
-rw-r--r--src/3rdparty/assimp/code/MD5Loader.cpp757
-rw-r--r--src/3rdparty/assimp/code/MD5Loader.h194
-rw-r--r--src/3rdparty/assimp/code/MD5Parser.cpp487
-rw-r--r--src/3rdparty/assimp/code/MD5Parser.h466
-rw-r--r--src/3rdparty/assimp/code/MDCFileData.h219
-rw-r--r--src/3rdparty/assimp/code/MDCLoader.cpp494
-rw-r--r--src/3rdparty/assimp/code/MDCLoader.h129
-rw-r--r--src/3rdparty/assimp/code/MDCNormalTable.h299
-rw-r--r--src/3rdparty/assimp/code/MDLDefaultColorMap.h119
-rw-r--r--src/3rdparty/assimp/code/MDLFileData.h947
-rw-r--r--src/3rdparty/assimp/code/MDLLoader.cpp1972
-rw-r--r--src/3rdparty/assimp/code/MDLLoader.h458
-rw-r--r--src/3rdparty/assimp/code/MDLMaterialLoader.cpp840
-rw-r--r--src/3rdparty/assimp/code/MMDCpp14.h82
-rw-r--r--src/3rdparty/assimp/code/MMDImporter.cpp370
-rw-r--r--src/3rdparty/assimp/code/MMDImporter.h96
-rw-r--r--src/3rdparty/assimp/code/MMDPmdParser.h596
-rw-r--r--src/3rdparty/assimp/code/MMDPmxParser.cpp637
-rw-r--r--src/3rdparty/assimp/code/MMDPmxParser.h780
-rw-r--r--src/3rdparty/assimp/code/MMDVmdParser.h375
-rw-r--r--src/3rdparty/assimp/code/MS3DLoader.cpp671
-rw-r--r--src/3rdparty/assimp/code/MS3DLoader.h161
-rw-r--r--src/3rdparty/assimp/code/Macros.h49
-rw-r--r--src/3rdparty/assimp/code/MakeVerboseFormat.cpp222
-rw-r--r--src/3rdparty/assimp/code/MakeVerboseFormat.h104
-rw-r--r--src/3rdparty/assimp/code/MaterialSystem.cpp627
-rw-r--r--src/3rdparty/assimp/code/MaterialSystem.h71
-rw-r--r--src/3rdparty/assimp/code/MathFunctions.h77
-rw-r--r--src/3rdparty/assimp/code/MemoryIOWrapper.h198
-rw-r--r--src/3rdparty/assimp/code/NDOLoader.cpp310
-rw-r--r--src/3rdparty/assimp/code/NDOLoader.h126
-rw-r--r--src/3rdparty/assimp/code/NFFLoader.cpp1276
-rw-r--r--src/3rdparty/assimp/code/NFFLoader.h214
-rw-r--r--src/3rdparty/assimp/code/OFFLoader.cpp254
-rw-r--r--src/3rdparty/assimp/code/OFFLoader.h93
-rw-r--r--src/3rdparty/assimp/code/ObjExporter.cpp454
-rw-r--r--src/3rdparty/assimp/code/ObjExporter.h176
-rw-r--r--src/3rdparty/assimp/code/ObjFileData.h335
-rw-r--r--src/3rdparty/assimp/code/ObjFileImporter.cpp769
-rw-r--r--src/3rdparty/assimp/code/ObjFileImporter.h122
-rw-r--r--src/3rdparty/assimp/code/ObjFileMtlImporter.cpp495
-rw-r--r--src/3rdparty/assimp/code/ObjFileMtlImporter.h116
-rw-r--r--src/3rdparty/assimp/code/ObjFileParser.cpp862
-rw-r--r--src/3rdparty/assimp/code/ObjFileParser.h163
-rw-r--r--src/3rdparty/assimp/code/ObjTools.h307
-rw-r--r--src/3rdparty/assimp/code/OgreBinarySerializer.cpp1110
-rw-r--r--src/3rdparty/assimp/code/OgreBinarySerializer.h422
-rw-r--r--src/3rdparty/assimp/code/OgreImporter.cpp149
-rw-r--r--src/3rdparty/assimp/code/OgreImporter.h101
-rw-r--r--src/3rdparty/assimp/code/OgreMaterial.cpp596
-rw-r--r--src/3rdparty/assimp/code/OgreParsingUtils.h144
-rw-r--r--src/3rdparty/assimp/code/OgreStructs.cpp1205
-rw-r--r--src/3rdparty/assimp/code/OgreStructs.h695
-rw-r--r--src/3rdparty/assimp/code/OgreXmlSerializer.cpp1005
-rw-r--r--src/3rdparty/assimp/code/OgreXmlSerializer.h117
-rw-r--r--src/3rdparty/assimp/code/OpenGEXExporter.cpp61
-rw-r--r--src/3rdparty/assimp/code/OpenGEXExporter.h67
-rw-r--r--src/3rdparty/assimp/code/OpenGEXImporter.cpp1303
-rw-r--r--src/3rdparty/assimp/code/OpenGEXImporter.h213
-rw-r--r--src/3rdparty/assimp/code/OpenGEXStructs.h263
-rw-r--r--src/3rdparty/assimp/code/OptimizeGraph.cpp362
-rw-r--r--src/3rdparty/assimp/code/OptimizeGraph.h144
-rw-r--r--src/3rdparty/assimp/code/OptimizeMeshes.cpp257
-rw-r--r--src/3rdparty/assimp/code/OptimizeMeshes.h183
-rw-r--r--src/3rdparty/assimp/code/ParsingUtils.h251
-rw-r--r--src/3rdparty/assimp/code/PlyExporter.cpp393
-rw-r--r--src/3rdparty/assimp/code/PlyExporter.h87
-rw-r--r--src/3rdparty/assimp/code/PlyLoader.cpp1014
-rw-r--r--src/3rdparty/assimp/code/PlyLoader.h140
-rw-r--r--src/3rdparty/assimp/code/PlyParser.cpp1121
-rw-r--r--src/3rdparty/assimp/code/PlyParser.h489
-rw-r--r--src/3rdparty/assimp/code/PolyTools.h228
-rw-r--r--src/3rdparty/assimp/code/PostStepRegistry.cpp230
-rw-r--r--src/3rdparty/assimp/code/PretransformVertices.cpp730
-rw-r--r--src/3rdparty/assimp/code/PretransformVertices.h167
-rw-r--r--src/3rdparty/assimp/code/ProcessHelper.cpp442
-rw-r--r--src/3rdparty/assimp/code/ProcessHelper.h385
-rw-r--r--src/3rdparty/assimp/code/Profiler.h98
-rw-r--r--src/3rdparty/assimp/code/Q3BSPFileData.h218
-rw-r--r--src/3rdparty/assimp/code/Q3BSPFileImporter.cpp771
-rw-r--r--src/3rdparty/assimp/code/Q3BSPFileImporter.h118
-rw-r--r--src/3rdparty/assimp/code/Q3BSPFileParser.cpp281
-rw-r--r--src/3rdparty/assimp/code/Q3BSPFileParser.h90
-rw-r--r--src/3rdparty/assimp/code/Q3BSPZipArchive.cpp316
-rw-r--r--src/3rdparty/assimp/code/Q3BSPZipArchive.h130
-rw-r--r--src/3rdparty/assimp/code/Q3DLoader.cpp616
-rw-r--r--src/3rdparty/assimp/code/Q3DLoader.h133
-rw-r--r--src/3rdparty/assimp/code/RawLoader.cpp327
-rw-r--r--src/3rdparty/assimp/code/RawLoader.h120
-rw-r--r--src/3rdparty/assimp/code/RemoveComments.cpp108
-rw-r--r--src/3rdparty/assimp/code/RemoveComments.h90
-rw-r--r--src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp222
-rw-r--r--src/3rdparty/assimp/code/RemoveRedundantMaterials.h105
-rw-r--r--src/3rdparty/assimp/code/RemoveVCProcess.cpp333
-rw-r--r--src/3rdparty/assimp/code/RemoveVCProcess.h122
-rw-r--r--src/3rdparty/assimp/code/SGSpatialSort.cpp167
-rw-r--r--src/3rdparty/assimp/code/SGSpatialSort.h141
-rw-r--r--src/3rdparty/assimp/code/SIBImporter.cpp941
-rw-r--r--src/3rdparty/assimp/code/SIBImporter.h116
-rw-r--r--src/3rdparty/assimp/code/SMDLoader.cpp1161
-rw-r--r--src/3rdparty/assimp/code/SMDLoader.h418
-rw-r--r--src/3rdparty/assimp/code/STEPFile.h1019
-rw-r--r--src/3rdparty/assimp/code/STEPFileEncoding.cpp427
-rw-r--r--src/3rdparty/assimp/code/STEPFileEncoding.h64
-rw-r--r--src/3rdparty/assimp/code/STEPFileReader.cpp544
-rw-r--r--src/3rdparty/assimp/code/STEPFileReader.h65
-rw-r--r--src/3rdparty/assimp/code/STLExporter.cpp188
-rw-r--r--src/3rdparty/assimp/code/STLExporter.h86
-rw-r--r--src/3rdparty/assimp/code/STLLoader.cpp537
-rw-r--r--src/3rdparty/assimp/code/STLLoader.h124
-rw-r--r--src/3rdparty/assimp/code/ScaleProcess.cpp105
-rw-r--r--src/3rdparty/assimp/code/ScaleProcess.h87
-rw-r--r--src/3rdparty/assimp/code/SceneCombiner.cpp1286
-rw-r--r--src/3rdparty/assimp/code/ScenePreprocessor.cpp260
-rw-r--r--src/3rdparty/assimp/code/ScenePreprocessor.h124
-rw-r--r--src/3rdparty/assimp/code/ScenePrivate.h87
-rw-r--r--src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp269
-rw-r--r--src/3rdparty/assimp/code/SkeletonMeshBuilder.h124
-rw-r--r--src/3rdparty/assimp/code/SmoothingGroups.h109
-rw-r--r--src/3rdparty/assimp/code/SmoothingGroups.inl138
-rw-r--r--src/3rdparty/assimp/code/SortByPTypeProcess.cpp410
-rw-r--r--src/3rdparty/assimp/code/SortByPTypeProcess.h84
-rw-r--r--src/3rdparty/assimp/code/SpatialSort.cpp341
-rw-r--r--src/3rdparty/assimp/code/SpatialSort.h171
-rw-r--r--src/3rdparty/assimp/code/SplitByBoneCountProcess.cpp406
-rw-r--r--src/3rdparty/assimp/code/SplitByBoneCountProcess.h110
-rw-r--r--src/3rdparty/assimp/code/SplitLargeMeshes.cpp676
-rw-r--r--src/3rdparty/assimp/code/SplitLargeMeshes.h209
-rw-r--r--src/3rdparty/assimp/code/StandardShapes.cpp506
-rw-r--r--src/3rdparty/assimp/code/StandardShapes.h199
-rw-r--r--src/3rdparty/assimp/code/StdOStreamLogStream.h100
-rw-r--r--src/3rdparty/assimp/code/StepExporter.cpp372
-rw-r--r--src/3rdparty/assimp/code/StepExporter.h110
-rw-r--r--src/3rdparty/assimp/code/StreamReader.h347
-rw-r--r--src/3rdparty/assimp/code/StreamWriter.h240
-rw-r--r--src/3rdparty/assimp/code/StringComparison.h225
-rw-r--r--src/3rdparty/assimp/code/StringUtils.h110
-rw-r--r--src/3rdparty/assimp/code/Subdivision.cpp590
-rw-r--r--src/3rdparty/assimp/code/Subdivision.h130
-rw-r--r--src/3rdparty/assimp/code/TargetAnimation.cpp247
-rw-r--r--src/3rdparty/assimp/code/TargetAnimation.h182
-rw-r--r--src/3rdparty/assimp/code/TerragenLoader.cpp273
-rw-r--r--src/3rdparty/assimp/code/TerragenLoader.h104
-rw-r--r--src/3rdparty/assimp/code/TextureTransform.cpp571
-rw-r--r--src/3rdparty/assimp/code/TextureTransform.h232
-rw-r--r--src/3rdparty/assimp/code/TinyFormatter.h165
-rw-r--r--src/3rdparty/assimp/code/TriangulateProcess.cpp527
-rw-r--r--src/3rdparty/assimp/code/TriangulateProcess.h94
-rw-r--r--src/3rdparty/assimp/code/UnrealLoader.cpp444
-rw-r--r--src/3rdparty/assimp/code/UnrealLoader.h205
-rw-r--r--src/3rdparty/assimp/code/ValidateDataStructure.cpp969
-rw-r--r--src/3rdparty/assimp/code/ValidateDataStructure.h187
-rw-r--r--src/3rdparty/assimp/code/Version.cpp174
-rw-r--r--src/3rdparty/assimp/code/Vertex.h323
-rw-r--r--src/3rdparty/assimp/code/VertexTriangleAdjacency.cpp136
-rw-r--r--src/3rdparty/assimp/code/VertexTriangleAdjacency.h127
-rw-r--r--src/3rdparty/assimp/code/Win32DebugLogStream.h94
-rw-r--r--src/3rdparty/assimp/code/X3DExporter.cpp735
-rw-r--r--src/3rdparty/assimp/code/X3DExporter.hpp235
-rw-r--r--src/3rdparty/assimp/code/X3DImporter.cpp1728
-rw-r--r--src/3rdparty/assimp/code/X3DImporter.hpp833
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Geometry2D.cpp521
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Geometry3D.cpp998
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Group.cpp317
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Light.cpp289
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Macro.hpp194
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Metadata.cpp276
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Networking.cpp133
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Node.hpp779
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Postprocess.cpp826
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Rendering.cpp1070
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Shape.cpp249
-rw-r--r--src/3rdparty/assimp/code/X3DImporter_Texturing.cpp196
-rw-r--r--src/3rdparty/assimp/code/X3DVocabulary.cpp1675
-rw-r--r--src/3rdparty/assimp/code/XFileExporter.cpp538
-rw-r--r--src/3rdparty/assimp/code/XFileExporter.h139
-rw-r--r--src/3rdparty/assimp/code/XFileHelper.h210
-rw-r--r--src/3rdparty/assimp/code/XFileImporter.cpp717
-rw-r--r--src/3rdparty/assimp/code/XFileImporter.h148
-rw-r--r--src/3rdparty/assimp/code/XFileParser.cpp1480
-rw-r--r--src/3rdparty/assimp/code/XFileParser.h163
-rw-r--r--src/3rdparty/assimp/code/XGLLoader.cpp964
-rw-r--r--src/3rdparty/assimp/code/XGLLoader.h215
-rw-r--r--src/3rdparty/assimp/code/XMLTools.h82
-rw-r--r--src/3rdparty/assimp/code/assbin_chunks.h196
-rw-r--r--src/3rdparty/assimp/code/fast_atof.h387
-rw-r--r--src/3rdparty/assimp/code/glTF2Asset.h1131
-rw-r--r--src/3rdparty/assimp/code/glTF2Asset.inl1449
-rw-r--r--src/3rdparty/assimp/code/glTF2AssetWriter.h93
-rw-r--r--src/3rdparty/assimp/code/glTF2AssetWriter.inl638
-rw-r--r--src/3rdparty/assimp/code/glTF2Exporter.cpp1080
-rw-r--r--src/3rdparty/assimp/code/glTF2Exporter.h134
-rw-r--r--src/3rdparty/assimp/code/glTF2Importer.cpp694
-rw-r--r--src/3rdparty/assimp/code/glTF2Importer.h91
-rw-r--r--src/3rdparty/assimp/code/glTFAsset.h1196
-rw-r--r--src/3rdparty/assimp/code/glTFAsset.inl1645
-rw-r--r--src/3rdparty/assimp/code/glTFAssetWriter.h95
-rw-r--r--src/3rdparty/assimp/code/glTFAssetWriter.inl680
-rw-r--r--src/3rdparty/assimp/code/glTFExporter.cpp1007
-rw-r--r--src/3rdparty/assimp/code/glTFExporter.h118
-rw-r--r--src/3rdparty/assimp/code/glTFImporter.cpp683
-rw-r--r--src/3rdparty/assimp/code/glTFImporter.h91
-rw-r--r--src/3rdparty/assimp/code/irrXMLWrapper.h143
-rw-r--r--src/3rdparty/assimp/code/qnan.h156
-rw-r--r--src/3rdparty/assimp/code/res/assimp.rc80
-rw-r--r--src/3rdparty/assimp/code/res/resource.h14
-rw-r--r--src/3rdparty/assimp/code/scene.cpp139
-rw-r--r--src/3rdparty/assimp/config.h (renamed from src/3rdparty/assimp/include/assimp/config.h)65
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcAdjacencyInfo.h155
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.cpp865
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.h339
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcBinaryStream.h433
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcCommon.h412
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDVEncodeParams.h62
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVector.h84
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp278
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.h76
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp295
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.h79
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcFIFO.h97
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.h263
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.inl47
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.h111
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.inl850
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h140
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.h116
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.inl927
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTimer.h134
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTools.cpp22
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.cpp475
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.h291
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.h133
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl364
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.h101
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.inl719
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.h184
-rw-r--r--src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.inl317
-rw-r--r--src/3rdparty/assimp/contrib/clipper/License.txt29
-rw-r--r--src/3rdparty/assimp/contrib/clipper/clipper.cpp3451
-rw-r--r--src/3rdparty/assimp/contrib/clipper/clipper.hpp306
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h809
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/heapsort.h73
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/irrArray.h444
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/irrString.h664
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/irrTypes.h108
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/irrXML.cpp151
-rw-r--r--src/3rdparty/assimp/contrib/irrXML/irrXML.h540
-rw-r--r--src/3rdparty/assimp/contrib/irrXML_note.txt6
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt170
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/CREDITS19
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/LICENSE22
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/README.md136
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp217
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp212
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp384
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp1025
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLStream.cpp96
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp439
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h173
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h246
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h80
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h201
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h282
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h89
-rw-r--r--src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h273
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/AUTHORS8
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/LICENSE27
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/README51
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc365
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h327
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/utils.h127
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/poly2tri.h38
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.cc108
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.h118
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.cc71
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.h105
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc799
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.h285
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc211
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h186
-rw-r--r--src/3rdparty/assimp/contrib/poly2tri_patch.txt75
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/allocators.h271
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/document.h2613
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodedstream.h299
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodings.h716
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/en.h74
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/error.h161
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filereadstream.h99
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filewritestream.h104
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/fwd.h151
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/biginteger.h290
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/diyfp.h258
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/dtoa.h245
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/ieee754.h78
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/itoa.h304
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/meta.h181
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/pow10.h55
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/regex.h734
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/stack.h231
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strfunc.h69
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strtod.h269
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/swap.h46
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/istreamwrapper.h115
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorybuffer.h70
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorystream.h71
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/inttypes.h316
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/stdint.h300
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/ostreamwrapper.h81
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/pointer.h1358
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/prettywriter.h277
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/rapidjson.h628
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/reader.h2221
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/schema.h2016
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stream.h179
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stringbuffer.h121
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/writer.h711
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/license.txt57
-rw-r--r--src/3rdparty/assimp/contrib/rapidjson/readme.md160
-rw-r--r--src/3rdparty/assimp/contrib/unzip/crypt.h132
-rw-r--r--src/3rdparty/assimp/contrib/unzip/ioapi.c177
-rw-r--r--src/3rdparty/assimp/contrib/unzip/ioapi.h75
-rw-r--r--src/3rdparty/assimp/contrib/unzip/unzip.c1611
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes12
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html1789
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/source/utf8.h34
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/source/utf8/checked.h327
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/source/utf8/core.h329
-rw-r--r--src/3rdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h228
-rw-r--r--src/3rdparty/assimp/contrib/zip/README.md139
-rw-r--r--src/3rdparty/assimp/contrib/zip/UNLICENSE26
-rw-r--r--src/3rdparty/assimp/contrib/zip/src/miniz.h4928
-rw-r--r--src/3rdparty/assimp/contrib/zip/src/zip.c640
-rw-r--r--src/3rdparty/assimp/contrib/zip/src/zip.h193
-rw-r--r--src/3rdparty/assimp/include/assimp/Compiler/poppack1.h22
-rw-r--r--src/3rdparty/assimp/include/assimp/Compiler/pstdint.h912
-rw-r--r--src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h43
-rw-r--r--src/3rdparty/assimp/include/assimp/DefaultIOStream.h141
-rw-r--r--src/3rdparty/assimp/include/assimp/DefaultIOSystem.h99
-rw-r--r--src/3rdparty/assimp/include/assimp/DefaultLogger.hpp191
-rw-r--r--src/3rdparty/assimp/include/assimp/Defines.h49
-rw-r--r--src/3rdparty/assimp/include/assimp/Exporter.hpp483
-rw-r--r--src/3rdparty/assimp/include/assimp/IOStream.hpp140
-rw-r--r--src/3rdparty/assimp/include/assimp/IOSystem.hpp359
-rw-r--r--src/3rdparty/assimp/include/assimp/Importer.hpp653
-rw-r--r--src/3rdparty/assimp/include/assimp/LogStream.hpp110
-rw-r--r--src/3rdparty/assimp/include/assimp/Logger.hpp268
-rw-r--r--src/3rdparty/assimp/include/assimp/NullLogger.hpp98
-rw-r--r--src/3rdparty/assimp/include/assimp/ProgressHandler.hpp126
-rw-r--r--src/3rdparty/assimp/include/assimp/SceneCombiner.h400
-rw-r--r--src/3rdparty/assimp/include/assimp/ai_assert.h53
-rw-r--r--src/3rdparty/assimp/include/assimp/anim.h572
-rw-r--r--src/3rdparty/assimp/include/assimp/camera.h225
-rw-r--r--src/3rdparty/assimp/include/assimp/cexport.h263
-rw-r--r--src/3rdparty/assimp/include/assimp/cfileio.h137
-rw-r--r--src/3rdparty/assimp/include/assimp/cimport.h564
-rw-r--r--src/3rdparty/assimp/include/assimp/color4.h104
-rw-r--r--src/3rdparty/assimp/include/assimp/color4.inl204
-rw-r--r--src/3rdparty/assimp/include/assimp/defs.h290
-rw-r--r--src/3rdparty/assimp/include/assimp/importerdesc.h145
-rw-r--r--src/3rdparty/assimp/include/assimp/light.h258
-rw-r--r--src/3rdparty/assimp/include/assimp/material.h1564
-rw-r--r--src/3rdparty/assimp/include/assimp/material.inl389
-rw-r--r--src/3rdparty/assimp/include/assimp/matrix3x3.h182
-rw-r--r--src/3rdparty/assimp/include/assimp/matrix3x3.inl356
-rw-r--r--src/3rdparty/assimp/include/assimp/matrix4x4.h279
-rw-r--r--src/3rdparty/assimp/include/assimp/matrix4x4.inl681
-rw-r--r--src/3rdparty/assimp/include/assimp/mesh.h773
-rw-r--r--src/3rdparty/assimp/include/assimp/metadata.h314
-rw-r--r--src/3rdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h92
-rw-r--r--src/3rdparty/assimp/include/assimp/postprocess.h645
-rw-r--r--src/3rdparty/assimp/include/assimp/quaternion.h129
-rw-r--r--src/3rdparty/assimp/include/assimp/quaternion.inl285
-rw-r--r--src/3rdparty/assimp/include/assimp/scene.h384
-rw-r--r--src/3rdparty/assimp/include/assimp/texture.h217
-rw-r--r--src/3rdparty/assimp/include/assimp/types.h518
-rw-r--r--src/3rdparty/assimp/include/assimp/vector2.h116
-rw-r--r--src/3rdparty/assimp/include/assimp/vector2.inl227
-rw-r--r--src/3rdparty/assimp/include/assimp/vector3.h145
-rw-r--r--src/3rdparty/assimp/include/assimp/vector3.inl260
-rw-r--r--src/3rdparty/assimp/include/assimp/version.h108
-rw-r--r--src/3rdparty/assimp/qt_attribution.json153
-rw-r--r--src/3rdparty/assimp/revision.h4
m---------src/3rdparty/assimp/src0
-rw-r--r--src/3rdparty/assimp/unzip/unzip.h (renamed from src/3rdparty/assimp/contrib/unzip/unzip.h)11
-rw-r--r--src/animation/backend/animationclip.cpp2
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.cpp71
-rw-r--r--src/render/backend/computecommand.cpp3
-rw-r--r--src/render/geometry/qgeometryfactory.h4
-rw-r--r--src/render/geometry/qmesh.cpp2
-rw-r--r--src/render/geometry/qmesh_p.h2
-rw-r--r--src/render/picking/objectpicker.cpp9
-rw-r--r--tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp6
-rw-r--r--tests/auto/render/computecommand/tst_computecommand.cpp16
-rw-r--r--tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp2
-rw-r--r--tests/auto/render/meshfunctors/tst_meshfunctors.cpp6
-rw-r--r--tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp2
597 files changed, 559 insertions, 242966 deletions
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 000000000..46804f477
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/3rdparty/assimp/src"]
+ path = src/3rdparty/assimp/src
+ url = ../qtquick3d-assimp.git
diff --git a/.qmake.conf b/.qmake.conf
index f8a5b3b95..f12bc5230 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -6,4 +6,4 @@ load(qt_build_config)
DEFINES += QT_NO_FOREACH
DEFINES += QT_NO_JAVA_STYLE_ITERATORS
-MODULE_VERSION = 5.15.7
+MODULE_VERSION = 5.15.8
diff --git a/config.tests/assimp/main.cpp b/config.tests/assimp/main.cpp
index 8d5e86f85..8a88e9e1b 100644
--- a/config.tests/assimp/main.cpp
+++ b/config.tests/assimp/main.cpp
@@ -45,5 +45,9 @@ int main(int , char **)
aiAnimation anim;
anim.mNumMorphMeshChannels = 0;
+ // Check for something that was set in a recent version
+ aiMaterial aiM;
+ (void)aiM.GetName();
+
return 0;
}
diff --git a/src/3rdparty/assimp/LICENSE b/src/3rdparty/assimp/LICENSE
index 262606aff..0723ececf 100644
--- a/src/3rdparty/assimp/LICENSE
+++ b/src/3rdparty/assimp/LICENSE
@@ -1,11 +1,6 @@
-Open Asset Import Library (assimp)
-
-Copyright (c) 2006-2016, 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:
+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
@@ -32,47 +27,3 @@ 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.
-
-
-
-******************************************************************************
-
-AN EXCEPTION applies to all files in the ./test/models-nonbsd folder.
-These are 3d models for testing purposes, from various free sources
-on the internet. They are - unless otherwise stated - copyright of
-their respective creators, which may impose additional requirements
-on the use of their work. For any of these models, see
-<model-name>.source.txt for more legal information. Contact us if you
-are a copyright holder and believe that we credited you inproperly or
-if you don't want your files to appear in the repository.
-
-
-******************************************************************************
-
-Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
-http://code.google.com/p/poly2tri/
-
-All rights reserved.
-Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- used to endorse or promote products derived from this software without specific
- prior written permission.
-
-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.
diff --git a/src/3rdparty/assimp/README b/src/3rdparty/assimp/README
deleted file mode 100644
index 24619ab94..000000000
--- a/src/3rdparty/assimp/README
+++ /dev/null
@@ -1 +0,0 @@
-See Readme.md
diff --git a/src/3rdparty/assimp/Readme.md b/src/3rdparty/assimp/Readme.md
deleted file mode 100644
index 1f6c4118f..000000000
--- a/src/3rdparty/assimp/Readme.md
+++ /dev/null
@@ -1,170 +0,0 @@
-Open Asset Import Library (assimp)
-==================================
-A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
-### Current build status ###
-[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
-[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
-<a href="https://scan.coverity.com/projects/5607">
- <img alt="Coverity Scan Build Status"
- src="https://scan.coverity.com/projects/5607/badge.svg"/>
-</a>
-[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
-[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-<br>
-
-APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
-
-Additionally, assimp features various __mesh post processing tools__: 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.
-
-This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
-
-Monthly donations via Patreon:
-<br>[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/assimp)
-
-<br>
-
-One-off donations via PayPal:
-<br>[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4)
-
-<br>
-
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki
-
-#### Supported file formats ####
-
-A full list [is here](http://assimp.org/main_features_formats.html).
-__Importers__:
-- 3D
-- 3DS
-- 3MF
-- AC
-- AC3D
-- ACC
-- AMJ
-- ASE
-- ASK
-- B3D;
-- BLEND (Blender)
-- BVH
-- COB
-- CMS
-- DAE/Collada
-- DXF
-- ENFF
-- FBX
-- glTF 1.0 + GLB
-- glTF 2.0
-- HMB
-- IFC-STEP
-- IRR / IRRMESH
-- LWO
-- LWS
-- LXO
-- MD2
-- MD3
-- MD5
-- MDC
-- MDL
-- MESH / MESH.XML
-- MOT
-- MS3D
-- NDO
-- NFF
-- OBJ
-- OFF
-- OGEX
-- PLY
-- PMX
-- PRJ
-- Q3O
-- Q3S
-- RAW
-- SCN
-- SIB
-- SMD
-- STL
-- STP
-- TER
-- UC
-- VTA
-- X
-- X3D
-- XGL
-- ZGL
-
-Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
-
-- C4D (https://github.com/assimp/assimp/wiki/Cinema4D-&-Melange)
-
-__Exporters__:
-
-- DAE (Collada)
-- STL
-- OBJ
-- PLY
-- X
-- 3DS
-- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
-- ASSBIN
-- STEP
-- glTF 1.0 (partial)
-- glTF 2.0 (partial)
-
-### Building ###
-Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
-
-### Ports ###
-* [Android](port/AndroidJNI/README.md)
-* [Python](port/PyAssimp/README.md)
-* [.NET](port/AssimpNET/Readme.md)
-* [Pascal](port/AssimpPascal/Readme.md)
-* [Javascript (Alpha)](https://github.com/makc/assimp2json)
-* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
-* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (currently supported obj, ply, stl, collada, md2)
-
-### Other tools ###
-[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
-
-#### Repository structure ####
-Open Asset Import Library is implemented in C++. The directory structure is:
-
- /code Source code
- /contrib Third-party libraries
- /doc Documentation (doxysource and pre-compiled docs)
- /include Public header C and C++ header files
- /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 (old assimp viewer, command line `assimp`)
- /samples A small number of samples to illustrate possible
- use cases for Assimp
- /workspaces Build environments for vc,xcode,... (deprecated,
- CMake has superseeded all legacy build options!)
-
-
-### Where to get help ###
-For more information, visit [our website](http://assimp.org/). 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 docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
-
-For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
- [(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
-
-Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
-
-And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
-
-### 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.
-
-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.
-
-### Why this name ###
-Sorry, we're germans :-), no english native speakers ...
diff --git a/src/3rdparty/assimp/assimp.pri b/src/3rdparty/assimp/assimp.pri
index 995f76e68..2ad74b9d6 100644
--- a/src/3rdparty/assimp/assimp.pri
+++ b/src/3rdparty/assimp/assimp.pri
@@ -12,13 +12,57 @@ else: \
QT_PRIVATE += zlib-private
DEFINES += \
- ASSIMP_BUILD_NO_OWN_ZLIB \
- ASSIMP_BUILD_NO_COMPRESSED_IFC \
- ASSIMP_BUILD_NO_Q3BSP_IMPORTER \
- ASSIMP_BUILD_NO_C4D_IMPORTER \
- ASSIMP_BUILD_NO_3MF_IMPORTER \
- OPENDDL_STATIC_LIBARY \
- NOUNCRYPT
+ ASSIMP_BUILD_NO_X_IMPORTER \
+ ASSIMP_BUILD_NO_AMF_IMPORTER \
+ ASSIMP_BUILD_NO_3DS_IMPORTER \
+ ASSIMP_BUILD_NO_MD3_IMPORTER \
+ ASSIMP_BUILD_NO_MDL_IMPORTER \
+ ASSIMP_BUILD_NO_MD2_IMPORTER \
+ ASSIMP_BUILD_NO_PLY_IMPORTER \
+ ASSIMP_BUILD_NO_ASE_IMPORTER \
+ ASSIMP_BUILD_NO_HMP_IMPORTER \
+ ASSIMP_BUILD_NO_SMD_IMPORTER \
+ ASSIMP_BUILD_NO_MDC_IMPORTER \
+ ASSIMP_BUILD_NO_MD5_IMPORTER \
+ ASSIMP_BUILD_NO_STL_IMPORTER \
+ ASSIMP_BUILD_NO_LWO_IMPORTER \
+ ASSIMP_BUILD_NO_DXF_IMPORTER \
+ ASSIMP_BUILD_NO_NFF_IMPORTER \
+ ASSIMP_BUILD_NO_RAW_IMPORTER \
+ ASSIMP_BUILD_NO_SIB_IMPORTER \
+ ASSIMP_BUILD_NO_OFF_IMPORTER \
+ ASSIMP_BUILD_NO_AC_IMPORTER \
+ ASSIMP_BUILD_NO_BVH_IMPORTER \
+ ASSIMP_BUILD_NO_IRRMESH_IMPORTER \
+ ASSIMP_BUILD_NO_IRR_IMPORTER \
+ ASSIMP_BUILD_NO_Q3D_IMPORTER \
+ ASSIMP_BUILD_NO_B3D_IMPORTER \
+ ASSIMP_BUILD_NO_TERRAGEN_IMPORTER \
+ ASSIMP_BUILD_NO_CSM_IMPORTER \
+ ASSIMP_BUILD_NO_3D_IMPORTER \
+ ASSIMP_BUILD_NO_LWS_IMPORTER \
+ ASSIMP_BUILD_NO_OGRE_IMPORTER \
+ ASSIMP_BUILD_NO_OPENGEX_IMPORTER \
+ ASSIMP_BUILD_NO_MS3D_IMPORTER \
+ ASSIMP_BUILD_NO_COB_IMPORTER \
+ ASSIMP_BUILD_NO_Q3BSP_IMPORTER \
+ ASSIMP_BUILD_NO_NDO_IMPORTER \
+ ASSIMP_BUILD_NO_IFC_IMPORTER \
+ ASSIMP_BUILD_NO_XGL_IMPORTER \
+ ASSIMP_BUILD_NO_ASSBIN_IMPORTER \
+ ASSIMP_BUILD_NO_C4D_IMPORTER \
+ ASSIMP_BUILD_NO_3MF_IMPORTER \
+ ASSIMP_BUILD_NO_X3D_IMPORTER \
+ ASSIMP_BUILD_NO_MMD_IMPORTER \
+ ASSIMP_BUILD_NO_STEP_IMPORTER \
+ ASSIMP_BUILD_NO_OWN_ZLIB \
+ ASSIMP_BUILD_NO_COMPRESSED_IFC \
+ ASSIMP_BUILD_NO_EXPORT \
+ ASSIMP_BUILD_BOOST_WORKAROUND \
+ OPENDDL_STATIC_LIBARY \
+ NOUNCRYPT
+
+win32: DEFINES += WindowsStore
intel_icc: {
# warning #310: old-style parameter list (anachronism)
@@ -58,556 +102,344 @@ msvc: QMAKE_CXXFLAGS += /bigobj
CONFIG += warn_on
VPATH += \
- $$PWD \
- $$PWD/code \
- $$PWD/code/res \
- $$PWD/contrib/clipper \
- $$PWD/contrib/ConvertUTF \
- $$PWD/contrib/irrXML \
- $$PWD/contrib/unzip
+ $$PWD/src \
+ $$PWD/src/code \
+ $$PWD/src/code/res
INCLUDEPATH += \
$$PWD \
- $$PWD/code \
- $$PWD/include \
- $$PWD/include/assimp/Compiler \
- $$PWD/contrib/clipper \
- $$PWD/contrib/ConvertUTF \
- $$PWD/contrib/irrXML \
- $$PWD/contrib/openddlparser/include \
- $$PWD/contrib/poly2tri/poly2tri \
- $$PWD/contrib/rapidjson/include \
- $$PWD/contrib/unzip
+ $$PWD/.. \
+ $$PWD/src \
+ $$PWD/src/code \
+ $$PWD/src/code/Common \
+ $$PWD/src/code/Collada \
+ $$PWD/src/code/Material \
+ $$PWD/src/code/Obj \
+ $$PWD/src/code/Blender \
+ $$PWD/src/code/FBX \
+ $$PWD/src/code/PostProcessing \
+ $$PWD/src/code/glTF \
+ $$PWD/src/code/glTF2 \
+ $$PWD/src/code/CApi \
+ $$PWD/src/include \
+ $$PWD/src/include/assimp/Compiler
+
+HEADERS += \
+ $$PWD/config.h \
+ $$PWD/revision.h
+
+HEADERS += \
+ $$PWD/src/include/assimp/Compiler/pushpack1.h \
+ $$PWD/src/include/assimp/Compiler/poppack1.h \
+ $$PWD/src/include/assimp/Compiler/pstdint.h \
+ $$PWD/src/include/assimp/anim.h \
+ $$PWD/src/include/assimp/ai_assert.h \
+ $$PWD/src/include/assimp/camera.h \
+ $$PWD/src/include/assimp/color4.h \
+ $$PWD/src/include/assimp/color4.inl \
+ $$PWD/src/include/assimp/defs.h \
+ $$PWD/src/include/assimp/Defines.h \
+ $$PWD/src/include/assimp/cfileio.h \
+ $$PWD/src/include/assimp/light.h \
+ $$PWD/src/include/assimp/material.h \
+ $$PWD/src/include/assimp/material.inl \
+ $$PWD/src/include/assimp/matrix3x3.h \
+ $$PWD/src/include/assimp/matrix3x3.inl \
+ $$PWD/src/include/assimp/matrix4x4.h \
+ $$PWD/src/include/assimp/matrix4x4.inl \
+ $$PWD/src/include/assimp/mesh.h \
+ $$PWD/src/include/assimp/pbrmaterial.h \
+ $$PWD/src/include/assimp/postprocess.h \
+ $$PWD/src/include/assimp/quaternion.h \
+ $$PWD/src/include/assimp/quaternion.inl \
+ $$PWD/src/include/assimp/scene.h \
+ $$PWD/src/include/assimp/metadata.h \
+ $$PWD/src/include/assimp/texture.h \
+ $$PWD/src/include/assimp/types.h \
+ $$PWD/src/include/assimp/vector2.h \
+ $$PWD/src/include/assimp/vector2.inl \
+ $$PWD/src/include/assimp/vector3.h \
+ $$PWD/src/include/assimp/vector3.inl \
+ $$PWD/src/include/assimp/version.h \
+ $$PWD/src/include/assimp/cimport.h \
+ $$PWD/src/include/assimp/importerdesc.h \
+ $$PWD/src/include/assimp/Importer.hpp \
+ $$PWD/src/include/assimp/DefaultLogger.hpp \
+ $$PWD/src/include/assimp/ProgressHandler.hpp \
+ $$PWD/src/include/assimp/IOStream.hpp \
+ $$PWD/src/include/assimp/IOSystem.hpp \
+ $$PWD/src/include/assimp/Logger.hpp \
+ $$PWD/src/include/assimp/LogStream.hpp \
+ $$PWD/src/include/assimp/NullLogger.hpp \
+ $$PWD/src/include/assimp/cexport.h \
+ $$PWD/src/include/assimp/Exporter.hpp \
+ $$PWD/src/include/assimp/DefaultIOStream.h \
+ $$PWD/src/include/assimp/DefaultIOSystem.h \
+ $$PWD/src/include/assimp/SceneCombiner.h \
+ $$PWD/src/include/assimp/fast_atof.h \
+ $$PWD/src/include/assimp/qnan.h \
+ $$PWD/src/include/assimp/BaseImporter.h \
+ $$PWD/src/include/assimp/Hash.h \
+ $$PWD/src/include/assimp/MemoryIOWrapper.h \
+ $$PWD/src/include/assimp/ParsingUtils.h \
+ $$PWD/src/include/assimp/StreamReader.h \
+ $$PWD/src/include/assimp/StreamWriter.h \
+ $$PWD/src/include/assimp/StringComparison.h \
+ $$PWD/src/include/assimp/StringUtils.h \
+ $$PWD/src/include/assimp/SGSpatialSort.h \
+ $$PWD/src/include/assimp/GenericProperty.h \
+ $$PWD/src/include/assimp/SpatialSort.h \
+ $$PWD/src/include/assimp/SkeletonMeshBuilder.h \
+ $$PWD/src/include/assimp/SmoothingGroups.h \
+ $$PWD/src/include/assimp/SmoothingGroups.inl \
+ $$PWD/src/include/assimp/StandardShapes.h \
+ $$PWD/src/include/assimp/RemoveComments.h \
+ $$PWD/src/include/assimp/Subdivision.h \
+ $$PWD/src/include/assimp/Vertex.h \
+ $$PWD/src/include/assimp/LineSplitter.h \
+ $$PWD/src/include/assimp/TinyFormatter.h \
+ $$PWD/src/include/assimp/Profiler.h \
+ $$PWD/src/include/assimp/LogAux.h \
+ $$PWD/src/include/assimp/Bitmap.h \
+ $$PWD/src/include/assimp/XMLTools.h \
+ $$PWD/src/include/assimp/IOStreamBuffer.h \
+ $$PWD/src/include/assimp/CreateAnimMesh.h \
+ $$PWD/src/include/assimp/irrXMLWrapper.h \
+ $$PWD/src/include/assimp/BlobIOSystem.h \
+ $$PWD/src/include/assimp/MathFunctions.h \
+ $$PWD/src/include/assimp/Macros.h \
+ $$PWD/src/include/assimp/Exceptional.h \
+ $$PWD/src/include/assimp/ByteSwapper.h \
+ $$PWD/src/include/assimp/DefaultLogger.hpp \
+ $$PWD/src/include/assimp/LogStream.hpp \
+ $$PWD/src/include/assimp/Logger.hpp \
+ $$PWD/src/include/assimp/NullLogger.hpp \
+ $$PWD/src/include/assimp/ZipArchiveIOSystem.h \
+ $$PWD/src/code/Common/FileLogStream.h \
+ $$PWD/src/code/Common/StdOStreamLogStream.h \
+ $$PWD/src/code/Common/BaseProcess.h \
+ $$PWD/src/code/Common/Importer.h \
+ $$PWD/src/code/Common/ScenePrivate.h \
+ $$PWD/src/code/Common/DefaultProgressHandler.h \
+ $$PWD/src/code/CApi/CInterfaceIOWrapper.h \
+ $$PWD/src/code/Common/IFF.h \
+ $$PWD/src/code/Common/VertexTriangleAdjacency.h \
+ $$PWD/src/code/Common/ScenePreprocessor.h \
+ $$PWD/src/code/Common/SplitByBoneCountProcess.h \
+ $$PWD/src/code/Common/TargetAnimation.h \
+ $$PWD/src/code/Common/simd.h \
+ $$PWD/src/code/Collada/ColladaHelper.h \
+ $$PWD/src/code/Collada/ColladaLoader.h \
+ $$PWD/src/code/Collada/ColladaParser.h \
+ $$PWD/src/code/Material/MaterialSystem.h \
+ $$PWD/src/code/Obj/ObjFileData.h \
+ $$PWD/src/code/Obj/ObjFileImporter.h \
+ $$PWD/src/code/Obj/ObjFileMtlImporter.h \
+ $$PWD/src/code/Obj/ObjFileParser.h \
+ $$PWD/src/code/Obj/ObjTools.h \
+ $$PWD/src/code/Blender/BlenderLoader.h \
+ $$PWD/src/code/Blender/BlenderDNA.h \
+ $$PWD/src/code/Blender/BlenderDNA.inl \
+ $$PWD/src/code/Blender/BlenderScene.h \
+ $$PWD/src/code/Blender/BlenderSceneGen.h \
+ $$PWD/src/code/Blender/BlenderIntermediate.h \
+ $$PWD/src/code/Blender/BlenderModifier.h \
+ $$PWD/src/code/Blender/BlenderBMesh.h \
+ $$PWD/src/code/Blender/BlenderTessellator.h \
+ $$PWD/src/code/Blender/BlenderCustomData.h \
+ $$PWD/src/code/FBX/FBXCompileConfig.h \
+ $$PWD/src/code/FBX/FBXImporter.h \
+ $$PWD/src/code/FBX/FBXParser.h \
+ $$PWD/src/code/FBX/FBXTokenizer.h \
+ $$PWD/src/code/FBX/FBXImportSettings.h \
+ $$PWD/src/code/FBX/FBXConverter.h \
+ $$PWD/src/code/FBX/FBXUtil.h \
+ $$PWD/src/code/FBX/FBXDocument.h \
+ $$PWD/src/code/FBX/FBXProperties.h \
+ $$PWD/src/code/FBX/FBXMeshGeometry.h \
+ $$PWD/src/code/FBX/FBXCommon.h \
+ $$PWD/src/code/PostProcessing/CalcTangentsProcess.h \
+ $$PWD/src/code/PostProcessing/ComputeUVMappingProcess.h \
+ $$PWD/src/code/PostProcessing/ConvertToLHProcess.h \
+ $$PWD/src/code/PostProcessing/EmbedTexturesProcess.h \
+ $$PWD/src/code/PostProcessing/FindDegenerates.h \
+ $$PWD/src/code/PostProcessing/FindInstancesProcess.h \
+ $$PWD/src/code/PostProcessing/FindInvalidDataProcess.h \
+ $$PWD/src/code/PostProcessing/FixNormalsStep.h \
+ $$PWD/src/code/PostProcessing/DropFaceNormalsProcess.h \
+ $$PWD/src/code/PostProcessing/GenBoundingBoxesProcess.h \
+ $$PWD/src/code/PostProcessing/GenFaceNormalsProcess.h \
+ $$PWD/src/code/PostProcessing/GenVertexNormalsProcess.h \
+ $$PWD/src/code/PostProcessing/PretransformVertices.h \
+ $$PWD/src/code/PostProcessing/ImproveCacheLocality.h \
+ $$PWD/src/code/PostProcessing/JoinVerticesProcess.h \
+ $$PWD/src/code/PostProcessing/LimitBoneWeightsProcess.h \
+ $$PWD/src/code/PostProcessing/RemoveRedundantMaterials.h \
+ $$PWD/src/code/PostProcessing/RemoveVCProcess.h \
+ $$PWD/src/code/PostProcessing/SortByPTypeProcess.h \
+ $$PWD/src/code/PostProcessing/SplitLargeMeshes.h \
+ $$PWD/src/code/PostProcessing/TextureTransform.h \
+ $$PWD/src/code/PostProcessing/TriangulateProcess.h \
+ $$PWD/src/code/PostProcessing/ValidateDataStructure.h \
+ $$PWD/src/code/PostProcessing/OptimizeGraph.h \
+ $$PWD/src/code/PostProcessing/OptimizeMeshes.h \
+ $$PWD/src/code/PostProcessing/DeboneProcess.h \
+ $$PWD/src/code/PostProcessing/ProcessHelper.h \
+ $$PWD/src/code/Common/PolyTools.h \
+ $$PWD/src/code/PostProcessing/MakeVerboseFormat.h \
+ $$PWD/src/code/PostProcessing/ScaleProcess.h \
+ $$PWD/src/code/glTF/glTFAsset.h \
+ $$PWD/src/code/glTF/glTFAsset.inl \
+ $$PWD/src/code/glTF/glTFAssetWriter.inl \
+ $$PWD/src/code/glTF/glTFAssetWriter.h \
+ $$PWD/src/code/glTF/glTFImporter.h \
+ $$PWD/src/code/glTF/glTFCommon.h \
+ $$PWD/src/code/glTF2/glTF2AssetWriter.h \
+ $$PWD/src/code/glTF2/glTF2Asset.h \
+ $$PWD/src/code/glTF2/glTF2Asset.inl \
+ $$PWD/src/code/glTF2/glTF2AssetWriter.inl \
+ $$PWD/src/code/glTF2/glTF2Importer.h
+
+SOURCES += \
+ $$PWD/src/code/Common/Assimp.cpp \
+ $$PWD/src/code/Common/DefaultLogger.cpp \
+ $$PWD/src/code/Common/BaseImporter.cpp \
+ $$PWD/src/code/Common/BaseProcess.cpp \
+ $$PWD/src/code/Common/PostStepRegistry.cpp \
+ $$PWD/src/code/Common/ImporterRegistry.cpp \
+ $$PWD/src/code/Common/DefaultIOStream.cpp \
+ $$PWD/src/code/Common/DefaultIOSystem.cpp \
+ $$PWD/src/code/CApi/CInterfaceIOWrapper.cpp \
+ $$PWD/src/code/Common/Importer.cpp \
+ $$PWD/src/code/Common/SGSpatialSort.cpp \
+ $$PWD/src/code/Common/VertexTriangleAdjacency.cpp \
+ $$PWD/src/code/Common/SpatialSort.cpp \
+ $$PWD/src/code/Common/SceneCombiner.cpp \
+ $$PWD/src/code/Common/ScenePreprocessor.cpp \
+ $$PWD/src/code/Common/SkeletonMeshBuilder.cpp \
+ $$PWD/src/code/Common/SplitByBoneCountProcess.cpp \
+ $$PWD/src/code/Common/StandardShapes.cpp \
+ $$PWD/src/code/Common/TargetAnimation.cpp \
+ $$PWD/src/code/Common/RemoveComments.cpp \
+ $$PWD/src/code/Common/Subdivision.cpp \
+ $$PWD/src/code/Common/scene.cpp \
+ $$PWD/src/code/Common/Bitmap.cpp \
+ $$PWD/src/code/Common/Version.cpp \
+ $$PWD/src/code/Common/CreateAnimMesh.cpp \
+ $$PWD/src/code/Common/simd.cpp \
+ $$PWD/src/code/Common/ZipArchiveIOSystem.cpp \
+ $$PWD/src/code/Collada/ColladaLoader.cpp \
+ $$PWD/src/code/Collada/ColladaParser.cpp \
+ $$PWD/src/code/Material/MaterialSystem.cpp \
+ $$PWD/src/code/Obj/ObjFileImporter.cpp \
+ $$PWD/src/code/Obj/ObjFileMtlImporter.cpp \
+ $$PWD/src/code/Obj/ObjFileParser.cpp \
+ $$PWD/src/code/Blender/BlenderLoader.cpp \
+ $$PWD/src/code/Blender/BlenderDNA.cpp \
+ $$PWD/src/code/Blender/BlenderScene.cpp \
+ $$PWD/src/code/Blender/BlenderModifier.cpp \
+ $$PWD/src/code/Blender/BlenderBMesh.cpp \
+ $$PWD/src/code/Blender/BlenderTessellator.cpp \
+ $$PWD/src/code/Blender/BlenderCustomData.cpp \
+ $$PWD/src/code/FBX/FBXImporter.cpp \
+ $$PWD/src/code/FBX/FBXParser.cpp \
+ $$PWD/src/code/FBX/FBXTokenizer.cpp \
+ $$PWD/src/code/FBX/FBXConverter.cpp \
+ $$PWD/src/code/FBX/FBXUtil.cpp \
+ $$PWD/src/code/FBX/FBXDocument.cpp \
+ $$PWD/src/code/FBX/FBXProperties.cpp \
+ $$PWD/src/code/FBX/FBXMeshGeometry.cpp \
+ $$PWD/src/code/FBX/FBXMaterial.cpp \
+ $$PWD/src/code/FBX/FBXModel.cpp \
+ $$PWD/src/code/FBX/FBXAnimation.cpp \
+ $$PWD/src/code/FBX/FBXNodeAttribute.cpp \
+ $$PWD/src/code/FBX/FBXDeformer.cpp \
+ $$PWD/src/code/FBX/FBXBinaryTokenizer.cpp \
+ $$PWD/src/code/FBX/FBXDocumentUtil.cpp \
+ $$PWD/src/code/PostProcessing/CalcTangentsProcess.cpp \
+ $$PWD/src/code/PostProcessing/ComputeUVMappingProcess.cpp \
+ $$PWD/src/code/PostProcessing/ConvertToLHProcess.cpp \
+ $$PWD/src/code/PostProcessing/EmbedTexturesProcess.cpp \
+ $$PWD/src/code/PostProcessing/FindDegenerates.cpp \
+ $$PWD/src/code/PostProcessing/FindInstancesProcess.cpp \
+ $$PWD/src/code/PostProcessing/FindInvalidDataProcess.cpp \
+ $$PWD/src/code/PostProcessing/FixNormalsStep.cpp \
+ $$PWD/src/code/PostProcessing/DropFaceNormalsProcess.cpp \
+ $$PWD/src/code/PostProcessing/GenBoundingBoxesProcess.cpp \
+ $$PWD/src/code/PostProcessing/GenFaceNormalsProcess.cpp \
+ $$PWD/src/code/PostProcessing/GenVertexNormalsProcess.cpp \
+ $$PWD/src/code/PostProcessing/PretransformVertices.cpp \
+ $$PWD/src/code/PostProcessing/ImproveCacheLocality.cpp \
+ $$PWD/src/code/PostProcessing/JoinVerticesProcess.cpp \
+ $$PWD/src/code/PostProcessing/LimitBoneWeightsProcess.cpp \
+ $$PWD/src/code/PostProcessing/RemoveRedundantMaterials.cpp \
+ $$PWD/src/code/PostProcessing/RemoveVCProcess.cpp \
+ $$PWD/src/code/PostProcessing/SortByPTypeProcess.cpp \
+ $$PWD/src/code/PostProcessing/SplitLargeMeshes.cpp \
+ $$PWD/src/code/PostProcessing/TextureTransform.cpp \
+ $$PWD/src/code/PostProcessing/TriangulateProcess.cpp \
+ $$PWD/src/code/PostProcessing/ValidateDataStructure.cpp \
+ $$PWD/src/code/PostProcessing/OptimizeGraph.cpp \
+ $$PWD/src/code/PostProcessing/OptimizeMeshes.cpp \
+ $$PWD/src/code/PostProcessing/DeboneProcess.cpp \
+ $$PWD/src/code/PostProcessing/ProcessHelper.cpp \
+ $$PWD/src/code/PostProcessing/MakeVerboseFormat.cpp \
+ $$PWD/src/code/PostProcessing/ScaleProcess.cpp \
+ $$PWD/src/code/glTF/glTFImporter.cpp \
+ $$PWD/src/code/glTF/glTFCommon.cpp \
+ $$PWD/src/code/glTF2/glTF2Importer.cpp
+
+# IrrXML (needed for DAE/Collada support)
+HEADERS += \
+ $$PWD/src/contrib/irrXML/CXMLReaderImpl.h \
+ $$PWD/src/contrib/irrXML/heapsort.h \
+ $$PWD/src/contrib/irrXML/irrArray.h \
+ $$PWD/src/contrib/irrXML/irrString.h \
+ $$PWD/src/contrib/irrXML/irrTypes.h \
+ $$PWD/src/contrib/irrXML/irrXML.h
+
+SOURCES += $$PWD/src/contrib/irrXML/irrXML.cpp
+
+VPATH += $$PWD/src/contrib/irrXML
+INCLUDEPATH += $$PWD/src/contrib/irrXML
+
+msvc: DEFINES += _SCL_SECURE_NO_WARNINGS _CRT_SECURE_NO_WARNINGS
+
+# rapidjson (needed for GLTF/GLTF2)
+VPATH += $$PWD/src/contrib/rapidjson/include
+INCLUDEPATH += $$PWD/src/contrib/rapidjson/include
+
+# utf8cpp
+VPATH += $$PWD/src/contrib/utf8cpp/source
+INCLUDEPATH += $$PWD/src/contrib/utf8cpp/source
+
+# poly2tri (blender tessellator)
+VPATH += $$PWD/src/contrib/poly2tri
+INCLUDEPATH += $$PWD/src/contrib/poly2tri
+
+HEADERS += \
+ $$PWD/src/contrib/poly2tri/poly2tri/common/shapes.h \
+ $$PWD/src/contrib/poly2tri/poly2tri/common/utils.h \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/advancing_front.h \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/cdt.h \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/sweep.h \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/sweep_context.h
+
+SOURCES += \
+ $$PWD/src/contrib/poly2tri/poly2tri/common/shapes.cc \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/advancing_front.cc \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/cdt.cc \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/sweep.cc \
+ $$PWD/src/contrib/poly2tri/poly2tri/sweep/sweep_context.cc
-# Input
-HEADERS += revision.h \
- code/3DSExporter.h \
- code/3DSHelper.h \
- code/3DSLoader.h \
- code/3MFXmlTags.h \
- code/ACLoader.h \
- code/ASELoader.h \
- code/ASEParser.h \
- code/AssbinExporter.h \
- code/AssbinLoader.h \
- code/AssxmlExporter.h \
- code/B3DImporter.h \
- code/BVHLoader.h \
- code/BaseImporter.h \
- code/BaseProcess.h \
- code/Bitmap.h \
- code/BlenderBMesh.h \
- code/BlenderDNA.h \
- code/BlenderIntermediate.h \
- code/BlenderLoader.h \
- code/BlenderModifier.h \
- code/BlenderScene.h \
- code/BlenderSceneGen.h \
- code/BlenderTessellator.h \
- code/BlobIOSystem.h \
- code/ByteSwapper.h \
- code/C4DImporter.h \
- code/CInterfaceIOWrapper.h \
- code/COBLoader.h \
- code/COBScene.h \
- code/CSMLoader.h \
- code/CalcTangentsProcess.h \
- code/ColladaExporter.h \
- code/ColladaHelper.h \
- code/ColladaLoader.h \
- code/ColladaParser.h \
- code/ComputeUVMappingProcess.h \
- code/ConvertToLHProcess.h \
- code/CreateAnimMesh.h \
- code/D3MFExporter.h \
- code/D3MFImporter.h \
- code/D3MFOpcPackage.h \
- code/DXFHelper.h \
- code/DXFLoader.h \
- code/DeboneProcess.h \
- code/DefaultProgressHandler.h \
- code/Exceptional.h \
- code/FBXCompileConfig.h \
- code/FBXConverter.h \
- code/FBXDocument.h \
- code/FBXDocumentUtil.h \
- code/FBXImportSettings.h \
- code/FBXImporter.h \
- code/FBXMeshGeometry.h \
- code/FBXParser.h \
- code/FBXProperties.h \
- code/FBXTokenizer.h \
- code/FBXUtil.h \
- code/FileLogStream.h \
- code/FileSystemFilter.h \
- code/FindDegenerates.h \
- code/FindInstancesProcess.h \
- code/FindInvalidDataProcess.h \
- code/FixNormalsStep.h \
- code/GenFaceNormalsProcess.h \
- code/GenVertexNormalsProcess.h \
- code/GenericProperty.h \
- code/HMPFileData.h \
- code/HMPLoader.h \
- code/HalfLifeFileData.h \
- code/Hash.h \
- code/IFCLoader.h \
- code/IFCReaderGen.h \
- code/IFCUtil.h \
- code/IFF.h \
- code/IOStreamBuffer.h \
- code/IRRLoader.h \
- code/IRRMeshLoader.h \
- code/IRRShared.h \
- code/Importer.h \
- code/ImproveCacheLocality.h \
- code/JoinVerticesProcess.h \
- code/LWOAnimation.h \
- code/LWOFileData.h \
- code/LWOLoader.h \
- code/LWSLoader.h \
- code/LimitBoneWeightsProcess.h \
- code/LineSplitter.h \
- code/LogAux.h \
- code/MD2FileData.h \
- code/MD2Loader.h \
- code/MD2NormalTable.h \
- code/MD3FileData.h \
- code/MD3Loader.h \
- code/MD4FileData.h \
- code/MD5Loader.h \
- code/MD5Parser.h \
- code/MDCFileData.h \
- code/MDCLoader.h \
- code/MDCNormalTable.h \
- code/MDLDefaultColorMap.h \
- code/MDLFileData.h \
- code/MDLLoader.h \
- code/MMDCpp14.h \
- code/MMDImporter.h \
- code/MMDPmdParser.h \
- code/MMDPmxParser.h \
- code/MMDVmdParser.h \
- code/MS3DLoader.h \
- code/Macros.h \
- code/MakeVerboseFormat.h \
- code/MaterialSystem.h \
- code/MathFunctions.h \
- code/MemoryIOWrapper.h \
- code/NDOLoader.h \
- code/NFFLoader.h \
- code/OFFLoader.h \
- code/ObjExporter.h \
- code/ObjFileData.h \
- code/ObjFileImporter.h \
- code/ObjFileMtlImporter.h \
- code/ObjFileParser.h \
- code/ObjTools.h \
- code/OgreBinarySerializer.h \
- code/OgreImporter.h \
- code/OgreParsingUtils.h \
- code/OgreStructs.h \
- code/OgreXmlSerializer.h \
- code/OpenGEXExporter.h \
- code/OpenGEXImporter.h \
- code/OpenGEXStructs.h \
- code/OptimizeGraph.h \
- code/OptimizeMeshes.h \
- code/ParsingUtils.h \
- code/PlyExporter.h \
- code/PlyLoader.h \
- code/PlyParser.h \
- code/PolyTools.h \
- code/PretransformVertices.h \
- code/ProcessHelper.h \
- code/Profiler.h \
- code/Q3BSPFileData.h \
- code/Q3BSPFileImporter.h \
- code/Q3BSPFileParser.h \
- code/Q3BSPZipArchive.h \
- code/Q3DLoader.h \
- code/RawLoader.h \
- code/RemoveComments.h \
- code/RemoveRedundantMaterials.h \
- code/RemoveVCProcess.h \
- code/SGSpatialSort.h \
- code/SIBImporter.h \
- code/SMDLoader.h \
- code/STEPFile.h \
- code/STEPFileEncoding.h \
- code/STEPFileReader.h \
- code/STLExporter.h \
- code/STLLoader.h \
- code/ScaleProcess.h \
- code/ScenePreprocessor.h \
- code/ScenePrivate.h \
- code/SkeletonMeshBuilder.h \
- code/SmoothingGroups.h \
- code/SortByPTypeProcess.h \
- code/SpatialSort.h \
- code/SplitByBoneCountProcess.h \
- code/SplitLargeMeshes.h \
- code/StandardShapes.h \
- code/StdOStreamLogStream.h \
- code/StepExporter.h \
- code/StreamReader.h \
- code/StreamWriter.h \
- code/StringComparison.h \
- code/StringUtils.h \
- code/Subdivision.h \
- code/TargetAnimation.h \
- code/TerragenLoader.h \
- code/TextureTransform.h \
- code/TinyFormatter.h \
- code/TriangulateProcess.h \
- code/UnrealLoader.h \
- code/ValidateDataStructure.h \
- code/Vertex.h \
- code/VertexTriangleAdjacency.h \
- code/Win32DebugLogStream.h \
- code/XFileExporter.h \
- code/XFileHelper.h \
- code/XFileImporter.h \
- code/XFileParser.h \
- code/XGLLoader.h \
- code/XMLTools.h \
- code/assbin_chunks.h \
- code/fast_atof.h \
- code/glTF2Asset.h \
- code/glTF2AssetWriter.h \
- code/glTF2Exporter.h \
- code/glTF2Importer.h \
- code/glTFAsset.h \
- code/glTFAssetWriter.h \
- code/glTFExporter.h \
- code/glTFImporter.h \
- code/irrXMLWrapper.h \
- code/qnan.h \
- code/res/resource.h \
- contrib/Open3DGC/o3dgcAdjacencyInfo.h \
- contrib/Open3DGC/o3dgcArithmeticCodec.h \
- contrib/Open3DGC/o3dgcBinaryStream.h \
- contrib/Open3DGC/o3dgcCommon.h \
- contrib/Open3DGC/o3dgcDVEncodeParams.h \
- contrib/Open3DGC/o3dgcDynamicVector.h \
- contrib/Open3DGC/o3dgcDynamicVectorDecoder.h \
- contrib/Open3DGC/o3dgcDynamicVectorEncoder.h \
- contrib/Open3DGC/o3dgcFIFO.h \
- contrib/Open3DGC/o3dgcIndexedFaceSet.h \
- contrib/Open3DGC/o3dgcSC3DMCDecoder.h \
- contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h \
- contrib/Open3DGC/o3dgcSC3DMCEncoder.h \
- contrib/Open3DGC/o3dgcTimer.h \
- contrib/Open3DGC/o3dgcTriangleFans.h \
- contrib/Open3DGC/o3dgcTriangleListDecoder.h \
- contrib/Open3DGC/o3dgcTriangleListEncoder.h \
- contrib/Open3DGC/o3dgcVector.h \
- contrib/clipper/clipper.hpp \
- contrib/irrXML/CXMLReaderImpl.h \
- contrib/irrXML/heapsort.h \
- contrib/irrXML/irrArray.h \
- contrib/irrXML/irrString.h \
- contrib/irrXML/irrTypes.h \
- contrib/irrXML/irrXML.h \
- contrib/openddlparser/include/openddlparser/DDLNode.h \
- contrib/openddlparser/include/openddlparser/OpenDDLCommon.h \
- contrib/openddlparser/include/openddlparser/OpenDDLExport.h \
- contrib/openddlparser/include/openddlparser/OpenDDLParser.h \
- contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h \
- contrib/openddlparser/include/openddlparser/OpenDDLStream.h \
- contrib/openddlparser/include/openddlparser/Value.h \
- contrib/poly2tri/poly2tri/common/shapes.h \
- contrib/poly2tri/poly2tri/common/utils.h \
- contrib/poly2tri/poly2tri/poly2tri.h \
- contrib/poly2tri/poly2tri/sweep/advancing_front.h \
- contrib/poly2tri/poly2tri/sweep/cdt.h \
- contrib/poly2tri/poly2tri/sweep/sweep.h \
- contrib/poly2tri/poly2tri/sweep/sweep_context.h \
- contrib/rapidjson/include/rapidjson/allocators.h \
- contrib/rapidjson/include/rapidjson/document.h \
- contrib/rapidjson/include/rapidjson/encodedstream.h \
- contrib/rapidjson/include/rapidjson/encodings.h \
- contrib/rapidjson/include/rapidjson/error/en.h \
- contrib/rapidjson/include/rapidjson/error/error.h \
- contrib/rapidjson/include/rapidjson/filereadstream.h \
- contrib/rapidjson/include/rapidjson/filewritestream.h \
- contrib/rapidjson/include/rapidjson/fwd.h \
- contrib/rapidjson/include/rapidjson/internal/biginteger.h \
- contrib/rapidjson/include/rapidjson/internal/diyfp.h \
- contrib/rapidjson/include/rapidjson/internal/dtoa.h \
- contrib/rapidjson/include/rapidjson/internal/ieee754.h \
- contrib/rapidjson/include/rapidjson/internal/itoa.h \
- contrib/rapidjson/include/rapidjson/internal/meta.h \
- contrib/rapidjson/include/rapidjson/internal/pow10.h \
- contrib/rapidjson/include/rapidjson/internal/regex.h \
- contrib/rapidjson/include/rapidjson/internal/stack.h \
- contrib/rapidjson/include/rapidjson/internal/strfunc.h \
- contrib/rapidjson/include/rapidjson/internal/strtod.h \
- contrib/rapidjson/include/rapidjson/internal/swap.h \
- contrib/rapidjson/include/rapidjson/istreamwrapper.h \
- contrib/rapidjson/include/rapidjson/memorybuffer.h \
- contrib/rapidjson/include/rapidjson/memorystream.h \
- contrib/rapidjson/include/rapidjson/msinttypes/inttypes.h \
- contrib/rapidjson/include/rapidjson/msinttypes/stdint.h \
- contrib/rapidjson/include/rapidjson/ostreamwrapper.h \
- contrib/rapidjson/include/rapidjson/pointer.h \
- contrib/rapidjson/include/rapidjson/prettywriter.h \
- contrib/rapidjson/include/rapidjson/rapidjson.h \
- contrib/rapidjson/include/rapidjson/reader.h \
- contrib/rapidjson/include/rapidjson/schema.h \
- contrib/rapidjson/include/rapidjson/stream.h \
- contrib/rapidjson/include/rapidjson/stringbuffer.h \
- contrib/rapidjson/include/rapidjson/writer.h \
- contrib/unzip/crypt.h \
- contrib/unzip/ioapi.h \
- contrib/unzip/unzip.h \
- contrib/utf8cpp/source/utf8.h \
- contrib/utf8cpp/source/utf8/checked.h \
- contrib/utf8cpp/source/utf8/core.h \
- contrib/utf8cpp/source/utf8/unchecked.h \
- include/assimp/Compiler/poppack1.h \
- include/assimp/Compiler/pstdint.h \
- include/assimp/Compiler/pushpack1.h \
- include/assimp/DefaultIOStream.h \
- include/assimp/DefaultIOSystem.h \
- include/assimp/DefaultLogger.hpp \
- include/assimp/Defines.h \
- include/assimp/Exporter.hpp \
- include/assimp/IOStream.hpp \
- include/assimp/IOSystem.hpp \
- include/assimp/Importer.hpp \
- include/assimp/LogStream.hpp \
- include/assimp/Logger.hpp \
- include/assimp/NullLogger.hpp \
- include/assimp/ProgressHandler.hpp \
- include/assimp/SceneCombiner.h \
- include/assimp/ai_assert.h \
- include/assimp/anim.h \
- include/assimp/camera.h \
- include/assimp/cexport.h \
- include/assimp/cfileio.h \
- include/assimp/cimport.h \
- include/assimp/color4.h \
- include/assimp/config.h \
- include/assimp/defs.h \
- include/assimp/importerdesc.h \
- include/assimp/light.h \
- include/assimp/material.h \
- include/assimp/matrix3x3.h \
- include/assimp/matrix4x4.h \
- include/assimp/mesh.h \
- include/assimp/metadata.h \
- include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h \
- include/assimp/postprocess.h \
- include/assimp/quaternion.h \
- include/assimp/scene.h \
- include/assimp/texture.h \
- include/assimp/types.h \
- include/assimp/vector2.h \
- include/assimp/vector3.h \
- include/assimp/version.h
+# unzip (collada loader)
+VPATH += $$PWD/unzip $$PWD/contrib/unzip
+INCLUDEPATH += $$PWD/unzip $$PWD/contrib/unzip
+HEADERS += \
+ $$PWD/src/contrib/unzip/crypt.h \
+ $$PWD/src/contrib/unzip/ioapi.h \
+ $$PWD/unzip/unzip.h
SOURCES += \
- code/3DSConverter.cpp \
- code/3DSExporter.cpp \
- code/3DSLoader.cpp \
- code/ACLoader.cpp \
- code/AMFImporter.cpp \
- code/AMFImporter_Geometry.cpp \
- code/AMFImporter_Material.cpp \
- code/AMFImporter_Postprocess.cpp \
- code/ASELoader.cpp \
- code/ASEParser.cpp \
- code/AssbinExporter.cpp \
- code/AssbinLoader.cpp \
- code/Assimp.cpp \
- code/AssimpCExport.cpp \
- code/AssxmlExporter.cpp \
- code/B3DImporter.cpp \
- code/BVHLoader.cpp \
- code/BaseImporter.cpp \
- code/BaseProcess.cpp \
- code/Bitmap.cpp \
- code/BlenderBMesh.cpp \
- code/BlenderDNA.cpp \
- code/BlenderLoader.cpp \
- code/BlenderModifier.cpp \
- code/BlenderScene.cpp \
- code/BlenderTessellator.cpp \
- code/C4DImporter.cpp \
- code/CInterfaceIOWrapper.cpp \
- code/COBLoader.cpp \
- code/CSMLoader.cpp \
- code/CalcTangentsProcess.cpp \
- code/ColladaExporter.cpp \
- code/ColladaLoader.cpp \
- code/ColladaParser.cpp \
- code/ComputeUVMappingProcess.cpp \
- code/ConvertToLHProcess.cpp \
- code/CreateAnimMesh.cpp \
- code/D3MFExporter.cpp \
- code/D3MFImporter.cpp \
- code/D3MFOpcPackage.cpp \
- code/DXFLoader.cpp \
- code/DeboneProcess.cpp \
- code/DefaultIOStream.cpp \
- code/DefaultIOSystem.cpp \
- code/DefaultLogger.cpp \
- code/Exporter.cpp \
- code/FBXAnimation.cpp \
- code/FBXBinaryTokenizer.cpp \
- code/FBXConverter.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/FIReader.cpp \
- code/FindDegenerates.cpp \
- code/FindInstancesProcess.cpp \
- code/FindInvalidDataProcess.cpp \
- code/FixNormalsStep.cpp \
- code/GenFaceNormalsProcess.cpp \
- code/GenVertexNormalsProcess.cpp \
- code/HMPLoader.cpp \
- code/IFCBoolean.cpp \
- code/IFCCurve.cpp \
- code/IFCGeometry.cpp \
- code/IFCLoader.cpp \
- code/IFCMaterial.cpp \
- code/IFCOpenings.cpp \
- code/IFCProfile.cpp \
- code/IFCReaderGen1.cpp \
- code/IFCReaderGen2.cpp \
- code/IFCUtil.cpp \
- code/IRRLoader.cpp \
- code/IRRMeshLoader.cpp \
- code/IRRShared.cpp \
- code/Importer.cpp \
- code/ImporterRegistry.cpp \
- code/ImproveCacheLocality.cpp \
- code/JoinVerticesProcess.cpp \
- code/LWOAnimation.cpp \
- code/LWOBLoader.cpp \
- code/LWOLoader.cpp \
- code/LWOMaterial.cpp \
- code/LWSLoader.cpp \
- code/LimitBoneWeightsProcess.cpp \
- code/MD2Loader.cpp \
- code/MD3Loader.cpp \
- code/MD5Loader.cpp \
- code/MD5Parser.cpp \
- code/MDCLoader.cpp \
- code/MDLLoader.cpp \
- code/MDLMaterialLoader.cpp \
- code/MMDImporter.cpp \
- code/MMDPmxParser.cpp \
- code/MS3DLoader.cpp \
- code/MakeVerboseFormat.cpp \
- code/MaterialSystem.cpp \
- code/NDOLoader.cpp \
- code/NFFLoader.cpp \
- code/OFFLoader.cpp \
- code/ObjExporter.cpp \
- code/ObjFileImporter.cpp \
- code/ObjFileMtlImporter.cpp \
- code/ObjFileParser.cpp \
- code/OgreBinarySerializer.cpp \
- code/OgreImporter.cpp \
- code/OgreMaterial.cpp \
- code/OgreStructs.cpp \
- code/OgreXmlSerializer.cpp \
- code/OpenGEXExporter.cpp \
- code/OpenGEXImporter.cpp \
- code/OptimizeGraph.cpp \
- code/OptimizeMeshes.cpp \
- code/PlyExporter.cpp \
- code/PlyLoader.cpp \
- code/PlyParser.cpp \
- code/PostStepRegistry.cpp \
- code/PretransformVertices.cpp \
- code/ProcessHelper.cpp \
- code/Q3BSPFileImporter.cpp \
- code/Q3BSPFileParser.cpp \
- code/Q3BSPZipArchive.cpp \
- code/Q3DLoader.cpp \
- code/RawLoader.cpp \
- code/RemoveComments.cpp \
- code/RemoveRedundantMaterials.cpp \
- code/RemoveVCProcess.cpp \
- code/SGSpatialSort.cpp \
- code/SIBImporter.cpp \
- code/SMDLoader.cpp \
- code/STEPFileEncoding.cpp \
- code/STEPFileReader.cpp \
- code/STLExporter.cpp \
- code/STLLoader.cpp \
- code/ScaleProcess.cpp \
- code/SceneCombiner.cpp \
- code/ScenePreprocessor.cpp \
- code/SkeletonMeshBuilder.cpp \
- code/SortByPTypeProcess.cpp \
- code/SpatialSort.cpp \
- code/SplitByBoneCountProcess.cpp \
- code/SplitLargeMeshes.cpp \
- code/StandardShapes.cpp \
- code/StepExporter.cpp \
- code/Subdivision.cpp \
- code/TargetAnimation.cpp \
- code/TerragenLoader.cpp \
- code/TextureTransform.cpp \
- code/TriangulateProcess.cpp \
- code/UnrealLoader.cpp \
- code/ValidateDataStructure.cpp \
- code/Version.cpp \
- code/VertexTriangleAdjacency.cpp \
- code/X3DExporter.cpp \
- code/X3DImporter.cpp \
- code/X3DImporter_Geometry2D.cpp \
- code/X3DImporter_Geometry3D.cpp \
- code/X3DImporter_Group.cpp \
- code/X3DImporter_Light.cpp \
- code/X3DImporter_Metadata.cpp \
- code/X3DImporter_Networking.cpp \
- code/X3DImporter_Postprocess.cpp \
- code/X3DImporter_Rendering.cpp \
- code/X3DImporter_Shape.cpp \
- code/X3DImporter_Texturing.cpp \
- code/X3DVocabulary.cpp \
- code/XFileExporter.cpp \
- code/XFileImporter.cpp \
- code/XFileParser.cpp \
- code/XGLLoader.cpp \
- code/glTF2Exporter.cpp \
- code/glTF2Importer.cpp \
- code/glTFExporter.cpp \
- code/glTFImporter.cpp \
- code/scene.cpp \
- contrib/Open3DGC/o3dgcArithmeticCodec.cpp \
- contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp \
- contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp \
- contrib/Open3DGC/o3dgcTools.cpp \
- contrib/Open3DGC/o3dgcTriangleFans.cpp \
- contrib/clipper/clipper.cpp \
- contrib/irrXML/irrXML.cpp \
- contrib/openddlparser/code/DDLNode.cpp \
- contrib/openddlparser/code/OpenDDLCommon.cpp \
- contrib/openddlparser/code/OpenDDLExport.cpp \
- contrib/openddlparser/code/OpenDDLParser.cpp \
- contrib/openddlparser/code/OpenDDLStream.cpp \
- contrib/openddlparser/code/Value.cpp \
- 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/unzip/ioapi.c \
- contrib/unzip/unzip.c \
- contrib/zip/src/zip.c
+ $$PWD/src/contrib/unzip/ioapi.c \
+ $$PWD/src/contrib/unzip/unzip.c
diff --git a/src/3rdparty/assimp/code/3DSConverter.cpp b/src/3rdparty/assimp/code/3DSConverter.cpp
deleted file mode 100644
index 820c28f90..000000000
--- a/src/3rdparty/assimp/code/3DSConverter.cpp
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the 3ds importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "3DSLoader.h"
-#include "TargetAnimation.h"
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include "StringComparison.h"
-#include <memory>
-#include <cctype>
-
-using namespace Assimp;
-
-static const unsigned int NotSet = 0xcdcdcdcd;
-
-// ------------------------------------------------------------------------------------------------
-// Setup final material indices, generae a default material if necessary
-void Discreet3DSImporter::ReplaceDefaultMaterial()
-{
- // Try to find an existing material that matches the
- // typical default material setting:
- // - no textures
- // - diffuse color (in grey!)
- // NOTE: This is here to workaround the fact that some
- // exporters are writing a default material, too.
- unsigned int idx( NotSet );
- for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
- {
- std::string s = mScene->mMaterials[i].mName;
- for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
- *it = static_cast< char >( ::tolower( *it ) );
- }
-
- if (std::string::npos == s.find("default"))continue;
-
- if (mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.g ||
- mScene->mMaterials[i].mDiffuse.r !=
- mScene->mMaterials[i].mDiffuse.b)continue;
-
- if (mScene->mMaterials[i].sTexDiffuse.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexBump.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexOpacity.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexEmissive.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexSpecular.mMapName.length() != 0 ||
- mScene->mMaterials[i].sTexShininess.mMapName.length() != 0 )
- {
- continue;
- }
- idx = i;
- }
- if ( NotSet == idx ) {
- idx = ( unsigned int )mScene->mMaterials.size();
- }
-
- // now iterate through all meshes and through all faces and
- // find all faces that are using the default material
- unsigned int cnt = 0;
- for (std::vector<D3DS::Mesh>::iterator
- i = mScene->mMeshes.begin();
- i != mScene->mMeshes.end();++i)
- {
- for (std::vector<unsigned int>::iterator
- a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end();++a)
- {
- // NOTE: The additional check seems to be necessary,
- // some exporters seem to generate invalid data here
- if (0xcdcdcdcd == (*a))
- {
- (*a) = idx;
- ++cnt;
- }
- else if ( (*a) >= mScene->mMaterials.size())
- {
- (*a) = idx;
- DefaultLogger::get()->warn("Material index overflow in 3DS file. Using default material");
- ++cnt;
- }
- }
- }
- if (cnt && idx == mScene->mMaterials.size())
- {
- // We need to create our own default material
- D3DS::Material sMat;
- sMat.mDiffuse = aiColor3D(0.3f,0.3f,0.3f);
- sMat.mName = "%%%DEFAULT";
- mScene->mMaterials.push_back(sMat);
-
- DefaultLogger::get()->info("3DS: Generating default material");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether all indices are valid. Otherwise we'd crash before the validation step is reached
-void Discreet3DSImporter::CheckIndices(D3DS::Mesh& sMesh)
-{
- for (std::vector< D3DS::Face >::iterator i = sMesh.mFaces.begin(); i != sMesh.mFaces.end();++i)
- {
- // check whether all indices are in range
- for (unsigned int a = 0; a < 3;++a)
- {
- if ((*i).mIndices[a] >= sMesh.mPositions.size())
- {
- DefaultLogger::get()->warn("3DS: Vertex index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mPositions.size()-1;
- }
- if ( !sMesh.mTexCoords.empty() && (*i).mIndices[a] >= sMesh.mTexCoords.size())
- {
- DefaultLogger::get()->warn("3DS: Texture coordinate index overflow)");
- (*i).mIndices[a] = (uint32_t)sMesh.mTexCoords.size()-1;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate out unique verbose format representation
-void Discreet3DSImporter::MakeUnique(D3DS::Mesh& sMesh)
-{
- // TODO: really necessary? I don't think. Just a waste of memory and time
- // to do it now in a separate buffer.
-
- // Allocate output storage
- std::vector<aiVector3D> vNew (sMesh.mFaces.size() * 3);
- std::vector<aiVector3D> vNew2;
- if (sMesh.mTexCoords.size())
- vNew2.resize(sMesh.mFaces.size() * 3);
-
- for (unsigned int i = 0, base = 0; i < sMesh.mFaces.size();++i)
- {
- D3DS::Face& face = sMesh.mFaces[i];
-
- // Positions
- for (unsigned int a = 0; a < 3;++a,++base)
- {
- vNew[base] = sMesh.mPositions[face.mIndices[a]];
- if (sMesh.mTexCoords.size())
- vNew2[base] = sMesh.mTexCoords[face.mIndices[a]];
-
- face.mIndices[a] = base;
- }
- }
- sMesh.mPositions = vNew;
- sMesh.mTexCoords = vNew2;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS texture to texture keys in an aiMaterial
-void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
-{
- // Setup the texture name
- aiString tex;
- tex.Set( texture.mMapName);
- mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
-
- // Setup the texture blend factor
- if (is_not_qnan(texture.mTextureBlend))
- mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
-
- // Setup the texture mapping mode
- mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
- mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_V(type,0));
-
- // Mirroring - double the scaling values
- // FIXME: this is not really correct ...
- if (texture.mMapMode == aiTextureMapMode_Mirror)
- {
- texture.mScaleU *= 2.0;
- texture.mScaleV *= 2.0;
- texture.mOffsetU /= 2.0;
- texture.mOffsetV /= 2.0;
- }
-
- // Setup texture UV transformations
- mat.AddProperty<ai_real>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a 3DS material to an aiMaterial
-void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
- aiMaterial& mat)
-{
- // NOTE: Pass the background image to the viewer by bypassing the
- // material system. This is an evil hack, never do it again!
- if (0 != mBackgroundImage.length() && bHasBG)
- {
- aiString tex;
- tex.Set( mBackgroundImage);
- mat.AddProperty( &tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
-
- // Be sure this is only done for the first material
- mBackgroundImage = std::string("");
- }
-
- // At first add the base ambient color of the scene to the material
- oldMat.mAmbient.r += mClrAmbient.r;
- oldMat.mAmbient.g += mClrAmbient.g;
- oldMat.mAmbient.b += mClrAmbient.b;
-
- aiString name;
- name.Set( oldMat.mName);
- mat.AddProperty( &name, AI_MATKEY_NAME);
-
- // Material colors
- mat.AddProperty( &oldMat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat.AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat.AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // Phong shininess and shininess strength
- if (D3DS::Discreet3DS::Phong == oldMat.mShading ||
- D3DS::Discreet3DS::Metal == oldMat.mShading)
- {
- if (!oldMat.mSpecularExponent || !oldMat.mShininessStrength)
- {
- oldMat.mShading = D3DS::Discreet3DS::Gouraud;
- }
- else
- {
- mat.AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
- mat.AddProperty( &oldMat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
- }
- }
-
- // Opacity
- mat.AddProperty<ai_real>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
-
- // Bump height scaling
- mat.AddProperty<ai_real>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
-
- // Two sided rendering?
- if (oldMat.mTwoSided)
- {
- int i = 1;
- mat.AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
- }
-
- // Shading mode
- aiShadingMode eShading = aiShadingMode_NoShading;
- switch (oldMat.mShading)
- {
- case D3DS::Discreet3DS::Flat:
- eShading = aiShadingMode_Flat; break;
-
- // I don't know what "Wire" shading should be,
- // assume it is simple lambertian diffuse shading
- case D3DS::Discreet3DS::Wire:
- {
- // Set the wireframe flag
- unsigned int iWire = 1;
- mat.AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- case D3DS::Discreet3DS::Gouraud:
- eShading = aiShadingMode_Gouraud; break;
-
- // assume cook-torrance shading for metals.
- case D3DS::Discreet3DS::Phong :
- eShading = aiShadingMode_Phong; break;
-
- case D3DS::Discreet3DS::Metal :
- eShading = aiShadingMode_CookTorrance; break;
-
- // FIX to workaround a warning with GCC 4 who complained
- // about a missing case Blinn: here - Blinn isn't a valid
- // value in the 3DS Loader, it is just needed for ASE
- case D3DS::Discreet3DS::Blinn :
- eShading = aiShadingMode_Blinn; break;
- }
- mat.AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
-
- // DIFFUSE texture
- if( oldMat.sTexDiffuse.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexDiffuse, aiTextureType_DIFFUSE);
-
- // SPECULAR texture
- if( oldMat.sTexSpecular.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexSpecular, aiTextureType_SPECULAR);
-
- // OPACITY texture
- if( oldMat.sTexOpacity.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexOpacity, aiTextureType_OPACITY);
-
- // EMISSIVE texture
- if( oldMat.sTexEmissive.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexEmissive, aiTextureType_EMISSIVE);
-
- // BUMP texture
- if( oldMat.sTexBump.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexBump, aiTextureType_HEIGHT);
-
- // SHININESS texture
- if( oldMat.sTexShininess.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexShininess, aiTextureType_SHININESS);
-
- // REFLECTION texture
- if( oldMat.sTexReflective.mMapName.length() > 0)
- CopyTexture(mat,oldMat.sTexReflective, aiTextureType_REFLECTION);
-
- // Store the name of the material itself, too
- if( oldMat.mName.length()) {
- aiString tex;
- tex.Set( oldMat.mName);
- mat.AddProperty( &tex, AI_MATKEY_NAME);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Split meshes by their materials and generate output aiMesh'es
-void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
-{
- std::vector<aiMesh*> avOutMeshes;
- avOutMeshes.reserve(mScene->mMeshes.size() * 2);
-
- unsigned int iFaceCnt = 0,num = 0;
- aiString name;
-
- // we need to split all meshes by their materials
- for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i) {
- std::unique_ptr< std::vector<unsigned int>[] > aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
-
- name.length = ASSIMP_itoa10(name.data,num++);
-
- unsigned int iNum = 0;
- for (std::vector<unsigned int>::const_iterator a = (*i).mFaceMaterials.begin();
- a != (*i).mFaceMaterials.end();++a,++iNum)
- {
- aiSplit[*a].push_back(iNum);
- }
- // now generate submeshes
- for (unsigned int p = 0; p < mScene->mMaterials.size();++p)
- {
- if (aiSplit[p].empty()) {
- continue;
- }
- aiMesh* meshOut = new aiMesh();
- meshOut->mName = name;
- meshOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // be sure to setup the correct material index
- meshOut->mMaterialIndex = p;
-
- // use the color data as temporary storage
- meshOut->mColors[0] = (aiColor4D*)(&*i);
- avOutMeshes.push_back(meshOut);
-
- // convert vertices
- meshOut->mNumFaces = (unsigned int)aiSplit[p].size();
- meshOut->mNumVertices = meshOut->mNumFaces*3;
-
- // allocate enough storage for faces
- meshOut->mFaces = new aiFace[meshOut->mNumFaces];
- iFaceCnt += meshOut->mNumFaces;
-
- meshOut->mVertices = new aiVector3D[meshOut->mNumVertices];
- meshOut->mNormals = new aiVector3D[meshOut->mNumVertices];
- if ((*i).mTexCoords.size())
- {
- meshOut->mTextureCoords[0] = new aiVector3D[meshOut->mNumVertices];
- }
- for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
- {
- unsigned int index = aiSplit[p][q];
- aiFace& face = meshOut->mFaces[q];
-
- face.mIndices = new unsigned int[3];
- face.mNumIndices = 3;
-
- for (unsigned int a = 0; a < 3;++a,++base)
- {
- unsigned int idx = (*i).mFaces[index].mIndices[a];
- meshOut->mVertices[base] = (*i).mPositions[idx];
- meshOut->mNormals [base] = (*i).mNormals[idx];
-
- if ((*i).mTexCoords.size())
- meshOut->mTextureCoords[0][base] = (*i).mTexCoords[idx];
-
- face.mIndices[a] = base;
- }
- }
- }
- }
-
- // Copy them to the output array
- pcOut->mNumMeshes = (unsigned int)avOutMeshes.size();
- pcOut->mMeshes = new aiMesh*[pcOut->mNumMeshes]();
- for (unsigned int a = 0; a < pcOut->mNumMeshes;++a) {
- pcOut->mMeshes[a] = avOutMeshes[a];
- }
-
- // We should have at least one face here
- if (!iFaceCnt) {
- throw DeadlyImportError("No faces loaded. The mesh is empty");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a node to the scenegraph and setup its final transformation
-void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
- D3DS::Node* pcIn, aiMatrix4x4& /*absTrafo*/)
-{
- std::vector<unsigned int> iArray;
- iArray.reserve(3);
-
- aiMatrix4x4 abs;
-
- // Find all meshes with the same name as the node
- for (unsigned int a = 0; a < pcSOut->mNumMeshes;++a)
- {
- const D3DS::Mesh* pcMesh = (const D3DS::Mesh*)pcSOut->mMeshes[a]->mColors[0];
- ai_assert(NULL != pcMesh);
-
- if (pcIn->mName == pcMesh->mName)
- iArray.push_back(a);
- }
- if (!iArray.empty())
- {
- // The matrix should be identical for all meshes with the
- // same name. It HAS to be identical for all meshes .....
- D3DS::Mesh* imesh = ((D3DS::Mesh*)pcSOut->mMeshes[iArray[0]]->mColors[0]);
-
- // Compute the inverse of the transformation matrix to move the
- // vertices back to their relative and local space
- aiMatrix4x4 mInv = imesh->mMat, mInvTransposed = imesh->mMat;
- mInv.Inverse();mInvTransposed.Transpose();
- aiVector3D pivot = pcIn->vPivot;
-
- pcOut->mNumMeshes = (unsigned int)iArray.size();
- pcOut->mMeshes = new unsigned int[iArray.size()];
- for (unsigned int i = 0;i < iArray.size();++i) {
- const unsigned int iIndex = iArray[i];
- aiMesh* const mesh = pcSOut->mMeshes[iIndex];
-
- if (mesh->mColors[1] == NULL)
- {
- // 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)
- {
- /* 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;
- }
- }
-
- // Setup the name of the node
- // 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
- if (pcIn->aRotationKeys.size()){
-
- // FIX to get to Assimp's quaternion conventions
- for (std::vector<aiQuatKey>::iterator it = pcIn->aRotationKeys.begin(); it != pcIn->aRotationKeys.end(); ++it) {
- (*it).mValue.w *= -1.f;
- }
-
- pcOut->mTransformation = aiMatrix4x4( pcIn->aRotationKeys[0].mValue.GetMatrix() );
- }
- else if (pcIn->aCameraRollKeys.size())
- {
- aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(- pcIn->aCameraRollKeys[0].mValue),
- pcOut->mTransformation);
- }
-
- // SCALING
- aiMatrix4x4& m = pcOut->mTransformation;
- if (pcIn->aScalingKeys.size())
- {
- const aiVector3D& v = pcIn->aScalingKeys[0].mValue;
- m.a1 *= v.x; m.b1 *= v.x; m.c1 *= v.x;
- m.a2 *= v.y; m.b2 *= v.y; m.c2 *= v.y;
- m.a3 *= v.z; m.b3 *= v.z; m.c3 *= v.z;
- }
-
- // TRANSLATION
- if (pcIn->aPositionKeys.size())
- {
- const aiVector3D& v = pcIn->aPositionKeys[0].mValue;
- m.a4 += v.x;
- m.b4 += v.y;
- m.c4 += v.z;
- }
-
- // Generate animation channels for the node
- if (pcIn->aPositionKeys.size() > 1 || pcIn->aRotationKeys.size() > 1 ||
- pcIn->aScalingKeys.size() > 1 || pcIn->aCameraRollKeys.size() > 1 ||
- pcIn->aTargetPositionKeys.size() > 1)
- {
- aiAnimation* anim = pcSOut->mAnimations[0];
- ai_assert(NULL != anim);
-
- if (pcIn->aCameraRollKeys.size() > 1)
- {
- DefaultLogger::get()->debug("3DS: Converting camera roll track ...");
-
- // Camera roll keys - in fact they're just rotations
- // around the camera's z axis. The angles are given
- // in degrees (and they're clockwise).
- pcIn->aRotationKeys.resize(pcIn->aCameraRollKeys.size());
- for (unsigned int i = 0; i < pcIn->aCameraRollKeys.size();++i)
- {
- aiQuatKey& q = pcIn->aRotationKeys[i];
- aiFloatKey& f = pcIn->aCameraRollKeys[i];
-
- q.mTime = f.mTime;
-
- // FIX to get to Assimp quaternion conventions
- q.mValue = aiQuaternion(0.f,0.f,AI_DEG_TO_RAD( /*-*/ f.mValue));
- }
- }
-#if 0
- if (pcIn->aTargetPositionKeys.size() > 1)
- {
- DefaultLogger::get()->debug("3DS: Converting target track ...");
-
- // Camera or spot light - need to convert the separate
- // target position channel to our representation
- TargetAnimationHelper helper;
-
- if (pcIn->aPositionKeys.empty())
- {
- // We can just pass zero here ...
- helper.SetFixedMainAnimationChannel(aiVector3D());
- }
- else helper.SetMainAnimationChannel(&pcIn->aPositionKeys);
- helper.SetTargetAnimationChannel(&pcIn->aTargetPositionKeys);
-
- // Do the conversion
- std::vector<aiVectorKey> distanceTrack;
- helper.Process(&distanceTrack);
-
- // Now add a new node as child, name it <ourName>.Target
- // and assign the distance track to it. This is that the
- // information where the target is and how it moves is
- // not lost
- D3DS::Node* nd = new D3DS::Node();
- pcIn->push_back(nd);
-
- nd->mName = pcIn->mName + ".Target";
-
- aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(nd->mName);
-
- nda->mNumPositionKeys = (unsigned int)distanceTrack.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys,&distanceTrack[0],
- sizeof(aiVectorKey)*nda->mNumPositionKeys);
- }
-#endif
-
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
- for (unsigned int n = 0; n < pcSOut->mNumCameras;++n) {
- if (pcSOut->mCameras[n]->mName == pcOut->mName) {
- pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f,0.f,1.f);
- }
- }
- for (unsigned int n = 0; n < pcSOut->mNumLights;++n) {
- if (pcSOut->mLights[n]->mName == pcOut->mName) {
- pcSOut->mLights[n]->mDirection = aiVector3D(0.f,0.f,1.f);
- }
- }
-
- // Allocate a new node anim and setup its name
- aiNodeAnim* nda = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nda->mNodeName.Set(pcIn->mName);
-
- // POSITION keys
- if (pcIn->aPositionKeys.size() > 0)
- {
- nda->mNumPositionKeys = (unsigned int)pcIn->aPositionKeys.size();
- nda->mPositionKeys = new aiVectorKey[nda->mNumPositionKeys];
- ::memcpy(nda->mPositionKeys,&pcIn->aPositionKeys[0],
- sizeof(aiVectorKey)*nda->mNumPositionKeys);
- }
-
- // ROTATION keys
- if (pcIn->aRotationKeys.size() > 0)
- {
- nda->mNumRotationKeys = (unsigned int)pcIn->aRotationKeys.size();
- nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
-
- // Rotations are quaternion offsets
- aiQuaternion abs1;
- for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
- {
- const aiQuatKey& q = pcIn->aRotationKeys[n];
-
- abs1 = (n ? abs1 * q.mValue : q.mValue);
- nda->mRotationKeys[n].mTime = q.mTime;
- nda->mRotationKeys[n].mValue = abs1.Normalize();
- }
- }
-
- // SCALING keys
- if (pcIn->aScalingKeys.size() > 0)
- {
- nda->mNumScalingKeys = (unsigned int)pcIn->aScalingKeys.size();
- nda->mScalingKeys = new aiVectorKey[nda->mNumScalingKeys];
- ::memcpy(nda->mScalingKeys,&pcIn->aScalingKeys[0],
- sizeof(aiVectorKey)*nda->mNumScalingKeys);
- }
- }
-
- // Allocate storage for children
- pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
- pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
-
- // Recursively process all children
- const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
- for (unsigned int i = 0; i < size;++i)
- {
- pcOut->mChildren[i] = new aiNode();
- pcOut->mChildren[i]->mParent = pcOut;
- AddNodeToGraph(pcSOut,pcOut->mChildren[i],pcIn->mChildren[i],abs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find out how many node animation channels we'll have finally
-void CountTracks(D3DS::Node* node, unsigned int& cnt)
-{
- //////////////////////////////////////////////////////////////////////////////
- // We will never generate more than one channel for a node, so
- // this is rather easy here.
-
- if (node->aPositionKeys.size() > 1 || node->aRotationKeys.size() > 1 ||
- node->aScalingKeys.size() > 1 || node->aCameraRollKeys.size() > 1 ||
- node->aTargetPositionKeys.size() > 1)
- {
- ++cnt;
-
- // account for the additional channel for the camera/spotlight target position
- if (node->aTargetPositionKeys.size() > 1)++cnt;
- }
-
- // Recursively process all children
- for (unsigned int i = 0; i < node->mChildren.size();++i)
- CountTracks(node->mChildren[i],cnt);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate the output node graph
-void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
-{
- pcOut->mRootNode = new aiNode();
- if (0 == mRootNode->mChildren.size())
- {
- //////////////////////////////////////////////////////////////////////////////
- // 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
- // |
- // ----------------------------------------
- // | | | | |
- // MESH_0 MESH_1 MESH_2 ... MESH_N CAMERA_0 ....
- //
- DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
-
- pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
- static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size());
-
- pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
- pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
-
- // Build dummy nodes for all meshes
- unsigned int a = 0;
- for (unsigned int i = 0; i < pcOut->mNumMeshes;++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- pcNode->mNumMeshes = 1;
-
- // Build a name for the node
- pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i);
- }
-
- // Build dummy nodes for all cameras
- for (unsigned int i = 0; i < (unsigned int )mScene->mCameras.size();++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mCameras[i]->mName;
- }
-
- // Build dummy nodes for all lights
- for (unsigned int i = 0; i < (unsigned int )mScene->mLights.size();++i,++a)
- {
- aiNode* pcNode = pcOut->mRootNode->mChildren[a] = new aiNode();
- pcNode->mParent = pcOut->mRootNode;
-
- // Build a name for the node
- pcNode->mName = mScene->mLights[i]->mName;
- }
- }
- else
- {
- // First of all: find out how many scaling, rotation and translation
- // animation tracks we'll have afterwards
- unsigned int numChannel = 0;
- CountTracks(mRootNode,numChannel);
-
- if (numChannel)
- {
- // Allocate a primary animation channel
- pcOut->mNumAnimations = 1;
- pcOut->mAnimations = new aiAnimation*[1];
- aiAnimation* anim = pcOut->mAnimations[0] = new aiAnimation();
-
- anim->mName.Set("3DSMasterAnim");
-
- // Allocate enough storage for all node animation channels,
- // but don't set the mNumChannels member - we'll use it to
- // index into the array
- anim->mChannels = new aiNodeAnim*[numChannel];
- }
-
- aiMatrix4x4 m;
- AddNodeToGraph(pcOut, pcOut->mRootNode, mRootNode,m);
- }
-
- // 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,
- 0.f,0.f,1.f,0.f,
- 0.f,-1.f,0.f,0.f,
- 0.f,0.f,0.f,1.f) * pcOut->mRootNode->mTransformation;
-
- // If the root node is unnamed name it "<3DSRoot>"
- if (::strstr( pcOut->mRootNode->mName.data, "UNNAMED" ) ||
- (pcOut->mRootNode->mName.data[0] == '$' && pcOut->mRootNode->mName.data[1] == '$') )
- {
- pcOut->mRootNode->mName.Set("<3DSRoot>");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert all meshes in the scene and generate the final output scene.
-void Discreet3DSImporter::ConvertScene(aiScene* pcOut)
-{
- // Allocate enough storage for all output materials
- pcOut->mNumMaterials = (unsigned int)mScene->mMaterials.size();
- pcOut->mMaterials = new aiMaterial*[pcOut->mNumMaterials];
-
- // ... and convert the 3DS materials to aiMaterial's
- for (unsigned int i = 0; i < pcOut->mNumMaterials;++i)
- {
- aiMaterial* pcNew = new aiMaterial();
- ConvertMaterial(mScene->mMaterials[i],*pcNew);
- pcOut->mMaterials[i] = pcNew;
- }
-
- // Generate the output mesh list
- ConvertMeshes(pcOut);
-
- // Now copy all light sources to the output scene
- pcOut->mNumLights = (unsigned int)mScene->mLights.size();
- if (pcOut->mNumLights)
- {
- pcOut->mLights = new aiLight*[pcOut->mNumLights];
- ::memcpy(pcOut->mLights,&mScene->mLights[0],sizeof(void*)*pcOut->mNumLights);
- }
-
- // Now copy all cameras to the output scene
- pcOut->mNumCameras = (unsigned int)mScene->mCameras.size();
- if (pcOut->mNumCameras)
- {
- pcOut->mCameras = new aiCamera*[pcOut->mNumCameras];
- ::memcpy(pcOut->mCameras,&mScene->mCameras[0],sizeof(void*)*pcOut->mNumCameras);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/src/3rdparty/assimp/code/3DSExporter.cpp b/src/3rdparty/assimp/code/3DSExporter.cpp
deleted file mode 100644
index 2f561fcd6..000000000
--- a/src/3rdparty/assimp/code/3DSExporter.cpp
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
-
-#include "3DSExporter.h"
-#include "3DSLoader.h"
-#include "3DSHelper.h"
-#include <assimp/SceneCombiner.h>
-#include "SplitLargeMeshes.h"
-#include "StringComparison.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Exporter.hpp>
-#include <memory>
-
-using namespace Assimp;
-namespace Assimp {
-using namespace D3DS;
-
-namespace {
-
- //////////////////////////////////////////////////////////////////////////////////////
- // Scope utility to write a 3DS file chunk.
- //
- // Upon construction, the chunk header is written with the chunk type (flags)
- // filled out, but the chunk size left empty. Upon destruction, the correct chunk
- // size based on the then-position of the output stream cursor is filled in.
- class ChunkWriter {
- enum {
- CHUNK_SIZE_NOT_SET = 0xdeadbeef
- , SIZE_OFFSET = 2
- };
- public:
-
- ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type)
- : writer(writer)
- {
- chunk_start_pos = writer.GetCurrentPos();
- writer.PutU2(chunk_type);
- writer.PutU4(CHUNK_SIZE_NOT_SET);
- }
-
- ~ChunkWriter() {
- std::size_t head_pos = writer.GetCurrentPos();
-
- ai_assert(head_pos > chunk_start_pos);
- const std::size_t chunk_size = head_pos - chunk_start_pos;
-
- writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
- writer.PutU4(static_cast<uint32_t>(chunk_size));
- writer.SetCurrentPos(head_pos);
- }
-
- private:
- StreamWriterLE& writer;
- std::size_t chunk_start_pos;
- };
-
-
- // Return an unique name for a given |mesh| attached to |node| that
- // preserves the mesh's given name if it has one. |index| is the index
- // of the mesh in |aiScene::mMeshes|.
- std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) {
- static const std::string underscore = "_";
- char postfix[10] = {0};
- ASSIMP_itoa10(postfix, index);
-
- std::string result = node.mName.C_Str();
- if (mesh.mName.length > 0) {
- result += underscore + mesh.mName.C_Str();
- }
- return result + underscore + postfix;
- }
-
- // Return an unique name for a given |mat| with original position |index|
- // in |aiScene::mMaterials|. The name preserves the original material
- // name if possible.
- std::string GetMaterialName(const aiMaterial& mat, unsigned int index) {
- static const std::string underscore = "_";
- char postfix[10] = {0};
- ASSIMP_itoa10(postfix, index);
-
- aiString mat_name;
- if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
- return mat_name.C_Str() + underscore + postfix;
- }
-
- return "Material" + underscore + postfix;
- }
-
- // Collect world transformations for each node
- void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
- const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
- trafos[node] = parent * node->mTransformation;
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectTrafos(node->mChildren[i], trafos);
- }
- }
-
- // Generate a flat list of the meshes (by index) assigned to each node
- void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
- for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
- meshes.insert(std::make_pair(node, node->mMeshes[i]));
- }
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectMeshes(node->mChildren[i], meshes);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
-void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- std::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
- if(!outfile) {
- throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
- }
-
- // TODO: This extra copy should be avoided and all of this made a preprocess
- // requirement of the 3DS exporter.
- //
- // 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
- // SplitLargeMeshes can do this, but it requires the correct limit to be set
- // which is not possible with the current way of specifying preprocess steps
- // in |Exporter::ExportFormatEntry|.
- aiScene* scenecopy_tmp;
- SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
- std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
-
- SplitLargeMeshesProcess_Triangle tri_splitter;
- tri_splitter.SetLimit(0xffff);
- tri_splitter.Execute(scenecopy.get());
-
- SplitLargeMeshesProcess_Vertex vert_splitter;
- vert_splitter.SetLimit(0xffff);
- vert_splitter.Execute(scenecopy.get());
-
- // Invoke the actual exporter
- Discreet3DSExporter exporter(outfile, scenecopy.get());
-}
-
-} // end of namespace Assimp
-
-// ------------------------------------------------------------------------------------------------
-Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* scene)
-: scene(scene)
-, writer(outfile)
-{
- CollectTrafos(scene->mRootNode, trafos);
- CollectMeshes(scene->mRootNode, meshes);
-
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
- WriteMaterials();
- WriteMeshes();
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
- writer.PutF4(1.0f);
- }
- }
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
- WriteHierarchy(*scene->mRootNode, -1, -1);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-Discreet3DSExporter::~Discreet3DSExporter() {
- // empty
-}
-
-
-// ------------------------------------------------------------------------------------------------
-int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
-{
- // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
-
- // Assimp node names are unique and distinct from all mesh-node
- // names we generate; thus we can use them as-is
- WriteString(node.mName);
-
- // Two unknown int16 values - it is even unclear if 0 is a safe value
- // but luckily importers do not know better either.
- writer.PutI4(0);
-
- int16_t hierarchy_pos = static_cast<int16_t>(seq);
- if (sibling_level != -1) {
- hierarchy_pos = sibling_level;
- }
-
- // Write the hierarchy position
- writer.PutI2(hierarchy_pos);
- }
- }
-
- // TODO: write transformation chunks
-
- ++seq;
- sibling_level = seq;
-
- // Write all children
- for (unsigned int i = 0; i < node.mNumChildren; ++i) {
- seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
- }
-
- // Write all meshes as separate nodes to be able to reference the meshes by name
- for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
- const bool first_child = node.mNumChildren == 0 && i == 0;
-
- const unsigned int mesh_idx = node.mMeshes[i];
- const aiMesh& mesh = *scene->mMeshes[mesh_idx];
-
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
- WriteString(GetMeshName(mesh, mesh_idx, node));
-
- writer.PutI4(0);
- writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
- ++seq;
- }
- }
- return seq;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteMaterials()
-{
- for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
- const aiMaterial& mat = *scene->mMaterials[i];
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
- const std::string& name = GetMaterialName(mat, i);
- WriteString(name);
- }
-
- aiColor3D color;
- if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
- WriteColor(color);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
- WriteColor(color);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
- WriteColor(color);
- }
-
- if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
- WriteColor(color);
- }
-
- aiShadingMode shading_mode = aiShadingMode_Flat;
- if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
-
- Discreet3DS::shadetype3ds shading_mode_out;
- switch(shading_mode) {
- case aiShadingMode_Flat:
- case aiShadingMode_NoShading:
- shading_mode_out = Discreet3DS::Flat;
- break;
-
- case aiShadingMode_Gouraud:
- case aiShadingMode_Toon:
- case aiShadingMode_OrenNayar:
- case aiShadingMode_Minnaert:
- shading_mode_out = Discreet3DS::Gouraud;
- break;
-
- case aiShadingMode_Phong:
- case aiShadingMode_Blinn:
- case aiShadingMode_CookTorrance:
- case aiShadingMode_Fresnel:
- shading_mode_out = Discreet3DS::Phong;
- break;
-
- default:
- shading_mode_out = Discreet3DS::Flat;
- ai_assert(false);
- };
- writer.PutU2(static_cast<uint16_t>(shading_mode_out));
- }
-
-
- float f;
- if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
- WritePercentChunk(f);
- }
-
- if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
- WritePercentChunk(f);
- }
-
- int twosided;
- if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
- writer.PutI2(1);
- }
-
- WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
- WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
- WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
- WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
- WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
- WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
- WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags)
-{
- aiString path;
- aiTextureMapMode map_mode[2] = {
- aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
- };
- ai_real blend = 1.0;
- if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
- return;
- }
-
- // TODO: handle embedded textures properly
- if (path.data[0] == '*') {
- DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
- return;
- }
-
- ChunkWriter chunk(writer, chunk_flags);
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
- WriteString(path);
- }
-
- WritePercentChunk(blend);
-
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
- uint16_t val = 0; // WRAP
- if (map_mode[0] == aiTextureMapMode_Mirror) {
- val = 0x2;
- }
- else if (map_mode[0] == aiTextureMapMode_Decal) {
- val = 0x10;
- }
- writer.PutU2(val);
- }
- // TODO: export texture transformation (i.e. UV offset, scale, rotation)
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteMeshes()
-{
- // NOTE: 3DS allows for instances. However:
- // i) not all importers support reading them
- // ii) instances are not as flexible as they are in assimp, in particular,
- // nodes can carry (and instance) only one mesh.
- //
- // This exporter currently deep clones all instanced meshes, i.e. for each mesh
- // attached to a node a full TRIMESH chunk is written to the file.
- //
- // Furthermore, the TRIMESH is transformed into world space so that it will
- // appear correctly if importers don't read the scene hierarchy at all.
- for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
- const aiNode& node = *(*it).first;
- const unsigned int mesh_idx = (*it).second;
-
- const aiMesh& mesh = *scene->mMeshes[mesh_idx];
-
- // This should not happen if the SLM step is correctly executed
- // before the scene is handed to the exporter
- ai_assert(mesh.mNumVertices <= 0xffff);
- ai_assert(mesh.mNumFaces <= 0xffff);
-
- const aiMatrix4x4& trafo = trafos[&node];
-
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
-
- // Mesh name is tied to the node it is attached to so it can later be referenced
- const std::string& name = GetMeshName(mesh, mesh_idx, node);
- WriteString(name);
-
-
- // TRIMESH chunk
- ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
-
- // Vertices in world space
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
-
- const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
- writer.PutU2(count);
- for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
- const aiVector3D& v = trafo * mesh.mVertices[i];
- writer.PutF4(v.x);
- writer.PutF4(v.y);
- writer.PutF4(v.z);
- }
- }
-
- // UV coordinates
- if (mesh.HasTextureCoords(0)) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
- const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
- writer.PutU2(count);
-
- for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
- const aiVector3D& v = mesh.mTextureCoords[0][i];
- writer.PutF4(v.x);
- writer.PutF4(v.y);
- }
- }
-
- // Faces (indices)
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
-
- ai_assert(mesh.mNumFaces <= 0xffff);
-
- // Count triangles, discard lines and points
- uint16_t count = 0;
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- const aiFace& f = mesh.mFaces[i];
- if (f.mNumIndices < 3) {
- continue;
- }
- // TRIANGULATE step is a pre-requisite so we should not see polys here
- ai_assert(f.mNumIndices == 3);
- ++count;
- }
-
- writer.PutU2(count);
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- const aiFace& f = mesh.mFaces[i];
- if (f.mNumIndices < 3) {
- continue;
- }
-
- for (unsigned int j = 0; j < 3; ++j) {
- ai_assert(f.mIndices[j] <= 0xffff);
- writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
- }
-
- // Edge visibility flag
- writer.PutI2(0x0);
- }
-
- // TODO: write smoothing groups (CHUNK_SMOOLIST)
-
- WriteFaceMaterialChunk(mesh);
- }
-
- // Transformation matrix by which the mesh vertices have been pre-transformed with.
- {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
- for (unsigned int r = 0; r < 4; ++r) {
- for (unsigned int c = 0; c < 3; ++c) {
- writer.PutF4(trafo[r][c]);
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
-{
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
- const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
- WriteString(name);
-
- // Because assimp splits meshes by material, only a single
- // FACEMAT chunk needs to be written
- ai_assert(mesh.mNumFaces <= 0xffff);
- const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
- writer.PutU2(count);
-
- for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
- writer.PutU2(static_cast<uint16_t>(i));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteString(const std::string& s) {
- for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
- writer.PutI1(*it);
- }
- writer.PutI1('\0');
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteString(const aiString& s) {
- for (std::size_t i = 0; i < s.length; ++i) {
- writer.PutI1(s.data[i]);
- }
- writer.PutI1('\0');
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
- writer.PutF4(color.r);
- writer.PutF4(color.g);
- writer.PutF4(color.b);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WritePercentChunk(float f) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
- writer.PutF4(f);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSExporter::WritePercentChunk(double f) {
- ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTD);
- writer.PutF8(f);
-}
-
-
-#endif // ASSIMP_BUILD_NO_3DS_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/3DSExporter.h b/src/3rdparty/assimp/code/3DSExporter.h
deleted file mode 100644
index fc02e2390..000000000
--- a/src/3rdparty/assimp/code/3DSExporter.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 3DSExporter.h
- * 3DS Exporter Main Header
- */
-#ifndef AI_3DSEXPORTER_H_INC
-#define AI_3DSEXPORTER_H_INC
-
-#include <map>
-#include <memory>
-
-#include "StreamWriter.h"
-#include <assimp/material.h>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-/**
- * @brief Helper class to export a given scene to a 3DS file.
- */
-// ------------------------------------------------------------------------------------------------
-class Discreet3DSExporter {
-public:
- Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* pScene);
- ~Discreet3DSExporter();
-
-private:
- void WriteMeshes();
- void WriteMaterials();
- void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
- void WriteFaceMaterialChunk(const aiMesh& mesh);
- int WriteHierarchy(const aiNode& node, int level, int sibling_level);
- void WriteString(const std::string& s);
- void WriteString(const aiString& s);
- void WriteColor(const aiColor3D& color);
- void WritePercentChunk(float f);
- void WritePercentChunk(double f);
-
-private:
- const aiScene* const scene;
- StreamWriterLE writer;
-
- std::map<const aiNode*, aiMatrix4x4> trafos;
-
- typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
- MeshesByNodeMap meshes;
-
-};
-
-} // Namespace Assimp
-
-#endif // AI_3DSEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/3DSHelper.h b/src/3rdparty/assimp/code/3DSHelper.h
deleted file mode 100644
index 9e701c3dd..000000000
--- a/src/3rdparty/assimp/code/3DSHelper.h
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines helper data structures for the import of 3DS files */
-
-#ifndef AI_3DSFILEHELPER_H_INC
-#define AI_3DSFILEHELPER_H_INC
-
-#include "SpatialSort.h"
-#include "SmoothingGroups.h"
-#include "StringUtils.h"
-#include "qnan.h"
-#include <assimp/material.h>
-#include <assimp/camera.h>
-#include <assimp/light.h>
-#include <assimp/anim.h>
-#include <stdio.h> //sprintf
-
-namespace Assimp {
-namespace D3DS {
-
-#include "./../include/assimp/Compiler/pushpack1.h"
-
-// ---------------------------------------------------------------------------
-/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
-* and data structures.
-*/
-class Discreet3DS {
-private:
- Discreet3DS() {
- // empty
- }
-
- ~Discreet3DS() {
- // empty
- }
-
-public:
- //! data structure for a single chunk in a .3ds file
- struct Chunk {
- uint16_t Flag;
- uint32_t Size;
- } PACK_STRUCT;
-
-
- //! Used for shading field in material3ds structure
- //! From AutoDesk 3ds SDK
- typedef enum
- {
- // translated to gouraud shading with wireframe active
- Wire = 0x0,
-
- // if this material is set, no vertex normals will
- // be calculated for the model. Face normals + gouraud
- Flat = 0x1,
-
- // standard gouraud shading
- Gouraud = 0x2,
-
- // phong shading
- Phong = 0x3,
-
- // cooktorrance or anistropic phong shading ...
- // the exact meaning is unknown, if you know it
- // feel free to tell me ;-)
- Metal = 0x4,
-
- // required by the ASE loader
- Blinn = 0x5
- } shadetype3ds;
-
- // Flags for animated keys
- enum
- {
- KEY_USE_TENS = 0x1,
- KEY_USE_CONT = 0x2,
- KEY_USE_BIAS = 0x4,
- KEY_USE_EASE_TO = 0x8,
- KEY_USE_EASE_FROM = 0x10
- } ;
-
- enum
- {
-
- // ********************************************************************
- // Basic chunks which can be found everywhere in the file
- CHUNK_VERSION = 0x0002,
- CHUNK_RGBF = 0x0010, // float4 R; float4 G; float4 B
- CHUNK_RGBB = 0x0011, // int1 R; int1 G; int B
-
- // Linear color values (gamma = 2.2?)
- CHUNK_LINRGBF = 0x0013, // float4 R; float4 G; float4 B
- CHUNK_LINRGBB = 0x0012, // int1 R; int1 G; int B
-
- CHUNK_PERCENTW = 0x0030, // int2 percentage
- CHUNK_PERCENTF = 0x0031, // float4 percentage
- CHUNK_PERCENTD = 0x0032, // float8 percentage
- // ********************************************************************
-
- // Prj master chunk
- CHUNK_PRJ = 0xC23D,
-
- // MDLI master chunk
- CHUNK_MLI = 0x3DAA,
-
- // Primary main chunk of the .3ds file
- CHUNK_MAIN = 0x4D4D,
-
- // Mesh main chunk
- CHUNK_OBJMESH = 0x3D3D,
-
- // Specifies the background color of the .3ds file
- // This is passed through the material system for
- // viewing purposes.
- CHUNK_BKGCOLOR = 0x1200,
-
- // Specifies the ambient base color of the scene.
- // This is added to all materials in the file
- CHUNK_AMBCOLOR = 0x2100,
-
- // Specifies the background image for the whole scene
- // This value is passed through the material system
- // to the viewer
- CHUNK_BIT_MAP = 0x1100,
- CHUNK_BIT_MAP_EXISTS = 0x1101,
-
- // ********************************************************************
- // Viewport related stuff. Ignored
- CHUNK_DEFAULT_VIEW = 0x3000,
- CHUNK_VIEW_TOP = 0x3010,
- CHUNK_VIEW_BOTTOM = 0x3020,
- CHUNK_VIEW_LEFT = 0x3030,
- CHUNK_VIEW_RIGHT = 0x3040,
- CHUNK_VIEW_FRONT = 0x3050,
- CHUNK_VIEW_BACK = 0x3060,
- CHUNK_VIEW_USER = 0x3070,
- CHUNK_VIEW_CAMERA = 0x3080,
- // ********************************************************************
-
- // Mesh chunks
- CHUNK_OBJBLOCK = 0x4000,
- CHUNK_TRIMESH = 0x4100,
- CHUNK_VERTLIST = 0x4110,
- CHUNK_VERTFLAGS = 0x4111,
- CHUNK_FACELIST = 0x4120,
- CHUNK_FACEMAT = 0x4130,
- CHUNK_MAPLIST = 0x4140,
- CHUNK_SMOOLIST = 0x4150,
- CHUNK_TRMATRIX = 0x4160,
- CHUNK_MESHCOLOR = 0x4165,
- CHUNK_TXTINFO = 0x4170,
- CHUNK_LIGHT = 0x4600,
- CHUNK_CAMERA = 0x4700,
- CHUNK_HIERARCHY = 0x4F00,
-
- // Specifies the global scaling factor. This is applied
- // to the root node's transformation matrix
- CHUNK_MASTER_SCALE = 0x0100,
-
- // ********************************************************************
- // Material chunks
- CHUNK_MAT_MATERIAL = 0xAFFF,
-
- // asciiz containing the name of the material
- CHUNK_MAT_MATNAME = 0xA000,
- CHUNK_MAT_AMBIENT = 0xA010, // followed by color chunk
- CHUNK_MAT_DIFFUSE = 0xA020, // followed by color chunk
- CHUNK_MAT_SPECULAR = 0xA030, // followed by color chunk
-
- // Specifies the shininess of the material
- // followed by percentage chunk
- CHUNK_MAT_SHININESS = 0xA040,
- CHUNK_MAT_SHININESS_PERCENT = 0xA041 ,
-
- // Specifies the shading mode to be used
- // followed by a short
- CHUNK_MAT_SHADING = 0xA100,
-
- // NOTE: Emissive color (self illumination) seems not
- // to be a color but a single value, type is unknown.
- // Make the parser accept both of them.
- // followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILLUM = 0xA080,
-
- // Always followed by percentage chunk (?)
- CHUNK_MAT_SELF_ILPCT = 0xA084,
-
- // Always followed by percentage chunk
- CHUNK_MAT_TRANSPARENCY = 0xA050,
-
- // Diffuse texture channel 0
- CHUNK_MAT_TEXTURE = 0xA200,
-
- // Contains opacity information for each texel
- CHUNK_MAT_OPACMAP = 0xA210,
-
- // Contains a reflection map to be used to reflect
- // the environment. This is partially supported.
- CHUNK_MAT_REFLMAP = 0xA220,
-
- // Self Illumination map (emissive colors)
- CHUNK_MAT_SELFIMAP = 0xA33d,
-
- // Bumpmap. Not specified whether it is a heightmap
- // or a normal map. Assme it is a heightmap since
- // artist normally prefer this format.
- CHUNK_MAT_BUMPMAP = 0xA230,
-
- // Specular map. Seems to influence the specular color
- CHUNK_MAT_SPECMAP = 0xA204,
-
- // Holds shininess data.
- CHUNK_MAT_MAT_SHINMAP = 0xA33C,
-
- // Scaling in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_USCALE = 0xA354,
- CHUNK_MAT_MAP_VSCALE = 0xA356,
-
- // Translation in U/V direction.
- // (need to gen separate UV coordinate set
- // and do this by hand)
- CHUNK_MAT_MAP_UOFFSET = 0xA358,
- CHUNK_MAT_MAP_VOFFSET = 0xA35a,
-
- // UV-coordinates rotation around the z-axis
- // Assumed to be in radians.
- CHUNK_MAT_MAP_ANG = 0xA35C,
-
- // Tiling flags for 3DS files
- CHUNK_MAT_MAP_TILING = 0xa351,
-
- // Specifies the file name of a texture
- CHUNK_MAPFILE = 0xA300,
-
- // Specifies whether a materail requires two-sided rendering
- CHUNK_MAT_TWO_SIDE = 0xA081,
- // ********************************************************************
-
- // Main keyframer chunk. Contains translation/rotation/scaling data
- CHUNK_KEYFRAMER = 0xB000,
-
- // Supported sub chunks
- CHUNK_TRACKINFO = 0xB002,
- CHUNK_TRACKOBJNAME = 0xB010,
- CHUNK_TRACKDUMMYOBJNAME = 0xB011,
- CHUNK_TRACKPIVOT = 0xB013,
- CHUNK_TRACKPOS = 0xB020,
- CHUNK_TRACKROTATE = 0xB021,
- CHUNK_TRACKSCALE = 0xB022,
-
- // ********************************************************************
- // Keyframes for various other stuff in the file
- // Partially ignored
- CHUNK_AMBIENTKEY = 0xB001,
- CHUNK_TRACKMORPH = 0xB026,
- CHUNK_TRACKHIDE = 0xB029,
- CHUNK_OBJNUMBER = 0xB030,
- CHUNK_TRACKCAMERA = 0xB003,
- CHUNK_TRACKFOV = 0xB023,
- CHUNK_TRACKROLL = 0xB024,
- CHUNK_TRACKCAMTGT = 0xB004,
- CHUNK_TRACKLIGHT = 0xB005,
- CHUNK_TRACKLIGTGT = 0xB006,
- CHUNK_TRACKSPOTL = 0xB007,
- CHUNK_FRAMES = 0xB008,
- // ********************************************************************
-
- // light sub-chunks
- CHUNK_DL_OFF = 0x4620,
- CHUNK_DL_OUTER_RANGE = 0x465A,
- CHUNK_DL_INNER_RANGE = 0x4659,
- CHUNK_DL_MULTIPLIER = 0x465B,
- CHUNK_DL_EXCLUDE = 0x4654,
- CHUNK_DL_ATTENUATE = 0x4625,
- CHUNK_DL_SPOTLIGHT = 0x4610,
-
- // camera sub-chunks
- CHUNK_CAM_RANGES = 0x4720
- };
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds mesh face */
-struct Face : public FaceWithSmoothingGroup
-{
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a texture */
-struct Texture
-{
- //! Default constructor
- Texture()
- : mOffsetU (0.0)
- , mOffsetV (0.0)
- , mScaleU (1.0)
- , mScaleV (1.0)
- , mRotation (0.0)
- , mMapMode (aiTextureMapMode_Wrap)
- , bPrivate()
- , iUVSrc (0)
- {
- mTextureBlend = get_qnan();
- }
-
- //! Specifies the blend factor for the texture
- ai_real mTextureBlend;
-
- //! Specifies the filename of the texture
- std::string mMapName;
-
- //! Specifies texture coordinate offsets/scaling/rotations
- ai_real mOffsetU;
- ai_real mOffsetV;
- ai_real mScaleU;
- ai_real mScaleV;
- ai_real mRotation;
-
- //! Specifies the mapping mode to be used for the texture
- aiTextureMapMode mMapMode;
-
- //! Used internally
- bool bPrivate;
- int iUVSrc;
-};
-
-#include "./../include/assimp/Compiler/poppack1.h"
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a 3ds material */
-struct Material
-{
- //! Default constructor. Builds a default name for the material
- Material()
- : mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
- , mSpecularExponent ( ai_real( 0.0 ) )
- , mShininessStrength ( ai_real( 1.0 ) )
- , mShading(Discreet3DS::Gouraud)
- , mTransparency ( ai_real( 1.0 ) )
- , mBumpHeight ( ai_real( 1.0 ) )
- , mTwoSided (false)
- {
- static int iCnt = 0;
-
- char szTemp[128];
- ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Name of the material
- std::string mName;
- //! Diffuse color of the material
- aiColor3D mDiffuse;
- //! Specular exponent
- ai_real mSpecularExponent;
- //! Shininess strength, in percent
- ai_real mShininessStrength;
- //! Specular color of the material
- aiColor3D mSpecular;
- //! Ambient color of the material
- aiColor3D mAmbient;
- //! Shading type to be used
- Discreet3DS::shadetype3ds mShading;
- //! Opacity of the material
- ai_real mTransparency;
- //! Diffuse texture channel
- Texture sTexDiffuse;
- //! Opacity texture channel
- Texture sTexOpacity;
- //! Specular texture channel
- Texture sTexSpecular;
- //! Reflective texture channel
- Texture sTexReflective;
- //! Bump texture channel
- Texture sTexBump;
- //! Emissive texture channel
- Texture sTexEmissive;
- //! Shininess texture channel
- Texture sTexShininess;
- //! Scaling factor for the bump values
- ai_real mBumpHeight;
- //! Emissive color
- aiColor3D mEmissive;
- //! Ambient texture channel
- //! (used by the ASE format)
- Texture sTexAmbient;
- //! True if the material must be rendered from two sides
- bool mTwoSided;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file mesh */
-struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
-{
- //! Default constructor
- Mesh()
- {
- static int iCnt = 0;
-
- // Generate a default name for the mesh
- char szTemp[128];
- ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Name of the mesh
- std::string mName;
-
- //! Texture coordinates
- std::vector<aiVector3D> mTexCoords;
-
- //! Face materials
- std::vector<unsigned int> mFaceMaterials;
-
- //! Local transformation matrix
- aiMatrix4x4 mMat;
-};
-
-// ---------------------------------------------------------------------------
-/** Float key - quite similar to aiVectorKey and aiQuatKey. Both are in the
- C-API, so it would be difficult to make them a template. */
-struct aiFloatKey
-{
- double mTime; ///< The time of this key
- ai_real mValue; ///< The value of this key
-
-#ifdef __cplusplus
-
- // time is not compared
- bool operator == (const aiFloatKey& o) const
- {return o.mValue == this->mValue;}
-
- bool operator != (const aiFloatKey& o) const
- {return o.mValue != this->mValue;}
-
- // Only time is compared. This operator is defined
- // for use with std::sort
- bool operator < (const aiFloatKey& o) const
- {return mTime < o.mTime;}
-
- bool operator > (const aiFloatKey& o) const
- {return mTime > o.mTime;}
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent a 3ds file node */
-struct Node
-{
- Node():
- mParent(NULL)
- , mInstanceNumber(0)
- , mHierarchyPos (0)
- , mHierarchyIndex (0)
- , mInstanceCount (1)
- {
- static int iCnt = 0;
-
- // Generate a default name for the node
- char szTemp[128];
- ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
- mName = szTemp;
-
- aRotationKeys.reserve (20);
- aPositionKeys.reserve (20);
- aScalingKeys.reserve (20);
- }
-
- ~Node()
- {
- for (unsigned int i = 0; i < mChildren.size();++i)
- delete mChildren[i];
- }
-
- //! Pointer to the parent node
- Node* mParent;
-
- //! Holds all child nodes
- std::vector<Node*> mChildren;
-
- //! 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;
-
- //! Position of the node in the hierarchy (tree depth)
- int16_t mHierarchyPos;
-
- //! Index of the node
- int16_t mHierarchyIndex;
-
- //! Rotation keys loaded from the file
- std::vector<aiQuatKey> aRotationKeys;
-
- //! Position keys loaded from the file
- std::vector<aiVectorKey> aPositionKeys;
-
- //! Scaling keys loaded from the file
- std::vector<aiVectorKey> aScalingKeys;
-
-
- // For target lights (spot lights and directional lights):
- // The position of the target
- std::vector< aiVectorKey > aTargetPositionKeys;
-
- // For cameras: the camera roll angle
- std::vector< aiFloatKey > aCameraRollKeys;
-
- //! 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)
- {
- mChildren.push_back(pc);
- pc->mParent = this;
- return *this;
- }
-};
-// ---------------------------------------------------------------------------
-/** Helper structure analogue to aiScene */
-struct Scene
-{
- //! List of all materials loaded
- //! NOTE: 3ds references materials globally
- std::vector<Material> mMaterials;
-
- //! List of all meshes loaded
- std::vector<Mesh> mMeshes;
-
- //! List of all cameras loaded
- std::vector<aiCamera*> mCameras;
-
- //! List of all lights loaded
- std::vector<aiLight*> mLights;
-
- //! Pointer to the root node of the scene
- // --- moved to main class
- // Node* pcRootNode;
-};
-
-
-} // end of namespace D3DS
-} // end of namespace Assimp
-
-#endif // AI_XFILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/3DSLoader.cpp b/src/3rdparty/assimp/code/3DSLoader.cpp
deleted file mode 100644
index 704884a57..000000000
--- a/src/3rdparty/assimp/code/3DSLoader.cpp
+++ /dev/null
@@ -1,1433 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 3DSLoader.cpp
- * @brief Implementation of the 3ds importer class
- *
- * http://www.the-labs.com/Blender/3DS-details.html
- */
-
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "3DSLoader.h"
-#include "Macros.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include "StringComparison.h"
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Discreet 3DS Importer",
- "",
- "",
- "Limited animation support",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "3ds prj"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Begins a new parsing block
-// - Reads the current chunk and validates it
-// - computes its length
-#define ASSIMP_3DS_BEGIN_CHUNK() \
- while (true) { \
- if (stream->GetRemainingSizeToLimit() < sizeof(Discreet3DS::Chunk)){ \
- return; \
- } \
- Discreet3DS::Chunk chunk; \
- ReadChunk(&chunk); \
- int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
- if(chunkSize <= 0) \
- continue; \
- const unsigned int oldReadLimit = stream->SetReadLimit( \
- stream->GetCurrentPos() + chunkSize); \
-
-
-// ------------------------------------------------------------------------------------------------
-// End a parsing block
-// Must follow at the end of each parsing block, reset chunk end marker to previous value
-#define ASSIMP_3DS_END_CHUNK() \
- stream->SkipToReadLimit(); \
- stream->SetReadLimit(oldReadLimit); \
- if (stream->GetRemainingSizeToLimit() == 0) \
- return; \
- }
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-Discreet3DSImporter::Discreet3DSImporter()
- : stream(),
- mLastNodeIndex(),
- mCurrentNode(),
- mRootNode(),
- mScene(),
- mMasterScale(),
- bHasBG(),
- bIsPrj()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
- if(extension == "3ds" || extension == "prj" ) {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint16_t token[3];
- token[0] = 0x4d4d;
- token[1] = 0x3dc2;
- //token[2] = 0x3daa;
- return CheckMagicToken(pIOHandler,pFile,token,2,0,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader registry entry
-const aiImporterDesc* Discreet3DSImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void Discreet3DSImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
- this->stream = &stream;
-
- // We should have at least one chunk
- if (stream.GetRemainingSize() < 16) {
- throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
- }
-
- // Allocate our temporary 3DS representation
- mScene = new D3DS::Scene();
-
- // Initialize members
- mLastNodeIndex = -1;
- mCurrentNode = new D3DS::Node();
- mRootNode = mCurrentNode;
- mRootNode->mHierarchyPos = -1;
- mRootNode->mHierarchyIndex = -1;
- mRootNode->mParent = NULL;
- mMasterScale = 1.0f;
- mBackgroundImage = "";
- bHasBG = false;
- bIsPrj = false;
-
- // Parse the file
- ParseMainChunk();
-
- // Process all meshes in the file. First check whether all
- // face indices have valid values. The generate our
- // internal verbose representation. Finally compute normal
- // vectors from the smoothing groups we read from the
- // file.
- for (auto &mesh : mScene->mMeshes) {
- if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
- delete mScene;
- throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
- }
- CheckIndices(mesh);
- MakeUnique (mesh);
- ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
- }
-
- // Replace all occurrences of the default material with a
- // valid material. Generate it if no material containing
- // DEFAULT in its name has been found in the file
- ReplaceDefaultMaterial();
-
- // Convert the scene from our internal representation to an
- // aiScene object. This involves copying all meshes, lights
- // and cameras to the scene
- ConvertScene(pScene);
-
- // Generate the node graph for the scene. This is a little bit
- // tricky since we'll need to split some meshes into submeshes
- GenerateNodeGraph(pScene);
-
- // Now apply the master scaling factor to the scene
- ApplyMasterScale(pScene);
-
- // Delete our internal scene representation and the root
- // node, so the whole hierarchy will follow
- delete mRootNode;
- delete mScene;
-
- AI_DEBUG_INVALIDATE_PTR(mRootNode);
- AI_DEBUG_INVALIDATE_PTR(mScene);
- AI_DEBUG_INVALIDATE_PTR(this->stream);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Applies a master-scaling factor to the imported scene
-void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
-{
- // There are some 3DS files with a zero scaling factor
- if (!mMasterScale)mMasterScale = 1.0f;
- else mMasterScale = 1.0f / mMasterScale;
-
- // Construct an uniform scaling matrix and multiply with it
- pScene->mRootNode->mTransformation *= aiMatrix4x4(
- mMasterScale,0.0f, 0.0f, 0.0f,
- 0.0f, mMasterScale,0.0f, 0.0f,
- 0.0f, 0.0f, mMasterScale,0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
- // Check whether a scaling track is assigned to the root node.
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a new chunk from the file
-void Discreet3DSImporter::ReadChunk(Discreet3DS::Chunk* pcOut)
-{
- ai_assert(pcOut != NULL);
-
- pcOut->Flag = stream->GetI2();
- pcOut->Size = stream->GetI4();
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSize())
- throw DeadlyImportError("Chunk is too large");
-
- if (pcOut->Size - sizeof(Discreet3DS::Chunk) > stream->GetRemainingSizeToLimit())
- DefaultLogger::get()->error("3DS: Chunk overflow");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip a chunk
-void Discreet3DSImporter::SkipChunk()
-{
- Discreet3DS::Chunk psChunk;
- ReadChunk(&psChunk);
-
- stream->IncPtr(psChunk.Size-sizeof(Discreet3DS::Chunk));
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Process the primary chunk of the file
-void Discreet3DSImporter::ParseMainChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
-
- case Discreet3DS::CHUNK_PRJ:
- bIsPrj = true;
- case Discreet3DS::CHUNK_MAIN:
- ParseEditorChunk();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
- // recursively continue processing this hierarchy level
- return ParseMainChunk();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseEditorChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_OBJMESH:
-
- ParseObjectChunk();
- break;
-
- // NOTE: In several documentations in the internet this
- // chunk appears at different locations
- case Discreet3DS::CHUNK_KEYFRAMER:
-
- ParseKeyframeChunk();
- break;
-
- case Discreet3DS::CHUNK_VERSION:
- {
- // print the version number
- char buff[10];
- ASSIMP_itoa10(buff,stream->GetI2());
- DefaultLogger::get()->info(std::string("3DS file format version: ") + buff);
- }
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseObjectChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_OBJBLOCK:
- {
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
-
- // Get the name of the geometry object
- while (stream->GetI1())++cnt;
- ParseChunk(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_MATERIAL:
-
- // Add a new material to the list
- mScene->mMaterials.push_back(D3DS::Material());
- ParseMaterialChunk();
- break;
-
- case Discreet3DS::CHUNK_AMBCOLOR:
-
- // This is the ambient base color of the scene.
- // We add it to the ambient color of all materials
- ParseColorChunk(&mClrAmbient,true);
- if (is_qnan(mClrAmbient.r))
- {
- // We failed to read the ambient base color.
- DefaultLogger::get()->error("3DS: Failed to read ambient base color");
- mClrAmbient.r = mClrAmbient.g = mClrAmbient.b = 0.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_BIT_MAP:
- {
- // Specifies the background image. The string should already be
- // properly 0 terminated but we need to be sure
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
- while (stream->GetI1())++cnt;
- mBackgroundImage = std::string(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_BIT_MAP_EXISTS:
- bHasBG = true;
- break;
-
- case Discreet3DS::CHUNK_MASTER_SCALE:
- // Scene master scaling factor
- mMasterScale = stream->GetF4();
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // IMPLEMENTATION NOTE;
- // Cameras or lights define their transformation in their parent node and in the
- // corresponding light or camera chunks. However, we read and process the latter
- // to to be able to return valid cameras/lights even if no scenegraph is given.
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRIMESH:
- {
- // this starts a new triangle mesh
- mScene->mMeshes.push_back(D3DS::Mesh());
- D3DS::Mesh& m = mScene->mMeshes.back();
-
- // Setup the name of the mesh
- m.mName = std::string(name, num);
-
- // Read mesh chunks
- ParseMeshChunk();
- }
- break;
-
- case Discreet3DS::CHUNK_LIGHT:
- {
- // This starts a new light
- aiLight* light = new aiLight();
- mScene->mLights.push_back(light);
-
- light->mName.Set(std::string(name, num));
-
- // First read the position of the light
- light->mPosition.x = stream->GetF4();
- light->mPosition.y = stream->GetF4();
- light->mPosition.z = stream->GetF4();
-
- light->mColorDiffuse = aiColor3D(1.f,1.f,1.f);
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */
- ParseLightChunk();
-
- // The specular light color is identical the the diffuse light color. The ambient light color
- // is equal to the ambient base color of the whole scene.
- light->mColorSpecular = light->mColorDiffuse;
- light->mColorAmbient = mClrAmbient;
-
- if (light->mType == aiLightSource_UNDEFINED)
- {
- // It must be a point light
- light->mType = aiLightSource_POINT;
- }}
- break;
-
- case Discreet3DS::CHUNK_CAMERA:
- {
- // This starts a new camera
- aiCamera* camera = new aiCamera();
- mScene->mCameras.push_back(camera);
- camera->mName.Set(std::string(name, num));
-
- // First read the position of the camera
- camera->mPosition.x = stream->GetF4();
- camera->mPosition.y = stream->GetF4();
- camera->mPosition.z = stream->GetF4();
-
- // Then the camera target
- camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
- camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
- camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
- ai_real len = camera->mLookAt.Length();
- if (len < 1e-5) {
-
- // There are some files with lookat == position. Don't know why or whether it's ok or not.
- DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
- camera->mLookAt = aiVector3D(0.0,1.0,0.0);
-
- }
- else camera->mLookAt /= len;
-
- // And finally - the camera rotation angle, in counter clockwise direction
- const ai_real angle = AI_DEG_TO_RAD( stream->GetF4() );
- aiQuaternion quat(camera->mLookAt,angle);
- camera->mUp = quat.GetMatrix() * aiVector3D(0.0,1.0,0.0);
-
- // Read the lense angle
- camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
- if (camera->mHorizontalFOV < 0.001f) {
- camera->mHorizontalFOV = AI_DEG_TO_RAD(45.f);
- }
-
- // Now check for further subchunks
- if (!bIsPrj) /* fixme */ {
- ParseCameraChunk();
- }}
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseLightChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- aiLight* light = mScene->mLights.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_DL_SPOTLIGHT:
- // Now we can be sure that the light is a spot light
- light->mType = aiLightSource_SPOT;
-
- // We wouldn't need to normalize here, but we do it
- light->mDirection.x = stream->GetF4() - light->mPosition.x;
- light->mDirection.y = stream->GetF4() - light->mPosition.y;
- light->mDirection.z = stream->GetF4() - light->mPosition.z;
- light->mDirection.Normalize();
-
- // Now the hotspot and falloff angles - in degrees
- light->mAngleInnerCone = AI_DEG_TO_RAD( stream->GetF4() );
-
- // FIX: the falloff angle is just an offset
- light->mAngleOuterCone = light->mAngleInnerCone+AI_DEG_TO_RAD( stream->GetF4() );
- break;
-
- // intensity multiplier
- case Discreet3DS::CHUNK_DL_MULTIPLIER:
- light->mColorDiffuse = light->mColorDiffuse * stream->GetF4();
- break;
-
- // light color
- case Discreet3DS::CHUNK_RGBF:
- case Discreet3DS::CHUNK_LINRGBF:
- light->mColorDiffuse.r *= stream->GetF4();
- light->mColorDiffuse.g *= stream->GetF4();
- light->mColorDiffuse.b *= stream->GetF4();
- break;
-
- // light attenuation
- case Discreet3DS::CHUNK_DL_ATTENUATE:
- light->mAttenuationLinear = stream->GetF4();
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseCameraChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- aiCamera* camera = mScene->mCameras.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- // near and far clip plane
- case Discreet3DS::CHUNK_CAM_RANGES:
- camera->mClipPlaneNear = stream->GetF4();
- camera->mClipPlaneFar = stream->GetF4();
- break;
- }
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseKeyframeChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRACKCAMTGT:
- case Discreet3DS::CHUNK_TRACKSPOTL:
- case Discreet3DS::CHUNK_TRACKCAMERA:
- case Discreet3DS::CHUNK_TRACKINFO:
- case Discreet3DS::CHUNK_TRACKLIGHT:
- case Discreet3DS::CHUNK_TRACKLIGTGT:
-
- // this starts a new mesh hierarchy chunk
- ParseHierarchyChunk(chunk.Flag);
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Little helper function for ParseHierarchyChunk
-void Discreet3DSImporter::InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent)
-{
- if (!pcCurrent) {
- mRootNode->push_back(pcNode);
- return;
- }
-
- if (pcCurrent->mHierarchyPos == pcNode->mHierarchyPos) {
- if(pcCurrent->mParent) {
- pcCurrent->mParent->push_back(pcNode);
- }
- else pcCurrent->push_back(pcNode);
- return;
- }
- return InverseNodeSearch(pcNode,pcCurrent->mParent);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a node with a specific name in the import hierarchy
-D3DS::Node* FindNode(D3DS::Node* root, const std::string& name)
-{
- if (root->mName == name)
- return root;
- for (std::vector<D3DS::Node*>::iterator it = root->mChildren.begin();it != root->mChildren.end(); ++it) {
- D3DS::Node* nd;
- if (( nd = FindNode(*it,name)))
- return nd;
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Binary predicate for std::unique()
-template <class T>
-bool KeyUniqueCompare(const T& first, const T& second)
-{
- return first.mTime == second.mTime;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip some additional import data.
-void Discreet3DSImporter::SkipTCBInfo()
-{
- unsigned int flags = stream->GetI2();
-
- if (!flags) {
- // Currently we can't do anything with these values. They occur
- // quite rare, so it wouldn't be worth the effort implementing
- // them. 3DS ist not really suitable for complex animations,
- // so full support is not required.
- DefaultLogger::get()->warn("3DS: Skipping TCB animation info");
- }
-
- if (flags & Discreet3DS::KEY_USE_TENS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_BIAS) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_CONT) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_FROM) {
- stream->IncPtr(4);
- }
- if (flags & Discreet3DS::KEY_USE_EASE_TO) {
- stream->IncPtr(4);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read hierarchy and keyframe info
-void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_TRACKOBJNAME:
-
- // This is the name of the object to which the track applies. The chunk also
- // defines the position of this object in the hierarchy.
- {
-
- // First of all: get the name of the object
- unsigned int cnt = 0;
- const char* sz = (const char*)stream->GetPtr();
-
- while (stream->GetI1())++cnt;
- std::string name = std::string(sz,cnt);
-
- // 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);
- int instanceNumber = 1;
-
- if ( pcNode)
- {
- // if the source is not a CHUNK_TRACKINFO block it won't 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);
-
- // Now read the hierarchy position of the object
- uint16_t hierarchy = stream->GetI2() + 1;
- pcNode->mHierarchyPos = hierarchy;
- pcNode->mHierarchyIndex = mLastNodeIndex;
-
- // And find a proper position in the graph for it
- if (mCurrentNode && mCurrentNode->mHierarchyPos == hierarchy) {
-
- // add to the parent of the last touched node
- mCurrentNode->mParent->push_back(pcNode);
- mLastNodeIndex++;
- }
- else if(hierarchy >= mLastNodeIndex) {
-
- // place it at the current position in the hierarchy
- mCurrentNode->push_back(pcNode);
- mLastNodeIndex = hierarchy;
- }
- else {
- // need to go back to the specified position in the hierarchy.
- InverseNodeSearch(pcNode,mCurrentNode);
- mLastNodeIndex++;
- }
- // Make this node the current node
- mCurrentNode = pcNode;
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKDUMMYOBJNAME:
-
- // This is the "real" name of a $$$DUMMY object
- {
- const char* sz = (const char*) stream->GetPtr();
- while (stream->GetI1());
-
- // If object name is DUMMY, take this one instead
- if (mCurrentNode->mName == "$$$DUMMY") {
- //DefaultLogger::get()->warn("3DS: Skipping dummy object name for non-dummy object");
- mCurrentNode->mName = std::string(sz);
- break;
- }
- }
- break;
-
- case Discreet3DS::CHUNK_TRACKPIVOT:
-
- if ( Discreet3DS::CHUNK_TRACKINFO != parent)
- {
- DefaultLogger::get()->warn("3DS: Skipping pivot subchunk for non usual object");
- break;
- }
-
- // Pivot = origin of rotation and scaling
- mCurrentNode->vPivot.x = stream->GetF4();
- mCurrentNode->vPivot.y = stream->GetF4();
- mCurrentNode->vPivot.z = stream->GetF4();
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // POSITION KEYFRAME
- case Discreet3DS::CHUNK_TRACKPOS:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- bool sortKeys = false;
-
- // This could also be meant as the target position for
- // (targeted) lights and cameras
- std::vector<aiVectorKey>* l;
- if ( Discreet3DS::CHUNK_TRACKCAMTGT == parent || Discreet3DS::CHUNK_TRACKLIGTGT == parent) {
- l = & mCurrentNode->aTargetPositionKeys;
- }
- else l = & mCurrentNode->aPositionKeys;
-
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- SkipTCBInfo();
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
- }}
-
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA ROLL KEYFRAME
- case Discreet3DS::CHUNK_TRACKROLL:
- {
- // roll keys are accepted for cameras only
- if (parent != Discreet3DS::CHUNK_TRACKCAMERA) {
- DefaultLogger::get()->warn("3DS: Ignoring roll track for non-camera object");
- break;
- }
- bool sortKeys = false;
- std::vector<aiFloatKey>* l = &mCurrentNode->aCameraRollKeys;
-
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
- l->reserve(numFrames);
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
-
- // Setup a new position key
- aiFloatKey v;
- v.mTime = (double)fidx;
-
- // This is just a single float
- SkipTCBInfo();
- v.mValue = stream->GetF4();
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Add the new keyframe to the list
- l->push_back(v);
- }
-
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiFloatKey>), l->end() );
- }}
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // CAMERA FOV KEYFRAME
- case Discreet3DS::CHUNK_TRACKFOV:
- {
- DefaultLogger::get()->error("3DS: Skipping FOV animation track. "
- "This is not supported");
- }
- break;
-
-
- // ////////////////////////////////////////////////////////////////////
- // ROTATION KEYFRAME
- case Discreet3DS::CHUNK_TRACKROTATE:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI4();
-
- bool sortKeys = false;
- std::vector<aiQuatKey>* l = &mCurrentNode->aRotationKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- aiQuatKey v;
- v.mTime = (double)fidx;
-
- // The rotation keyframe is given as an axis-angle pair
- const float rad = stream->GetF4();
- aiVector3D axis;
- axis.x = stream->GetF4();
- axis.y = stream->GetF4();
- axis.z = stream->GetF4();
-
- if (!axis.x && !axis.y && !axis.z)
- axis.y = 1.f;
-
- // Construct a rotation quaternion from the axis-angle pair
- v.mValue = aiQuaternion(axis,rad);
-
- // Check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // add the new keyframe to the list
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiQuatKey>), l->end() );
- }}
- break;
-
- // ////////////////////////////////////////////////////////////////////
- // SCALING KEYFRAME
- case Discreet3DS::CHUNK_TRACKSCALE:
- {
- stream->IncPtr(10);
- const unsigned int numFrames = stream->GetI2();
- stream->IncPtr(2);
-
- bool sortKeys = false;
- std::vector<aiVectorKey>* l = &mCurrentNode->aScalingKeys;
- l->reserve(numFrames);
-
- for (unsigned int i = 0; i < numFrames;++i) {
- const unsigned int fidx = stream->GetI4();
- SkipTCBInfo();
-
- // Setup a new key
- aiVectorKey v;
- v.mTime = (double)fidx;
-
- // ... and read its value
- v.mValue.x = stream->GetF4();
- v.mValue.y = stream->GetF4();
- v.mValue.z = stream->GetF4();
-
- // check whether we'll need to sort the keys
- if (!l->empty() && v.mTime <= l->back().mTime)
- sortKeys = true;
-
- // Remove zero-scalings on singular axes - they've been reported to be there erroneously in some strange files
- if (!v.mValue.x) v.mValue.x = 1.f;
- if (!v.mValue.y) v.mValue.y = 1.f;
- if (!v.mValue.z) v.mValue.z = 1.f;
-
- l->push_back(v);
- }
- // Sort all keys with ascending time values and remove duplicates?
- if (sortKeys) {
- std::stable_sort(l->begin(),l->end());
- l->erase ( std::unique (l->begin(),l->end(),&KeyUniqueCompare<aiVectorKey>), l->end() );
- }}
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a face chunk - it contains smoothing groups and material assignments
-void Discreet3DSImporter::ParseFaceChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh& mMesh = mScene->mMeshes.back();
-
- // Get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_SMOOLIST:
- {
- // This is the list of smoothing groups - a bitfield for every face.
- // Up to 32 smoothing groups assigned to a single face.
- unsigned int num = chunkSize/4, m = 0;
- if (num > mMesh.mFaces.size()) {
- throw DeadlyImportError("3DS: More smoothing groups than faces");
- }
- for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) {
- // nth bit is set for nth smoothing group
- (*i).iSmoothGroup = stream->GetI4();
- }}
- break;
-
- case Discreet3DS::CHUNK_FACEMAT:
- {
- // at fist an asciiz with the material name
- const char* sz = (const char*)stream->GetPtr();
- while (stream->GetI1());
-
- // find the index of the material
- unsigned int idx = 0xcdcdcdcd, cnt = 0;
- for (std::vector<D3DS::Material>::const_iterator i = mScene->mMaterials.begin();i != mScene->mMaterials.end();++i,++cnt) {
- // use case independent comparisons. hopefully it will work.
- if ((*i).mName.length() && !ASSIMP_stricmp(sz, (*i).mName.c_str())) {
- idx = cnt;
- break;
- }
- }
- if (0xcdcdcdcd == idx) {
- DefaultLogger::get()->error(std::string("3DS: Unknown material: ") + sz);
- }
-
- // Now continue and read all material indices
- cnt = (uint16_t)stream->GetI2();
- for (unsigned int i = 0; i < cnt;++i) {
- unsigned int fidx = (uint16_t)stream->GetI2();
-
- // check range
- if (fidx >= mMesh.mFaceMaterials.size()) {
- DefaultLogger::get()->error("3DS: Invalid face index in face material list");
- }
- else mMesh.mFaceMaterials[fidx] = idx;
- }}
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a mesh chunk. Here's the actual mesh data
-void Discreet3DSImporter::ParseMeshChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // Get the mesh we're currently working on
- D3DS::Mesh& mMesh = mScene->mMeshes.back();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_VERTLIST:
- {
- // This is the list of all vertices in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mPositions.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- v.z = stream->GetF4();
- mMesh.mPositions.push_back(v);
- }}
- break;
- case Discreet3DS::CHUNK_TRMATRIX:
- {
- // This is the RLEATIVE transformation matrix of the current mesh. Vertices are
- // pretransformed by this matrix wonder.
- mMesh.mMat.a1 = stream->GetF4();
- mMesh.mMat.b1 = stream->GetF4();
- mMesh.mMat.c1 = stream->GetF4();
- mMesh.mMat.a2 = stream->GetF4();
- mMesh.mMat.b2 = stream->GetF4();
- mMesh.mMat.c2 = stream->GetF4();
- mMesh.mMat.a3 = stream->GetF4();
- mMesh.mMat.b3 = stream->GetF4();
- mMesh.mMat.c3 = stream->GetF4();
- mMesh.mMat.a4 = stream->GetF4();
- mMesh.mMat.b4 = stream->GetF4();
- mMesh.mMat.c4 = stream->GetF4();
- }
- break;
-
- case Discreet3DS::CHUNK_MAPLIST:
- {
- // This is the list of all UV coords in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mTexCoords.reserve(num);
- while (num-- > 0) {
- aiVector3D v;
- v.x = stream->GetF4();
- v.y = stream->GetF4();
- mMesh.mTexCoords.push_back(v);
- }}
- break;
-
- case Discreet3DS::CHUNK_FACELIST:
- {
- // This is the list of all faces in the current mesh
- int num = (int)(uint16_t)stream->GetI2();
- mMesh.mFaces.reserve(num);
- while (num-- > 0) {
- // 3DS faces are ALWAYS triangles
- mMesh.mFaces.push_back(D3DS::Face());
- D3DS::Face& sFace = mMesh.mFaces.back();
-
- sFace.mIndices[0] = (uint16_t)stream->GetI2();
- sFace.mIndices[1] = (uint16_t)stream->GetI2();
- sFace.mIndices[2] = (uint16_t)stream->GetI2();
-
- stream->IncPtr(2); // skip edge visibility flag
- }
-
- // Resize the material array (0xcdcdcdcd marks the default material; so if a face is
- // not referenced by a material, $$DEFAULT will be assigned to it)
- mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
-
- // Larger 3DS files could have multiple FACE chunks here
- chunkSize = stream->GetRemainingSizeToLimit();
- if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
- ParseFaceChunk();
- }
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a 3DS material chunk
-void Discreet3DSImporter::ParseMaterialChunk()
-{
- ASSIMP_3DS_BEGIN_CHUNK();
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_MAT_MATNAME:
-
- {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char* sz = (const char*)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
-
- if (!cnt) {
- // This may not be, we use the default name instead
- DefaultLogger::get()->error("3DS: Empty material name");
- }
- else mScene->mMaterials.back().mName = std::string(sz,cnt);
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_DIFFUSE:
- {
- // This is the diffuse material color
- aiColor3D* pc = &mScene->mMaterials.back().mDiffuse;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read DIFFUSE chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_SPECULAR:
- {
- // This is the specular material color
- aiColor3D* pc = &mScene->mMaterials.back().mSpecular;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read SPECULAR chunk");
- pc->r = pc->g = pc->b = 1.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_AMBIENT:
- {
- // This is the ambient material color
- aiColor3D* pc = &mScene->mMaterials.back().mAmbient;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read AMBIENT chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILLUM:
- {
- // This is the emissive material color
- aiColor3D* pc = &mScene->mMaterials.back().mEmissive;
- ParseColorChunk(pc);
- if (is_qnan(pc->r)) {
- // color chunk is invalid. Simply ignore it
- DefaultLogger::get()->error("3DS: Unable to read EMISSIVE chunk");
- pc->r = pc->g = pc->b = 0.0f;
- }}
- break;
-
- case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
- {
- // This is the material's transparency
- ai_real* pcf = &mScene->mMaterials.back().mTransparency;
- *pcf = ParsePercentageChunk();
-
- // NOTE: transparency, not opacity
- if (is_qnan(*pcf))
- *pcf = ai_real( 1.0 );
- else
- *pcf = ai_real( 1.0 ) - *pcf * (ai_real)0xFFFF / ai_real( 100.0 );
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SHADING:
- // This is the material shading mode
- mScene->mMaterials.back().mShading = (D3DS::Discreet3DS::shadetype3ds)stream->GetI2();
- break;
-
- case Discreet3DS::CHUNK_MAT_TWO_SIDE:
- // This is the two-sided flag
- mScene->mMaterials.back().mTwoSided = true;
- break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS:
- { // This is the shininess of the material
- ai_real* pcf = &mScene->mMaterials.back().mSpecularExponent;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = 0.0;
- else *pcf *= (ai_real)0xFFFF;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
- { // This is the shininess strength of the material
- ai_real* pcf = &mScene->mMaterials.back().mShininessStrength;
- *pcf = ParsePercentageChunk();
- if (is_qnan(*pcf))
- *pcf = ai_real( 0.0 );
- else
- *pcf *= (ai_real)0xffff / ai_real( 100.0 );
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
- { // This is the self illumination strength of the material
- ai_real f = ParsePercentageChunk();
- if (is_qnan(f))
- f = ai_real( 0.0 );
- else
- f *= (ai_real)0xFFFF / ai_real( 100.0 );
- mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
- }
- break;
-
- // Parse texture chunks
- case Discreet3DS::CHUNK_MAT_TEXTURE:
- // Diffuse texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexDiffuse);
- break;
- case Discreet3DS::CHUNK_MAT_BUMPMAP:
- // Height map
- ParseTextureChunk(&mScene->mMaterials.back().sTexBump);
- break;
- case Discreet3DS::CHUNK_MAT_OPACMAP:
- // Opacity texture
- ParseTextureChunk(&mScene->mMaterials.back().sTexOpacity);
- break;
- case Discreet3DS::CHUNK_MAT_MAT_SHINMAP:
- // Shininess map
- ParseTextureChunk(&mScene->mMaterials.back().sTexShininess);
- break;
- case Discreet3DS::CHUNK_MAT_SPECMAP:
- // Specular map
- ParseTextureChunk(&mScene->mMaterials.back().sTexSpecular);
- break;
- case Discreet3DS::CHUNK_MAT_SELFIMAP:
- // Self-illumination (emissive) map
- ParseTextureChunk(&mScene->mMaterials.back().sTexEmissive);
- break;
- case Discreet3DS::CHUNK_MAT_REFLMAP:
- // Reflection map
- ParseTextureChunk(&mScene->mMaterials.back().sTexReflective);
- break;
- };
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
-{
- ASSIMP_3DS_BEGIN_CHUNK();
-
- // get chunk type
- switch (chunk.Flag)
- {
- case Discreet3DS::CHUNK_MAPFILE:
- {
- // The material name string is already zero-terminated, but we need to be sure ...
- const char* sz = (const char*)stream->GetPtr();
- unsigned int cnt = 0;
- while (stream->GetI1())
- ++cnt;
- pcOut->mMapName = std::string(sz,cnt);
- }
- break;
-
-
- case Discreet3DS::CHUNK_PERCENTD:
- // Manually parse the blend factor
- pcOut->mTextureBlend = ai_real( stream->GetF8() );
- break;
-
- case Discreet3DS::CHUNK_PERCENTF:
- // Manually parse the blend factor
- pcOut->mTextureBlend = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_PERCENTW:
- // Manually parse the blend factor
- pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real( 100.0 );
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_USCALE:
- // Texture coordinate scaling in the U direction
- pcOut->mScaleU = stream->GetF4();
- if (0.0f == pcOut->mScaleU)
- {
- DefaultLogger::get()->warn("Texture coordinate scaling in the x direction is zero. Assuming 1.");
- pcOut->mScaleU = 1.0f;
- }
- break;
- case Discreet3DS::CHUNK_MAT_MAP_VSCALE:
- // Texture coordinate scaling in the V direction
- pcOut->mScaleV = stream->GetF4();
- if (0.0f == pcOut->mScaleV)
- {
- DefaultLogger::get()->warn("Texture coordinate scaling in the y direction is zero. Assuming 1.");
- pcOut->mScaleV = 1.0f;
- }
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_UOFFSET:
- // Texture coordinate offset in the U direction
- pcOut->mOffsetU = -stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_VOFFSET:
- // Texture coordinate offset in the V direction
- pcOut->mOffsetV = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_ANG:
- // Texture coordinate rotation, CCW in DEGREES
- pcOut->mRotation = -AI_DEG_TO_RAD( stream->GetF4() );
- break;
-
- case Discreet3DS::CHUNK_MAT_MAP_TILING:
- {
- const uint16_t iFlags = stream->GetI2();
-
- // Get the mapping mode (for both axes)
- if (iFlags & 0x2u)
- pcOut->mMapMode = aiTextureMapMode_Mirror;
-
- else if (iFlags & 0x10u)
- pcOut->mMapMode = aiTextureMapMode_Decal;
-
- // wrapping in all remaining cases
- else pcOut->mMapMode = aiTextureMapMode_Wrap;
- }
- break;
- };
-
- ASSIMP_3DS_END_CHUNK();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a percentage chunk
-ai_real Discreet3DSImporter::ParsePercentageChunk()
-{
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
-
- if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
- return stream->GetF4();
- else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
- return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
- return get_qnan();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
-void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
-{
- ai_assert(out != NULL);
-
- // error return value
- const ai_real qnan = get_qnan();
- static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
-
- Discreet3DS::Chunk chunk;
- ReadChunk(&chunk);
- const unsigned int diff = chunk.Size - sizeof(Discreet3DS::Chunk);
-
- bool bGamma = false;
-
- // Get the type of the chunk
- switch(chunk.Flag)
- {
- case Discreet3DS::CHUNK_LINRGBF:
- bGamma = true;
-
- case Discreet3DS::CHUNK_RGBF:
- if (sizeof(float) * 3 > diff) {
- *out = clrError;
- return;
- }
- out->r = stream->GetF4();
- out->g = stream->GetF4();
- out->b = stream->GetF4();
- break;
-
- case Discreet3DS::CHUNK_LINRGBB:
- bGamma = true;
- case Discreet3DS::CHUNK_RGBB:
- {
- if ( sizeof( char ) * 3 > diff ) {
- *out = clrError;
- return;
- }
- const ai_real invVal = ai_real( 1.0 ) / ai_real( 255.0 );
- out->r = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
- out->g = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
- out->b = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
- }
- break;
-
- // Percentage chunks are accepted, too.
- case Discreet3DS::CHUNK_PERCENTF:
- if (acceptPercent && 4 <= diff) {
- out->g = out->b = out->r = stream->GetF4();
- break;
- }
- *out = clrError;
- return;
-
- case Discreet3DS::CHUNK_PERCENTW:
- if (acceptPercent && 1 <= diff) {
- out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real( 255.0 );
- break;
- }
- *out = clrError;
- return;
-
- default:
- stream->IncPtr(diff);
- // Skip unknown chunks, hope this won't cause any problems.
- return ParseColorChunk(out,acceptPercent);
- };
- (void)bGamma;
-}
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
diff --git a/src/3rdparty/assimp/code/3DSLoader.h b/src/3rdparty/assimp/code/3DSLoader.h
deleted file mode 100644
index 0e377180b..000000000
--- a/src/3rdparty/assimp/code/3DSLoader.h
+++ /dev/null
@@ -1,283 +0,0 @@
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 3DSLoader.h
- * @brief 3DS File format loader
- */
-#ifndef AI_3DSIMPORTER_H_INC
-#define AI_3DSIMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#include "3DSHelper.h"
-#include "StreamReader.h"
-
-struct aiNode;
-
-namespace Assimp {
-
-
-using namespace D3DS;
-
-// ---------------------------------------------------------------------------------
-/** Importer class for 3D Studio r3 and r4 3DS files
- */
-class Discreet3DSImporter : public BaseImporter
-{
-public:
-
- Discreet3DSImporter();
- ~Discreet3DSImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Converts a temporary material to the outer representation
- */
- void ConvertMaterial(D3DS::Material& p_cMat,
- aiMaterial& p_pcOut);
-
- // -------------------------------------------------------------------
- /** Read a chunk
- *
- * @param pcOut Receives the current chunk
- */
- void ReadChunk(Discreet3DS::Chunk* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a percentage chunk. mCurrent will point to the next
- * chunk behind afterwards. If no percentage chunk is found
- * QNAN is returned.
- */
- ai_real ParsePercentageChunk();
-
- // -------------------------------------------------------------------
- /** Parse a color chunk. mCurrent will point to the next
- * chunk behind afterwards. If no color chunk is found
- * QNAN is returned in all members.
- */
- void ParseColorChunk(aiColor3D* p_pcOut,
- bool p_bAcceptPercent = true);
-
-
- // -------------------------------------------------------------------
- /** Skip a chunk in the file
- */
- void SkipChunk();
-
- // -------------------------------------------------------------------
- /** Generate the nodegraph
- */
- void GenerateNodeGraph(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Parse a main top-level chunk in the file
- */
- void ParseMainChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level chunk in the file
- */
- void ParseChunk(const char* name, unsigned int num);
-
- // -------------------------------------------------------------------
- /** Parse a top-level editor chunk in the file
- */
- void ParseEditorChunk();
-
- // -------------------------------------------------------------------
- /** Parse a top-level object chunk in the file
- */
- void ParseObjectChunk();
-
- // -------------------------------------------------------------------
- /** Parse a material chunk in the file
- */
- void ParseMaterialChunk();
-
- // -------------------------------------------------------------------
- /** Parse a mesh chunk in the file
- */
- void ParseMeshChunk();
-
- // -------------------------------------------------------------------
- /** Parse a light chunk in the file
- */
- void ParseLightChunk();
-
- // -------------------------------------------------------------------
- /** Parse a camera chunk in the file
- */
- void ParseCameraChunk();
-
- // -------------------------------------------------------------------
- /** Parse a face list chunk in the file
- */
- void ParseFaceChunk();
-
- // -------------------------------------------------------------------
- /** Parse a keyframe chunk in the file
- */
- void ParseKeyframeChunk();
-
- // -------------------------------------------------------------------
- /** Parse a hierarchy chunk in the file
- */
- void ParseHierarchyChunk(uint16_t parent);
-
- // -------------------------------------------------------------------
- /** Parse a texture chunk in the file
- */
- void ParseTextureChunk(D3DS::Texture* pcOut);
-
- // -------------------------------------------------------------------
- /** Convert the meshes in the file
- */
- void ConvertMeshes(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** Replace the default material in the scene
- */
- void ReplaceDefaultMaterial();
-
- // -------------------------------------------------------------------
- /** Convert the whole scene
- */
- void ConvertScene(aiScene* pcOut);
-
- // -------------------------------------------------------------------
- /** generate unique vertices for a mesh
- */
- void MakeUnique(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Add a node to the node graph
- */
- void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
- aiMatrix4x4& absTrafo);
-
- // -------------------------------------------------------------------
- /** Search for a node in the graph.
- * Called recursively
- */
- void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
-
- // -------------------------------------------------------------------
- /** Apply the master scaling factor to the mesh
- */
- void ApplyMasterScale(aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Clamp all indices in the file to a valid range
- */
- void CheckIndices(D3DS::Mesh& sMesh);
-
- // -------------------------------------------------------------------
- /** Skip the TCB info in a track key
- */
- void SkipTCBInfo();
-
-protected:
-
- /** Stream to read from */
- StreamReaderLE* stream;
-
- /** Last touched node index */
- short mLastNodeIndex;
-
- /** Current node, root node */
- D3DS::Node* mCurrentNode, *mRootNode;
-
- /** Scene under construction */
- D3DS::Scene* mScene;
-
- /** Ambient base color of the scene */
- aiColor3D mClrAmbient;
-
- /** Master scaling factor of the scene */
- ai_real mMasterScale;
-
- /** Path to the background image of the scene */
- std::string mBackgroundImage;
- bool bHasBG;
-
- /** true if PRJ file */
- bool bIsPrj;
-};
-
-} // end of namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/3MFXmlTags.h b/src/3rdparty/assimp/code/3MFXmlTags.h
deleted file mode 100644
index 7e47422f1..000000000
--- a/src/3rdparty/assimp/code/3MFXmlTags.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-namespace Assimp {
-namespace D3MF {
-
-namespace XmlTag {
- static const std::string model = "model";
- static const std::string model_unit = "unit";
- static const std::string metadata = "metadata";
- static const std::string resources = "resources";
- static const std::string object = "object";
- static const std::string mesh = "mesh";
- static const std::string vertices = "vertices";
- static const std::string vertex = "vertex";
- static const std::string triangles = "triangles";
- static const std::string triangle = "triangle";
- static const std::string x = "x";
- static const std::string y = "y";
- static const std::string z = "z";
- static const std::string v1 = "v1";
- static const std::string v2 = "v2";
- static const std::string v3 = "v3";
- static const std::string id = "id";
- static const std::string name = "name";
- static const std::string type = "type";
- static const std::string build = "build";
- static const std::string item = "item";
- static const std::string objectid = "objectid";
- static const std::string transform = "transform";
-
- static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
- static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
- static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
- static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
- static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
- static const std::string RELS_RELATIONSHIP_NODE = "Relationship";
- static const std::string RELS_ATTRIB_TARGET = "Target";
- static const std::string RELS_ATTRIB_TYPE = "Type";
- static const std::string RELS_ATTRIB_ID = "Id";
- static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
- static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
- static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
- static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
- static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
-
-}
-
-} // Namespace D3MF
-} // Namespace Assimp
diff --git a/src/3rdparty/assimp/code/ACLoader.cpp b/src/3rdparty/assimp/code/ACLoader.cpp
deleted file mode 100644
index a30baa75a..000000000
--- a/src/3rdparty/assimp/code/ACLoader.cpp
+++ /dev/null
@@ -1,909 +0,0 @@
-
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the AC3D importer class */
-
-
-
-#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-
-// internal headers
-#include "ACLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "Subdivision.h"
-#include "Importer.h"
-#include "BaseImporter.h"
-#include <assimp/Importer.hpp>
-#include <assimp/light.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <assimp/config.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "AC3D Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "ac acc ac3d"
-};
-
-// ------------------------------------------------------------------------------------------------
-// skip to the next token
-#define AI_AC_SKIP_TO_NEXT_TOKEN() \
- if (!SkipSpaces(&buffer)) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL"); \
- continue; \
- }
-
-// ------------------------------------------------------------------------------------------------
-// read a string (may be enclosed in double quotation marks). buffer must point to "
-#define AI_AC_GET_STRING(out) \
- if (*buffer == '\0') { \
- throw DeadlyImportError("AC3D: Unexpected EOF in string"); \
- } \
- ++buffer; \
- const char* sz = buffer; \
- while ('\"' != *buffer) \
- { \
- if (IsLineEnd( *buffer )) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpected EOF/EOL in string"); \
- out = "ERROR"; \
- break; \
- } \
- ++buffer; \
- } \
- if (IsLineEnd( *buffer ))continue; \
- out = std::string(sz,(unsigned int)(buffer-sz)); \
- ++buffer;
-
-
-// ------------------------------------------------------------------------------------------------
-// read 1 to n floats prefixed with an optional predefined identifier
-#define AI_AC_CHECKED_LOAD_FLOAT_ARRAY(name,name_length,num,out) \
- AI_AC_SKIP_TO_NEXT_TOKEN(); \
- if (name_length) \
- { \
- if (strncmp(buffer,name,name_length) || !IsSpace(buffer[name_length])) \
- { \
- DefaultLogger::get()->error("AC3D: Unexpexted token. " name " was expected."); \
- continue; \
- } \
- buffer += name_length+1; \
- } \
- for (unsigned int i = 0; i < num;++i) \
- { \
- AI_AC_SKIP_TO_NEXT_TOKEN(); \
- buffer = fast_atoreal_move<float>(buffer,((float*)out)[i]); \
- }
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-AC3DImporter::AC3DImporter()
- : buffer(),
- configSplitBFCull(),
- configEvalSubdivision(),
- mNumMeshes(),
- mLights(),
- lights(),
- groups(),
- polys(),
- worlds()
-{
- // nothing to be done here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-AC3DImporter::~AC3DImporter()
-{
- // nothing to be done here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool AC3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
-
- // fixme: are acc and ac3d *really* used? Some sources say they are
- if(extension == "ac" || extension == "ac3d" || extension == "acc") {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint32_t token = AI_MAKE_MAGIC("AC3D");
- return CheckMagicToken(pIOHandler,pFile,&token,1,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader meta information
-const aiImporterDesc* AC3DImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a pointer to the next line from the file
-bool AC3DImporter::GetNextLine( )
-{
- SkipLine(&buffer);
- return SkipSpaces(&buffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse an object section in an AC file
-void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
-{
- if (!TokenMatch(buffer,"OBJECT",6))
- return;
-
- SkipSpaces(&buffer);
-
- ++mNumMeshes;
-
- objects.push_back(Object());
- Object& obj = objects.back();
-
- aiLight* light = NULL;
- if (!ASSIMP_strincmp(buffer,"light",5))
- {
- // This is a light source. Add it to the list
- mLights->push_back(light = new aiLight());
-
- // Return a point light with no attenuation
- light->mType = aiLightSource_POINT;
- light->mColorDiffuse = light->mColorSpecular = aiColor3D(1.f,1.f,1.f);
- light->mAttenuationConstant = 1.f;
-
- // Generate a default name for both the light source and the node
- // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
- light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
- obj.name = std::string( light->mName.data );
-
- DefaultLogger::get()->debug("AC3D: Light source encountered");
- obj.type = Object::Light;
- }
- else if (!ASSIMP_strincmp(buffer,"group",5))
- {
- obj.type = Object::Group;
- }
- else if (!ASSIMP_strincmp(buffer,"world",5))
- {
- obj.type = Object::World;
- }
- else obj.type = Object::Poly;
- while (GetNextLine())
- {
- if (TokenMatch(buffer,"kids",4))
- {
- SkipSpaces(&buffer);
- unsigned int num = strtoul10(buffer,&buffer);
- GetNextLine();
- if (num)
- {
- // load the children of this object recursively
- obj.children.reserve(num);
- for (unsigned int i = 0; i < num; ++i)
- LoadObjectSection(obj.children);
- }
- return;
- }
- else if (TokenMatch(buffer,"name",4))
- {
- SkipSpaces(&buffer);
- AI_AC_GET_STRING(obj.name);
-
- // If this is a light source, we'll also need to store
- // the name of the node in it.
- if (light)
- {
- light->mName.Set(obj.name);
- }
- }
- else if (TokenMatch(buffer,"texture",7))
- {
- SkipSpaces(&buffer);
- AI_AC_GET_STRING(obj.texture);
- }
- else if (TokenMatch(buffer,"texrep",6))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texRepeat);
- if (!obj.texRepeat.x || !obj.texRepeat.y)
- obj.texRepeat = aiVector2D (1.f,1.f);
- }
- else if (TokenMatch(buffer,"texoff",6))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&obj.texOffset);
- }
- else if (TokenMatch(buffer,"rot",3))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,9,&obj.rotation);
- }
- else if (TokenMatch(buffer,"loc",3))
- {
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&obj.translation);
- }
- else if (TokenMatch(buffer,"subdiv",6))
- {
- SkipSpaces(&buffer);
- obj.subDiv = strtoul10(buffer,&buffer);
- }
- else if (TokenMatch(buffer,"crease",6))
- {
- SkipSpaces(&buffer);
- obj.crease = fast_atof(buffer);
- }
- else if (TokenMatch(buffer,"numvert",7))
- {
- SkipSpaces(&buffer);
-
- unsigned int t = strtoul10(buffer,&buffer);
- if (t >= AI_MAX_ALLOC(aiVector3D)) {
- throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
- }
- obj.vertices.reserve(t);
- for (unsigned int i = 0; i < t;++i)
- {
- if (!GetNextLine())
- {
- DefaultLogger::get()->error("AC3D: Unexpected EOF: not all vertices have been parsed yet");
- break;
- }
- else if (!IsNumeric(*buffer))
- {
- DefaultLogger::get()->error("AC3D: Unexpected token: not all vertices have been parsed yet");
- --buffer; // make sure the line is processed a second time
- break;
- }
- obj.vertices.push_back(aiVector3D());
- aiVector3D& v = obj.vertices.back();
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,3,&v.x);
- }
- }
- else if (TokenMatch(buffer,"numsurf",7))
- {
- SkipSpaces(&buffer);
-
- bool Q3DWorkAround = false;
-
- const unsigned int t = strtoul10(buffer,&buffer);
- obj.surfaces.reserve(t);
- for (unsigned int i = 0; i < t;++i)
- {
- GetNextLine();
- if (!TokenMatch(buffer,"SURF",4))
- {
- // FIX: this can occur for some files - Quick 3D for
- // example writes no surf chunks
- if (!Q3DWorkAround)
- {
- DefaultLogger::get()->warn("AC3D: SURF token was expected");
- DefaultLogger::get()->debug("Continuing with Quick3D Workaround enabled");
- }
- --buffer; // make sure the line is processed a second time
- // break; --- see fix notes above
-
- Q3DWorkAround = true;
- }
- SkipSpaces(&buffer);
- obj.surfaces.push_back(Surface());
- Surface& surf = obj.surfaces.back();
- surf.flags = strtoul_cppstyle(buffer);
-
- while (1)
- {
- if(!GetNextLine())
- {
- throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
- }
- if (TokenMatch(buffer,"mat",3))
- {
- SkipSpaces(&buffer);
- surf.mat = strtoul10(buffer);
- }
- else if (TokenMatch(buffer,"refs",4))
- {
- // --- see fix notes above
- if (Q3DWorkAround)
- {
- if (!surf.entries.empty())
- {
- buffer -= 6;
- break;
- }
- }
-
- SkipSpaces(&buffer);
- const unsigned int m = strtoul10(buffer);
- surf.entries.reserve(m);
-
- obj.numRefs += m;
-
- for (unsigned int k = 0; k < m; ++k)
- {
- if(!GetNextLine())
- {
- DefaultLogger::get()->error("AC3D: Unexpected EOF: surface references are incomplete");
- break;
- }
- surf.entries.push_back(Surface::SurfaceEntry());
- Surface::SurfaceEntry& entry = surf.entries.back();
-
- entry.first = strtoul10(buffer,&buffer);
- SkipSpaces(&buffer);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("",0,2,&entry.second);
- }
- }
- else
- {
-
- --buffer; // make sure the line is processed a second time
- break;
- }
- }
- }
- }
- }
- DefaultLogger::get()->error("AC3D: Unexpected EOF: \'kids\' line was expected");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a material from AC3DImporter::Material to aiMaterial
-void AC3DImporter::ConvertMaterial(const Object& object,
- const Material& matSrc,
- aiMaterial& matDest)
-{
- aiString s;
-
- if (matSrc.name.length())
- {
- s.Set(matSrc.name);
- matDest.AddProperty(&s,AI_MATKEY_NAME);
- }
- if (object.texture.length())
- {
- s.Set(object.texture);
- matDest.AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // UV transformation
- if (1.f != object.texRepeat.x || 1.f != object.texRepeat.y ||
- object.texOffset.x || object.texOffset.y)
- {
- aiUVTransform transform;
- transform.mScaling = object.texRepeat;
- transform.mTranslation = object.texOffset;
- matDest.AddProperty(&transform,1,AI_MATKEY_UVTRANSFORM_DIFFUSE(0));
- }
- }
-
- matDest.AddProperty<aiColor3D>(&matSrc.rgb,1, AI_MATKEY_COLOR_DIFFUSE);
- matDest.AddProperty<aiColor3D>(&matSrc.amb,1, AI_MATKEY_COLOR_AMBIENT);
- matDest.AddProperty<aiColor3D>(&matSrc.emis,1,AI_MATKEY_COLOR_EMISSIVE);
- matDest.AddProperty<aiColor3D>(&matSrc.spec,1,AI_MATKEY_COLOR_SPECULAR);
-
- int n;
- if (matSrc.shin)
- {
- n = aiShadingMode_Phong;
- matDest.AddProperty<float>(&matSrc.shin,1,AI_MATKEY_SHININESS);
- }
- else n = aiShadingMode_Gouraud;
- matDest.AddProperty<int>(&n,1,AI_MATKEY_SHADING_MODEL);
-
- float f = 1.f - matSrc.trans;
- matDest.AddProperty<float>(&f,1,AI_MATKEY_OPACITY);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the loaded data to the internal verbose representation
-aiNode* AC3DImporter::ConvertObjectSection(Object& object,
- std::vector<aiMesh*>& meshes,
- std::vector<aiMaterial*>& outMaterials,
- const std::vector<Material>& materials,
- aiNode* parent)
-{
- aiNode* node = new aiNode();
- node->mParent = parent;
- if (object.vertices.size())
- {
- if (!object.surfaces.size() || !object.numRefs)
- {
- /* " An object with 7 vertices (no surfaces, no materials defined).
- This is a good way of getting point data into AC3D.
- The Vertex->create convex-surface/object can be used on these
- vertices to 'wrap' a 3d shape around them "
- (http://www.opencity.info/html/ac3dfileformat.html)
-
- therefore: if no surfaces are defined return point data only
- */
-
- DefaultLogger::get()->info("AC3D: No surfaces defined in object definition, "
- "a point list is returned");
-
- meshes.push_back(new aiMesh());
- aiMesh* mesh = meshes.back();
-
- mesh->mNumFaces = mesh->mNumVertices = (unsigned int)object.vertices.size();
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
-
- for (unsigned int i = 0; i < mesh->mNumVertices;++i,++faces,++verts)
- {
- *verts = object.vertices[i];
- faces->mNumIndices = 1;
- faces->mIndices = new unsigned int[1];
- faces->mIndices[0] = i;
- }
-
- // use the primary material in this case. this should be the
- // default material if all objects of the file contain points
- // and no faces.
- mesh->mMaterialIndex = 0;
- outMaterials.push_back(new aiMaterial());
- ConvertMaterial(object, materials[0], *outMaterials.back());
- }
- else
- {
- // need to generate one or more meshes for this object.
- // find out how many different materials we have
- typedef std::pair< unsigned int, unsigned int > IntPair;
- typedef std::vector< IntPair > MatTable;
- MatTable needMat(materials.size(),IntPair(0,0));
-
- std::vector<Surface>::iterator it,end = object.surfaces.end();
- std::vector<Surface::SurfaceEntry>::iterator it2,end2;
-
- for (it = object.surfaces.begin(); it != end; ++it)
- {
- unsigned int idx = (*it).mat;
- if (idx >= needMat.size())
- {
- DefaultLogger::get()->error("AC3D: material index is out of range");
- idx = 0;
- }
- if ((*it).entries.empty())
- {
- DefaultLogger::get()->warn("AC3D: surface her zero vertex references");
- }
-
- // validate all vertex indices to make sure we won't crash here
- for (it2 = (*it).entries.begin(),
- end2 = (*it).entries.end(); it2 != end2; ++it2)
- {
- if ((*it2).first >= object.vertices.size())
- {
- DefaultLogger::get()->warn("AC3D: Invalid vertex reference");
- (*it2).first = 0;
- }
- }
-
- if (!needMat[idx].first)++node->mNumMeshes;
-
- switch ((*it).flags & 0xf)
- {
- // closed line
- case 0x1:
-
- needMat[idx].first += (unsigned int)(*it).entries.size();
- needMat[idx].second += (unsigned int)(*it).entries.size()<<1u;
- break;
-
- // unclosed line
- case 0x2:
-
- needMat[idx].first += (unsigned int)(*it).entries.size()-1;
- needMat[idx].second += ((unsigned int)(*it).entries.size()-1)<<1u;
- break;
-
- // 0 == polygon, else unknown
- default:
-
- if ((*it).flags & 0xf)
- {
- DefaultLogger::get()->warn("AC3D: The type flag of a surface is unknown");
- (*it).flags &= ~(0xf);
- }
-
- // the number of faces increments by one, the number
- // of vertices by surface.numref.
- needMat[idx].first++;
- needMat[idx].second += (unsigned int)(*it).entries.size();
- };
- }
- unsigned int* pip = node->mMeshes = new unsigned int[node->mNumMeshes];
- unsigned int mat = 0;
- const size_t oldm = meshes.size();
- for (MatTable::const_iterator cit = needMat.begin(), cend = needMat.end();
- cit != cend; ++cit, ++mat)
- {
- if (!(*cit).first)continue;
-
- // allocate a new aiMesh object
- *pip++ = (unsigned int)meshes.size();
- aiMesh* mesh = new aiMesh();
- meshes.push_back(mesh);
-
- mesh->mMaterialIndex = (unsigned int)outMaterials.size();
- outMaterials.push_back(new aiMaterial());
- ConvertMaterial(object, materials[mat], *outMaterials.back());
-
- // allocate storage for vertices and normals
- mesh->mNumFaces = (*cit).first;
- if (mesh->mNumFaces == 0) {
- throw DeadlyImportError("AC3D: No faces");
- } else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) {
- throw DeadlyImportError("AC3D: Too many faces, would run out of memory");
- }
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- mesh->mNumVertices = (*cit).second;
- if (mesh->mNumVertices == 0) {
- throw DeadlyImportError("AC3D: No vertices");
- } else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
- throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
- }
- aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- unsigned int cur = 0;
-
- // allocate UV coordinates, but only if the texture name for the
- // surface is not empty
- aiVector3D* uv = NULL;
- if(object.texture.length())
- {
- uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
- }
-
- for (it = object.surfaces.begin(); it != end; ++it)
- {
- if (mat == (*it).mat)
- {
- const Surface& src = *it;
-
- // closed polygon
- unsigned int type = (*it).flags & 0xf;
- if (!type)
- {
- aiFace& face = *faces++;
- if((face.mNumIndices = (unsigned int)src.entries.size()))
- {
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices;++i,++vertices)
- {
- const Surface::SurfaceEntry& entry = src.entries[i];
- face.mIndices[i] = cur++;
-
- // copy vertex positions
- if (static_cast<unsigned>(vertices - mesh->mVertices) >= mesh->mNumVertices) {
- throw DeadlyImportError("AC3D: Invalid number of vertices");
- }
- *vertices = object.vertices[entry.first] + object.translation;
-
-
- // copy texture coordinates
- if (uv)
- {
- uv->x = entry.second.x;
- uv->y = entry.second.y;
- ++uv;
- }
- }
- }
- }
- else
- {
-
- it2 = (*it).entries.begin();
-
- // either a closed or an unclosed line
- unsigned int tmp = (unsigned int)(*it).entries.size();
- if (0x2 == type)--tmp;
- for (unsigned int m = 0; m < tmp;++m)
- {
- aiFace& face = *faces++;
-
- face.mNumIndices = 2;
- face.mIndices = new unsigned int[2];
- face.mIndices[0] = cur++;
- face.mIndices[1] = cur++;
-
- // copy vertex positions
- if (it2 == (*it).entries.end() ) {
- throw DeadlyImportError("AC3D: Bad line");
- }
- ai_assert((*it2).first < object.vertices.size());
- *vertices++ = object.vertices[(*it2).first];
-
- // copy texture coordinates
- if (uv)
- {
- uv->x = (*it2).second.x;
- uv->y = (*it2).second.y;
- ++uv;
- }
-
-
- if (0x1 == type && tmp-1 == m)
- {
- // if this is a closed line repeat its beginning now
- it2 = (*it).entries.begin();
- }
- else ++it2;
-
- // second point
- *vertices++ = object.vertices[(*it2).first];
-
- if (uv)
- {
- uv->x = (*it2).second.x;
- uv->y = (*it2).second.y;
- ++uv;
- }
- }
- }
- }
- }
- }
-
- // Now apply catmull clark subdivision if necessary. We split meshes into
- // materials which is not done by AC3D during smoothing, so we need to
- // collect all meshes using the same material group.
- if (object.subDiv) {
- if (configEvalSubdivision) {
- std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
- DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
-
- std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
- div->Subdivide(&meshes[oldm],cpy.size(),&cpy.front(),object.subDiv,true);
- std::copy(cpy.begin(),cpy.end(),meshes.begin()+oldm);
-
- // previous meshes are deleted vy Subdivide().
- }
- else {
- DefaultLogger::get()->info("AC3D: Letting the subdivision surface untouched due to my configuration: "
- +object.name);
- }
- }
- }
- }
-
- if (object.name.length())
- node->mName.Set(object.name);
- else
- {
- // generate a name depending on the type of the node
- switch (object.type)
- {
- case Object::Group:
- node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++);
- break;
- case Object::Poly:
- node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++);
- break;
- case Object::Light:
- node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++);
- break;
-
- // there shouldn't be more than one world, but we don't care
- case Object::World:
- node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++);
- break;
- }
- }
-
-
- // setup the local transformation matrix of the object
- // compute the transformation offset to the parent node
- node->mTransformation = aiMatrix4x4 ( object.rotation );
-
- if (object.type == Object::Group || !object.numRefs)
- {
- node->mTransformation.a4 = object.translation.x;
- node->mTransformation.b4 = object.translation.y;
- node->mTransformation.c4 = object.translation.z;
- }
-
- // add children to the object
- if (object.children.size())
- {
- node->mNumChildren = (unsigned int)object.children.size();
- node->mChildren = new aiNode*[node->mNumChildren];
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- {
- node->mChildren[i] = ConvertObjectSection(object.children[i],meshes,outMaterials,materials,node);
- }
- }
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-void AC3DImporter::SetupProperties(const Importer* pImp)
-{
- configSplitBFCull = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL,1) ? true : false;
- configEvalSubdivision = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION,1) ? true : false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void AC3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open AC3D file " + pFile + ".");
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- buffer = &mBuffer2[0];
- mNumMeshes = 0;
-
- lights = polys = worlds = groups = 0;
-
- if (::strncmp(buffer,"AC3D",4)) {
- throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
- }
-
- // print the file format version to the console
- unsigned int version = HexDigitToDecimal( buffer[4] );
- char msg[3];
- ASSIMP_itoa10(msg,3,version);
- DefaultLogger::get()->info(std::string("AC3D file format version: ") + msg);
-
- std::vector<Material> materials;
- materials.reserve(5);
-
- std::vector<Object> rootObjects;
- rootObjects.reserve(5);
-
- std::vector<aiLight*> lights;
- mLights = & lights;
-
- while (GetNextLine())
- {
- if (TokenMatch(buffer,"MATERIAL",8))
- {
- materials.push_back(Material());
- Material& mat = materials.back();
-
- // manually parse the material ... sscanf would use the buldin atof ...
- // Format: (name) rgb %f %f %f amb %f %f %f emis %f %f %f spec %f %f %f shi %d trans %f
-
- AI_AC_SKIP_TO_NEXT_TOKEN();
- if ('\"' == *buffer)
- {
- AI_AC_GET_STRING(mat.name);
- AI_AC_SKIP_TO_NEXT_TOKEN();
- }
-
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("rgb",3,3,&mat.rgb);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("amb",3,3,&mat.amb);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("emis",4,3,&mat.emis);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("spec",4,3,&mat.spec);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("shi",3,1,&mat.shin);
- AI_AC_CHECKED_LOAD_FLOAT_ARRAY("trans",5,1,&mat.trans);
- }
- LoadObjectSection(rootObjects);
- }
-
- if (rootObjects.empty() || !mNumMeshes)
- {
- throw DeadlyImportError("AC3D: No meshes have been loaded");
- }
- if (materials.empty())
- {
- DefaultLogger::get()->warn("AC3D: No material has been found");
- materials.push_back(Material());
- }
-
- mNumMeshes += (mNumMeshes>>2u) + 1;
- std::vector<aiMesh*> meshes;
- meshes.reserve(mNumMeshes);
-
- std::vector<aiMaterial*> omaterials;
- materials.reserve(mNumMeshes);
-
- // generate a dummy root if there are multiple objects on the top layer
- Object* root;
- if (1 == rootObjects.size())
- root = &rootObjects[0];
- else
- {
- root = new Object();
- }
-
- // now convert the imported stuff to our output data structure
- pScene->mRootNode = ConvertObjectSection(*root,meshes,omaterials,materials);
- if (1 != rootObjects.size())delete root;
-
- if (!::strncmp( pScene->mRootNode->mName.data, "Node", 4))
- pScene->mRootNode->mName.Set("<AC3DWorld>");
-
- // copy meshes
- if (meshes.empty())
- {
- throw DeadlyImportError("An unknown error occurred during converting");
- }
- pScene->mNumMeshes = (unsigned int)meshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- ::memcpy(pScene->mMeshes,&meshes[0],pScene->mNumMeshes*sizeof(void*));
-
- // copy materials
- pScene->mNumMaterials = (unsigned int)omaterials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- ::memcpy(pScene->mMaterials,&omaterials[0],pScene->mNumMaterials*sizeof(void*));
-
- // copy lights
- pScene->mNumLights = (unsigned int)lights.size();
- if (lights.size())
- {
- pScene->mLights = new aiLight*[lights.size()];
- ::memcpy(pScene->mLights,&lights[0],lights.size()*sizeof(void*));
- }
-}
-
-#endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
diff --git a/src/3rdparty/assimp/code/ACLoader.h b/src/3rdparty/assimp/code/ACLoader.h
deleted file mode 100644
index 4b202b77a..000000000
--- a/src/3rdparty/assimp/code/ACLoader.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ACLoader.h
- * @brief Declaration of the .ac importer class.
- */
-#ifndef AI_AC3DLOADER_H_INCLUDED
-#define AI_AC3DLOADER_H_INCLUDED
-
-#include <vector>
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-
-struct aiNode;
-struct aiMesh;
-struct aiMaterial;
-struct aiLight;
-
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** AC3D (*.ac) importer class
-*/
-class AC3DImporter : public BaseImporter
-{
-public:
- AC3DImporter();
- ~AC3DImporter();
-
-
-
- // Represents an AC3D material
- struct Material
- {
- Material()
- : rgb (0.6f,0.6f,0.6f)
- , spec (1.f,1.f,1.f)
- , shin (0.f)
- , trans (0.f)
- {}
-
- // base color of the material
- aiColor3D rgb;
-
- // ambient color of the material
- aiColor3D amb;
-
- // emissive color of the material
- aiColor3D emis;
-
- // specular color of the material
- aiColor3D spec;
-
- // shininess exponent
- float shin;
-
- // transparency. 0 == opaque
- float trans;
-
- // name of the material. optional.
- std::string name;
- };
-
- // Represents an AC3D surface
- struct Surface
- {
- Surface()
- : mat (0)
- , flags (0)
- {}
-
- unsigned int mat,flags;
-
- typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
- std::vector< SurfaceEntry > entries;
- };
-
- // Represents an AC3D object
- struct Object
- {
- Object()
- : type (World)
- , name( "" )
- , children()
- , texture( "" )
- , texRepeat( 1.f, 1.f )
- , texOffset( 0.0f, 0.0f )
- , rotation()
- , translation()
- , vertices()
- , surfaces()
- , numRefs (0)
- , subDiv (0)
- , crease()
- {}
-
- // Type description
- enum Type
- {
- World = 0x0,
- Poly = 0x1,
- Group = 0x2,
- Light = 0x4
- } type;
-
- // name of the object
- std::string name;
-
- // object children
- std::vector<Object> children;
-
- // texture to be assigned to all surfaces of the object
- std::string texture;
-
- // texture repat factors (scaling for all coordinates)
- aiVector2D texRepeat, texOffset;
-
- // rotation matrix
- aiMatrix3x3 rotation;
-
- // translation vector
- aiVector3D translation;
-
- // vertices
- std::vector<aiVector3D> vertices;
-
- // surfaces
- std::vector<Surface> surfaces;
-
- // number of indices (= num verts in verbose format)
- unsigned int numRefs;
-
- // number of subdivisions to be performed on the
- // imported data
- unsigned int subDiv;
-
- // max angle limit for smoothing
- float crease;
- };
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details*/
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.*/
- void SetupProperties(const Importer* pImp);
-
-private:
-
- // -------------------------------------------------------------------
- /** Get the next line from the file.
- * @return false if the end of the file was reached*/
- bool GetNextLine();
-
- // -------------------------------------------------------------------
- /** Load the object section. This method is called recursively to
- * load subobjects, the method returns after a 'kids 0' was
- * encountered.
- * @objects List of output objects*/
- void LoadObjectSection(std::vector<Object>& objects);
-
- // -------------------------------------------------------------------
- /** Convert all objects into meshes and nodes.
- * @param object Current object to work on
- * @param meshes Pointer to the list of output meshes
- * @param outMaterials List of output materials
- * @param materials Material list
- * @param Scenegraph node for the object */
- aiNode* ConvertObjectSection(Object& object,
- std::vector<aiMesh*>& meshes,
- std::vector<aiMaterial*>& outMaterials,
- const std::vector<Material>& materials,
- aiNode* parent = NULL);
-
- // -------------------------------------------------------------------
- /** Convert a material
- * @param object Current object
- * @param matSrc Source material description
- * @param matDest Destination material to be filled */
- void ConvertMaterial(const Object& object,
- const Material& matSrc,
- aiMaterial& matDest);
-
-private:
-
-
- // points to the next data line
- const char* buffer;
-
- // Configuration option: if enabled, up to two meshes
- // are generated per material: those faces who have
- // their bf cull flags set are separated.
- bool configSplitBFCull;
-
- // Configuration switch: subdivision surfaces are only
- // evaluated if the value is true.
- bool configEvalSubdivision;
-
- // counts how many objects we have in the tree.
- // basing on this information we can find a
- // good estimate how many meshes we'll have in the final scene.
- unsigned int mNumMeshes;
-
- // current list of light sources
- std::vector<aiLight*>* mLights;
-
- // name counters
- unsigned int lights, groups, polys, worlds;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_AC3DIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/AMFImporter.cpp b/src/3rdparty/assimp/code/AMFImporter.cpp
deleted file mode 100644
index e9211fe53..000000000
--- a/src/3rdparty/assimp/code/AMFImporter.cpp
+++ /dev/null
@@ -1,704 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter.cpp
-/// \brief AMF-format files importer for Assimp: main algorithm implementation.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-
-// Header files, Assimp.
-#include "AMFImporter.hpp"
-#include "AMFImporter_Macro.hpp"
-
-#include "fast_atof.h"
-#include <assimp/DefaultIOSystem.h>
-
-// Header files, stdlib.
-#include <memory>
-
-namespace Assimp
-{
-
-/// \var aiImporterDesc AMFImporter::Description
-/// Conastant which hold importer description
-const aiImporterDesc AMFImporter::Description = {
- "Additive manufacturing file format(AMF) Importer",
- "smalcom",
- "",
- "See documentation in source code. Chapter: Limitations.",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
- 0,
- 0,
- 0,
- 0,
- "amf"
-};
-
-void AMFImporter::Clear()
-{
- mNodeElement_Cur = nullptr;
- mUnit.clear();
- mMaterial_Converted.clear();
- mTexture_Converted.clear();
- // Delete all elements
- if(mNodeElement_List.size())
- {
- for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
-
- mNodeElement_List.clear();
- }
-}
-
-AMFImporter::~AMFImporter()
-{
- if(mReader != nullptr) delete mReader;
- // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
- Clear();
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: find set ************************************************************/
-/*********************************************************************************************************************************************/
-
-bool AMFImporter::Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const
-{
- for(CAMFImporter_NodeElement* ne: mNodeElement_List)
- {
- if((ne->ID == pID) && (ne->Type == pType))
- {
- if(pNodeElement != nullptr) *pNodeElement = ne;
-
- return true;
- }
- }// for(CAMFImporter_NodeElement* ne: mNodeElement_List)
-
- return false;
-}
-
-bool AMFImporter::Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
-{
-aiString node_name(pID.c_str());
-
- for(aiNode* node: pNodeList)
- {
- if(node->mName == node_name)
- {
- if(pNode != nullptr) *pNode = node;
-
- return true;
- }
- }// for(aiNode* node: pNodeList)
-
- return false;
-}
-
-bool AMFImporter::Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
-{
- for(const SPP_Material& mat: mMaterial_Converted)
- {
- if(mat.ID == pID)
- {
- if(pConvertedMaterial != nullptr) *pConvertedMaterial = &mat;
-
- return true;
- }
- }// for(const SPP_Material& mat: mMaterial_Converted)
-
- return false;
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: throw set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::Throw_CloseNotFound(const std::string& pNode)
-{
- throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
-}
-
-void AMFImporter::Throw_IncorrectAttr(const std::string& pAttrName)
-{
- throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
-}
-
-void AMFImporter::Throw_IncorrectAttrValue(const std::string& pAttrName)
-{
- throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
-}
-
-void AMFImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription)
-{
- throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription);
-}
-
-void AMFImporter::Throw_ID_NotFound(const std::string& pID) const
-{
- throw DeadlyImportError("Not found node with name \"" + pID + "\".");
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************* Functions: XML set ************************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::XML_CheckNode_MustHaveChildren()
-{
- if(mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children.");
-}
-
-void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
-{
- static const size_t Uns_Skip_Len = 3;
- const char* Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
-
- static bool skipped_before[Uns_Skip_Len] = { false, false, false };
-
- std::string nn(mReader->getNodeName());
- bool found = false;
- bool close_found = false;
- size_t sk_idx;
-
- for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
- {
- if(nn != Uns_Skip[sk_idx]) continue;
-
- found = true;
- if(mReader->isEmptyElement())
- {
- close_found = true;
-
- goto casu_cres;
- }
-
- while(mReader->read())
- {
- if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName()))
- {
- close_found = true;
-
- goto casu_cres;
- }
- }
- }// for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
-
-casu_cres:
-
- if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
- if(!close_found) Throw_CloseNotFound(nn);
-
- if(!skipped_before[sk_idx])
- {
- skipped_before[sk_idx] = true;
- LogWarning("Skipping node \"" + nn + "\" in " + pParentNodeName + ".");
- }
-}
-
-bool AMFImporter::XML_SearchNode(const std::string& pNodeName)
-{
- while(mReader->read())
- {
- if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true;
- }
-
- return false;
-}
-
-bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
-{
- std::string val(mReader->getAttributeValue(pAttrIdx));
-
- if((val == "false") || (val == "0"))
- return false;
- else if((val == "true") || (val == "1"))
- return true;
- else
- throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\"");
-}
-
-float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
-{
- std::string val;
- float tvalf;
-
- ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
- fast_atoreal_move(val.c_str(), tvalf, false);
-
- return tvalf;
-}
-
-uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
-{
- return strtoul10(mReader->getAttributeValue(pAttrIdx));
-}
-
-float AMFImporter::XML_ReadNode_GetVal_AsFloat()
-{
- std::string val;
- float tvalf;
-
- if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt.");
- if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt.");
-
- ParseHelper_FixTruncatedFloatString(mReader->getNodeData(), val);
- fast_atoreal_move(val.c_str(), tvalf, false);
-
- return tvalf;
-}
-
-uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32()
-{
- if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt.");
- if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt.");
-
- return strtoul10(mReader->getNodeData());
-}
-
-void AMFImporter::XML_ReadNode_GetVal_AsString(std::string& pValue)
-{
- if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt.");
- if(mReader->getNodeType() != irr::io::EXN_TEXT)
- throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt.");
-
- pValue = mReader->getNodeData();
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: parse set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
-{
- mNodeElement_Cur->Child.push_back(pNode);// add new element to current element child list.
- mNodeElement_Cur = pNode;// switch current element to new one.
-}
-
-void AMFImporter::ParseHelper_Node_Exit()
-{
- // check if we can walk up.
- if(mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
-}
-
-void AMFImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
-{
- size_t instr_len;
-
- pOutString.clear();
- instr_len = strlen(pInStr);
- if(!instr_len) return;
-
- pOutString.reserve(instr_len * 3 / 2);
- // check and correct floats in format ".x". Must be "x.y".
- if(pInStr[0] == '.') pOutString.push_back('0');
-
- pOutString.push_back(pInStr[0]);
- for(size_t ci = 1; ci < instr_len; ci++)
- {
- if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t')))
- {
- pOutString.push_back('0');
- pOutString.push_back('.');
- }
- else
- {
- pOutString.push_back(pInStr[ci]);
- }
- }
-}
-
-static bool ParseHelper_Decode_Base64_IsBase64(const char pChar)
-{
- return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
-}
-
-void AMFImporter::ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
-{
- // With help from
- // René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html
- const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- uint8_t tidx = 0;
- uint8_t arr4[4], arr3[3];
-
- // check input data
- if(pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
- // prepare output place
- pOutputData.clear();
- pOutputData.reserve(pInputBase64.size() / 4 * 3);
-
- for(size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--)
- {
- if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
- {
- arr4[tidx++] = pInputBase64[in_idx++];
- if(tidx == 4)
- {
- for(tidx = 0; tidx < 4; tidx++) arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]);
-
- arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
- arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
- arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
- for(tidx = 0; tidx < 3; tidx++) pOutputData.push_back(arr3[tidx]);
-
- tidx = 0;
- }// if(tidx == 4)
- }// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
- else
- {
- in_idx++;
- }// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else
- }
-
- if(tidx)
- {
- for(uint8_t i = tidx; i < 4; i++) arr4[i] = 0;
- for(uint8_t i = 0; i < 4; i++) arr4[i] = (uint8_t)(base64_chars.find(arr4[i]));
-
- arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
- arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
- arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
- for(uint8_t i = 0; i < (tidx - 1); i++) pOutputData.push_back(arr3[i]);
- }
-}
-
-void AMFImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
-{
- irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader.
- std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
-
- // Check whether we can read from the file
- if(file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
-
- // generate a XML reader for it
- std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
- mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
- if(!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
- //
- // start reading
- // search for root tag <amf>
- if(XML_SearchNode("amf"))
- ParseNode_Root();
- else
- throw DeadlyImportError("Root node \"amf\" not found.");
-
- delete mReader;
- // restore old XMLreader
- mReader = OldReader;
-}
-
-// <amf
-// unit="" - The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
-// version="" - Version of file format.
-// >
-// </amf>
-// Root XML element.
-// Multi elements - No.
-void AMFImporter::ParseNode_Root()
-{
- std::string unit, version;
- CAMFImporter_NodeElement *ne( nullptr );
-
- // Read attributes for node <amf>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND_WSKIP;
-
- // Check attributes
- if(!mUnit.empty())
- {
- if((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) Throw_IncorrectAttrValue("unit");
- }
-
- // create root node element.
- ne = new CAMFImporter_NodeElement_Root(nullptr);
- mNodeElement_Cur = ne;// set first "current" element
- // and assign attribute's values
- ((CAMFImporter_NodeElement_Root*)ne)->Unit = unit;
- ((CAMFImporter_NodeElement_Root*)ne)->Version = version;
-
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- MACRO_NODECHECK_LOOPBEGIN("amf");
- if(XML_CheckNode_NameEqual("object")) { ParseNode_Object(); continue; }
- if(XML_CheckNode_NameEqual("material")) { ParseNode_Material(); continue; }
- if(XML_CheckNode_NameEqual("texture")) { ParseNode_Texture(); continue; }
- if(XML_CheckNode_NameEqual("constellation")) { ParseNode_Constellation(); continue; }
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("amf");
- mNodeElement_Cur = ne;// force restore "current" element
- }// if(!mReader->isEmptyElement())
-
- mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
-}
-
-// <constellation
-// id="" - The Object ID of the new constellation being defined.
-// >
-// </constellation>
-// A collection of objects or constellations with specific relative locations.
-// Multi elements - Yes.
-// Parent element - <amf>.
-void AMFImporter::ParseNode_Constellation()
-{
- std::string id;
- CAMFImporter_NodeElement* ne( nullptr );
-
- // Read attributes for node <constellation>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create and if needed - define new grouping object.
- ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Constellation& als = *((CAMFImporter_NodeElement_Constellation*)ne);// alias for convenience
-
- if(!id.empty()) als.ID = id;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("constellation");
- if(XML_CheckNode_NameEqual("instance")) { ParseNode_Instance(); continue; }
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("constellation");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <instance
-// objectid="" - The Object ID of the new constellation being defined.
-// >
-// </instance>
-// A collection of objects or constellations with specific relative locations.
-// Multi elements - Yes.
-// Parent element - <amf>.
-void AMFImporter::ParseNode_Instance()
-{
- std::string objectid;
- CAMFImporter_NodeElement* ne( nullptr );
-
- // Read attributes for node <constellation>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // used object id must be defined, check that.
- if(objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
- // create and define new grouping object.
- ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);// alias for convenience
-
- als.ObjectID = objectid;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool read_flag[6] = { false, false, false, false, false, false };
-
- als.Delta.Set(0, 0, 0);
- als.Rotation.Set(0, 0, 0);
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("instance");
- MACRO_NODECHECK_READCOMP_F("deltax", read_flag[0], als.Delta.x);
- MACRO_NODECHECK_READCOMP_F("deltay", read_flag[1], als.Delta.y);
- MACRO_NODECHECK_READCOMP_F("deltaz", read_flag[2], als.Delta.z);
- MACRO_NODECHECK_READCOMP_F("rx", read_flag[3], als.Rotation.x);
- MACRO_NODECHECK_READCOMP_F("ry", read_flag[4], als.Rotation.y);
- MACRO_NODECHECK_READCOMP_F("rz", read_flag[5], als.Rotation.z);
- MACRO_NODECHECK_LOOPEND("instance");
- ParseHelper_Node_Exit();
- // also convert degrees to radians.
- als.Rotation.x = AI_MATH_PI_F * als.Rotation.x / 180.0f;
- als.Rotation.y = AI_MATH_PI_F * als.Rotation.y / 180.0f;
- als.Rotation.z = AI_MATH_PI_F * als.Rotation.z / 180.0f;
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <object
-// id="" - A unique ObjectID for the new object being defined.
-// >
-// </object>
-// An object definition.
-// Multi elements - Yes.
-// Parent element - <amf>.
-void AMFImporter::ParseNode_Object()
-{
- std::string id;
- CAMFImporter_NodeElement* ne( nullptr );
-
- // Read attributes for node <object>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create and if needed - define new geometry object.
- ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Object& als = *((CAMFImporter_NodeElement_Object*)ne);// alias for convenience
-
- if(!id.empty()) als.ID = id;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool col_read = false;
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("object");
- if(XML_CheckNode_NameEqual("color"))
- {
- // Check if color already defined for object.
- if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <object>.");
- // read data and set flag about it
- ParseNode_Color();
- col_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("mesh")) { ParseNode_Mesh(); continue; }
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("object");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <metadata
-// type="" - The type of the attribute.
-// >
-// </metadata>
-// Specify additional information about an entity.
-// Multi elements - Yes.
-// Parent element - <amf>, <object>, <volume>, <material>, <vertex>.
-//
-// Reserved types are:
-// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user.
-// "Description" - A description of the content of the entity
-// "URL" - A link to an external resource relating to the entity
-// "Author" - Specifies the name(s) of the author(s) of the entity
-// "Company" - Specifying the company generating the entity
-// "CAD" - specifies the name of the originating CAD software and version
-// "Revision" - specifies the revision of the entity
-// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system
-// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only)
-void AMFImporter::ParseNode_Metadata()
-{
- std::string type, value;
- CAMFImporter_NodeElement* ne( nullptr );
-
- // read attribute
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
- // and value of node.
- value = mReader->getNodeData();
- // Create node element and assign read data.
- ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur);
- ((CAMFImporter_NodeElement_Metadata*)ne)->Type = type;
- ((CAMFImporter_NodeElement_Metadata*)ne)->Value = value;
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-/*********************************************************************************************************************************************/
-/******************************************************** Functions: BaseImporter set ********************************************************/
-/*********************************************************************************************************************************************/
-
-bool AMFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if ( extension == "amf" ) {
- return true;
- }
-
- if(!extension.length() || pCheckSig)
- {
- const char* tokens[] = { "<amf" };
-
- return SearchFileHeaderForToken( pIOHandler, pFile, tokens, 1 );
- }
-
- return false;
-}
-
-void AMFImporter::GetExtensionList(std::set<std::string>& pExtensionList)
-{
- pExtensionList.insert("amf");
-}
-
-const aiImporterDesc* AMFImporter::GetInfo () const
-{
- return &Description;
-}
-
-void AMFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- Clear();// delete old graph.
- ParseFile(pFile, pIOHandler);
- Postprocess_BuildScene(pScene);
- // scene graph is ready, exit.
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
diff --git a/src/3rdparty/assimp/code/AMFImporter.hpp b/src/3rdparty/assimp/code/AMFImporter.hpp
deleted file mode 100644
index 47ddc073b..000000000
--- a/src/3rdparty/assimp/code/AMFImporter.hpp
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter.hpp
-/// \brief AMF-format files importer for Assimp.
-/// \date 2016
-/// \author smal.root@gmail.com
-// Thanks to acorn89 for support.
-
-#pragma once
-#ifndef INCLUDED_AI_AMF_IMPORTER_H
-#define INCLUDED_AI_AMF_IMPORTER_H
-
-#include "AMFImporter_Node.hpp"
-
-// Header files, Assimp.
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include "assimp/types.h"
-#include "BaseImporter.h"
-#include "irrXMLWrapper.h"
-
-// Header files, stdlib.
-#include <set>
-
-namespace Assimp
-{
-/// \class AMFImporter
-/// Class that holding scene graph which include: geometry, metadata, materials etc.
-///
-/// Implementing features.
-///
-/// Limitations.
-///
-/// 1. When for texture mapping used set of source textures (r, g, b, a) not only one then attribute "tiled" for all set will be true if it true in any of
-/// source textures.
-/// Example. Triangle use for texture mapping three textures. Two of them has "tiled" set to false and one - set to true. In scene all three textures
-/// will be tiled.
-///
-/// Unsupported features:
-/// 1. Node <composite>, formulas in <composite> and <color>. For implementing this feature can be used expression parser "muParser" like in project
-/// "amf_tools".
-/// 2. Attribute "profile" in node <color>.
-/// 3. Curved geometry: <edge>, <normal> and children nodes of them.
-/// 4. Attributes: "unit" and "version" in <amf> read but do nothing.
-/// 5. <metadata> stored only for root node <amf>.
-/// 6. Color averaging of vertices for which <triangle>'s set different colors.
-///
-/// Supported nodes:
-/// General:
-/// <amf>; <constellation>; <instance> and children <deltax>, <deltay>, <deltaz>, <rx>, <ry>, <rz>; <metadata>;
-///
-/// Geometry:
-/// <object>; <mesh>; <vertices>; <vertex>; <coordinates> and children <x>, <y>, <z>; <volume>; <triangle> and children <v1>, <v2>, <v3>;
-///
-/// Material:
-/// <color> and children <r>, <g>, <b>, <a>; <texture>; <material>;
-/// two variants of texture coordinates:
-/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
-/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
-///
-class AMFImporter : public BaseImporter
-{
- /***********************************************/
- /******************** Types ********************/
- /***********************************************/
-
-private:
-
- struct SPP_Material;// forward declaration
-
- /// \struct SPP_Composite
- /// Data type for postprocessing step. More suitable container for part of material's composition.
- struct SPP_Composite
- {
- SPP_Material* Material;///< Pointer to material - part of composition.
- std::string Formula;///< Formula for calculating ratio of \ref Material.
- };
-
- /// \struct SPP_Material
- /// Data type for postprocessing step. More suitable container for material.
- struct SPP_Material
- {
- std::string ID;///< Material ID.
- std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
- CAMFImporter_NodeElement_Color* Color;///< Color of material.
- std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
-
- /// \fn aiColor4D GetColor(const float pX, const float pY, const float pZ) const
- /// Return color calculated for specified coordinate.
- /// \param [in] pX - "x" coordinate.
- /// \param [in] pY - "y" coordinate.
- /// \param [in] pZ - "z" coordinate.
- /// \return calculated color.
- aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
- };
-
- /// \struct SPP_Texture
- /// Data type for post-processing step. More suitable container for texture.
- struct SPP_Texture
- {
- std::string ID;
- size_t Width, Height, Depth;
- bool Tiled;
- char FormatHint[ 9 ];// 8 for string + 1 for terminator.
- uint8_t *Data;
- };
-
- /// \struct SComplexFace
- /// Data type for post-processing step. Contain face data.
- struct SComplexFace
- {
- aiFace Face;///< Face vertices.
- const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
- const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
- };
-
-
-
- /***********************************************/
- /****************** Constants ******************/
- /***********************************************/
-
-private:
-
- static const aiImporterDesc Description;
-
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-private:
-
- CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
- std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
- irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
- std::string mUnit;
- std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
- std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn AMFImporter(const AMFImporter& pScene)
- /// Disabled copy constructor.
- AMFImporter(const AMFImporter& pScene);
-
- /// \fn AMFImporter& operator=(const AMFImporter& pScene)
- /// Disabled assign operator.
- AMFImporter& operator=(const AMFImporter& pScene);
-
- /// \fn void Clear()
- /// Clear all temporary data.
- void Clear();
-
- /***********************************************/
- /************* Functions: find set *************/
- /***********************************************/
-
- /// \fn bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, aiNode** pNode) const
- /// Find specified node element in node elements list ( \ref mNodeElement_List).
- /// \param [in] pID - ID(name) of requested node element.
- /// \param [in] pType - type of node element.
- /// \param [out] pNode - pointer to pointer to item found.
- /// \return true - if the node element is found, else - false.
- bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
-
- /// \fn bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
- /// Find requested aiNode in node list.
- /// \param [in] pID - ID(name) of requested node.
- /// \param [in] pNodeList - list of nodes where to find the node.
- /// \param [out] pNode - pointer to pointer to item found.
- /// \return true - if the node is found, else - false.
- bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
-
- /// \fn bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
- /// Find material in list for converted materials. Use at postprocessing step.
- /// \param [in] pID - material ID.
- /// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
- /// \return true - if the material is found, else - false.
- bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
-
- /// \fn bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, uint32_t* pConvertedTextureIndex = nullptr) const
- /// Find texture in list of converted textures. Use at postprocessing step,
- /// \param [in] pID_R - ID of source "red" texture.
- /// \param [in] pID_G - ID of source "green" texture.
- /// \param [in] pID_B - ID of source "blue" texture.
- /// \param [in] pID_A - ID of source "alpha" texture. Use empty string to find RGB-texture.
- /// \param [out] pConvertedTextureIndex - pointer where index in list of found texture will be written. If equivalent to nullptr then nothing will be
- /// written.
- /// \return true - if the texture is found, else - false.
- bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
- uint32_t* pConvertedTextureIndex = nullptr) const;
-
- /***********************************************/
- /********* Functions: postprocess set **********/
- /***********************************************/
-
- /// \fn void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
- /// Get data stored in <vertices> and place it to arrays.
- /// \param [in] pNodeElement - reference to node element which kept <object> data.
- /// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
- /// \param [in] pVertexColorArray - reference to vertices colors for all <vertex's. If color for vertex is not set then corresponding member of array
- /// contain nullptr.
- void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
- std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
-
- /// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
- /// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
- /// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
- /// to converted textures list.
- /// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
- /// \param [in] pID_R - ID of source "red" texture.
- /// \param [in] pID_G - ID of source "green" texture.
- /// \param [in] pID_B - ID of source "blue" texture.
- /// \param [in] pID_A - ID of source "alpha" texture.
- /// \return index of the texture in array of the converted textures.
- size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
-
- /// \fn void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> > pOutputList_Separated)
- /// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
- /// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
- /// processing.
- /// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
- void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
-
- /// \fn void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const
- /// Check if child elements of node element is metadata and add it to scene node.
- /// \param [in] pMetadataList - reference to list with collected metadata.
- /// \param [out] pSceneNode - scene node in which metadata will be added.
- void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
-
- /// \fn void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
- /// To create aiMesh and aiNode for it from <object>.
- /// \param [in] pNodeElement - reference to node element which kept <object> data.
- /// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
- /// \param [out] pSceneNode - pointer to place where new aiNode will be created.
- void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
-
- /// \fn void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
- /// Create mesh for every <volume> in <mesh>.
- /// \param [in] pNodeElement - reference to node element which kept <mesh> data.
- /// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
- /// \param [in] pVertexColorArray - reference to vertices colors for all <volume>'s. If color for vertex is not set then corresponding member of array
- /// contain nullptr.
- /// \param [in] pObjectColor - pointer to colors for <object>. If color is not set then argument contain nullptr.
- /// \param [in] pMaterialList - reference to a list with defined materials.
- /// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
- /// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's.
- void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
- const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
- std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
-
- /// \fn void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
- /// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
- /// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
- void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
-
- /// \fn void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
- /// Create and add to aiNode's list new part of scene graph defined by <constellation>.
- /// \param [in] pConstellation - reference to <constellation> node.
- /// \param [out] pNodeList - reference to aiNode's list.
- void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
-
- /// \fn void Postprocess_BuildScene()
- /// Build Assimp scene graph in aiScene from collected data.
- /// \param [out] pScene - pointer to aiScene where tree will be built.
- void Postprocess_BuildScene(aiScene* pScene);
-
- /***********************************************/
- /************* Functions: throw set ************/
- /***********************************************/
-
- /// \fn void Throw_CloseNotFound(const std::string& pNode)
- /// Call that function when close tag of node not found and exception must be raised.
- /// E.g.:
- /// <amf>
- /// <object>
- /// </amf> <!--- object not closed --->
- /// \throw DeadlyImportError.
- /// \param [in] pNode - node name in which exception happened.
- void Throw_CloseNotFound(const std::string& pNode);
-
- /// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
- /// Call that function when attribute name is incorrect and exception must be raised.
- /// \param [in] pAttrName - attribute name.
- /// \throw DeadlyImportError.
- void Throw_IncorrectAttr(const std::string& pAttrName);
-
- /// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
- /// Call that function when attribute value is incorrect and exception must be raised.
- /// \param [in] pAttrName - attribute name.
- /// \throw DeadlyImportError.
- void Throw_IncorrectAttrValue(const std::string& pAttrName);
-
- /// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
- /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
- /// E.g.:
- /// <object>
- /// <color>... <!--- color defined --->
- /// <color>... <!--- color defined again --->
- /// </object>
- /// \throw DeadlyImportError.
- /// \param [in] pNodeType - type of node which defined one more time.
- /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
- void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
-
- /// \fn void Throw_ID_NotFound(const std::string& pID) const
- /// Call that function when referenced element ID are not found in graph and exception must be raised.
- /// \param [in] pID - ID of of element which not found.
- /// \throw DeadlyImportError.
- void Throw_ID_NotFound(const std::string& pID) const;
-
- /***********************************************/
- /************** Functions: LOG set *************/
- /***********************************************/
-
- /// \fn void LogInfo(const std::string& pMessage)
- /// Short variant for calling \ref DefaultLogger::get()->info()
- void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
-
- /// \fn void LogWarning(const std::string& pMessage)
- /// Short variant for calling \ref DefaultLogger::get()->warn()
- void LogWarning(const std::string& pMessage) { DefaultLogger::get()->warn(pMessage); }
-
- /// \fn void LogError(const std::string& pMessage)
- /// Short variant for calling \ref DefaultLogger::get()->error()
- void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
-
- /***********************************************/
- /************** Functions: XML set *************/
- /***********************************************/
-
- /// \fn void XML_CheckNode_MustHaveChildren()
- /// Check if current node have children: <node>...</node>. If not then exception will throwed.
- void XML_CheckNode_MustHaveChildren();
-
- /// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
- /// Check if current node name is equal to pNodeName.
- /// \param [in] pNodeName - name for checking.
- /// return true if current node name is equal to pNodeName, else - false.
- bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
-
- /// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
- /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
- /// \param [in] pParentNodeName - parent node name. Used for reporting.
- void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
-
- /// \fn bool XML_SearchNode(const std::string& pNodeName)
- /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
- /// \param [in] pNodeName - requested node name.
- /// return true - if node is found, else - false.
- bool XML_SearchNode(const std::string& pNodeName);
-
- /// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
-
- /// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
-
- /// \fn uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
-
- /// \fn float XML_ReadNode_GetVal_AsFloat()
- /// Read node value.
- /// \return read data.
- float XML_ReadNode_GetVal_AsFloat();
-
- /// \fn uint32_t XML_ReadNode_GetVal_AsU32()
- /// Read node value.
- /// \return read data.
- uint32_t XML_ReadNode_GetVal_AsU32();
-
- /// \fn void XML_ReadNode_GetVal_AsString(std::string& pValue)
- /// Read node value.
- /// \return read data.
- void XML_ReadNode_GetVal_AsString(std::string& pValue);
-
- /***********************************************/
- /******** Functions: parse set private *********/
- /***********************************************/
-
- /// \fn void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
- /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
- /// \param [in] pNode - new current node.
- void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
-
- /// \fn void ParseHelper_Group_End()
- /// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
- void ParseHelper_Node_Exit();
-
- /// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
- /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
- /// must be converted to right form - "0.xxx".
- /// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
- /// \param [out[ pOutString - output string with right form of values.
- void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
-
- /// \fn void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
- /// Decode Base64-encoded data.
- /// \param [in] pInputBase64 - reference to input Base64-encoded string.
- /// \param [out] pOutputData - reference to output array for decoded data.
- void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
-
- /// \fn void ParseNode_Root()
- /// Parse <AMF> node of the file.
- void ParseNode_Root();
-
- /******** Functions: top nodes *********/
-
- /// \fn void ParseNode_Constellation()
- /// Parse <constellation> node of the file.
- void ParseNode_Constellation();
-
- /// \fn void ParseNode_Constellation()
- /// Parse <instance> node of the file.
- void ParseNode_Instance();
-
- /// \fn void ParseNode_Material()
- /// Parse <material> node of the file.
- void ParseNode_Material();
-
- /// \fn void ParseNode_Metadata()
- /// Parse <metadata> node.
- void ParseNode_Metadata();
-
- /// \fn void ParseNode_Object()
- /// Parse <object> node of the file.
- void ParseNode_Object();
-
- /// \fn void ParseNode_Texture()
- /// Parse <texture> node of the file.
- void ParseNode_Texture();
-
- /******** Functions: geometry nodes *********/
-
- /// \fn void ParseNode_Coordinates()
- /// Parse <coordinates> node of the file.
- void ParseNode_Coordinates();
-
- /// \fn void ParseNode_Edge()
- /// Parse <edge> node of the file.
- void ParseNode_Edge();
-
- /// \fn void ParseNode_Mesh()
- /// Parse <mesh> node of the file.
- void ParseNode_Mesh();
-
- /// \fn void ParseNode_Triangle()
- /// Parse <triangle> node of the file.
- void ParseNode_Triangle();
-
- /// \fn void ParseNode_Vertex()
- /// Parse <vertex> node of the file.
- void ParseNode_Vertex();
-
- /// \fn void ParseNode_Vertices()
- /// Parse <vertices> node of the file.
- void ParseNode_Vertices();
-
- /// \fn void ParseNode_Volume()
- /// Parse <volume> node of the file.
- void ParseNode_Volume();
-
- /******** Functions: material nodes *********/
-
- /// \fn void ParseNode_Color()
- /// Parse <color> node of the file.
- void ParseNode_Color();
-
- /// \fn void ParseNode_TexMap(const bool pUseOldName = false)
- /// Parse <texmap> of <map> node of the file.
- /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
- void ParseNode_TexMap(const bool pUseOldName = false);
-
-public:
-
- /// \fn AMFImporter()
- /// Default constructor.
- AMFImporter()
- : mNodeElement_Cur(nullptr), mReader(nullptr)
- {}
-
- /// \fn ~AMFImporter()
- /// Default destructor.
- ~AMFImporter();
-
- /***********************************************/
- /******** Functions: parse set, public *********/
- /***********************************************/
-
- /// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
- /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
- /// Also exception can be throwed if trouble will found.
- /// \param [in] pFile - name of file to be parsed.
- /// \param [in] pIOHandler - pointer to IO helper object.
- void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
-
- /***********************************************/
- /********* Functions: BaseImporter set *********/
- /***********************************************/
-
- bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
- void GetExtensionList(std::set<std::string>& pExtensionList);
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
- const aiImporterDesc* GetInfo ()const;
-
-};// class AMFImporter
-
-}// namespace Assimp
-
-#endif // INCLUDED_AI_AMF_IMPORTER_H
diff --git a/src/3rdparty/assimp/code/AMFImporter_Geometry.cpp b/src/3rdparty/assimp/code/AMFImporter_Geometry.cpp
deleted file mode 100644
index afba3f2bc..000000000
--- a/src/3rdparty/assimp/code/AMFImporter_Geometry.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter_Geometry.cpp
-/// \brief Parsing data from geometry nodes.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-
-#include "AMFImporter.hpp"
-#include "AMFImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <mesh>
-// </mesh>
-// A 3D mesh hull.
-// Multi elements - Yes.
-// Parent element - <object>.
-void AMFImporter::ParseNode_Mesh()
-{
-CAMFImporter_NodeElement* ne;
-
- // create new mesh object.
- ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur);
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool vert_read = false;
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("mesh");
- if(XML_CheckNode_NameEqual("vertices"))
- {
- // Check if data already defined.
- if(vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for <mesh>.");
- // read data and set flag about it
- ParseNode_Vertices();
- vert_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("volume")) { ParseNode_Volume(); continue; }
- MACRO_NODECHECK_LOOPEND("mesh");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <vertices>
-// </vertices>
-// The list of vertices to be used in defining triangles.
-// Multi elements - No.
-// Parent element - <mesh>.
-void AMFImporter::ParseNode_Vertices()
-{
-CAMFImporter_NodeElement* ne;
-
- // create new mesh object.
- ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur);
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("vertices");
- if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; }
- MACRO_NODECHECK_LOOPEND("vertices");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <vertex>
-// </vertex>
-// A vertex to be referenced in triangles.
-// Multi elements - Yes.
-// Parent element - <vertices>.
-void AMFImporter::ParseNode_Vertex()
-{
-CAMFImporter_NodeElement* ne;
-
- // create new mesh object.
- ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur);
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool col_read = false;
- bool coord_read = false;
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("vertex");
- if(XML_CheckNode_NameEqual("color"))
- {
- // Check if data already defined.
- if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
- // read data and set flag about it
- ParseNode_Color();
- col_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("coordinates"))
- {
- // Check if data already defined.
- if(coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
- // read data and set flag about it
- ParseNode_Coordinates();
- coord_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("vertex");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <coordinates>
-// </coordinates>
-// Specifies the 3D location of this vertex.
-// Multi elements - No.
-// Parent element - <vertex>.
-//
-// Children elements:
-// <x>, <y>, <z>
-// Multi elements - No.
-// X, Y, or Z coordinate, respectively, of a vertex position in space.
-void AMFImporter::ParseNode_Coordinates()
-{
-CAMFImporter_NodeElement* ne;
-
- // create new color object.
- ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience
-
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool read_flag[3] = { false, false, false };
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("coordinates");
- MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x);
- MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y);
- MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z);
- MACRO_NODECHECK_LOOPEND("coordinates");
- ParseHelper_Node_Exit();
- // check that all components was defined
- if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined.");
-
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <volume
-// materialid="" - Which material to use.
-// type="" - What this volume describes can be “region†or “supportâ€. If none specified, “object†is assumed. If support, then the geometric
-// requirements 1-8 listed in section 5 do not need to be maintained.
-// >
-// </volume>
-// Defines a volume from the established vertex list.
-// Multi elements - Yes.
-// Parent element - <mesh>.
-void AMFImporter::ParseNode_Volume()
-{
-std::string materialid;
-std::string type;
-CAMFImporter_NodeElement* ne;
-
- // Read attributes for node <color>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create new object.
- ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
- // and assign read data
- ((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid;
- ((CAMFImporter_NodeElement_Volume*)ne)->Type = type;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool col_read = false;
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("volume");
- if(XML_CheckNode_NameEqual("color"))
- {
- // Check if data already defined.
- if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
- // read data and set flag about it
- ParseNode_Color();
- col_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; }
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("volume");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <triangle>
-// </triangle>
-// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside).
-// Multi elements - Yes.
-// Parent element - <volume>.
-//
-// Children elements:
-// <v1>, <v2>, <v3>
-// Multi elements - No.
-// Index of the desired vertices in a triangle or edge.
-void AMFImporter::ParseNode_Triangle()
-{
-CAMFImporter_NodeElement* ne;
-
- // create new color object.
- ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience
-
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool col_read = false, tex_read = false;
- bool read_flag[3] = { false, false, false };
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("triangle");
- if(XML_CheckNode_NameEqual("color"))
- {
- // Check if data already defined.
- if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
- // read data and set flag about it
- ParseNode_Color();
- col_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap".
- {
- // Check if data already defined.
- if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for <triangle>.");
- // read data and set flag about it
- ParseNode_TexMap();
- tex_read = true;
-
- continue;
- }
- else if(XML_CheckNode_NameEqual("map"))// old name of node: "map".
- {
- // Check if data already defined.
- if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>.");
- // read data and set flag about it
- ParseNode_TexMap(true);
- tex_read = true;
-
- continue;
- }
-
- MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]);
- MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]);
- MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]);
- MACRO_NODECHECK_LOOPEND("triangle");
- ParseHelper_Node_Exit();
- // check that all components was defined
- if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined.");
-
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
diff --git a/src/3rdparty/assimp/code/AMFImporter_Macro.hpp b/src/3rdparty/assimp/code/AMFImporter_Macro.hpp
deleted file mode 100644
index b7c0f9863..000000000
--- a/src/3rdparty/assimp/code/AMFImporter_Macro.hpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter_Macro.hpp
-/// \brief Useful macrodefines.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#pragma once
-#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
-#define AMFIMPORTER_MACRO_HPP_INCLUDED
-
-/// \def MACRO_ATTRREAD_LOOPBEG
-/// Begin of loop that read attributes values.
-#define MACRO_ATTRREAD_LOOPBEG \
- for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
- { \
- std::string an(mReader->getAttributeName(idx));
-
-/// \def MACRO_ATTRREAD_LOOPEND
-/// End of loop that read attributes values.
-#define MACRO_ATTRREAD_LOOPEND \
- Throw_IncorrectAttr(an); \
- }
-
-/// \def MACRO_ATTRREAD_LOOPEND_WSKIP
-/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
-/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
-#define MACRO_ATTRREAD_LOOPEND_WSKIP \
- continue; \
- }
-
-/// \def MACRO_ATTRREAD_CHECK_REF
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
-/// "continue" will called.
-/// \param [in] pAttrName - attribute name.
-/// \param [out] pVarName - output variable name.
-/// \param [in] pFunction - function which read attribute value and write it to pVarName.
-#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
- if(an == pAttrName) \
- { \
- pFunction(idx, pVarName); \
- continue; \
- }
-
-/// \def MACRO_ATTRREAD_CHECK_RET
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
-/// If result was read then "continue" will called.
-/// \param [in] pAttrName - attribute name.
-/// \param [out] pVarName - output variable name.
-/// \param [in] pFunction - function which read attribute value and write it to pVarName.
-#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
- if(an == pAttrName) \
- { \
- pVarName = pFunction(idx); \
- continue; \
- }
-
-/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
-/// Begin of loop of parsing child nodes. Do not add ';' at end.
-/// \param [in] pNodeName - current node name.
-#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
- do { \
- bool close_found = false; \
- \
- while(mReader->read()) \
- { \
- if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
- {
-
-/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
-/// End of loop of parsing child nodes.
-/// \param [in] pNodeName - current node name.
-#define MACRO_NODECHECK_LOOPEND(pNodeName) \
- XML_CheckNode_SkipUnsupported(pNodeName); \
- }/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
- else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
- { \
- if(XML_CheckNode_NameEqual(pNodeName)) \
- { \
- close_found = true; \
- \
- break; \
- } \
- }/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
- }/* while(mReader->read()) */ \
- \
- if(!close_found) Throw_CloseNotFound(pNodeName); \
- \
- } while(false)
-
-/// \def MACRO_NODECHECK_READCOMP_F
-/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float".
-/// If result was read then "continue" will called. Also check if node data already read then raise exception.
-/// \param [in] pNodeName - node name.
-/// \param [in, out] pReadFlag - read flag.
-/// \param [out] pVarName - output variable name.
-#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
- if(XML_CheckNode_NameEqual(pNodeName)) \
- { \
- /* Check if field already read before. */ \
- if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
- /* Read color component and assign it to object. */ \
- pVarName = XML_ReadNode_GetVal_AsFloat(); \
- pReadFlag = true; \
- continue; \
- }
-
-/// \def MACRO_NODECHECK_READCOMP_U32
-/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
-/// If result was read then "continue" will called. Also check if node data already read then raise exception.
-/// \param [in] pNodeName - node name.
-/// \param [in, out] pReadFlag - read flag.
-/// \param [out] pVarName - output variable name.
-#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
- if(XML_CheckNode_NameEqual(pNodeName)) \
- { \
- /* Check if field already read before. */ \
- if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
- /* Read color component and assign it to object. */ \
- pVarName = XML_ReadNode_GetVal_AsU32(); \
- pReadFlag = true; \
- continue; \
- }
-
-#endif // AMFIMPORTER_MACRO_HPP_INCLUDED
diff --git a/src/3rdparty/assimp/code/AMFImporter_Material.cpp b/src/3rdparty/assimp/code/AMFImporter_Material.cpp
deleted file mode 100644
index d15099fac..000000000
--- a/src/3rdparty/assimp/code/AMFImporter_Material.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter_Material.cpp
-/// \brief Parsing data from material nodes.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-
-#include "AMFImporter.hpp"
-#include "AMFImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <color
-// profile="" - The ICC color space used to interpret the three color channels <r>, <g> and <b>.
-// >
-// </color>
-// A color definition.
-// Multi elements - No.
-// Parent element - <material>, <object>, <volume>, <vertex>, <triangle>.
-//
-// "profile" can be one of "sRGB", "AdobeRGB", "Wide-Gamut-RGB", "CIERGB", "CIELAB", or "CIEXYZ".
-// Children elements:
-// <r>, <g>, <b>, <a>
-// Multi elements - No.
-// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
-// values can be specified as constants, or as a formula depending on the coordinates.
-void AMFImporter::ParseNode_Color()
-{
-std::string profile;
-CAMFImporter_NodeElement* ne;
-
- // Read attributes for node <color>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("profile", profile, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create new color object.
- ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience
-
- als.Profile = profile;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool read_flag[4] = { false, false, false, false };
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("color");
- MACRO_NODECHECK_READCOMP_F("r", read_flag[0], als.Color.r);
- MACRO_NODECHECK_READCOMP_F("g", read_flag[1], als.Color.g);
- MACRO_NODECHECK_READCOMP_F("b", read_flag[2], als.Color.b);
- MACRO_NODECHECK_READCOMP_F("a", read_flag[3], als.Color.a);
- MACRO_NODECHECK_LOOPEND("color");
- ParseHelper_Node_Exit();
- // check that all components was defined
- if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
- // check if <a> is absent. Then manualy add "a == 1".
- if(!read_flag[3]) als.Color.a = 1;
-
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- als.Composed = false;
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <material
-// id="" - A unique material id. material ID "0" is reserved to denote no material (void) or sacrificial material.
-// >
-// </material>
-// An available material.
-// Multi elements - Yes.
-// Parent element - <amf>.
-void AMFImporter::ParseNode_Material()
-{
-std::string id;
-CAMFImporter_NodeElement* ne;
-
- // Read attributes for node <color>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create new object.
- ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
- // and assign read data
- ((CAMFImporter_NodeElement_Material*)ne)->ID = id;
- // Check for child nodes
- if(!mReader->isEmptyElement())
- {
- bool col_read = false;
-
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("material");
- if(XML_CheckNode_NameEqual("color"))
- {
- // Check if data already defined.
- if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <material>.");
- // read data and set flag about it
- ParseNode_Color();
- col_read = true;
-
- continue;
- }
-
- if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
- MACRO_NODECHECK_LOOPEND("material");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- }// if(!mReader->isEmptyElement()) else
-
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <texture
-// id="" - Assigns a unique texture id for the new texture.
-// width="" - Width (horizontal size, x) of the texture, in pixels.
-// height="" - Height (lateral size, y) of the texture, in pixels.
-// depth="" - Depth (vertical size, z) of the texture, in pixels.
-// type="" - Encoding of the data in the texture. Currently allowed values are "grayscale" only. In grayscale mode, each pixel is represented by one byte
-// in the range of 0-255. When the texture is referenced using the tex function, these values are converted into a single floating point number in the
-// range of 0-1 (see Annex 2). A full color graphics will typically require three textures, one for each of the color channels. A graphic involving
-// transparency may require a fourth channel.
-// tiled="" - If true then texture repeated when UV-coordinates is greater than 1.
-// >
-// </triangle>
-// Specifies an texture data to be used as a map. Lists a sequence of Base64 values specifying values for pixels from left to right then top to bottom,
-// then layer by layer.
-// Multi elements - Yes.
-// Parent element - <amf>.
-void AMFImporter::ParseNode_Texture()
-{
-std::string id;
-uint32_t width = 0;
-uint32_t height = 0;
-uint32_t depth = 1;
-std::string type;
-bool tiled = false;
-std::string enc64_data;
-CAMFImporter_NodeElement* ne;
-
- // Read attributes for node <color>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("width", width, XML_ReadNode_GetAttrVal_AsU32);
- MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsU32);
- MACRO_ATTRREAD_CHECK_RET("depth", depth, XML_ReadNode_GetAttrVal_AsU32);
- MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("tiled", tiled, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // create new texture object.
- ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
-
- // Check for child nodes
- if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data);
-
- // check that all components was defined
- if(id.empty()) throw DeadlyImportError("ID for texture must be defined.");
- if(width < 1) Throw_IncorrectAttrValue("width");
- if(height < 1) Throw_IncorrectAttrValue("height");
- if(depth < 1) Throw_IncorrectAttrValue("depth");
- if(type != "grayscale") Throw_IncorrectAttrValue("type");
- if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined.");
- // copy data
- als.ID = id;
- als.Width = width;
- als.Height = height;
- als.Depth = depth;
- als.Tiled = tiled;
- ParseHelper_Decode_Base64(enc64_data, als.Data);
- // check data size
- if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size.");
-
- mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
- mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
-}
-
-// <texmap
-// rtexid="" - Texture ID for red color component.
-// gtexid="" - Texture ID for green color component.
-// btexid="" - Texture ID for blue color component.
-// atexid="" - Texture ID for alpha color component. Optional.
-// >
-// </texmap>, old name: <map>
-// Specifies texture coordinates for triangle.
-// Multi elements - No.
-// Parent element - <triangle>.
-// Children elements:
-// <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
-// Multi elements - No.
-// Texture coordinates for every vertex of triangle.
-void AMFImporter::ParseNode_TexMap(const bool pUseOldName)
-{
-std::string rtexid, gtexid, btexid, atexid;
-CAMFImporter_NodeElement* ne;
-
- // Read attributes for node <color>.
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECK_RET("rtexid", rtexid, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("gtexid", gtexid, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("btexid", btexid, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("atexid", atexid, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // create new texture coordinates object.
- ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
-
- CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
- // check data
- if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");
- // Check for children nodes
- XML_CheckNode_MustHaveChildren();
- // read children nodes
- bool read_flag[6] = { false, false, false, false, false, false };
-
- ParseHelper_Node_Enter(ne);
- if(!pUseOldName)
- {
- MACRO_NODECHECK_LOOPBEGIN("texmap");
- MACRO_NODECHECK_READCOMP_F("utex1", read_flag[0], als.TextureCoordinate[0].x);
- MACRO_NODECHECK_READCOMP_F("utex2", read_flag[1], als.TextureCoordinate[1].x);
- MACRO_NODECHECK_READCOMP_F("utex3", read_flag[2], als.TextureCoordinate[2].x);
- MACRO_NODECHECK_READCOMP_F("vtex1", read_flag[3], als.TextureCoordinate[0].y);
- MACRO_NODECHECK_READCOMP_F("vtex2", read_flag[4], als.TextureCoordinate[1].y);
- MACRO_NODECHECK_READCOMP_F("vtex3", read_flag[5], als.TextureCoordinate[2].y);
- MACRO_NODECHECK_LOOPEND("texmap");
- }
- else
- {
- MACRO_NODECHECK_LOOPBEGIN("map");
- MACRO_NODECHECK_READCOMP_F("u1", read_flag[0], als.TextureCoordinate[0].x);
- MACRO_NODECHECK_READCOMP_F("u2", read_flag[1], als.TextureCoordinate[1].x);
- MACRO_NODECHECK_READCOMP_F("u3", read_flag[2], als.TextureCoordinate[2].x);
- MACRO_NODECHECK_READCOMP_F("v1", read_flag[3], als.TextureCoordinate[0].y);
- MACRO_NODECHECK_READCOMP_F("v2", read_flag[4], als.TextureCoordinate[1].y);
- MACRO_NODECHECK_READCOMP_F("v3", read_flag[5], als.TextureCoordinate[2].y);
- MACRO_NODECHECK_LOOPEND("map");
- }// if(!pUseOldName) else
-
- ParseHelper_Node_Exit();
-
- // check that all components was defined
- if(!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5]))
- throw DeadlyImportError("Not all texture coordinates are defined.");
-
- // copy attributes data
- als.TextureID_R = rtexid;
- als.TextureID_G = gtexid;
- als.TextureID_B = btexid;
- als.TextureID_A = atexid;
-
- mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
diff --git a/src/3rdparty/assimp/code/AMFImporter_Node.hpp b/src/3rdparty/assimp/code/AMFImporter_Node.hpp
deleted file mode 100644
index 522e6ccca..000000000
--- a/src/3rdparty/assimp/code/AMFImporter_Node.hpp
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter_Node.hpp
-/// \brief Elements of scene graph.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#pragma once
-#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H
-#define INCLUDED_AI_AMF_IMPORTER_NODE_H
-
-// Header files, stdlib.
-#include <list>
-#include <string>
-#include <vector>
-
-// Header files, Assimp.
-#include "assimp/types.h"
-#include "assimp/scene.h"
-
-/// \class CAMFImporter_NodeElement
-/// Base class for elements of nodes.
-class CAMFImporter_NodeElement {
-
-public:
- /// Define what data type contain node element.
- enum EType {
- ENET_Color, ///< Color element: <color>.
- ENET_Constellation,///< Grouping element: <constellation>.
- ENET_Coordinates, ///< Coordinates element: <coordinates>.
- ENET_Edge, ///< Edge element: <edge>.
- ENET_Instance, ///< Grouping element: <constellation>.
- ENET_Material, ///< Material element: <material>.
- ENET_Metadata, ///< Metadata element: <metadata>.
- ENET_Mesh, ///< Metadata element: <mesh>.
- ENET_Object, ///< Element which hold object: <object>.
- ENET_Root, ///< Root element: <amf>.
- ENET_Triangle, ///< Triangle element: <triangle>.
- ENET_TexMap, ///< Texture coordinates element: <texmap> or <map>.
- ENET_Texture, ///< Texture element: <texture>.
- ENET_Vertex, ///< Vertex element: <vertex>.
- ENET_Vertices, ///< Vertex element: <vertices>.
- ENET_Volume, ///< Volume element: <volume>.
-
- ENET_Invalid ///< Element has invalid type and possible contain invalid data.
- };
-
- const EType Type;///< Type of element.
- std::string ID;///< ID of element.
- CAMFImporter_NodeElement* Parent;///< Parent element. If nullptr then this node is root.
- std::list<CAMFImporter_NodeElement*> Child;///< Child elements.
-
-public: /// Destructor, virtual..
- virtual ~CAMFImporter_NodeElement() {
- // empty
- }
-
-private:
- /// Disabled copy constructor.
- CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement);
-
- /// Disabled assign operator.
- CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement);
-
- /// Disabled default constructor.
- CAMFImporter_NodeElement();
-
-protected:
- /// In constructor inheritor must set element type.
- /// \param [in] pType - element type.
- /// \param [in] pParent - parent element.
- CAMFImporter_NodeElement(const EType pType, CAMFImporter_NodeElement* pParent)
- : Type(pType)
- , ID()
- , Parent(pParent)
- , Child() {
- // empty
- }
-};// class IAMFImporter_NodeElement
-
-/// \struct CAMFImporter_NodeElement_Constellation
-/// A collection of objects or constellations with specific relative locations.
-struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Constellation, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Constellation
-
-/// \struct CAMFImporter_NodeElement_Instance
-/// Part of constellation.
-struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- std::string ObjectID;///< ID of object for instantiation.
- /// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
- /// create an instance of the object in the current constellation.
- aiVector3D Delta;
-
- /// \var Rotation - The rotation, in degrees, to rotate the referenced object about its x, y, and z axes, respectively, to create an
- /// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
- aiVector3D Rotation;
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Instance, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Instance
-
-/// \struct CAMFImporter_NodeElement_Metadata
-/// Structure that define metadata node.
-struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- std::string Type;///< Type of "Value".
- std::string Value;///< Value.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Metadata, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Metadata
-
-/// \struct CAMFImporter_NodeElement_Root
-/// Structure that define root node.
-struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
- std::string Version;///< Version of format.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Root, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Root
-
-/// \struct CAMFImporter_NodeElement_Color
-/// Structure that define object node.
-struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- bool Composed;///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
- std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA.
- aiColor4D Color;///< Constant color.
- std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Color, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Color
-
-/// \struct CAMFImporter_NodeElement_Material
-/// Structure that define material node.
-struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Material, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Material
-
-/// \struct CAMFImporter_NodeElement_Object
-/// Structure that define object node.
-struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Object, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Object
-
-/// \struct CAMFImporter_NodeElement_Mesh
-/// Structure that define mesh node.
-struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Mesh, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Mesh
-
-/// \struct CAMFImporter_NodeElement_Vertex
-/// Structure that define vertex node.
-struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Vertex, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Vertex
-
-/// \struct CAMFImporter_NodeElement_Edge
-/// Structure that define edge node.
-struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Edge, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Vertex
-
-/// \struct CAMFImporter_NodeElement_Vertices
-/// Structure that define vertices node.
-struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement
-{
- /// \fn CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Vertices, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Vertices
-
-/// \struct CAMFImporter_NodeElement_Volume
-/// Structure that define volume node.
-struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- std::string MaterialID;///< Which material to use.
- std::string Type;///< What this volume describes can be “region†or “supportâ€. If none specified, “object†is assumed.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Volume, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Volume
-
-/// \struct CAMFImporter_NodeElement_Coordinates
-/// Structure that define coordinates node.
-struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- aiVector3D Coordinate;///< Coordinate.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Coordinates, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Coordinates
-
-/// \struct CAMFImporter_NodeElement_TexMap
-/// Structure that define texture coordinates node.
-struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- aiVector3D TextureCoordinate[3];///< Texture coordinates.
- std::string TextureID_R;///< Texture ID for red color component.
- std::string TextureID_G;///< Texture ID for green color component.
- std::string TextureID_B;///< Texture ID for blue color component.
- std::string TextureID_A;///< Texture ID for alpha color component.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_TexMap, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_TexMap
-
-/// \struct CAMFImporter_NodeElement_Triangle
-/// Structure that define triangle node.
-struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement
-{
- /****************** Variables ******************/
-
- size_t V[3];///< Triangle vertices.
-
- /****************** Functions ******************/
-
- /// \fn CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Triangle, pParent)
- {}
-
-};// struct CAMFImporter_NodeElement_Triangle
-
-/// Structure that define texture node.
-struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement {
- size_t Width, Height, Depth;///< Size of the texture.
- std::vector<uint8_t> Data;///< Data of the texture.
- bool Tiled;
-
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- CAMFImporter_NodeElement_Texture(CAMFImporter_NodeElement* pParent)
- : CAMFImporter_NodeElement(ENET_Texture, pParent)
- , Width( 0 )
- , Height( 0 )
- , Depth( 0 )
- , Data()
- , Tiled( false ){
- // empty
- }
-};// struct CAMFImporter_NodeElement_Texture
-
-#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H
diff --git a/src/3rdparty/assimp/code/AMFImporter_Postprocess.cpp b/src/3rdparty/assimp/code/AMFImporter_Postprocess.cpp
deleted file mode 100644
index 991eb97e7..000000000
--- a/src/3rdparty/assimp/code/AMFImporter_Postprocess.cpp
+++ /dev/null
@@ -1,976 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AMFImporter_Postprocess.cpp
-/// \brief Convert built scenegraph and objects to Assimp scenegraph.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-
-#include "AMFImporter.hpp"
-
-// Header files, Assimp.
-#include <assimp/SceneCombiner.h>
-#include "StandardShapes.h"
-#include "StringUtils.h"
-
-// Header files, stdlib.
-#include <iterator>
-
-namespace Assimp
-{
-
-aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*pY*/, const float /*pZ*/) const
-{
- aiColor4D tcol;
-
- // Check if stored data are supported.
- if(Composition.size() != 0)
- {
- throw DeadlyImportError("IME. GetColor for composition");
- }
- else if(Color->Composed)
- {
- throw DeadlyImportError("IME. GetColor, composed color");
- }
- else
- {
- tcol = Color->Color;
- }
-
- // Check if default color must be used
- if((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0))
- {
- tcol.r = 0.5f;
- tcol.g = 0.5f;
- tcol.b = 0.5f;
- tcol.a = 1;
- }
-
- return tcol;
-}
-
-void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
- std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
-{
- CAMFImporter_NodeElement_Vertices* vn = nullptr;
- size_t col_idx;
-
- // All data stored in "vertices", search for it.
- for(CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
- {
- if(ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices*)ne_child;
- }
-
- // If "vertices" not found then no work for us.
- if(vn == nullptr) return;
-
- pVertexCoordinateArray.reserve(vn->Child.size());// all coordinates stored as child and we need to reserve space for future push_back's.
- pVertexColorArray.resize(vn->Child.size());// colors count equal vertices count.
- col_idx = 0;
- // Inside vertices collect all data and place to arrays
- for(CAMFImporter_NodeElement* vn_child: vn->Child)
- {
- // vertices, colors
- if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
- {
- // by default clear color for current vertex
- pVertexColorArray[col_idx] = nullptr;
-
- for(CAMFImporter_NodeElement* vtx: vn_child->Child)
- {
- if(vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates)
- {
- pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates*)vtx)->Coordinate);
-
- continue;
- }
-
- if(vtx->Type == CAMFImporter_NodeElement::ENET_Color)
- {
- pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color*)vtx;
-
- continue;
- }
- }// for(CAMFImporter_NodeElement* vtx: vn_child->Child)
-
- col_idx++;
- }// if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
- }// for(CAMFImporter_NodeElement* vn_child: vn->Child)
-}
-
-size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B,
- const std::string& pID_A)
-{
- size_t TextureConverted_Index;
- std::string TextureConverted_ID;
-
- // check input data
- if(pID_R.empty() && pID_G.empty() && pID_B.empty() && pID_A.empty())
- throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. At least one texture ID must be defined.");
-
- // Create ID
- TextureConverted_ID = pID_R + "_" + pID_G + "_" + pID_B + "_" + pID_A;
- // Check if texture specified by set of IDs is converted already.
- TextureConverted_Index = 0;
- for(const SPP_Texture& tex_convd: mTexture_Converted)
- {
- if(tex_convd.ID == TextureConverted_ID)
- return TextureConverted_Index;
- else
- TextureConverted_Index++;
- }
-
- //
- // Converted texture not found, create it.
- //
- CAMFImporter_NodeElement_Texture* src_texture[4]{nullptr};
- std::vector<CAMFImporter_NodeElement_Texture*> src_texture_4check;
- SPP_Texture converted_texture;
-
- {// find all specified source textures
- CAMFImporter_NodeElement* t_tex;
-
- // R
- if(!pID_R.empty())
- {
- if(!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
-
- src_texture[0] = (CAMFImporter_NodeElement_Texture*)t_tex;
- src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
- }
- else
- {
- src_texture[0] = nullptr;
- }
-
- // G
- if(!pID_G.empty())
- {
- if(!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
-
- src_texture[1] = (CAMFImporter_NodeElement_Texture*)t_tex;
- src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
- }
- else
- {
- src_texture[1] = nullptr;
- }
-
- // B
- if(!pID_B.empty())
- {
- if(!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);
-
- src_texture[2] = (CAMFImporter_NodeElement_Texture*)t_tex;
- src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
- }
- else
- {
- src_texture[2] = nullptr;
- }
-
- // A
- if(!pID_A.empty())
- {
- if(!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
-
- src_texture[3] = (CAMFImporter_NodeElement_Texture*)t_tex;
- src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
- }
- else
- {
- src_texture[3] = nullptr;
- }
- }// END: find all specified source textures
-
- // check that all textures has same size
- if(src_texture_4check.size() > 1)
- {
- for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++)
- {
- if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
- (src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth))
- {
- throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. Source texture must has the same size.");
- }
- }
- }// if(src_texture_4check.size() > 1)
-
- // set texture attributes
- converted_texture.Width = src_texture_4check[0]->Width;
- converted_texture.Height = src_texture_4check[0]->Height;
- converted_texture.Depth = src_texture_4check[0]->Depth;
- // if one of source texture is tiled then converted texture is tiled too.
- converted_texture.Tiled = false;
- for(uint8_t i = 0; i < src_texture_4check.size(); i++) converted_texture.Tiled |= src_texture_4check[i]->Tiled;
-
- // Create format hint.
- strcpy(converted_texture.FormatHint, "rgba0000");// copy initial string.
- if(!pID_R.empty()) converted_texture.FormatHint[4] = '8';
- if(!pID_G.empty()) converted_texture.FormatHint[5] = '8';
- if(!pID_B.empty()) converted_texture.FormatHint[6] = '8';
- if(!pID_A.empty()) converted_texture.FormatHint[7] = '8';
-
- //
- // Сopy data of textures.
- //
- size_t tex_size = 0;
- size_t step = 0;
- size_t off_g = 0;
- size_t off_b = 0;
-
- // Calculate size of the target array and rule how data will be copied.
- if(!pID_R.empty() && nullptr != src_texture[ 0 ] ) {
- tex_size += src_texture[0]->Data.size(); step++, off_g++, off_b++;
- }
- if(!pID_G.empty() && nullptr != src_texture[ 1 ] ) {
- tex_size += src_texture[1]->Data.size(); step++, off_b++;
- }
- if(!pID_B.empty() && nullptr != src_texture[ 2 ] ) {
- tex_size += src_texture[2]->Data.size(); step++;
- }
- if(!pID_A.empty() && nullptr != src_texture[ 3 ] ) {
- tex_size += src_texture[3]->Data.size(); step++;
- }
-
- // Create target array.
- converted_texture.Data = new uint8_t[tex_size];
- // And copy data
- auto CopyTextureData = [&](const std::string& pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
- {
- if(!pID.empty())
- {
- for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
- CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
- ai_assert(tex);
- converted_texture.Data[idx_target] = tex->Data.at(idx_src);
- }
- }
- };// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
-
- CopyTextureData(pID_R, 0, step, 0);
- CopyTextureData(pID_G, off_g, step, 1);
- CopyTextureData(pID_B, off_b, step, 2);
- CopyTextureData(pID_A, step - 1, step, 3);
-
- // Store new converted texture ID
- converted_texture.ID = TextureConverted_ID;
- // Store new converted texture
- mTexture_Converted.push_back(converted_texture);
-
- return TextureConverted_Index;
-}
-
-void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated)
-{
- auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const CAMFImporter_NodeElement_TexMap* pTexMap2) -> bool
- {
- if((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
- if(pTexMap1 == nullptr) return false;
- if(pTexMap2 == nullptr) return false;
-
- if(pTexMap1->TextureID_R != pTexMap2->TextureID_R) return false;
- if(pTexMap1->TextureID_G != pTexMap2->TextureID_G) return false;
- if(pTexMap1->TextureID_B != pTexMap2->TextureID_B) return false;
- if(pTexMap1->TextureID_A != pTexMap2->TextureID_A) return false;
-
- return true;
- };
-
- pOutputList_Separated.clear();
- if(pInputList.size() == 0) return;
-
- do
- {
- SComplexFace face_start = pInputList.front();
- std::list<SComplexFace> face_list_cur;
-
- for(std::list<SComplexFace>::iterator it = pInputList.begin(), it_end = pInputList.end(); it != it_end;)
- {
- if(texmap_is_equal(face_start.TexMap, it->TexMap))
- {
- auto it_old = it;
-
- it++;
- face_list_cur.push_back(*it_old);
- pInputList.erase(it_old);
- }
- else
- {
- it++;
- }
- }
-
- if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);
-
- } while(pInputList.size() > 0);
-}
-
-void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
-{
- if ( !metadataList.empty() )
- {
- if(sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
-
- // copy collected metadata to output node.
- sceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(metadataList.size()) );
- size_t meta_idx( 0 );
-
- for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList)
- {
- sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
- }
- }// if(!metadataList.empty())
-}
-
-void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
-{
-CAMFImporter_NodeElement_Color* object_color = nullptr;
-
- // create new aiNode and set name as <object> has.
- *pSceneNode = new aiNode;
- (*pSceneNode)->mName = pNodeElement.ID;
- // read mesh and color
- for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
- {
- std::vector<aiVector3D> vertex_arr;
- std::vector<CAMFImporter_NodeElement_Color*> color_arr;
-
- // color for object
- if(ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color*)ne_child;
-
- if(ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh)
- {
- // Create arrays from children of mesh: vertices.
- PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr);
- // Use this arrays as a source when creating every aiMesh
- Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
- }
- }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
-}
-
-void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
- const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray,
- const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
-{
-std::list<unsigned int> mesh_idx;
-
- // all data stored in "volume", search for it.
- for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
- {
- const CAMFImporter_NodeElement_Color* ne_volume_color = nullptr;
- const SPP_Material* cur_mat = nullptr;
-
- if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
- {
- /******************* Get faces *******************/
- const CAMFImporter_NodeElement_Volume* ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume*>(ne_child);
-
- std::list<SComplexFace> complex_faces_list;// List of the faces of the volume.
- std::list<std::list<SComplexFace> > complex_faces_toplist;// List of the face list for every mesh.
-
- // check if volume use material
- if(!ne_volume->MaterialID.empty())
- {
- if(!Find_ConvertedMaterial(ne_volume->MaterialID, &cur_mat)) Throw_ID_NotFound(ne_volume->MaterialID);
- }
-
- // inside "volume" collect all data and place to arrays or create new objects
- for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
- {
- // color for volume
- if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color)
- {
- ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_volume_child);
- }
- else if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle)// triangles, triangles colors
- {
- const CAMFImporter_NodeElement_Triangle& tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle*>(ne_volume_child);
-
- SComplexFace complex_face;
-
- // initialize pointers
- complex_face.Color = nullptr;
- complex_face.TexMap = nullptr;
- // get data from triangle children: color, texture coordinates.
- if(tri_al.Child.size())
- {
- for(const CAMFImporter_NodeElement* ne_triangle_child: tri_al.Child)
- {
- if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color)
- complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_triangle_child);
- else if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap)
- complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap*>(ne_triangle_child);
- }
- }// if(tri_al.Child.size())
-
- // create new face and store it.
- complex_face.Face.mNumIndices = 3;
- complex_face.Face.mIndices = new unsigned int[3];
- complex_face.Face.mIndices[0] = static_cast<unsigned int>(tri_al.V[0]);
- complex_face.Face.mIndices[1] = static_cast<unsigned int>(tri_al.V[1]);
- complex_face.Face.mIndices[2] = static_cast<unsigned int>(tri_al.V[2]);
- complex_faces_list.push_back(complex_face);
- }
- }// for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
-
- /**** Split faces list: one list per mesh ****/
- PostprocessHelper_SplitFacesByTextureID(complex_faces_list, complex_faces_toplist);
-
- /***** Create mesh for every faces list ******/
- for(std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
- {
- auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
- {
- size_t rv;
-
- if(pBiggerThan != nullptr)
- {
- bool found = false;
-
- for(const SComplexFace& face: pFaceList)
- {
- for(size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++)
- {
- if(face.Face.mIndices[idx_vert] > *pBiggerThan)
- {
- rv = face.Face.mIndices[idx_vert];
- found = true;
-
- break;
- }
- }
-
- if(found) break;
- }
-
- if(!found) return *pBiggerThan;
- }
- else
- {
- rv = pFaceList.front().Face.mIndices[0];
- }// if(pBiggerThan != nullptr) else
-
- for(const SComplexFace& face: pFaceList)
- {
- for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
- {
- if(face.Face.mIndices[vi] < rv)
- {
- if(pBiggerThan != nullptr)
- {
- if(face.Face.mIndices[vi] > *pBiggerThan) rv = face.Face.mIndices[vi];
- }
- else
- {
- rv = face.Face.mIndices[vi];
- }
- }
- }
- }// for(const SComplexFace& face: pFaceList)
-
- return rv;
- };// auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
-
- auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void
- {
- for(const SComplexFace& face: pFaceList)
- {
- for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
- {
- if(face.Face.mIndices[vi] == pIdx_From) face.Face.mIndices[vi] = static_cast<unsigned int>(pIdx_To);
- }
- }
- };// auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void
-
- auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D
- {
- // Color priorities(In descending order):
- // 1. triangle color;
- // 2. vertex color;
- // 3. volume color;
- // 4. object color;
- // 5. material;
- // 6. default - invisible coat.
- //
- // Fill vertices colors in color priority list above that's points from 1 to 6.
- if((pIdx < pVertexColorArray.size()) && (pVertexColorArray[pIdx] != nullptr))// check for vertex color
- {
- if(pVertexColorArray[pIdx]->Composed)
- throw DeadlyImportError("IME: vertex color composed");
- else
- return pVertexColorArray[pIdx]->Color;
- }
- else if(ne_volume_color != nullptr)// check for volume color
- {
- if(ne_volume_color->Composed)
- throw DeadlyImportError("IME: volume color composed");
- else
- return ne_volume_color->Color;
- }
- else if(pObjectColor != nullptr)// check for object color
- {
- if(pObjectColor->Composed)
- throw DeadlyImportError("IME: object color composed");
- else
- return pObjectColor->Color;
- }
- else if(cur_mat != nullptr)// check for material
- {
- return cur_mat->GetColor(pVertexCoordinateArray.at(pIdx).x, pVertexCoordinateArray.at(pIdx).y, pVertexCoordinateArray.at(pIdx).z);
- }
- else// set default color.
- {
- return {0, 0, 0, 0};
- }// if((vi < pVertexColorArray.size()) && (pVertexColorArray[vi] != nullptr)) else
-
- };// auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D
-
- aiMesh* tmesh = new aiMesh;
-
- tmesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;// Only triangles is supported by AMF.
- //
- // set geometry and colors (vertices)
- //
- // copy faces/triangles
- tmesh->mNumFaces = static_cast<unsigned int>(face_list_cur.size());
- tmesh->mFaces = new aiFace[tmesh->mNumFaces];
-
- // Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume
- // can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10.
- // Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous.
- size_t VertexCount_Max = tmesh->mNumFaces * 3;// 3 - triangles.
- std::vector<aiVector3D> vert_arr, texcoord_arr;
- std::vector<aiColor4D> col_arr;
-
- vert_arr.reserve(VertexCount_Max * 2);// "* 2" - see below TODO.
- col_arr.reserve(VertexCount_Max * 2);
-
- {// fill arrays
- size_t vert_idx_from, vert_idx_to;
-
- // first iteration.
- vert_idx_to = 0;
- vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
- vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
- col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
- if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
-
- // rest iterations
- do
- {
- vert_idx_from = VertexIndex_GetMinimal(face_list_cur, &vert_idx_to);
- if(vert_idx_from == vert_idx_to) break;// all indices are transferred,
-
- vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
- col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
- vert_idx_to++;
- if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
-
- } while(true);
- }// fill arrays. END.
-
- //
- // check if triangle colors are used and create additional faces if needed.
- //
- for(const SComplexFace& face_cur: face_list_cur)
- {
- if(face_cur.Color != nullptr)
- {
- aiColor4D face_color;
- size_t vert_idx_new = vert_arr.size();
-
- if(face_cur.Color->Composed)
- throw DeadlyImportError("IME: face color composed");
- else
- face_color = face_cur.Color->Color;
-
- for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
- {
- vert_arr.push_back(vert_arr.at(face_cur.Face.mIndices[idx_ind]));
- col_arr.push_back(face_color);
- face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(vert_idx_new++);
- }
- }// if(face_cur.Color != nullptr)
- }// for(const SComplexFace& face_cur: face_list_cur)
-
- //
- // if texture is used then copy texture coordinates too.
- //
- if(face_list_cur.front().TexMap != nullptr)
- {
- size_t idx_vert_new = vert_arr.size();
- ///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for
- /// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about
- /// optimisation.
- bool* idx_vert_used;
-
- idx_vert_used = new bool[VertexCount_Max * 2];
- for(size_t i = 0, i_e = VertexCount_Max * 2; i < i_e; i++) idx_vert_used[i] = false;
-
- // This ID's will be used when set materials ID in scene.
- tmesh->mMaterialIndex = static_cast<unsigned int>(PostprocessHelper_GetTextureID_Or_Create(face_list_cur.front().TexMap->TextureID_R,
- face_list_cur.front().TexMap->TextureID_G,
- face_list_cur.front().TexMap->TextureID_B,
- face_list_cur.front().TexMap->TextureID_A));
- texcoord_arr.resize(VertexCount_Max * 2);
- for(const SComplexFace& face_cur: face_list_cur)
- {
- for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
- {
- const size_t idx_vert = face_cur.Face.mIndices[idx_ind];
-
- if(!idx_vert_used[idx_vert])
- {
- texcoord_arr.at(idx_vert) = face_cur.TexMap->TextureCoordinate[idx_ind];
- idx_vert_used[idx_vert] = true;
- }
- else if(texcoord_arr.at(idx_vert) != face_cur.TexMap->TextureCoordinate[idx_ind])
- {
- // in that case one vertex is shared with many texture coordinates. We need to duplicate vertex with another texture
- // coordinates.
- vert_arr.push_back(vert_arr.at(idx_vert));
- col_arr.push_back(col_arr.at(idx_vert));
- texcoord_arr.at(idx_vert_new) = face_cur.TexMap->TextureCoordinate[idx_ind];
- face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(idx_vert_new++);
- }
- }// for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
- }// for(const SComplexFace& face_cur: face_list_cur)
-
- delete [] idx_vert_used;
- // shrink array
- texcoord_arr.resize(idx_vert_new);
- }// if(face_list_cur.front().TexMap != nullptr)
-
- //
- // copy collected data to mesh
- //
- tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
- tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
- tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];
-
- memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
- memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
- if(texcoord_arr.size() > 0)
- {
- tmesh->mTextureCoords[0] = new aiVector3D[tmesh->mNumVertices];
- memcpy(tmesh->mTextureCoords[0], texcoord_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
- tmesh->mNumUVComponents[0] = 2;// U and V stored in "x", "y" of aiVector3D.
- }
-
- size_t idx_face = 0;
- for(const SComplexFace& face_cur: face_list_cur) tmesh->mFaces[idx_face++] = face_cur.Face;
-
- // store new aiMesh
- mesh_idx.push_back(static_cast<unsigned int>(pMeshList.size()));
- pMeshList.push_back(tmesh);
- }// for(const std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
- }// if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
- }// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
-
- // if meshes was created then assign new indices with current aiNode
- if(mesh_idx.size() > 0)
- {
- std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
-
- pSceneNode.mNumMeshes = static_cast<unsigned int>(mesh_idx.size());
- pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes];
- for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *mit++;
- }// if(mesh_idx.size() > 0)
-}
-
-void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
-{
-SPP_Material new_mat;
-
- new_mat.ID = pMaterial.ID;
- for(const CAMFImporter_NodeElement* mat_child: pMaterial.Child)
- {
- if(mat_child->Type == CAMFImporter_NodeElement::ENET_Color)
- {
- new_mat.Color = (CAMFImporter_NodeElement_Color*)mat_child;
- }
- else if(mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata)
- {
- new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata*)mat_child);
- }
- }// for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)
-
- // place converted material to special list
- mMaterial_Converted.push_back(new_mat);
-}
-
-void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
-{
-aiNode* con_node;
-std::list<aiNode*> ch_node;
-
- // We will build next hierarchy:
- // aiNode as parent (<constellation>) for set of nodes as a children
- // |- aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
- // ...
- // \_ aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
- con_node = new aiNode;
- con_node->mName = pConstellation.ID;
- // Walk through children and search for instances of another objects, constellations.
- for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
- {
- aiMatrix4x4 tmat;
- aiNode* t_node;
- aiNode* found_node;
-
- if(ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue;
- if(ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
-
- // create alias for conveniance
- CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);
- // find referenced object
- if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
-
- // create node for apllying transformation
- t_node = new aiNode;
- t_node->mParent = con_node;
- // apply transformation
- aiMatrix4x4::Translation(als.Delta, tmat), t_node->mTransformation *= tmat;
- aiMatrix4x4::RotationX(als.Rotation.x, tmat), t_node->mTransformation *= tmat;
- aiMatrix4x4::RotationY(als.Rotation.y, tmat), t_node->mTransformation *= tmat;
- aiMatrix4x4::RotationZ(als.Rotation.z, tmat), t_node->mTransformation *= tmat;
- // create array for one child node
- t_node->mNumChildren = 1;
- t_node->mChildren = new aiNode*[t_node->mNumChildren];
- SceneCombiner::Copy(&t_node->mChildren[0], found_node);
- t_node->mChildren[0]->mParent = t_node;
- ch_node.push_back(t_node);
- }// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
-
- // copy found aiNode's as children
- if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");
-
- size_t ch_idx = 0;
-
- con_node->mNumChildren = static_cast<unsigned int>(ch_node.size());
- con_node->mChildren = new aiNode*[con_node->mNumChildren];
- for(aiNode* node: ch_node) con_node->mChildren[ch_idx++] = node;
-
- // and place "root" of <constellation> node to node list
- pNodeList.push_back(con_node);
-}
-
-void AMFImporter::Postprocess_BuildScene(aiScene* pScene)
-{
-std::list<aiNode*> node_list;
-std::list<aiMesh*> mesh_list;
-std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
-
- //
- // Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
- // For building aiScene we are must to do few steps:
- // at first creating root node for aiScene.
- pScene->mRootNode = new aiNode;
- pScene->mRootNode->mParent = nullptr;
- pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
- // search for root(<amf>) element
- CAMFImporter_NodeElement* root_el = nullptr;
-
- for(CAMFImporter_NodeElement* ne: mNodeElement_List)
- {
- if(ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;
-
- root_el = ne;
-
- break;
- }// for(const CAMFImporter_NodeElement* ne: mNodeElement_List)
-
- // Check if root element are found.
- if(root_el == nullptr) throw DeadlyImportError("Root(<amf>) element not found.");
-
- // after that walk through children of root and collect data. Five types of nodes can be placed at top level - in <amf>: <object>, <material>, <texture>,
- // <constellation> and <metadata>. But at first we must read <material> and <texture> because they will be used in <object>. <metadata> can be read
- // at any moment.
- //
- // 1. <material>
- // 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
- for(const CAMFImporter_NodeElement* root_child: root_el->Child)
- {
- if(root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material*)root_child));
- }
-
- // After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>.
- //
- // 3. <object>
- for(const CAMFImporter_NodeElement* root_child: root_el->Child)
- {
- if(root_child->Type == CAMFImporter_NodeElement::ENET_Object)
- {
- aiNode* tnode = nullptr;
-
- // for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
- Postprocess_BuildNodeAndObject(*((CAMFImporter_NodeElement_Object*)root_child), mesh_list, &tnode);
- if(tnode != nullptr) node_list.push_back(tnode);
-
- }
- }// for(const CAMFImporter_NodeElement* root_child: root_el->Child)
-
- // And finally read rest of nodes.
- //
- for(const CAMFImporter_NodeElement* root_child: root_el->Child)
- {
- // 4. <constellation>
- if(root_child->Type == CAMFImporter_NodeElement::ENET_Constellation)
- {
- // <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's.
- Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation*)root_child), node_list);
- }
-
- // 5, <metadata>
- if(root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata*)root_child);
- }// for(const CAMFImporter_NodeElement* root_child: root_el->Child)
-
- // at now we can add collected metadata to root node
- Postprocess_AddMetadata(meta_list, *pScene->mRootNode);
- //
- // Check constellation children
- //
- // As said in specification:
- // "When multiple objects and constellations are defined in a single file, only the top level objects and constellations are available for printing."
- // What that means? For example: if some object is used in constellation then you must show only constellation but not original object.
- // And at this step we are checking that relations.
-nl_clean_loop:
-
- if(node_list.size() > 1)
- {
- // walk through all nodes
- for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
- {
- // and try to find them in another top nodes.
- std::list<aiNode*>::const_iterator next_it = nl_it;
-
- next_it++;
- for(; next_it != node_list.end(); next_it++)
- {
- if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
- {
- // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
- node_list.erase(nl_it);
-
- goto nl_clean_loop;
- }
- }// for(; next_it != node_list.end(); next_it++)
- }// for(std::list<aiNode*>::const_iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
- }
-
- //
- // move created objects to aiScene
- //
- //
- // Nodes
- if(node_list.size() > 0)
- {
- std::list<aiNode*>::const_iterator nl_it = node_list.begin();
-
- pScene->mRootNode->mNumChildren = static_cast<unsigned int>(node_list.size());
- pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
- for(size_t i = 0; i < pScene->mRootNode->mNumChildren; i++)
- {
- // Objects and constellation that must be showed placed at top of hierarchy in <amf> node. So all aiNode's in node_list must have
- // mRootNode only as parent.
- (*nl_it)->mParent = pScene->mRootNode;
- pScene->mRootNode->mChildren[i] = *nl_it++;
- }
- }// if(node_list.size() > 0)
-
- //
- // Meshes
- if(mesh_list.size() > 0)
- {
- std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
-
- pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *ml_it++;
- }// if(mesh_list.size() > 0)
-
- //
- // Textures
- pScene->mNumTextures = static_cast<unsigned int>(mTexture_Converted.size());
- if(pScene->mNumTextures > 0)
- {
- size_t idx;
-
- idx = 0;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures];
- for(const SPP_Texture& tex_convd: mTexture_Converted)
- {
- pScene->mTextures[idx] = new aiTexture;
- pScene->mTextures[idx]->mWidth = static_cast<unsigned int>(tex_convd.Width);
- pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
- pScene->mTextures[idx]->pcData = (aiTexel*)tex_convd.Data;
- // texture format description.
- strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
- idx++;
- }// for(const SPP_Texture& tex_convd: mTexture_Converted)
-
- // Create materials for embedded textures.
- idx = 0;
- pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size());
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for(const SPP_Texture& tex_convd: mTexture_Converted)
- {
- const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
- const int mode = aiTextureOp_Multiply;
- const int repeat = tex_convd.Tiled ? 1 : 0;
-
- pScene->mMaterials[idx] = new aiMaterial;
- pScene->mMaterials[idx]->AddProperty(&texture_id, AI_MATKEY_TEXTURE_DIFFUSE(0));
- pScene->mMaterials[idx]->AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0));
- pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
- pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
- idx++;
- }
- }// if(pScene->mNumTextures > 0)
-}// END: after that walk through children of root and collect data
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
diff --git a/src/3rdparty/assimp/code/ASELoader.cpp b/src/3rdparty/assimp/code/ASELoader.cpp
deleted file mode 100644
index 65935f48f..000000000
--- a/src/3rdparty/assimp/code/ASELoader.cpp
+++ /dev/null
@@ -1,1328 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASELoader.cpp
- * @brief Implementation of the ASE importer class
- */
-
-#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "ASELoader.h"
-#include "StringComparison.h"
-#include "SkeletonMeshBuilder.h"
-#include "TargetAnimation.h"
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-// utilities
-#include "fast_atof.h"
-
-using namespace Assimp;
-using namespace Assimp::ASE;
-
-static const aiImporterDesc desc = {
- "ASE Importer",
- "",
- "",
- "Similar to 3DS but text-encoded",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "ase ask"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ASEImporter::ASEImporter()
- : mParser(),
- mBuffer(),
- pcScene(),
- configRecomputeNormals(),
- noSkeletonMesh()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ASEImporter::~ASEImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool ASEImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if( extension == "ase" || extension == "ask")
- return true;
-
- if ((!extension.length() || cs) && pIOHandler) {
- const char* tokens[] = {"*3dsmax_asciiexport"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader meta information
-const aiImporterDesc* ASEImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration options
-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;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void ASEImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open ASE file " + pFile + ".");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- this->mBuffer = &mBuffer2[0];
- this->pcScene = pScene;
-
- // ------------------------------------------------------------------
- // Guess the file format by looking at the extension
- // ASC is considered to be the older format 110,
- // ASE is the actual version 200 (that is currently written by max)
- // ------------------------------------------------------------------
- unsigned int defaultFormat;
- std::string::size_type s = pFile.length()-1;
- switch (pFile.c_str()[s]) {
-
- case 'C':
- case 'c':
- defaultFormat = AI_ASE_OLD_FILE_FORMAT;
- break;
- default:
- defaultFormat = AI_ASE_NEW_FILE_FORMAT;
- };
-
- // Construct an ASE parser and parse the file
- ASE::Parser parser(mBuffer,defaultFormat);
- mParser = &parser;
- mParser->Parse();
-
- //------------------------------------------------------------------
- // Check whether we god at least one mesh. If we did - generate
- // materials and copy meshes.
- // ------------------------------------------------------------------
- if ( !mParser->m_vMeshes.empty()) {
-
- // If absolutely no material has been loaded from the file
- // we need to generate a default material
- GenerateDefaultMaterial();
-
- // process all meshes
- bool tookNormals = false;
- std::vector<aiMesh*> avOutMeshes;
- avOutMeshes.reserve(mParser->m_vMeshes.size()*2);
- for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
- if ((*i).bSkip) {
- continue;
- }
- BuildUniqueRepresentation(*i);
-
- // Need to generate proper vertex normals if necessary
- if(GenerateNormals(*i)) {
- tookNormals = true;
- }
-
- // Convert all meshes to aiMesh objects
- ConvertMeshes(*i,avOutMeshes);
- }
- if (tookNormals) {
- DefaultLogger::get()->debug("ASE: Taking normals from the file. Use "
- "the AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS setting if you "
- "experience problems");
- }
-
- // Now build the output mesh list. Remove dummies
- pScene->mNumMeshes = (unsigned int)avOutMeshes.size();
- aiMesh** pp = pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (std::vector<aiMesh*>::const_iterator i = avOutMeshes.begin();i != avOutMeshes.end();++i) {
- if (!(*i)->mNumFaces) {
- continue;
- }
- *pp++ = *i;
- }
- pScene->mNumMeshes = (unsigned int)(pp - pScene->mMeshes);
-
- // Build final material indices (remove submaterials and setup
- // the final list)
- BuildMaterialIndices();
- }
-
- // ------------------------------------------------------------------
- // Copy all scene graph nodes - lights, cameras, dummies and meshes
- // into one huge list.
- //------------------------------------------------------------------
- std::vector<BaseNode*> nodes;
- nodes.reserve(mParser->m_vMeshes.size() +mParser->m_vLights.size()
- + mParser->m_vCameras.size() + mParser->m_vDummies.size());
-
- // Lights
- for (auto &light : mParser->m_vLights)nodes.push_back(&light);
- // Cameras
- for (auto &camera : mParser->m_vCameras)nodes.push_back(&camera);
- // Meshes
- for (auto &mesh : mParser->m_vMeshes)nodes.push_back(&mesh);
- // Dummies
- for (auto &dummy : mParser->m_vDummies)nodes.push_back(&dummy);
-
- // build the final node graph
- BuildNodes(nodes);
-
- // build output animations
- BuildAnimations(nodes);
-
- // build output cameras
- BuildCameras();
-
- // build output lights
- BuildLights();
-
- // ------------------------------------------------------------------
- // If we have no meshes use the SkeletonMeshBuilder helper class
- // to build a mesh for the animation skeleton
- // FIXME: very strange results
- // ------------------------------------------------------------------
- if (!pScene->mNumMeshes) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- if (!noSkeletonMesh) {
- SkeletonMeshBuilder skeleton(pScene);
- }
- }
-}
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::GenerateDefaultMaterial()
-{
- ai_assert(NULL != mParser);
-
- bool bHas = false;
- for (std::vector<ASE::Mesh>::iterator i = mParser->m_vMeshes.begin();i != mParser->m_vMeshes.end();++i) {
- if ((*i).bSkip)continue;
- if (ASE::Face::DEFAULT_MATINDEX == (*i).iMaterialIndex) {
- (*i).iMaterialIndex = (unsigned int)mParser->m_vMaterials.size();
- bHas = true;
- }
- }
- if (bHas || mParser->m_vMaterials.empty()) {
- // add a simple material without submaterials to the parser's list
- mParser->m_vMaterials.push_back ( ASE::Material() );
- ASE::Material& mat = mParser->m_vMaterials.back();
-
- mat.mDiffuse = aiColor3D(0.6f,0.6f,0.6f);
- mat.mSpecular = aiColor3D(1.0f,1.0f,1.0f);
- mat.mAmbient = aiColor3D(0.05f,0.05f,0.05f);
- mat.mShading = Discreet3DS::Gouraud;
- mat.mName = AI_DEFAULT_MATERIAL_NAME;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::BuildAnimations(const std::vector<BaseNode*>& nodes)
-{
- // check whether we have at least one mesh which has animations
- std::vector<ASE::BaseNode*>::const_iterator i = nodes.begin();
- unsigned int iNum = 0;
- for (;i != nodes.end();++i) {
-
- // TODO: Implement Bezier & TCB support
- if ((*i)->mAnim.mPositionType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
- if ((*i)->mAnim.mRotationType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Rotation controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
- if ((*i)->mAnim.mScalingType != ASE::Animation::TRACK) {
- DefaultLogger::get()->warn("ASE: Position controller uses Bezier/TCB keys. "
- "This is not supported.");
- }
-
- // We compare against 1 here - firstly one key is not
- // really an animation and secondly MAX writes dummies
- // that represent the node transformation.
- if ((*i)->mAnim.akeyPositions.size()>1 || (*i)->mAnim.akeyRotations.size()>1 || (*i)->mAnim.akeyScaling.size()>1){
- ++iNum;
- }
- if ((*i)->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( (*i)->mTargetPosition.x )) {
- ++iNum;
- }
- }
- if (iNum) {
- // Generate a new animation channel and setup everything for it
- pcScene->mNumAnimations = 1;
- pcScene->mAnimations = new aiAnimation*[1];
- aiAnimation* pcAnim = pcScene->mAnimations[0] = new aiAnimation();
- pcAnim->mNumChannels = iNum;
- pcAnim->mChannels = new aiNodeAnim*[iNum];
- pcAnim->mTicksPerSecond = mParser->iFrameSpeed * mParser->iTicksPerFrame;
-
- iNum = 0;
-
- // Now iterate through all meshes and collect all data we can find
- for (i = nodes.begin();i != nodes.end();++i) {
-
- ASE::BaseNode* me = *i;
- if ( me->mTargetAnim.akeyPositions.size() > 1 && is_not_qnan( me->mTargetPosition.x )) {
- // Generate an extra channel for the camera/light target.
- // BuildNodes() does also generate an extra node, named
- // <baseName>.Target.
- aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
- nd->mNodeName.Set(me->mName + ".Target");
-
- // If there is no input position channel we will need
- // to supply the default position from the node's
- // local transformation matrix.
- /*TargetAnimationHelper helper;
- if (me->mAnim.akeyPositions.empty())
- {
- aiMatrix4x4& mat = (*i)->mTransform;
- helper.SetFixedMainAnimationChannel(aiVector3D(
- mat.a4, mat.b4, mat.c4));
- }
- else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
- helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
-
- helper.Process(&me->mTargetAnim.akeyPositions);*/
-
- // Allocate the key array and fill it
- nd->mNumPositionKeys = (unsigned int) me->mTargetAnim.akeyPositions.size();
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
-
- ::memcpy(nd->mPositionKeys,&me->mTargetAnim.akeyPositions[0],
- nd->mNumPositionKeys * sizeof(aiVectorKey));
- }
-
- if (me->mAnim.akeyPositions.size() > 1 || me->mAnim.akeyRotations.size() > 1 || me->mAnim.akeyScaling.size() > 1) {
- // Begin a new node animation channel for this node
- aiNodeAnim* nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
- nd->mNodeName.Set(me->mName);
-
- // copy position keys
- if (me->mAnim.akeyPositions.size() > 1 )
- {
- // Allocate the key array and fill it
- nd->mNumPositionKeys = (unsigned int) me->mAnim.akeyPositions.size();
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
-
- ::memcpy(nd->mPositionKeys,&me->mAnim.akeyPositions[0],
- nd->mNumPositionKeys * sizeof(aiVectorKey));
- }
- // copy rotation keys
- if (me->mAnim.akeyRotations.size() > 1 ) {
- // Allocate the key array and fill it
- nd->mNumRotationKeys = (unsigned int) me->mAnim.akeyRotations.size();
- nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
-
- // --------------------------------------------------------------------
- // Rotation keys are offsets to the previous keys.
- // We have the quaternion representations of all
- // of them, so we just need to concatenate all
- // (unit-length) quaternions to get the absolute
- // rotations.
- // Rotation keys are ABSOLUTE for older files
- // --------------------------------------------------------------------
-
- aiQuaternion cur;
- for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
- aiQuatKey q = me->mAnim.akeyRotations[a];
-
- if (mParser->iFileFormat > 110) {
- cur = (a ? cur*q.mValue : q.mValue);
- q.mValue = cur.Normalize();
- }
- nd->mRotationKeys[a] = q;
-
- // need this to get to Assimp quaternion conventions
- nd->mRotationKeys[a].mValue.w *= -1.f;
- }
- }
- // copy scaling keys
- if (me->mAnim.akeyScaling.size() > 1 ) {
- // Allocate the key array and fill it
- nd->mNumScalingKeys = (unsigned int) me->mAnim.akeyScaling.size();
- nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
-
- ::memcpy(nd->mScalingKeys,&me->mAnim.akeyScaling[0],
- nd->mNumScalingKeys * sizeof(aiVectorKey));
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output cameras
-void ASEImporter::BuildCameras()
-{
- if (!mParser->m_vCameras.empty()) {
- pcScene->mNumCameras = (unsigned int)mParser->m_vCameras.size();
- pcScene->mCameras = new aiCamera*[pcScene->mNumCameras];
-
- for (unsigned int i = 0; i < pcScene->mNumCameras;++i) {
- aiCamera* out = pcScene->mCameras[i] = new aiCamera();
- ASE::Camera& in = mParser->m_vCameras[i];
-
- // copy members
- out->mClipPlaneFar = in.mFar;
- out->mClipPlaneNear = (in.mNear ? in.mNear : 0.1f);
- out->mHorizontalFOV = in.mFOV;
-
- out->mName.Set(in.mName);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output lights
-void ASEImporter::BuildLights()
-{
- if (!mParser->m_vLights.empty()) {
- pcScene->mNumLights = (unsigned int)mParser->m_vLights.size();
- pcScene->mLights = new aiLight*[pcScene->mNumLights];
-
- for (unsigned int i = 0; i < pcScene->mNumLights;++i) {
- aiLight* out = pcScene->mLights[i] = new aiLight();
- ASE::Light& in = mParser->m_vLights[i];
-
- // The direction is encoded in the transformation matrix of the node.
- // In 3DS MAX the light source points into negative Z direction if
- // the node transformation is the identity.
- out->mDirection = aiVector3D(0.f,0.f,-1.f);
-
- out->mName.Set(in.mName);
- switch (in.mLightType)
- {
- case ASE::Light::TARGET:
- out->mType = aiLightSource_SPOT;
- out->mAngleInnerCone = AI_DEG_TO_RAD(in.mAngle);
- out->mAngleOuterCone = (in.mFalloff ? AI_DEG_TO_RAD(in.mFalloff) : out->mAngleInnerCone);
- break;
-
- case ASE::Light::DIRECTIONAL:
- out->mType = aiLightSource_DIRECTIONAL;
- break;
-
- default:
- //case ASE::Light::OMNI:
- out->mType = aiLightSource_POINT;
- break;
- };
- out->mColorDiffuse = out->mColorSpecular = in.mColor * in.mIntensity;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ASEImporter::AddNodes(const std::vector<BaseNode*>& nodes,
- aiNode* pcParent,const char* szName)
-{
- aiMatrix4x4 m;
- AddNodes(nodes,pcParent,szName,m);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add meshes to a given node
-void ASEImporter::AddMeshes(const ASE::BaseNode* snode,aiNode* node)
-{
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i) {
- // Get the name of the mesh (the mesh instance has been temporarily stored in the third vertex color)
- const aiMesh* pcMesh = pcScene->mMeshes[i];
- const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
-
- if (mesh == snode) {
- ++node->mNumMeshes;
- }
- }
-
- if(node->mNumMeshes) {
- node->mMeshes = new unsigned int[node->mNumMeshes];
- for (unsigned int i = 0, p = 0; i < pcScene->mNumMeshes;++i) {
-
- const aiMesh* pcMesh = pcScene->mMeshes[i];
- const ASE::Mesh* mesh = (const ASE::Mesh*)pcMesh->mColors[2];
- if (mesh == snode) {
- node->mMeshes[p++] = i;
-
- // Transform all vertices of the mesh back into their local space ->
- // at the moment they are pretransformed
- aiMatrix4x4 m = mesh->mTransform;
- m.Inverse();
-
- aiVector3D* pvCurPtr = pcMesh->mVertices;
- const aiVector3D* pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
- while (pvCurPtr != pvEndPtr) {
- *pvCurPtr = m * (*pvCurPtr);
- pvCurPtr++;
- }
-
- // Do the same for the normal vectors, if we have them.
- // As always, inverse transpose.
- if (pcMesh->mNormals) {
- aiMatrix3x3 m3 = aiMatrix3x3( mesh->mTransform );
- m3.Transpose();
-
- pvCurPtr = pcMesh->mNormals;
- pvEndPtr = pvCurPtr + pcMesh->mNumVertices;
- while (pvCurPtr != pvEndPtr) {
- *pvCurPtr = m3 * (*pvCurPtr);
- pvCurPtr++;
- }
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add child nodes to a given parent node
-void ASEImporter::AddNodes (const std::vector<BaseNode*>& nodes,
- aiNode* pcParent, const char* szName,
- const aiMatrix4x4& mat)
-{
- const size_t len = szName ? ::strlen(szName) : 0;
- ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
-
- // Receives child nodes for the pcParent node
- std::vector<aiNode*> apcNodes;
-
- // Now iterate through all nodes in the scene and search for one
- // which has *us* as parent.
- for (std::vector<BaseNode*>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
- const BaseNode* snode = *it;
- if (szName) {
- if (len != snode->mParent.length() || ::strcmp(szName,snode->mParent.c_str()))
- continue;
- }
- else if (snode->mParent.length())
- continue;
-
- (*it)->mProcessed = true;
-
- // Allocate a new node and add it to the output data structure
- apcNodes.push_back(new aiNode());
- aiNode* node = apcNodes.back();
-
- node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
- node->mParent = pcParent;
-
- // Setup the transformation matrix of the node
- aiMatrix4x4 mParentAdjust = mat;
- mParentAdjust.Inverse();
- node->mTransformation = mParentAdjust*snode->mTransform;
-
- // Add sub nodes - prevent stack overflow due to recursive parenting
- if (node->mName != node->mParent->mName) {
- AddNodes(nodes,node,node->mName.data,snode->mTransform);
- }
-
- // Further processing depends on the type of the node
- if (snode->mType == ASE::BaseNode::Mesh) {
- // If the type of this node is "Mesh" we need to search
- // the list of output meshes in the data structure for
- // all those that belonged to this node once. This is
- // slightly inconvinient here and a better solution should
- // be used when this code is refactored next.
- AddMeshes(snode,node);
- }
- else if (is_not_qnan( snode->mTargetPosition.x )) {
- // If this is a target camera or light we generate a small
- // child node which marks the position of the camera
- // target (the direction information is contained in *this*
- // node's animation track but the exact target position
- // would be lost otherwise)
- if (!node->mNumChildren) {
- node->mChildren = new aiNode*[1];
- }
-
- aiNode* nd = new aiNode();
-
- nd->mName.Set ( snode->mName + ".Target" );
-
- nd->mTransformation.a4 = snode->mTargetPosition.x - snode->mTransform.a4;
- nd->mTransformation.b4 = snode->mTargetPosition.y - snode->mTransform.b4;
- nd->mTransformation.c4 = snode->mTargetPosition.z - snode->mTransform.c4;
-
- nd->mParent = node;
-
- // The .Target node is always the first child node
- for (unsigned int m = 0; m < node->mNumChildren;++m)
- node->mChildren[m+1] = node->mChildren[m];
-
- node->mChildren[0] = nd;
- node->mNumChildren++;
-
- // What we did is so great, it is at least worth a debug message
- DefaultLogger::get()->debug("ASE: Generating separate target node ("+snode->mName+")");
- }
- }
-
- // Allocate enough space for the child nodes
- // We allocate one slot more in case this is a target camera/light
- pcParent->mNumChildren = (unsigned int)apcNodes.size();
- if (pcParent->mNumChildren) {
- pcParent->mChildren = new aiNode*[apcNodes.size()+1 /* PLUS ONE !!! */];
-
- // now build all nodes for our nice new children
- for (unsigned int p = 0; p < apcNodes.size();++p)
- pcParent->mChildren[p] = apcNodes[p];
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build the output node graph
-void ASEImporter::BuildNodes(std::vector<BaseNode*>& nodes) {
- ai_assert(NULL != pcScene);
-
- // allocate the one and only root node
- aiNode* root = pcScene->mRootNode = new aiNode();
- root->mName.Set("<ASERoot>");
-
- // Setup the coordinate system transformation
- pcScene->mRootNode->mNumChildren = 1;
- pcScene->mRootNode->mChildren = new aiNode*[1];
- aiNode* ch = pcScene->mRootNode->mChildren[0] = new aiNode();
- ch->mParent = root;
-
- // Change the transformation matrix of all nodes
- for (BaseNode *node : nodes) {
- aiMatrix4x4& m = node->mTransform;
- m.Transpose(); // row-order vs column-order
- }
-
- // add all nodes
- AddNodes(nodes,ch,NULL);
-
- // now iterate through al nodes and find those that have not yet
- // been added to the nodegraph (= their parent could not be recognized)
- std::vector<const BaseNode*> aiList;
- for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it) {
- if ((*it)->mProcessed) {
- continue;
- }
-
- // check whether our parent is known
- bool bKnowParent = false;
-
- // search the list another time, starting *here* and try to find out whether
- // there is a node that references *us* as a parent
- for (std::vector<BaseNode*>::const_iterator it2 = nodes.begin();it2 != end; ++it2) {
- if (it2 == it) {
- continue;
- }
-
- if ((*it2)->mName == (*it)->mParent) {
- bKnowParent = true;
- break;
- }
- }
- if (!bKnowParent) {
- aiList.push_back(*it);
- }
- }
-
- // Are there ane orphaned nodes?
- if (!aiList.empty()) {
- std::vector<aiNode*> apcNodes;
- apcNodes.reserve(aiList.size() + pcScene->mRootNode->mNumChildren);
-
- for (unsigned int i = 0; i < pcScene->mRootNode->mNumChildren;++i)
- apcNodes.push_back(pcScene->mRootNode->mChildren[i]);
-
- delete[] pcScene->mRootNode->mChildren;
- for (std::vector<const BaseNode*>::/*const_*/iterator i = aiList.begin();i != aiList.end();++i) {
- const ASE::BaseNode* src = *i;
-
- // The parent is not known, so we can assume that we must add
- // this node to the root node of the whole scene
- aiNode* pcNode = new aiNode();
- pcNode->mParent = pcScene->mRootNode;
- pcNode->mName.Set(src->mName);
- AddMeshes(src,pcNode);
- AddNodes(nodes,pcNode,pcNode->mName.data);
- apcNodes.push_back(pcNode);
- }
-
- // Regenerate our output array
- pcScene->mRootNode->mChildren = new aiNode*[apcNodes.size()];
- for (unsigned int i = 0; i < apcNodes.size();++i)
- pcScene->mRootNode->mChildren[i] = apcNodes[i];
-
- pcScene->mRootNode->mNumChildren = (unsigned int)apcNodes.size();
- }
-
- // Reset the third color set to NULL - we used this field to store a temporary pointer
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
- pcScene->mMeshes[i]->mColors[2] = NULL;
-
- // The root node should not have at least one child or the file is valid
- if (!pcScene->mRootNode->mNumChildren) {
- throw DeadlyImportError("ASE: No nodes loaded. The file is either empty or corrupt");
- }
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pcScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert the imported data to the internal verbose representation
-void ASEImporter::BuildUniqueRepresentation(ASE::Mesh& mesh) {
- // allocate output storage
- std::vector<aiVector3D> mPositions;
- std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- std::vector<aiColor4D> mVertexColors;
- std::vector<aiVector3D> mNormals;
- std::vector<BoneVertex> mBoneVertices;
-
- unsigned int iSize = (unsigned int)mesh.mFaces.size() * 3;
- mPositions.resize(iSize);
-
- // optional texture coordinates
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i) {
- if (!mesh.amTexCoords[i].empty()) {
- amTexCoords[i].resize(iSize);
- }
- }
- // optional vertex colors
- if (!mesh.mVertexColors.empty()) {
- mVertexColors.resize(iSize);
- }
-
- // optional vertex normals (vertex normals can simply be copied)
- if (!mesh.mNormals.empty()) {
- mNormals.resize(iSize);
- }
- // bone vertices. There is no need to change the bone list
- if (!mesh.mBoneVertices.empty()) {
- mBoneVertices.resize(iSize);
- }
-
- // iterate through all faces in the mesh
- unsigned int iCurrent = 0, fi = 0;
- for (std::vector<ASE::Face>::iterator i = mesh.mFaces.begin();i != mesh.mFaces.end();++i,++fi) {
- for (unsigned int n = 0; n < 3;++n,++iCurrent)
- {
- mPositions[iCurrent] = mesh.mPositions[(*i).mIndices[n]];
-
- // add texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (mesh.amTexCoords[c].empty())break;
- amTexCoords[c][iCurrent] = mesh.amTexCoords[c][(*i).amUVIndices[c][n]];
- }
- // add vertex colors
- if (!mesh.mVertexColors.empty()) {
- mVertexColors[iCurrent] = mesh.mVertexColors[(*i).mColorIndices[n]];
- }
- // add normal vectors
- if (!mesh.mNormals.empty()) {
- mNormals[iCurrent] = mesh.mNormals[fi*3+n];
- mNormals[iCurrent].Normalize();
- }
-
- // handle bone vertices
- if ((*i).mIndices[n] < mesh.mBoneVertices.size()) {
- // (sometimes this will cause bone verts to be duplicated
- // however, I' quite sure Schrompf' JoinVerticesStep
- // will fix that again ...)
- mBoneVertices[iCurrent] = mesh.mBoneVertices[(*i).mIndices[n]];
- }
- (*i).mIndices[n] = iCurrent;
- }
- }
-
- // replace the old arrays
- mesh.mNormals = mNormals;
- mesh.mPositions = mPositions;
- mesh.mVertexColors = mVertexColors;
-
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- mesh.amTexCoords[c] = amTexCoords[c];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy a texture from the ASE structs to the output material
-void CopyASETexture(aiMaterial& mat, ASE::Texture& texture, aiTextureType type)
-{
- // Setup the texture name
- aiString tex;
- tex.Set( texture.mMapName);
- mat.AddProperty( &tex, AI_MATKEY_TEXTURE(type,0));
-
- // Setup the texture blend factor
- if (is_not_qnan(texture.mTextureBlend))
- mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
-
- // Setup texture UV transformations
- mat.AddProperty<ai_real>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert from ASE material to output material
-void ASEImporter::ConvertMaterial(ASE::Material& mat)
-{
- // LARGE TODO: Much code her is copied from 3DS ... join them maybe?
-
- // Allocate the output material
- mat.pcInstance = new aiMaterial();
-
- // At first add the base ambient color of the
- // scene to the material
- mat.mAmbient.r += mParser->m_clrAmbient.r;
- mat.mAmbient.g += mParser->m_clrAmbient.g;
- mat.mAmbient.b += mParser->m_clrAmbient.b;
-
- aiString name;
- name.Set( mat.mName);
- mat.pcInstance->AddProperty( &name, AI_MATKEY_NAME);
-
- // material colors
- mat.pcInstance->AddProperty( &mat.mAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat.pcInstance->AddProperty( &mat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.pcInstance->AddProperty( &mat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- mat.pcInstance->AddProperty( &mat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
-
- // shininess
- if (0.0f != mat.mSpecularExponent && 0.0f != mat.mShininessStrength)
- {
- mat.pcInstance->AddProperty( &mat.mSpecularExponent, 1, AI_MATKEY_SHININESS);
- mat.pcInstance->AddProperty( &mat.mShininessStrength, 1, AI_MATKEY_SHININESS_STRENGTH);
- }
- // If there is no shininess, we can disable phong lighting
- else if (D3DS::Discreet3DS::Metal == mat.mShading ||
- D3DS::Discreet3DS::Phong == mat.mShading ||
- D3DS::Discreet3DS::Blinn == mat.mShading)
- {
- mat.mShading = D3DS::Discreet3DS::Gouraud;
- }
-
- // opacity
- mat.pcInstance->AddProperty<ai_real>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
-
- // Two sided rendering?
- if (mat.mTwoSided)
- {
- int i = 1;
- mat.pcInstance->AddProperty<int>(&i,1,AI_MATKEY_TWOSIDED);
- }
-
- // shading mode
- aiShadingMode eShading = aiShadingMode_NoShading;
- switch (mat.mShading)
- {
- case D3DS::Discreet3DS::Flat:
- eShading = aiShadingMode_Flat; break;
- case D3DS::Discreet3DS::Phong :
- eShading = aiShadingMode_Phong; break;
- case D3DS::Discreet3DS::Blinn :
- eShading = aiShadingMode_Blinn; break;
-
- // I don't know what "Wire" shading should be,
- // assume it is simple lambertian diffuse (L dot N) shading
- case D3DS::Discreet3DS::Wire:
- {
- // set the wireframe flag
- unsigned int iWire = 1;
- mat.pcInstance->AddProperty<int>( (int*)&iWire,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
- case D3DS::Discreet3DS::Gouraud:
- eShading = aiShadingMode_Gouraud; break;
- case D3DS::Discreet3DS::Metal :
- eShading = aiShadingMode_CookTorrance; break;
- }
- mat.pcInstance->AddProperty<int>( (int*)&eShading,1,AI_MATKEY_SHADING_MODEL);
-
- // DIFFUSE texture
- if( mat.sTexDiffuse.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexDiffuse, aiTextureType_DIFFUSE);
-
- // SPECULAR texture
- if( mat.sTexSpecular.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexSpecular, aiTextureType_SPECULAR);
-
- // AMBIENT texture
- if( mat.sTexAmbient.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexAmbient, aiTextureType_AMBIENT);
-
- // OPACITY texture
- if( mat.sTexOpacity.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexOpacity, aiTextureType_OPACITY);
-
- // EMISSIVE texture
- if( mat.sTexEmissive.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexEmissive, aiTextureType_EMISSIVE);
-
- // BUMP texture
- if( mat.sTexBump.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexBump, aiTextureType_HEIGHT);
-
- // SHININESS texture
- if( mat.sTexShininess.mMapName.length() > 0)
- CopyASETexture(*mat.pcInstance,mat.sTexShininess, aiTextureType_SHININESS);
-
- // store the name of the material itself, too
- if( mat.mName.length() > 0) {
- aiString tex;tex.Set( mat.mName);
- mat.pcInstance->AddProperty( &tex, AI_MATKEY_NAME);
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output meshes
-void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMeshes)
-{
- // validate the material index of the mesh
- if (mesh.iMaterialIndex >= mParser->m_vMaterials.size()) {
- mesh.iMaterialIndex = (unsigned int)mParser->m_vMaterials.size()-1;
- DefaultLogger::get()->warn("Material index is out of range");
- }
-
- // If the material the mesh is assigned to is consisting of submeshes, split it
- if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
- std::vector<ASE::Material> vSubMaterials = mParser->
- m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
-
- std::vector<unsigned int>* aiSplit = new std::vector<unsigned int>[vSubMaterials.size()];
-
- // build a list of all faces per submaterial
- for (unsigned int i = 0; i < mesh.mFaces.size();++i) {
- // check range
- if (mesh.mFaces[i].iMaterial >= vSubMaterials.size()) {
- DefaultLogger::get()->warn("Submaterial index is out of range");
-
- // use the last material instead
- aiSplit[vSubMaterials.size()-1].push_back(i);
- }
- else aiSplit[mesh.mFaces[i].iMaterial].push_back(i);
- }
-
- // now generate submeshes
- for (unsigned int p = 0; p < vSubMaterials.size();++p) {
- if (!aiSplit[p].empty()) {
-
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // let the sub material index
- p_pcOut->mMaterialIndex = p;
-
- // we will need this material
- mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials[p].bNeed = true;
-
- // store the real index here ... color channel 3
- p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
-
- // store a pointer to the mesh in color channel 2
- p_pcOut->mColors[2] = (aiColor4D*) &mesh;
- avOutMeshes.push_back(p_pcOut);
-
- // convert vertices
- p_pcOut->mNumVertices = (unsigned int)aiSplit[p].size()*3;
- p_pcOut->mNumFaces = (unsigned int)aiSplit[p].size();
-
- // receive output vertex weights
- std::vector<std::pair<unsigned int, float> > *avOutputBones = NULL;
- if (!mesh.mBones.empty()) {
- avOutputBones = new std::vector<std::pair<unsigned int, float> >[mesh.mBones.size()];
- }
-
- // allocate enough storage for faces
- p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
-
- unsigned int iBase = 0,iIndex;
- if (p_pcOut->mNumVertices) {
- p_pcOut->mVertices = new aiVector3D[p_pcOut->mNumVertices];
- p_pcOut->mNormals = new aiVector3D[p_pcOut->mNumVertices];
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
-
- iIndex = aiSplit[p][q];
-
- p_pcOut->mFaces[q].mIndices = new unsigned int[3];
- p_pcOut->mFaces[q].mNumIndices = 3;
-
- for (unsigned int t = 0; t < 3;++t, ++iBase) {
- const uint32_t iIndex2 = mesh.mFaces[iIndex].mIndices[t];
-
- p_pcOut->mVertices[iBase] = mesh.mPositions [iIndex2];
- p_pcOut->mNormals [iBase] = mesh.mNormals [iIndex2];
-
- // convert bones, if existing
- if (!mesh.mBones.empty()) {
- ai_assert(avOutputBones);
- // check whether there is a vertex weight for this vertex index
- if (iIndex2 < mesh.mBoneVertices.size()) {
-
- for (std::vector<std::pair<int,float> >::const_iterator
- blubb = mesh.mBoneVertices[iIndex2].mBoneWeights.begin();
- blubb != mesh.mBoneVertices[iIndex2].mBoneWeights.end();++blubb) {
-
- // NOTE: illegal cases have already been filtered out
- avOutputBones[(*blubb).first].push_back(std::pair<unsigned int, float>(
- iBase,(*blubb).second));
- }
- }
- }
- p_pcOut->mFaces[q].mIndices[t] = iBase;
- }
- }
- }
- // convert texture coordinates (up to AI_MAX_NUMBER_OF_TEXTURECOORDS sets supported)
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (!mesh.amTexCoords[c].empty())
- {
- p_pcOut->mTextureCoords[c] = new aiVector3D[p_pcOut->mNumVertices];
- iBase = 0;
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
- iIndex = aiSplit[p][q];
- for (unsigned int t = 0; t < 3;++t) {
- p_pcOut->mTextureCoords[c][iBase++] = mesh.amTexCoords[c][mesh.mFaces[iIndex].mIndices[t]];
- }
- }
- // Setup the number of valid vertex components
- p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
- }
- }
-
- // Convert vertex colors (only one set supported)
- if (!mesh.mVertexColors.empty()){
- p_pcOut->mColors[0] = new aiColor4D[p_pcOut->mNumVertices];
- iBase = 0;
- for (unsigned int q = 0; q < aiSplit[p].size();++q) {
- iIndex = aiSplit[p][q];
- for (unsigned int t = 0; t < 3;++t) {
- p_pcOut->mColors[0][iBase++] = mesh.mVertexColors[mesh.mFaces[iIndex].mIndices[t]];
- }
- }
- }
- // Copy bones
- if (!mesh.mBones.empty()) {
- p_pcOut->mNumBones = 0;
- for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
- if (!avOutputBones[mrspock].empty())p_pcOut->mNumBones++;
-
- p_pcOut->mBones = new aiBone* [ p_pcOut->mNumBones ];
- aiBone** pcBone = p_pcOut->mBones;
- for (unsigned int mrspock = 0; mrspock < mesh.mBones.size();++mrspock)
- {
- if (!avOutputBones[mrspock].empty()) {
- // we will need this bone. add it to the output mesh and
- // add all per-vertex weights
- aiBone* pc = *pcBone = new aiBone();
- pc->mName.Set(mesh.mBones[mrspock].mName);
-
- pc->mNumWeights = (unsigned int)avOutputBones[mrspock].size();
- pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- for (unsigned int captainkirk = 0; captainkirk < pc->mNumWeights;++captainkirk)
- {
- const std::pair<unsigned int,float>& ref = avOutputBones[mrspock][captainkirk];
- pc->mWeights[captainkirk].mVertexId = ref.first;
- pc->mWeights[captainkirk].mWeight = ref.second;
- }
- ++pcBone;
- }
- }
- // delete allocated storage
- delete[] avOutputBones;
- }
- }
- }
- // delete storage
- delete[] aiSplit;
- }
- else
- {
- // Otherwise we can simply copy the data to one output mesh
- // This codepath needs less memory and uses fast memcpy()s
- // to do the actual copying. So I think it is worth the
- // effort here.
-
- aiMesh* p_pcOut = new aiMesh();
- p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // set an empty sub material index
- p_pcOut->mMaterialIndex = ASE::Face::DEFAULT_MATINDEX;
- mParser->m_vMaterials[mesh.iMaterialIndex].bNeed = true;
-
- // store the real index here ... in color channel 3
- p_pcOut->mColors[3] = (aiColor4D*)(uintptr_t)mesh.iMaterialIndex;
-
- // store a pointer to the mesh in color channel 2
- p_pcOut->mColors[2] = (aiColor4D*) &mesh;
- avOutMeshes.push_back(p_pcOut);
-
- // If the mesh hasn't faces or vertices, there are two cases
- // possible: 1. the model is invalid. 2. This is a dummy
- // helper object which we are going to remove later ...
- if (mesh.mFaces.empty() || mesh.mPositions.empty()) {
- return;
- }
-
- // convert vertices
- p_pcOut->mNumVertices = (unsigned int)mesh.mPositions.size();
- p_pcOut->mNumFaces = (unsigned int)mesh.mFaces.size();
-
- // allocate enough storage for faces
- p_pcOut->mFaces = new aiFace[p_pcOut->mNumFaces];
-
- // copy vertices
- p_pcOut->mVertices = new aiVector3D[mesh.mPositions.size()];
- memcpy(p_pcOut->mVertices,&mesh.mPositions[0],
- mesh.mPositions.size() * sizeof(aiVector3D));
-
- // copy normals
- p_pcOut->mNormals = new aiVector3D[mesh.mNormals.size()];
- memcpy(p_pcOut->mNormals,&mesh.mNormals[0],
- mesh.mNormals.size() * sizeof(aiVector3D));
-
- // copy texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c) {
- if (!mesh.amTexCoords[c].empty()) {
- p_pcOut->mTextureCoords[c] = new aiVector3D[mesh.amTexCoords[c].size()];
- memcpy(p_pcOut->mTextureCoords[c],&mesh.amTexCoords[c][0],
- mesh.amTexCoords[c].size() * sizeof(aiVector3D));
-
- // setup the number of valid vertex components
- p_pcOut->mNumUVComponents[c] = mesh.mNumUVComponents[c];
- }
- }
-
- // copy vertex colors
- if (!mesh.mVertexColors.empty()) {
- p_pcOut->mColors[0] = new aiColor4D[mesh.mVertexColors.size()];
- memcpy(p_pcOut->mColors[0],&mesh.mVertexColors[0],
- mesh.mVertexColors.size() * sizeof(aiColor4D));
- }
-
- // copy faces
- for (unsigned int iFace = 0; iFace < p_pcOut->mNumFaces;++iFace) {
- p_pcOut->mFaces[iFace].mNumIndices = 3;
- p_pcOut->mFaces[iFace].mIndices = new unsigned int[3];
-
- // copy indices
- p_pcOut->mFaces[iFace].mIndices[0] = mesh.mFaces[iFace].mIndices[0];
- p_pcOut->mFaces[iFace].mIndices[1] = mesh.mFaces[iFace].mIndices[1];
- p_pcOut->mFaces[iFace].mIndices[2] = mesh.mFaces[iFace].mIndices[2];
- }
-
- // copy vertex bones
- if (!mesh.mBones.empty() && !mesh.mBoneVertices.empty()) {
- std::vector<std::vector<aiVertexWeight> > avBonesOut( mesh.mBones.size() );
-
- // find all vertex weights for this bone
- unsigned int quak = 0;
- for (std::vector<BoneVertex>::const_iterator harrypotter = mesh.mBoneVertices.begin();
- harrypotter != mesh.mBoneVertices.end();++harrypotter,++quak) {
-
- for (std::vector<std::pair<int,float> >::const_iterator
- ronaldweasley = (*harrypotter).mBoneWeights.begin();
- ronaldweasley != (*harrypotter).mBoneWeights.end();++ronaldweasley)
- {
- aiVertexWeight weight;
- weight.mVertexId = quak;
- weight.mWeight = (*ronaldweasley).second;
- avBonesOut[(*ronaldweasley).first].push_back(weight);
- }
- }
-
- // now build a final bone list
- p_pcOut->mNumBones = 0;
- for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy)
- if (!avBonesOut[jfkennedy].empty())p_pcOut->mNumBones++;
-
- p_pcOut->mBones = new aiBone*[p_pcOut->mNumBones];
- aiBone** pcBone = p_pcOut->mBones;
- for (unsigned int jfkennedy = 0; jfkennedy < mesh.mBones.size();++jfkennedy) {
- if (!avBonesOut[jfkennedy].empty()) {
- aiBone* pc = *pcBone = new aiBone();
- pc->mName.Set(mesh.mBones[jfkennedy].mName);
- pc->mNumWeights = (unsigned int)avBonesOut[jfkennedy].size();
- pc->mWeights = new aiVertexWeight[pc->mNumWeights];
- ::memcpy(pc->mWeights,&avBonesOut[jfkennedy][0],
- sizeof(aiVertexWeight) * pc->mNumWeights);
- ++pcBone;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup proper material indices and build output materials
-void ASEImporter::BuildMaterialIndices()
-{
- ai_assert(NULL != pcScene);
-
- // iterate through all materials and check whether we need them
- for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat)
- {
- ASE::Material& mat = mParser->m_vMaterials[iMat];
- if (mat.bNeed) {
- // Convert it to the aiMaterial layout
- ConvertMaterial(mat);
- ++pcScene->mNumMaterials;
- }
- for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat)
- {
- ASE::Material& submat = mat.avSubMaterials[iSubMat];
- if (submat.bNeed) {
- // Convert it to the aiMaterial layout
- ConvertMaterial(submat);
- ++pcScene->mNumMaterials;
- }
- }
- }
-
- // allocate the output material array
- pcScene->mMaterials = new aiMaterial*[pcScene->mNumMaterials];
- D3DS::Material** pcIntMaterials = new D3DS::Material*[pcScene->mNumMaterials];
-
- unsigned int iNum = 0;
- for (unsigned int iMat = 0; iMat < mParser->m_vMaterials.size();++iMat) {
- ASE::Material& mat = mParser->m_vMaterials[iMat];
- if (mat.bNeed)
- {
- ai_assert(NULL != mat.pcInstance);
- pcScene->mMaterials[iNum] = mat.pcInstance;
-
- // Store the internal material, too
- pcIntMaterials[iNum] = &mat;
-
- // Iterate through all meshes and search for one which is using
- // this top-level material index
- for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh)
- {
- aiMesh* mesh = pcScene->mMeshes[iMesh];
- if (ASE::Face::DEFAULT_MATINDEX == mesh->mMaterialIndex &&
- iMat == (uintptr_t)mesh->mColors[3])
- {
- mesh->mMaterialIndex = iNum;
- mesh->mColors[3] = NULL;
- }
- }
- iNum++;
- }
- for (unsigned int iSubMat = 0; iSubMat < mat.avSubMaterials.size();++iSubMat) {
- ASE::Material& submat = mat.avSubMaterials[iSubMat];
- if (submat.bNeed) {
- ai_assert(NULL != submat.pcInstance);
- pcScene->mMaterials[iNum] = submat.pcInstance;
-
- // Store the internal material, too
- pcIntMaterials[iNum] = &submat;
-
- // Iterate through all meshes and search for one which is using
- // this sub-level material index
- for (unsigned int iMesh = 0; iMesh < pcScene->mNumMeshes;++iMesh) {
- aiMesh* mesh = pcScene->mMeshes[iMesh];
-
- if (iSubMat == mesh->mMaterialIndex && iMat == (uintptr_t)mesh->mColors[3]) {
- mesh->mMaterialIndex = iNum;
- mesh->mColors[3] = NULL;
- }
- }
- iNum++;
- }
- }
- }
-
- // Dekete our temporary array
- delete[] pcIntMaterials;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate normal vectors basing on smoothing groups
-bool ASEImporter::GenerateNormals(ASE::Mesh& mesh) {
-
- if (!mesh.mNormals.empty() && !configRecomputeNormals)
- {
- // Check whether there are only uninitialized normals. If there are
- // some, skip all normals from the file and compute them on our own
- for (std::vector<aiVector3D>::const_iterator qq = mesh.mNormals.begin();qq != mesh.mNormals.end();++qq) {
- if ((*qq).x || (*qq).y || (*qq).z)
- {
- return true;
- }
- }
- }
- // The array is reused.
- ComputeNormalsWithSmoothingsGroups<ASE::Face>(mesh);
- return false;
-}
-
-#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
diff --git a/src/3rdparty/assimp/code/ASELoader.h b/src/3rdparty/assimp/code/ASELoader.h
deleted file mode 100644
index 8a8d4faa4..000000000
--- a/src/3rdparty/assimp/code/ASELoader.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASELoader.h
- * @brief Definition of the .ASE importer class.
- */
-#ifndef AI_ASELOADER_H_INCLUDED
-#define AI_ASELOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include "ASEParser.h"
-
-struct aiNode;
-
-namespace Assimp {
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// --------------------------------------------------------------------------------
-/** Importer class for the 3DS ASE ASCII format.
- *
- */
-class ASEImporter : public BaseImporter {
-public:
- ASEImporter();
- ~ASEImporter();
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-
-private:
-
- // -------------------------------------------------------------------
- /** Generate normal vectors basing on smoothing groups
- * (in some cases the normal are already contained in the file)
- * \param mesh Mesh to work on
- * \return false if the normals have been recomputed
- */
- bool GenerateNormals(ASE::Mesh& mesh);
-
-
- // -------------------------------------------------------------------
- /** Create valid vertex/normal/UV/color/face lists.
- * All elements are unique, faces have only one set of indices
- * after this step occurs.
- * \param mesh Mesh to work on
- */
- void BuildUniqueRepresentation(ASE::Mesh& mesh);
-
-
- /** Create one-material-per-mesh meshes ;-)
- * \param mesh Mesh to work with
- * \param Receives the list of all created meshes
- */
- void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
-
-
- // -------------------------------------------------------------------
- /** Convert a material to a aiMaterial object
- * \param mat Input material
- */
- void ConvertMaterial(ASE::Material& mat);
-
-
- // -------------------------------------------------------------------
- /** Setup the final material indices for each mesh
- */
- void BuildMaterialIndices();
-
-
- // -------------------------------------------------------------------
- /** Build the node graph
- */
- void BuildNodes(std::vector<ASE::BaseNode*>& nodes);
-
-
- // -------------------------------------------------------------------
- /** Build output cameras
- */
- void BuildCameras();
-
-
- // -------------------------------------------------------------------
- /** Build output lights
- */
- void BuildLights();
-
-
- // -------------------------------------------------------------------
- /** Build output animations
- */
- void BuildAnimations(const std::vector<ASE::BaseNode*>& nodes);
-
-
- // -------------------------------------------------------------------
- /** Add sub nodes to a node
- * \param pcParent parent node to be filled
- * \param szName Name of the parent node
- * \param matrix Current transform
- */
- void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
- aiNode* pcParent,const char* szName);
-
- void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
- aiNode* pcParent,const char* szName,
- const aiMatrix4x4& matrix);
-
- void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
-
- // -------------------------------------------------------------------
- /** Generate a default material and add it to the parser's list
- * Called if no material has been found in the file (rare for ASE,
- * but not impossible)
- */
- void GenerateDefaultMaterial();
-
-protected:
-
- /** Parser instance */
- ASE::Parser* mParser;
-
- /** Buffer to hold the loaded file */
- char* mBuffer;
-
- /** Scene to be filled */
- aiScene* pcScene;
-
- /** Config options: Recompute the normals in every case - WA
- for 3DS Max broken ASE normal export */
- bool configRecomputeNormals;
- bool noSkeletonMesh;
-};
-
-#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
-
-} // end of namespace Assimp
-
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/ASEParser.cpp b/src/3rdparty/assimp/code/ASEParser.cpp
deleted file mode 100644
index 7de80a2d8..000000000
--- a/src/3rdparty/assimp/code/ASEParser.cpp
+++ /dev/null
@@ -1,2157 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASEParser.cpp
- * @brief Implementation of the ASE parser class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// internal headers
-#include "TextureTransform.h"
-#include "ASELoader.h"
-#include "fast_atof.h"
-#include <assimp/DefaultLogger.hpp>
-
-using namespace Assimp;
-using namespace Assimp::ASE;
-
-
-// ------------------------------------------------------------------------------------------------
-// Begin an ASE parsing function
-
-#define AI_ASE_PARSER_INIT() \
- int iDepth = 0;
-
-// ------------------------------------------------------------------------------------------------
-// Handle a "top-level" section in the file. EOF is no error in this case.
-
-#define AI_ASE_HANDLE_TOP_LEVEL_SECTION() \
- else if ('{' == *filePtr)iDepth++; \
- else if ('}' == *filePtr) \
- { \
- if (0 == --iDepth) \
- { \
- ++filePtr; \
- SkipToNextToken(); \
- return; \
- } \
- } \
- else if ('\0' == *filePtr) \
- { \
- return; \
- } \
- if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
- { \
- ++iLineNumber; \
- bLastWasEndLine = true; \
- } else bLastWasEndLine = false; \
- ++filePtr;
-
-// ------------------------------------------------------------------------------------------------
-// Handle a nested section in the file. EOF is an error in this case
-// @param level "Depth" of the section
-// @param msg Full name of the section (including the asterisk)
-
-#define AI_ASE_HANDLE_SECTION(level, msg) \
- if ('{' == *filePtr)iDepth++; \
- else if ('}' == *filePtr) \
- { \
- if (0 == --iDepth) \
- { \
- ++filePtr; \
- SkipToNextToken(); \
- return; \
- } \
- } \
- else if ('\0' == *filePtr) \
- { \
- LogError("Encountered unexpected EOL while parsing a " msg \
- " chunk (Level " level ")"); \
- } \
- if(IsLineEnd(*filePtr) && !bLastWasEndLine) \
- { \
- ++iLineNumber; \
- bLastWasEndLine = true; \
- } else bLastWasEndLine = false; \
- ++filePtr;
-
-// ------------------------------------------------------------------------------------------------
-Parser::Parser (const char* szFile, unsigned int fileFormatDefault)
-{
- ai_assert(NULL != szFile);
- filePtr = szFile;
- iFileFormat = fileFormatDefault;
-
- // make sure that the color values are invalid
- m_clrBackground.r = get_qnan();
- m_clrAmbient.r = get_qnan();
-
- // setup some default values
- iLineNumber = 0;
- iFirstFrame = 0;
- iLastFrame = 0;
- iFrameSpeed = 30; // use 30 as default value for this property
- iTicksPerFrame = 1; // use 1 as default value for this property
- bLastWasEndLine = false; // need to handle \r\n seqs due to binary file mapping
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::LogWarning(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
-#else
- ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
-#endif
-
- // output the warning to the logger ...
- DefaultLogger::get()->warn(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::LogInfo(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
-#else
- ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
-#endif
-
- // output the information to the logger ...
- DefaultLogger::get()->info(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void Parser::LogError(const char* szWarn)
-{
- ai_assert(NULL != szWarn);
-
- char szTemp[1024];
-#if _MSC_VER >= 1400
- sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
-#else
- ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
-#endif
-
- // throw an exception
- throw DeadlyImportError(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::SkipToNextToken()
-{
- while (true)
- {
- char me = *filePtr;
-
- // increase the line number counter if necessary
- if (IsLineEnd(me) && !bLastWasEndLine)
- {
- ++iLineNumber;
- bLastWasEndLine = true;
- }
- else bLastWasEndLine = false;
- if ('*' == me || '}' == me || '{' == me)return true;
- if ('\0' == me)return false;
-
- ++filePtr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::SkipSection()
-{
- // must handle subsections ...
- int iCnt = 0;
- while (true)
- {
- if ('}' == *filePtr)
- {
- --iCnt;
- if (0 == iCnt)
- {
- // go to the next valid token ...
- ++filePtr;
- SkipToNextToken();
- return true;
- }
- }
- else if ('{' == *filePtr)
- {
- ++iCnt;
- }
- else if ('\0' == *filePtr)
- {
- LogWarning("Unable to parse block: Unexpected EOF, closing bracket \'}\' was expected [#1]");
- return false;
- }
- else if(IsLineEnd(*filePtr))++iLineNumber;
- ++filePtr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::Parse()
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Version should be 200. Validate this ...
- if (TokenMatch(filePtr,"3DSMAX_ASCIIEXPORT",18))
- {
- unsigned int fmt;
- ParseLV4MeshLong(fmt);
-
- if (fmt > 200)
- {
- LogWarning("Unknown file format version: *3DSMAX_ASCIIEXPORT should \
- be <= 200");
- }
- // *************************************************************
- // - fmt will be 0 if we're unable to read the version number
- // there are some faulty files without a version number ...
- // in this case we'll guess the exact file format by looking
- // at the file extension (ASE, ASK, ASC)
- // *************************************************************
-
- if (fmt)iFileFormat = fmt;
- continue;
- }
- // main scene information
- if (TokenMatch(filePtr,"SCENE",5))
- {
- ParseLV1SceneBlock();
- continue;
- }
- // "group" - no implementation yet, in facte
- // we're just ignoring them for the moment
- if (TokenMatch(filePtr,"GROUP",5))
- {
- Parse();
- continue;
- }
- // material list
- if (TokenMatch(filePtr,"MATERIAL_LIST",13))
- {
- ParseLV1MaterialListBlock();
- continue;
- }
- // geometric object (mesh)
- if (TokenMatch(filePtr,"GEOMOBJECT",10))
-
- {
- m_vMeshes.push_back(Mesh());
- ParseLV1ObjectBlock(m_vMeshes.back());
- continue;
- }
- // helper object = dummy in the hierarchy
- if (TokenMatch(filePtr,"HELPEROBJECT",12))
-
- {
- m_vDummies.push_back(Dummy());
- ParseLV1ObjectBlock(m_vDummies.back());
- continue;
- }
- // light object
- if (TokenMatch(filePtr,"LIGHTOBJECT",11))
-
- {
- m_vLights.push_back(Light());
- ParseLV1ObjectBlock(m_vLights.back());
- continue;
- }
- // camera object
- if (TokenMatch(filePtr,"CAMERAOBJECT",12))
- {
- m_vCameras.push_back(Camera());
- ParseLV1ObjectBlock(m_vCameras.back());
- continue;
- }
- // comment - print it on the console
- if (TokenMatch(filePtr,"COMMENT",7))
- {
- std::string out = "<unknown>";
- ParseString(out,"*COMMENT");
- LogInfo(("Comment: " + out).c_str());
- continue;
- }
- // ASC bone weights
- if (AI_ASE_IS_OLD_FILE_FORMAT() && TokenMatch(filePtr,"MESH_SOFTSKINVERTS",18))
- {
- ParseLV1SoftSkinBlock();
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1SoftSkinBlock()
-{
- // TODO: fix line counting here
-
- // **************************************************************
- // The soft skin block is formatted differently. There are no
- // nested sections supported and the single elements aren't
- // marked by keywords starting with an asterisk.
-
- /**
- FORMAT BEGIN
-
- *MESH_SOFTSKINVERTS {
- <nodename>
- <number of vertices>
-
- [for <number of vertices> times:]
- <number of weights> [for <number of weights> times:] <bone name> <weight>
- }
-
- FORMAT END
- */
- // **************************************************************
- while (true)
- {
- if (*filePtr == '}' ) {++filePtr;return;}
- else if (*filePtr == '\0') return;
- else if (*filePtr == '{' ) ++filePtr;
-
- else // if (!IsSpace(*filePtr) && !IsLineEnd(*filePtr))
- {
- ASE::Mesh* curMesh = NULL;
- unsigned int numVerts = 0;
-
- const char* sz = filePtr;
- while (!IsSpaceOrNewLine(*filePtr))++filePtr;
-
- const unsigned int diff = (unsigned int)(filePtr-sz);
- if (diff)
- {
- std::string name = std::string(sz,diff);
- for (std::vector<ASE::Mesh>::iterator it = m_vMeshes.begin();
- it != m_vMeshes.end(); ++it)
- {
- if ((*it).mName == name)
- {
- curMesh = & (*it);
- break;
- }
- }
- if (!curMesh)
- {
- LogWarning("Encountered unknown mesh in *MESH_SOFTSKINVERTS section");
-
- // Skip the mesh data - until we find a new mesh
- // or the end of the *MESH_SOFTSKINVERTS section
- while (true)
- {
- SkipSpacesAndLineEnd(&filePtr);
- if (*filePtr == '}')
- {++filePtr;return;}
- else if (!IsNumeric(*filePtr))
- break;
-
- SkipLine(&filePtr);
- }
- }
- else
- {
- SkipSpacesAndLineEnd(&filePtr);
- ParseLV4MeshLong(numVerts);
-
- // Reserve enough storage
- curMesh->mBoneVertices.reserve(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- SkipSpacesAndLineEnd(&filePtr);
- unsigned int numWeights;
- ParseLV4MeshLong(numWeights);
-
- curMesh->mBoneVertices.push_back(ASE::BoneVertex());
- ASE::BoneVertex& vert = curMesh->mBoneVertices.back();
-
- // Reserve enough storage
- vert.mBoneWeights.reserve(numWeights);
-
- for (unsigned int w = 0; w < numWeights;++w)
- {
- std::string bone;
- ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
-
- // Find the bone in the mesh's list
- std::pair<int,ai_real> me;
- me.first = -1;
-
- for (unsigned int n = 0; n < curMesh->mBones.size();++n)
- {
- if (curMesh->mBones[n].mName == bone)
- {
- me.first = n;
- break;
- }
- }
- if (-1 == me.first)
- {
- // We don't have this bone yet, so add it to the list
- me.first = (int)curMesh->mBones.size();
- curMesh->mBones.push_back(ASE::Bone(bone));
- }
- ParseLV4MeshFloat( me.second );
-
- // Add the new bone weight to list
- vert.mBoneWeights.push_back(me);
- }
- }
- }
- }
- }
- ++filePtr;
- SkipSpacesAndLineEnd(&filePtr);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1SceneBlock()
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"SCENE_BACKGROUND_STATIC",23))
-
- {
- // parse a color triple and assume it is really the bg color
- ParseLV4MeshFloatTriple( &m_clrBackground.r );
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_AMBIENT_STATIC",20))
-
- {
- // parse a color triple and assume it is really the bg color
- ParseLV4MeshFloatTriple( &m_clrAmbient.r );
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_FIRSTFRAME",16))
- {
- ParseLV4MeshLong(iFirstFrame);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_LASTFRAME",15))
- {
- ParseLV4MeshLong(iLastFrame);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_FRAMESPEED",16))
- {
- ParseLV4MeshLong(iFrameSpeed);
- continue;
- }
- if (TokenMatch(filePtr,"SCENE_TICKSPERFRAME",19))
- {
- ParseLV4MeshLong(iTicksPerFrame);
- continue;
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1MaterialListBlock()
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iMaterialCount = 0;
- unsigned int iOldMaterialCount = (unsigned int)m_vMaterials.size();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"MATERIAL_COUNT",14))
- {
- ParseLV4MeshLong(iMaterialCount);
-
- // now allocate enough storage to hold all materials
- m_vMaterials.resize(iOldMaterialCount+iMaterialCount);
- continue;
- }
- if (TokenMatch(filePtr,"MATERIAL",8))
- {
- unsigned int iIndex = 0;
- ParseLV4MeshLong(iIndex);
-
- if (iIndex >= iMaterialCount)
- {
- LogWarning("Out of range: material index is too large");
- iIndex = iMaterialCount-1;
- }
-
- // get a reference to the material
- Material& sMat = m_vMaterials[iIndex+iOldMaterialCount];
- // parse the material block
- ParseLV2MaterialBlock(sMat);
- continue;
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumSubMaterials = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"MATERIAL_NAME",13))
- {
- if (!ParseString(mat.mName,"*MATERIAL_NAME"))
- SkipToNextToken();
- continue;
- }
- // ambient material color
- if (TokenMatch(filePtr,"MATERIAL_AMBIENT",16))
- {
- ParseLV4MeshFloatTriple(&mat.mAmbient.r);
- continue;
- }
- // diffuse material color
- if (TokenMatch(filePtr,"MATERIAL_DIFFUSE",16) )
- {
- ParseLV4MeshFloatTriple(&mat.mDiffuse.r);
- continue;
- }
- // specular material color
- if (TokenMatch(filePtr,"MATERIAL_SPECULAR",17))
- {
- ParseLV4MeshFloatTriple(&mat.mSpecular.r);
- continue;
- }
- // material shading type
- if (TokenMatch(filePtr,"MATERIAL_SHADING",16))
- {
- if (TokenMatch(filePtr,"Blinn",5))
- {
- mat.mShading = Discreet3DS::Blinn;
- }
- else if (TokenMatch(filePtr,"Phong",5))
- {
- mat.mShading = Discreet3DS::Phong;
- }
- else if (TokenMatch(filePtr,"Flat",4))
- {
- mat.mShading = Discreet3DS::Flat;
- }
- else if (TokenMatch(filePtr,"Wire",4))
- {
- mat.mShading = Discreet3DS::Wire;
- }
- else
- {
- // assume gouraud shading
- mat.mShading = Discreet3DS::Gouraud;
- SkipToNextToken();
- }
- continue;
- }
- // material transparency
- if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
- {
- ParseLV4MeshFloat(mat.mTransparency);
- mat.mTransparency = ai_real( 1.0 ) - mat.mTransparency;
- continue;
- }
- // material self illumination
- if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
- {
- ai_real f = 0.0;
- ParseLV4MeshFloat(f);
-
- mat.mEmissive.r = f;
- mat.mEmissive.g = f;
- mat.mEmissive.b = f;
- continue;
- }
- // material shininess
- if (TokenMatch(filePtr,"MATERIAL_SHINE",14) )
- {
- ParseLV4MeshFloat(mat.mSpecularExponent);
- mat.mSpecularExponent *= 15;
- continue;
- }
- // two-sided material
- if (TokenMatch(filePtr,"MATERIAL_TWOSIDED",17) )
- {
- mat.mTwoSided = true;
- continue;
- }
- // material shininess strength
- if (TokenMatch(filePtr,"MATERIAL_SHINESTRENGTH",22))
- {
- ParseLV4MeshFloat(mat.mShininessStrength);
- continue;
- }
- // diffuse color map
- if (TokenMatch(filePtr,"MAP_DIFFUSE",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexDiffuse);
- continue;
- }
- // ambient color map
- if (TokenMatch(filePtr,"MAP_AMBIENT",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexAmbient);
- continue;
- }
- // specular color map
- if (TokenMatch(filePtr,"MAP_SPECULAR",12))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexSpecular);
- continue;
- }
- // opacity map
- if (TokenMatch(filePtr,"MAP_OPACITY",11))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexOpacity);
- continue;
- }
- // emissive map
- if (TokenMatch(filePtr,"MAP_SELFILLUM",13))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexEmissive);
- continue;
- }
- // bump map
- if (TokenMatch(filePtr,"MAP_BUMP",8))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexBump);
- }
- // specular/shininess map
- if (TokenMatch(filePtr,"MAP_SHINESTRENGTH",17))
- {
- // parse the texture block
- ParseLV3MapBlock(mat.sTexShininess);
- continue;
- }
- // number of submaterials
- if (TokenMatch(filePtr,"NUMSUBMTLS",10))
- {
- ParseLV4MeshLong(iNumSubMaterials);
-
- // allocate enough storage
- mat.avSubMaterials.resize(iNumSubMaterials);
- }
- // submaterial chunks
- if (TokenMatch(filePtr,"SUBMATERIAL",11))
- {
-
- unsigned int iIndex = 0;
- ParseLV4MeshLong(iIndex);
-
- if (iIndex >= iNumSubMaterials)
- {
- LogWarning("Out of range: submaterial index is too large");
- iIndex = iNumSubMaterials-1;
- }
-
- // get a reference to the material
- Material& sMat = mat.avSubMaterials[iIndex];
-
- // parse the material block
- ParseLV2MaterialBlock(sMat);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","*MATERIAL");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MapBlock(Texture& map)
-{
- AI_ASE_PARSER_INIT();
-
- // ***********************************************************
- // *BITMAP should not be there if *MAP_CLASS is not BITMAP,
- // but we need to expect that case ... if the path is
- // empty the texture won't be used later.
- // ***********************************************************
- bool parsePath = true;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // type of map
- if (TokenMatch(filePtr,"MAP_CLASS" ,9))
- {
- std::string temp;
- if(!ParseString(temp,"*MAP_CLASS"))
- SkipToNextToken();
- if (temp != "Bitmap" && temp != "Normal Bump")
- {
- DefaultLogger::get()->warn("ASE: Skipping unknown map type: " + temp);
- parsePath = false;
- }
- continue;
- }
- // path to the texture
- if (parsePath && TokenMatch(filePtr,"BITMAP" ,6))
- {
- if(!ParseString(map.mMapName,"*BITMAP"))
- SkipToNextToken();
-
- if (map.mMapName == "None")
- {
- // Files with 'None' as map name are produced by
- // an Maja to ASE exporter which name I forgot ..
- DefaultLogger::get()->warn("ASE: Skipping invalid map entry");
- map.mMapName = "";
- }
-
- continue;
- }
- // offset on the u axis
- if (TokenMatch(filePtr,"UVW_U_OFFSET" ,12))
- {
- ParseLV4MeshFloat(map.mOffsetU);
- continue;
- }
- // offset on the v axis
- if (TokenMatch(filePtr,"UVW_V_OFFSET" ,12))
- {
- ParseLV4MeshFloat(map.mOffsetV);
- continue;
- }
- // tiling on the u axis
- if (TokenMatch(filePtr,"UVW_U_TILING" ,12))
- {
- ParseLV4MeshFloat(map.mScaleU);
- continue;
- }
- // tiling on the v axis
- if (TokenMatch(filePtr,"UVW_V_TILING" ,12))
- {
- ParseLV4MeshFloat(map.mScaleV);
- continue;
- }
- // rotation around the z-axis
- if (TokenMatch(filePtr,"UVW_ANGLE" ,9))
- {
- ParseLV4MeshFloat(map.mRotation);
- continue;
- }
- // map blending factor
- if (TokenMatch(filePtr,"MAP_AMOUNT" ,10))
- {
- ParseLV4MeshFloat(map.mTextureBlend);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MAP_XXXXXX");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Parser::ParseString(std::string& out,const char* szName)
-{
- char szBuffer[1024];
- if (!SkipSpaces(&filePtr))
- {
-
- ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL",szName);
- LogWarning(szBuffer);
- return false;
- }
- // there must be '"'
- if ('\"' != *filePtr)
- {
-
- ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected "
- "to be enclosed in double quotation marks",szName);
- LogWarning(szBuffer);
- return false;
- }
- ++filePtr;
- const char* sz = filePtr;
- while (true)
- {
- if ('\"' == *sz)break;
- else if ('\0' == *sz)
- {
- ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected to "
- "be enclosed in double quotation marks but EOF was reached before "
- "a closing quotation mark was encountered",szName);
- LogWarning(szBuffer);
- return false;
- }
- sz++;
- }
- out = std::string(filePtr,(uintptr_t)sz-(uintptr_t)filePtr);
- filePtr = sz+1;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV1ObjectBlock(ASE::BaseNode& node)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // first process common tokens such as node name and transform
- // name of the mesh/node
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- if(!ParseString(node.mName,"*NODE_NAME"))
- SkipToNextToken();
- continue;
- }
- // name of the parent of the node
- if (TokenMatch(filePtr,"NODE_PARENT" ,11) )
- {
- if(!ParseString(node.mParent,"*NODE_PARENT"))
- SkipToNextToken();
- continue;
- }
- // transformation matrix of the node
- if (TokenMatch(filePtr,"NODE_TM" ,7))
- {
- ParseLV2NodeTransformBlock(node);
- continue;
- }
- // animation data of the node
- if (TokenMatch(filePtr,"TM_ANIMATION" ,12))
- {
- ParseLV2AnimationBlock(node);
- continue;
- }
-
- if (node.mType == BaseNode::Light)
- {
- // light settings
- if (TokenMatch(filePtr,"LIGHT_SETTINGS" ,14))
- {
- ParseLV2LightSettingsBlock((ASE::Light&)node);
- continue;
- }
- // type of the light source
- if (TokenMatch(filePtr,"LIGHT_TYPE" ,10))
- {
- if (!ASSIMP_strincmp("omni",filePtr,4))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::OMNI;
- }
- else if (!ASSIMP_strincmp("target",filePtr,6))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::TARGET;
- }
- else if (!ASSIMP_strincmp("free",filePtr,4))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::FREE;
- }
- else if (!ASSIMP_strincmp("directional",filePtr,11))
- {
- ((ASE::Light&)node).mLightType = ASE::Light::DIRECTIONAL;
- }
- else
- {
- LogWarning("Unknown kind of light source");
- }
- continue;
- }
- }
- else if (node.mType == BaseNode::Camera)
- {
- // Camera settings
- if (TokenMatch(filePtr,"CAMERA_SETTINGS" ,15))
- {
- ParseLV2CameraSettingsBlock((ASE::Camera&)node);
- continue;
- }
- else if (TokenMatch(filePtr,"CAMERA_TYPE" ,11))
- {
- if (!ASSIMP_strincmp("target",filePtr,6))
- {
- ((ASE::Camera&)node).mCameraType = ASE::Camera::TARGET;
- }
- else if (!ASSIMP_strincmp("free",filePtr,4))
- {
- ((ASE::Camera&)node).mCameraType = ASE::Camera::FREE;
- }
- else
- {
- LogWarning("Unknown kind of camera");
- }
- continue;
- }
- }
- else if (node.mType == BaseNode::Mesh)
- {
- // mesh data
- // FIX: Older files use MESH_SOFTSKIN
- if (TokenMatch(filePtr,"MESH" ,4) ||
- TokenMatch(filePtr,"MESH_SOFTSKIN",13))
- {
- ParseLV2MeshBlock((ASE::Mesh&)node);
- continue;
- }
- // mesh material index
- if (TokenMatch(filePtr,"MATERIAL_REF" ,12))
- {
- ParseLV4MeshLong(((ASE::Mesh&)node).iMaterialIndex);
- continue;
- }
- }
- }
- AI_ASE_HANDLE_TOP_LEVEL_SECTION();
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2CameraSettingsBlock(ASE::Camera& camera)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"CAMERA_NEAR" ,11))
- {
- ParseLV4MeshFloat(camera.mNear);
- continue;
- }
- if (TokenMatch(filePtr,"CAMERA_FAR" ,10))
- {
- ParseLV4MeshFloat(camera.mFar);
- continue;
- }
- if (TokenMatch(filePtr,"CAMERA_FOV" ,10))
- {
- ParseLV4MeshFloat(camera.mFOV);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","CAMERA_SETTINGS");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2LightSettingsBlock(ASE::Light& light)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"LIGHT_COLOR" ,11))
- {
- ParseLV4MeshFloatTriple(&light.mColor.r);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_INTENS" ,12))
- {
- ParseLV4MeshFloat(light.mIntensity);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_HOTSPOT" ,13))
- {
- ParseLV4MeshFloat(light.mAngle);
- continue;
- }
- if (TokenMatch(filePtr,"LIGHT_FALLOFF" ,13))
- {
- ParseLV4MeshFloat(light.mFalloff);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","LIGHT_SETTINGS");
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2AnimationBlock(ASE::BaseNode& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- ASE::Animation* anim = &mesh.mAnim;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- std::string temp;
- if(!ParseString(temp,"*NODE_NAME"))
- SkipToNextToken();
-
- // If the name of the node contains .target it
- // represents an animated camera or spot light
- // target.
- if (std::string::npos != temp.find(".Target"))
- {
- if ((mesh.mType != BaseNode::Camera || ((ASE::Camera&)mesh).mCameraType != ASE::Camera::TARGET) &&
- ( mesh.mType != BaseNode::Light || ((ASE::Light&)mesh).mLightType != ASE::Light::TARGET))
- {
-
- DefaultLogger::get()->error("ASE: Found target animation channel "
- "but the node is neither a camera nor a spot light");
- anim = NULL;
- }
- else anim = &mesh.mTargetAnim;
- }
- continue;
- }
-
- // position keyframes
- if (TokenMatch(filePtr,"CONTROL_POS_TRACK" ,17) ||
- TokenMatch(filePtr,"CONTROL_POS_BEZIER" ,18) ||
- TokenMatch(filePtr,"CONTROL_POS_TCB" ,15))
- {
- if (!anim)SkipSection();
- else ParseLV3PosAnimationBlock(*anim);
- continue;
- }
- // scaling keyframes
- if (TokenMatch(filePtr,"CONTROL_SCALE_TRACK" ,19) ||
- TokenMatch(filePtr,"CONTROL_SCALE_BEZIER" ,20) ||
- TokenMatch(filePtr,"CONTROL_SCALE_TCB" ,17))
- {
- if (!anim || anim == &mesh.mTargetAnim)
- {
- // Target animation channels may have no rotation channels
- DefaultLogger::get()->error("ASE: Ignoring scaling channel in target animation");
- SkipSection();
- }
- else ParseLV3ScaleAnimationBlock(*anim);
- continue;
- }
- // rotation keyframes
- if (TokenMatch(filePtr,"CONTROL_ROT_TRACK" ,17) ||
- TokenMatch(filePtr,"CONTROL_ROT_BEZIER" ,18) ||
- TokenMatch(filePtr,"CONTROL_ROT_TCB" ,15))
- {
- if (!anim || anim == &mesh.mTargetAnim)
- {
- // Target animation channels may have no rotation channels
- DefaultLogger::get()->error("ASE: Ignoring rotation channel in target animation");
- SkipSection();
- }
- else ParseLV3RotAnimationBlock(*anim);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","TM_ANIMATION");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
-
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the three floats -
- // we ignore the additional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
- {
- b = true;
- anim.mScalingType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_SCALE_KEY" ,24))
- {
- b = true;
- anim.mScalingType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_SCALE_KEY" ,21))
- {
- b = true;
- anim.mScalingType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyScaling.push_back(aiVectorKey());
- aiVectorKey& key = anim.akeyScaling.back();
- ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
- key.mTime = (double)iIndex;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the three floats -
- // we ignore the additional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
- {
- b = true;
- anim.mPositionType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_POS_KEY" ,22))
- {
- b = true;
- anim.mPositionType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_POS_KEY" ,19))
- {
- b = true;
- anim.mPositionType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyPositions.push_back(aiVectorKey());
- aiVectorKey& key = anim.akeyPositions.back();
- ParseLV4MeshFloatTriple(&key.mValue.x,iIndex);
- key.mTime = (double)iIndex;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_POS_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
-{
- AI_ASE_PARSER_INIT();
- unsigned int iIndex;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- bool b = false;
-
- // For the moment we're just reading the floats -
- // we ignore the additional information for bezier's and TCBs
-
- // simple scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
- {
- b = true;
- anim.mRotationType = ASE::Animation::TRACK;
- }
-
- // Bezier scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_BEZIER_ROT_KEY" ,22))
- {
- b = true;
- anim.mRotationType = ASE::Animation::BEZIER;
- }
- // TCB scaling keyframe
- if (TokenMatch(filePtr,"CONTROL_TCB_ROT_KEY" ,19))
- {
- b = true;
- anim.mRotationType = ASE::Animation::TCB;
- }
- if (b)
- {
- anim.akeyRotations.push_back(aiQuatKey());
- aiQuatKey& key = anim.akeyRotations.back();
- aiVector3D v;ai_real f;
- ParseLV4MeshFloatTriple(&v.x,iIndex);
- ParseLV4MeshFloat(f);
- key.mTime = (double)iIndex;
- key.mValue = aiQuaternion(v,f);
- }
- }
- AI_ASE_HANDLE_SECTION("3","*CONTROL_ROT_TRACK");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode& mesh)
-{
- AI_ASE_PARSER_INIT();
- int mode = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // name of the node
- if (TokenMatch(filePtr,"NODE_NAME" ,9))
- {
- std::string temp;
- if(!ParseString(temp,"*NODE_NAME"))
- SkipToNextToken();
-
- std::string::size_type s;
- if (temp == mesh.mName)
- {
- mode = 1;
- }
- else if (std::string::npos != (s = temp.find(".Target")) &&
- mesh.mName == temp.substr(0,s))
- {
- // This should be either a target light or a target camera
- if ( (mesh.mType == BaseNode::Light && ((ASE::Light&)mesh) .mLightType == ASE::Light::TARGET) ||
- (mesh.mType == BaseNode::Camera && ((ASE::Camera&)mesh).mCameraType == ASE::Camera::TARGET))
- {
- mode = 2;
- }
- else DefaultLogger::get()->error("ASE: Ignoring target transform, "
- "this is no spot light or target camera");
- }
- else
- {
- DefaultLogger::get()->error("ASE: Unknown node transformation: " + temp);
- // mode = 0
- }
- continue;
- }
- if (mode)
- {
- // fourth row of the transformation matrix - and also the
- // only information here that is interesting for targets
- if (TokenMatch(filePtr,"TM_ROW3" ,7))
- {
- ParseLV4MeshFloatTriple((mode == 1 ? mesh.mTransform[3] : &mesh.mTargetPosition.x));
- continue;
- }
- if (mode == 1)
- {
- // first row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW0" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[0]);
- continue;
- }
- // second row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW1" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[1]);
- continue;
- }
- // third row of the transformation matrix
- if (TokenMatch(filePtr,"TM_ROW2" ,7))
- {
- ParseLV4MeshFloatTriple(mesh.mTransform[2]);
- continue;
- }
- // inherited position axes
- if (TokenMatch(filePtr,"INHERIT_POS" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritPosition[i] = aiVal[i] != 0;
- continue;
- }
- // inherited rotation axes
- if (TokenMatch(filePtr,"INHERIT_ROT" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritRotation[i] = aiVal[i] != 0;
- continue;
- }
- // inherited scaling axes
- if (TokenMatch(filePtr,"INHERIT_SCL" ,11))
- {
- unsigned int aiVal[3];
- ParseLV4MeshLongTriple(aiVal);
-
- for (unsigned int i = 0; i < 3;++i)
- mesh.inherit.abInheritScaling[i] = aiVal[i] != 0;
- continue;
- }
- }
- }
- }
- AI_ASE_HANDLE_SECTION("2","*NODE_TM");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumVertices = 0;
- unsigned int iNumFaces = 0;
- unsigned int iNumTVertices = 0;
- unsigned int iNumTFaces = 0;
- unsigned int iNumCVertices = 0;
- unsigned int iNumCFaces = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
- // Number of vertices in the mesh
- if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
- {
- ParseLV4MeshLong(iNumVertices);
- continue;
- }
- // Number of texture coordinates in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumTVertices);
- continue;
- }
- // Number of vertex colors in the mesh
- if (TokenMatch(filePtr,"MESH_NUMCVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumCVertices);
- continue;
- }
- // Number of regular faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMFACES" ,13))
- {
- ParseLV4MeshLong(iNumFaces);
- continue;
- }
- // Number of UVWed faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
- {
- ParseLV4MeshLong(iNumTFaces);
- continue;
- }
- // Number of colored faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMCVFACES" ,15))
- {
- ParseLV4MeshLong(iNumCFaces);
- continue;
- }
- // mesh vertex list block
- if (TokenMatch(filePtr,"MESH_VERTEX_LIST" ,16))
- {
- ParseLV3MeshVertexListBlock(iNumVertices,mesh);
- continue;
- }
- // mesh face list block
- if (TokenMatch(filePtr,"MESH_FACE_LIST" ,14))
- {
- ParseLV3MeshFaceListBlock(iNumFaces,mesh);
- continue;
- }
- // mesh texture vertex list block
- if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
- {
- ParseLV3MeshTListBlock(iNumTVertices,mesh);
- continue;
- }
- // mesh texture face block
- if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
- {
- ParseLV3MeshTFaceListBlock(iNumTFaces,mesh);
- continue;
- }
- // mesh color vertex list block
- if (TokenMatch(filePtr,"MESH_CVERTLIST" ,14))
- {
- ParseLV3MeshCListBlock(iNumCVertices,mesh);
- continue;
- }
- // mesh color face block
- if (TokenMatch(filePtr,"MESH_CFACELIST" ,14))
- {
- ParseLV3MeshCFaceListBlock(iNumCFaces,mesh);
- continue;
- }
- // mesh normals
- if (TokenMatch(filePtr,"MESH_NORMALS" ,12))
- {
- ParseLV3MeshNormalListBlock(mesh);
- continue;
- }
- // another mesh UV channel ...
- if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19)) {
- unsigned int iIndex( 0 );
- ParseLV4MeshLong(iIndex);
- if ( 0 == iIndex ) {
- LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
- // skip it ...
- SkipSection();
- } else {
- if ( iIndex < 2 ) {
- LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
- // skip it ...
- SkipSection();
- }
- if ( iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS ) {
- LogWarning( "Too many UV channels specified. Skipping channel .." );
- // skip it ...
- SkipSection();
- } else {
- // parse the mapping channel
- ParseLV3MappingChannel( iIndex - 1, mesh );
- }
- continue;
- }
- }
- // mesh animation keyframe. Not supported
- if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
- {
-
- LogWarning("Found *MESH_ANIMATION element in ASE/ASK file. "
- "Keyframe animation is not supported by Assimp, this element "
- "will be ignored");
- //SkipSection();
- continue;
- }
- if (TokenMatch(filePtr,"MESH_WEIGHTS" ,12))
- {
- ParseLV3MeshWeightsBlock(mesh);continue;
- }
- }
- AI_ASE_HANDLE_SECTION("2","*MESH");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumVertices = 0, iNumBones = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Number of bone vertices ...
- if (TokenMatch(filePtr,"MESH_NUMVERTEX" ,14))
- {
- ParseLV4MeshLong(iNumVertices);
- continue;
- }
- // Number of bones
- if (TokenMatch(filePtr,"MESH_NUMBONE" ,12))
- {
- ParseLV4MeshLong(iNumBones);
- continue;
- }
- // parse the list of bones
- if (TokenMatch(filePtr,"MESH_BONE_LIST" ,14))
- {
- ParseLV4MeshBones(iNumBones,mesh);
- continue;
- }
- // parse the list of bones vertices
- if (TokenMatch(filePtr,"MESH_BONE_VERTEX_LIST" ,21) )
- {
- ParseLV4MeshBonesVertices(iNumVertices,mesh);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_WEIGHTS");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- mesh.mBones.resize(iNumBones);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Mesh bone with name ...
- if (TokenMatch(filePtr,"MESH_BONE_NAME" ,14))
- {
- // parse an index ...
- if(SkipSpaces(&filePtr))
- {
- unsigned int iIndex = strtoul10(filePtr,&filePtr);
- if (iIndex >= iNumBones)
- {
- LogWarning("Bone index is out of bounds");
- continue;
- }
- if (!ParseString(mesh.mBones[iIndex].mName,"*MESH_BONE_NAME"))
- SkipToNextToken();
- continue;
- }
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_BONE_LIST");
- }
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- mesh.mBoneVertices.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Mesh bone vertex
- if (TokenMatch(filePtr,"MESH_BONE_VERTEX" ,16))
- {
- // read the vertex index
- unsigned int iIndex = strtoul10(filePtr,&filePtr);
- if (iIndex >= mesh.mPositions.size())
- {
- iIndex = (unsigned int)mesh.mPositions.size()-1;
- LogWarning("Bone vertex index is out of bounds. Using the largest valid "
- "bone vertex index instead");
- }
-
- // --- ignored
- ai_real afVert[3];
- ParseLV4MeshFloatTriple(afVert);
-
- std::pair<int,float> pairOut;
- while (true)
- {
- // first parse the bone index ...
- if (!SkipSpaces(&filePtr))break;
- pairOut.first = strtoul10(filePtr,&filePtr);
-
- // then parse the vertex weight
- if (!SkipSpaces(&filePtr))break;
- filePtr = fast_atoreal_move<float>(filePtr,pairOut.second);
-
- // -1 marks unused entries
- if (-1 != pairOut.first)
- {
- mesh.mBoneVertices[iIndex].mBoneWeights.push_back(pairOut);
- }
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("4","*MESH_BONE_VERTEX");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshVertexListBlock(
- unsigned int iNumVertices, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.mPositions.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_VERTEX" ,11))
- {
-
- aiVector3D vTemp;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Invalid vertex index. It will be ignored");
- }
- else mesh.mPositions[iIndex] = vTemp;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_VERTEX_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the face array
- mesh.mFaces.resize(iNumFaces);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_FACE" ,9))
- {
-
- ASE::Face mFace;
- ParseLV4MeshFace(mFace);
-
- if (mFace.iFace >= iNumFaces)
- {
- LogWarning("Face has an invalid index. It will be ignored");
- }
- else mesh.mFaces[mFace.iFace] = mFace;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_FACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
- ASE::Mesh& mesh, unsigned int iChannel)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.amTexCoords[iChannel].resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_TVERT" ,10))
- {
- aiVector3D vTemp;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.x,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Tvertex has an invalid index. It will be ignored");
- }
- else mesh.amTexCoords[iChannel][iIndex] = vTemp;
-
- if (0.0f != vTemp.z)
- {
- // we need 3 coordinate channels
- mesh.mNumUVComponents[iChannel] = 3;
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_TVERT_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
- ASE::Mesh& mesh, unsigned int iChannel)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_TFACE" ,10))
- {
- unsigned int aiValues[3];
- unsigned int iIndex = 0;
-
- ParseLV4MeshLongTriple(aiValues,iIndex);
- if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
- {
- LogWarning("UV-Face has an invalid index. It will be ignored");
- }
- else
- {
- // copy UV indices
- mesh.mFaces[iIndex].amUVIndices[iChannel][0] = aiValues[0];
- mesh.mFaces[iIndex].amUVIndices[iChannel][1] = aiValues[1];
- mesh.mFaces[iIndex].amUVIndices[iChannel][2] = aiValues[2];
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_TFACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- unsigned int iNumTVertices = 0;
- unsigned int iNumTFaces = 0;
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Number of texture coordinates in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVERTEX" ,15))
- {
- ParseLV4MeshLong(iNumTVertices);
- continue;
- }
- // Number of UVWed faces in the mesh
- if (TokenMatch(filePtr,"MESH_NUMTVFACES" ,15))
- {
- ParseLV4MeshLong(iNumTFaces);
- continue;
- }
- // mesh texture vertex list block
- if (TokenMatch(filePtr,"MESH_TVERTLIST" ,14))
- {
- ParseLV3MeshTListBlock(iNumTVertices,mesh,iChannel);
- continue;
- }
- // mesh texture face block
- if (TokenMatch(filePtr,"MESH_TFACELIST" ,14))
- {
- ParseLV3MeshTFaceListBlock(iNumTFaces,mesh, iChannel);
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_MAPPING_CHANNEL");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
-
- // allocate enough storage in the array
- mesh.mVertexColors.resize(iNumVertices);
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Vertex entry
- if (TokenMatch(filePtr,"MESH_VERTCOL" ,12))
- {
- aiColor4D vTemp;
- vTemp.a = 1.0f;
- unsigned int iIndex;
- ParseLV4MeshFloatTriple(&vTemp.r,iIndex);
-
- if (iIndex >= iNumVertices)
- {
- LogWarning("Vertex color has an invalid index. It will be ignored");
- }
- else mesh.mVertexColors[iIndex] = vTemp;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_CVERTEX_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh& mesh)
-{
- AI_ASE_PARSER_INIT();
- while (true)
- {
- if ('*' == *filePtr)
- {
- ++filePtr;
-
- // Face entry
- if (TokenMatch(filePtr,"MESH_CFACE" ,10))
- {
- unsigned int aiValues[3];
- unsigned int iIndex = 0;
-
- ParseLV4MeshLongTriple(aiValues,iIndex);
- if (iIndex >= iNumFaces || iIndex >= mesh.mFaces.size())
- {
- LogWarning("UV-Face has an invalid index. It will be ignored");
- }
- else
- {
- // copy color indices
- mesh.mFaces[iIndex].mColorIndices[0] = aiValues[0];
- mesh.mFaces[iIndex].mColorIndices[1] = aiValues[1];
- mesh.mFaces[iIndex].mColorIndices[2] = aiValues[2];
- }
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_CFACE_LIST");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh& sMesh)
-{
- AI_ASE_PARSER_INIT();
-
- // Allocate enough storage for the normals
- sMesh.mNormals.resize(sMesh.mFaces.size()*3,aiVector3D( 0.f, 0.f, 0.f ));
- unsigned int index, faceIdx = UINT_MAX;
-
- // FIXME: rewrite this and find out how to interpret the normals
- // correctly. This is crap.
-
- // Smooth the vertex and face normals together. The result
- // will be edgy then, but otherwise everything would be soft ...
- while (true) {
- if ('*' == *filePtr) {
- ++filePtr;
- if (faceIdx != UINT_MAX && TokenMatch(filePtr,"MESH_VERTEXNORMAL",17)) {
- aiVector3D vNormal;
- ParseLV4MeshFloatTriple(&vNormal.x,index);
- if (faceIdx >= sMesh.mFaces.size())
- continue;
-
- // Make sure we assign it to the correct face
- const ASE::Face& face = sMesh.mFaces[faceIdx];
- if (index == face.mIndices[0])
- index = 0;
- else if (index == face.mIndices[1])
- index = 1;
- else if (index == face.mIndices[2])
- index = 2;
- else {
- DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_VERTEXNORMAL section");
- continue;
- }
- // We'll renormalize later
- sMesh.mNormals[faceIdx*3+index] += vNormal;
- continue;
- }
- if (TokenMatch(filePtr,"MESH_FACENORMAL",15)) {
- aiVector3D vNormal;
- ParseLV4MeshFloatTriple(&vNormal.x,faceIdx);
-
- if (faceIdx >= sMesh.mFaces.size()) {
- DefaultLogger::get()->error("ASE: Invalid vertex index in MESH_FACENORMAL section");
- continue;
- }
-
- // We'll renormalize later
- sMesh.mNormals[faceIdx*3] += vNormal;
- sMesh.mNormals[faceIdx*3+1] += vNormal;
- sMesh.mNormals[faceIdx*3+2] += vNormal;
- continue;
- }
- }
- AI_ASE_HANDLE_SECTION("3","*MESH_NORMALS");
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFace(ASE::Face& out)
-{
- // skip spaces and tabs
- if(!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL [#1]");
- SkipToNextToken();
- return;
- }
-
- // parse the face index
- out.iFace = strtoul10(filePtr,&filePtr);
-
- // next character should be ':'
- if(!SkipSpaces(&filePtr))
- {
- // FIX: there are some ASE files which haven't got : here ....
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. \':\' expected [#2]");
- SkipToNextToken();
- return;
- }
- // FIX: There are some ASE files which haven't got ':' here
- if(':' == *filePtr)++filePtr;
-
- // Parse all mesh indices
- for (unsigned int i = 0; i < 3;++i)
- {
- unsigned int iIndex = 0;
- if(!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL");
- SkipToNextToken();
- return;
- }
- switch (*filePtr)
- {
- case 'A':
- case 'a':
- break;
- case 'B':
- case 'b':
- iIndex = 1;
- break;
- case 'C':
- case 'c':
- iIndex = 2;
- break;
- default:
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
- "A,B or C expected [#3]");
- SkipToNextToken();
- return;
- };
- ++filePtr;
-
- // next character should be ':'
- if(!SkipSpaces(&filePtr) || ':' != *filePtr)
- {
- LogWarning("Unable to parse *MESH_FACE Element: "
- "Unexpected EOL. \':\' expected [#2]");
- SkipToNextToken();
- return;
- }
-
- ++filePtr;
- if(!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_FACE Element: Unexpected EOL. "
- "Vertex index ecpected [#4]");
- SkipToNextToken();
- return;
- }
- out.mIndices[iIndex] = strtoul10(filePtr,&filePtr);
- }
-
- // now we need to skip the AB, BC, CA blocks.
- while (true)
- {
- if ('*' == *filePtr)break;
- if (IsLineEnd(*filePtr))
- {
- //iLineNumber++;
- return;
- }
- filePtr++;
- }
-
- // parse the smoothing group of the face
- if (TokenMatch(filePtr,"*MESH_SMOOTHING",15))
- {
- if(!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_SMOOTHING Element: "
- "Unexpected EOL. Smoothing group(s) expected [#5]");
- SkipToNextToken();
- return;
- }
-
- // Parse smoothing groups until we don't anymore see commas
- // FIX: There needn't always be a value, sad but true
- while (true)
- {
- if (*filePtr < '9' && *filePtr >= '0')
- {
- out.iSmoothGroup |= (1 << strtoul10(filePtr,&filePtr));
- }
- SkipSpaces(&filePtr);
- if (',' != *filePtr)
- {
- break;
- }
- ++filePtr;
- SkipSpaces(&filePtr);
- }
- }
-
- // *MESH_MTLID is optional, too
- while (true)
- {
- if ('*' == *filePtr)break;
- if (IsLineEnd(*filePtr))
- {
- return;
- }
- filePtr++;
- }
-
- if (TokenMatch(filePtr,"*MESH_MTLID",11))
- {
- if(!SkipSpaces(&filePtr))
- {
- LogWarning("Unable to parse *MESH_MTLID Element: Unexpected EOL. "
- "Material index expected [#6]");
- SkipToNextToken();
- return;
- }
- out.iMaterial = strtoul10(filePtr,&filePtr);
- }
- return;
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLongTriple(unsigned int* apOut)
-{
- ai_assert(NULL != apOut);
-
- for (unsigned int i = 0; i < 3;++i)
- ParseLV4MeshLong(apOut[i]);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut)
-{
- ai_assert(NULL != apOut);
-
- // parse the index
- ParseLV4MeshLong(rIndexOut);
-
- // parse the three others
- ParseLV4MeshLongTriple(apOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut)
-{
- ai_assert(NULL != apOut);
-
- // parse the index
- ParseLV4MeshLong(rIndexOut);
-
- // parse the three others
- ParseLV4MeshFloatTriple(apOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloatTriple(ai_real* apOut)
-{
- ai_assert(NULL != apOut);
-
- for (unsigned int i = 0; i < 3;++i)
- ParseLV4MeshFloat(apOut[i]);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshFloat(ai_real& fOut)
-{
- // skip spaces and tabs
- if(!SkipSpaces(&filePtr))
- {
- // LOG
- LogWarning("Unable to parse float: unexpected EOL [#1]");
- fOut = 0.0;
- ++iLineNumber;
- return;
- }
- // parse the first float
- filePtr = fast_atoreal_move<ai_real>(filePtr,fOut);
-}
-// ------------------------------------------------------------------------------------------------
-void Parser::ParseLV4MeshLong(unsigned int& iOut)
-{
- // Skip spaces and tabs
- if(!SkipSpaces(&filePtr))
- {
- // LOG
- LogWarning("Unable to parse long: unexpected EOL [#1]");
- iOut = 0;
- ++iLineNumber;
- return;
- }
- // parse the value
- iOut = strtoul10(filePtr,&filePtr);
-}
-
-#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
diff --git a/src/3rdparty/assimp/code/ASEParser.h b/src/3rdparty/assimp/code/ASEParser.h
deleted file mode 100644
index db64f2a16..000000000
--- a/src/3rdparty/assimp/code/ASEParser.h
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the helper data structures for importing ASE files */
-#ifndef AI_ASEFILEHELPER_H_INC
-#define AI_ASEFILEHELPER_H_INC
-
-// public ASSIMP headers
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-#include <assimp/anim.h>
-
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-
-// for some helper routines like IsSpace()
-#include "ParsingUtils.h"
-#include "qnan.h"
-
-// ASE is quite similar to 3ds. We can reuse some structures
-#include "3DSLoader.h"
-
-namespace Assimp {
-namespace ASE {
-
-using namespace D3DS;
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing an ASE material */
-struct Material : public D3DS::Material
-{
- //! Default constructor
- Material() : pcInstance(NULL), bNeed (false)
- {}
-
- //! Contains all sub materials of this material
- std::vector<Material> avSubMaterials;
-
- //! aiMaterial object
- aiMaterial* pcInstance;
-
- //! Can we remove this material?
- bool bNeed;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file face */
-struct Face : public FaceWithSmoothingGroup
-{
- //! Default constructor. Initializes everything with 0
- Face()
- {
- mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
- }
-
- iMaterial = DEFAULT_MATINDEX;
- iFace = 0;
- }
-
- //! special value to indicate that no material index has
- //! been assigned to a face. The default material index
- //! will replace this value later.
- static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;
-
-
-
- //! Indices into each list of texture coordinates
- unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];
-
- //! Index into the list of vertex colors
- unsigned int mColorIndices[3];
-
- //! (Sub)Material index to be assigned to this face
- unsigned int iMaterial;
-
- //! Index of the face. It is not specified whether it is
- //! a requirement of the file format that all faces are
- //! written in sequential order, so we have to expect this case
- unsigned int iFace;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file bone */
-struct Bone
-{
- //! Constructor
- Bone()
- {
- static int iCnt = 0;
-
- // Generate a default name for the bone
- char szTemp[128];
- ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
- mName = szTemp;
- }
-
- //! Construction from an existing name
- explicit Bone( const std::string& name)
- : mName (name)
- {}
-
- //! Name of the bone
- std::string mName;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file bone vertex */
-struct BoneVertex
-{
- //! Bone and corresponding vertex weight.
- //! -1 for unrequired bones ....
- std::vector<std::pair<int,float> > mBoneWeights;
-
- //! Position of the bone vertex.
- //! MUST be identical to the vertex position
- //aiVector3D mPosition;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file animation */
-struct Animation
-{
- enum Type
- {
- TRACK = 0x0,
- BEZIER = 0x1,
- TCB = 0x2
- } mRotationType, mScalingType, mPositionType;
-
- Animation()
- : mRotationType (TRACK)
- , mScalingType (TRACK)
- , mPositionType (TRACK)
- {}
-
- //! List of track rotation keyframes
- std::vector< aiQuatKey > akeyRotations;
-
- //! List of track position keyframes
- std::vector< aiVectorKey > akeyPositions;
-
- //! List of track scaling keyframes
- std::vector< aiVectorKey > akeyScaling;
-
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent the inheritance information of an ASE node */
-struct InheritanceInfo
-{
- //! Default constructor
- InheritanceInfo()
- {
- // set the inheritance flag for all axes by default to true
- for (unsigned int i = 0; i < 3;++i)
- abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
- }
-
- //! Inherit the parent's position?, axis order is x,y,z
- bool abInheritPosition[3];
-
- //! Inherit the parent's rotation?, axis order is x,y,z
- bool abInheritRotation[3];
-
- //! Inherit the parent's scaling?, axis order is x,y,z
- bool abInheritScaling[3];
-};
-
-// ---------------------------------------------------------------------------
-/** Represents an ASE file node. Base class for mesh, light and cameras */
-struct BaseNode
-{
- enum Type {Light, Camera, Mesh, Dummy} mType;
-
- //! Constructor. Creates a default name for the node
- explicit BaseNode(Type _mType)
- : mType (_mType)
- , mProcessed (false)
- {
- // generate a default name for the node
- static int iCnt = 0;
- char szTemp[128]; // should be sufficiently large
- ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
- mName = szTemp;
-
- // Set mTargetPosition to qnan
- const ai_real qnan = get_qnan();
- mTargetPosition.x = qnan;
- }
-
- //! Name of the mesh
- std::string mName;
-
- //! Name of the parent of the node
- //! "" if there is no parent ...
- std::string mParent;
-
- //! Transformation matrix of the node
- aiMatrix4x4 mTransform;
-
- //! Target position (target lights and cameras)
- aiVector3D mTargetPosition;
-
- //! Specifies which axes transformations a node inherits
- //! from its parent ...
- InheritanceInfo inherit;
-
- //! Animation channels for the node
- Animation mAnim;
-
- //! Needed for lights and cameras: target animation channel
- //! Should contain position keys only.
- Animation mTargetAnim;
-
- bool mProcessed;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE file mesh */
-struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
-{
- //! Constructor.
- Mesh()
- : BaseNode (BaseNode::Mesh)
- , bSkip (false)
- {
- // use 2 texture vertex components by default
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- this->mNumUVComponents[c] = 2;
-
- // setup the default material index by default
- iMaterialIndex = Face::DEFAULT_MATINDEX;
- }
-
- //! List of all texture coordinate sets
- std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- //! List of all vertex color sets.
- std::vector<aiColor4D> mVertexColors;
-
- //! List of all bone vertices
- std::vector<BoneVertex> mBoneVertices;
-
- //! List of all bones
- std::vector<Bone> mBones;
-
- //! Material index of the mesh
- unsigned int iMaterialIndex;
-
- //! Number of vertex components for each UVW set
- unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- //! used internally
- bool bSkip;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE light source */
-struct Light : public BaseNode
-{
- enum LightType
- {
- OMNI,
- TARGET,
- FREE,
- DIRECTIONAL
- };
-
- //! Constructor.
- Light()
- : BaseNode (BaseNode::Light)
- , mLightType (OMNI)
- , mColor (1.f,1.f,1.f)
- , mIntensity (1.f) // light is white by default
- , mAngle (45.f)
- , mFalloff (0.f)
- {
- }
-
- LightType mLightType;
- aiColor3D mColor;
- ai_real mIntensity;
- ai_real mAngle; // in degrees
- ai_real mFalloff;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE camera */
-struct Camera : public BaseNode
-{
- enum CameraType
- {
- FREE,
- TARGET
- };
-
- //! Constructor
- Camera()
- : BaseNode (BaseNode::Camera)
- , mFOV (0.75f) // in radians
- , mNear (0.1f)
- , mFar (1000.f) // could be zero
- , mCameraType (FREE)
- {
- }
-
- ai_real mFOV, mNear, mFar;
- CameraType mCameraType;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to represent an ASE helper object (dummy) */
-struct Dummy : public BaseNode
-{
- //! Constructor
- Dummy()
- : BaseNode (BaseNode::Dummy)
- {
- }
-};
-
-// Parameters to Parser::Parse()
-#define AI_ASE_NEW_FILE_FORMAT 200
-#define AI_ASE_OLD_FILE_FORMAT 110
-
-// Internally we're a little bit more tolerant
-#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
-#define AI_ASE_IS_OLD_FILE_FORMAT() (iFileFormat < 200)
-
-// -------------------------------------------------------------------------------
-/** \brief Class to parse ASE files
- */
-class Parser
-{
-
-private:
-
- Parser() {}
-
-public:
-
- // -------------------------------------------------------------------
- //! Construct a parser from a given input file which is
- //! guaranted to be terminated with zero.
- //! @param szFile Input file
- //! @param fileFormatDefault Assumed file format version. If the
- //! file format is specified in the file the new value replaces
- //! the default value.
- Parser (const char* szFile, unsigned int fileFormatDefault);
-
- // -------------------------------------------------------------------
- //! Parses the file into the parsers internal representation
- void Parse();
-
-
-private:
-
- // -------------------------------------------------------------------
- //! Parse the *SCENE block in a file
- void ParseLV1SceneBlock();
-
- // -------------------------------------------------------------------
- //! Parse the *MESH_SOFTSKINVERTS block in a file
- void ParseLV1SoftSkinBlock();
-
- // -------------------------------------------------------------------
- //! Parse the *MATERIAL_LIST block in a file
- void ParseLV1MaterialListBlock();
-
- // -------------------------------------------------------------------
- //! Parse a *<xxx>OBJECT block in a file
- //! \param mesh Node to be filled
- void ParseLV1ObjectBlock(BaseNode& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MATERIAL blocks in a material list
- //! \param mat Material structure to be filled
- void ParseLV2MaterialBlock(Material& mat);
-
- // -------------------------------------------------------------------
- //! Parse a *NODE_TM block in a file
- //! \param mesh Node (!) object to be filled
- void ParseLV2NodeTransformBlock(BaseNode& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *TM_ANIMATION block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV2AnimationBlock(BaseNode& mesh);
- void ParseLV3PosAnimationBlock(ASE::Animation& anim);
- void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
- void ParseLV3RotAnimationBlock(ASE::Animation& anim);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV2MeshBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *LIGHT_SETTINGS block in a file
- //! \param light Light object to be filled
- void ParseLV2LightSettingsBlock(Light& light);
-
- // -------------------------------------------------------------------
- //! Parse a *CAMERA_SETTINGS block in a file
- //! \param cam Camera object to be filled
- void ParseLV2CameraSettingsBlock(Camera& cam);
-
- // -------------------------------------------------------------------
- //! Parse the *MAP_XXXXXX blocks in a material
- //! \param map Texture structure to be filled
- void ParseLV3MapBlock(Texture& map);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERTEX_LIST block in a file
- //! \param iNumVertices Value of *MESH_NUMVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshVertexListBlock(
- unsigned int iNumVertices,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_FACE_LIST block in a file
- //! \param iNumFaces Value of *MESH_NUMFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshFaceListBlock(
- unsigned int iNumFaces,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TVERT_LIST block in a file
- //! \param iNumVertices Value of *MESH_NUMTVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- //! \param iChannel Output UVW channel
- void ParseLV3MeshTListBlock(
- unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACELIST block in a file
- //! \param iNumFaces Value of *MESH_NUMTVFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- //! \param iChannel Output UVW channel
- void ParseLV3MeshTFaceListBlock(
- unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0);
-
- // -------------------------------------------------------------------
- //! Parse an additional mapping channel
- //! (specified via *MESH_MAPPINGCHANNEL)
- //! \param iChannel Channel index to be filled
- //! \param mesh Mesh object to be filled
- void ParseLV3MappingChannel(
- unsigned int iChannel, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_CVERTLIST block in a file
- //! \param iNumVertices Value of *MESH_NUMCVERTEX, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshCListBlock(
- unsigned int iNumVertices, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_CFACELIST block in a file
- //! \param iNumFaces Value of *MESH_NUMCVFACES, if present.
- //! Otherwise zero. This is used to check the consistency of the file.
- //! A warning is sent to the logger if the validations fails.
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshCFaceListBlock(
- unsigned int iNumFaces, Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_NORMALS block in a file
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshNormalListBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_WEIGHTSblock in a file
- //! \param mesh Mesh object to be filled
- void ParseLV3MeshWeightsBlock(Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse the bone list of a file
- //! \param mesh Mesh object to be filled
- //! \param iNumBones Number of bones in the mesh
- void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse the bone vertices list of a file
- //! \param mesh Mesh object to be filled
- //! \param iNumVertices Number of vertices to be parsed
- void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_FACE block in a file
- //! \param out receive the face data
- void ParseLV4MeshFace(ASE::Face& out);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERT block in a file
- //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
- //! \param apOut Output buffer (3 floats)
- //! \param rIndexOut Output index
- void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_VERT block in a file
- //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
- //! \param apOut Output buffer (3 floats)
- void ParseLV4MeshFloatTriple(ai_real* apOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACE block in a file
- //! (also works for MESH_CFACE)
- //! \param apOut Output buffer (3 ints)
- //! \param rIndexOut Output index
- void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut);
-
- // -------------------------------------------------------------------
- //! Parse a *MESH_TFACE block in a file
- //! (also works for MESH_CFACE)
- //! \param apOut Output buffer (3 ints)
- void ParseLV4MeshLongTriple(unsigned int* apOut);
-
- // -------------------------------------------------------------------
- //! Parse a single float element
- //! \param fOut Output float
- void ParseLV4MeshFloat(ai_real& fOut);
-
- // -------------------------------------------------------------------
- //! Parse a single int element
- //! \param iOut Output integer
- void ParseLV4MeshLong(unsigned int& iOut);
-
- // -------------------------------------------------------------------
- //! Skip everything to the next: '*' or '\0'
- bool SkipToNextToken();
-
- // -------------------------------------------------------------------
- //! Skip the current section until the token after the closing }.
- //! This function handles embedded subsections correctly
- bool SkipSection();
-
- // -------------------------------------------------------------------
- //! Output a warning to the logger
- //! \param szWarn Warn message
- void LogWarning(const char* szWarn);
-
- // -------------------------------------------------------------------
- //! Output a message to the logger
- //! \param szWarn Message
- void LogInfo(const char* szWarn);
-
- // -------------------------------------------------------------------
- //! Output an error to the logger
- //! \param szWarn Error message
- AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX;
-
- // -------------------------------------------------------------------
- //! Parse a string, enclosed in double quotation marks
- //! \param out Output string
- //! \param szName Name of the enclosing element -> used in error
- //! messages.
- //! \return false if an error occurred
- bool ParseString(std::string& out,const char* szName);
-
-public:
-
- //! Pointer to current data
- const char* filePtr;
-
- //! background color to be passed to the viewer
- //! QNAN if none was found
- aiColor3D m_clrBackground;
-
- //! Base ambient color to be passed to all materials
- //! QNAN if none was found
- aiColor3D m_clrAmbient;
-
- //! List of all materials found in the file
- std::vector<Material> m_vMaterials;
-
- //! List of all meshes found in the file
- std::vector<Mesh> m_vMeshes;
-
- //! List of all dummies found in the file
- std::vector<Dummy> m_vDummies;
-
- //! List of all lights found in the file
- std::vector<Light> m_vLights;
-
- //! List of all cameras found in the file
- std::vector<Camera> m_vCameras;
-
- //! Current line in the file
- unsigned int iLineNumber;
-
- //! First frame
- unsigned int iFirstFrame;
-
- //! Last frame
- unsigned int iLastFrame;
-
- //! Frame speed - frames per second
- unsigned int iFrameSpeed;
-
- //! Ticks per frame
- unsigned int iTicksPerFrame;
-
- //! true if the last character read was an end-line character
- bool bLastWasEndLine;
-
- //! File format version
- unsigned int iFileFormat;
-};
-
-
-} // Namespace ASE
-} // Namespace ASSIMP
-
-#endif // ASSIMP_BUILD_NO_3DS_IMPORTER
-
-#endif // !! include guard
diff --git a/src/3rdparty/assimp/code/AssbinExporter.cpp b/src/3rdparty/assimp/code/AssbinExporter.cpp
deleted file mode 100644
index bcac2e08f..000000000
--- a/src/3rdparty/assimp/code/AssbinExporter.cpp
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssbinExporter.cpp
- * ASSBIN exporter main code
- */
-#include "assbin_chunks.h"
-#include <assimp/version.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include "ProcessHelper.h"
-#include "Exceptional.h"
-
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-#else
-# include "../contrib/zlib/zlib.h"
-#endif
-
-#include <time.h>
-
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
-
-using namespace Assimp;
-
-namespace Assimp {
-
-template <typename T>
-size_t Write(IOStream * stream, const T& v)
-{
- return stream->Write( &v, sizeof(T), 1 );
-}
-
-
-// -----------------------------------------------------------------------------------
-// Serialize an aiString
-template <>
-inline size_t Write<aiString>(IOStream * stream, const aiString& s)
-{
- const size_t s2 = (uint32_t)s.length;
- stream->Write(&s,4,1);
- stream->Write(s.data,s2,1);
- return s2+4;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize an unsigned int as uint32_t
-template <>
-inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
-{
- const uint32_t t = (uint32_t)w;
- if (w > t) {
- // this shouldn't happen, integers in Assimp data structures never exceed 2^32
- throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
- }
-
- stream->Write(&t,4,1);
- return 4;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize an unsigned int as uint16_t
-template <>
-inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
-{
- static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
- stream->Write(&w,2,1);
- return 2;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a float
-template <>
-inline size_t Write<float>(IOStream * stream, const float& f)
-{
- static_assert(sizeof(float)==4, "sizeof(float)==4");
- stream->Write(&f,4,1);
- return 4;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a double
-template <>
-inline size_t Write<double>(IOStream * stream, const double& f)
-{
- static_assert(sizeof(double)==8, "sizeof(double)==8");
- stream->Write(&f,8,1);
- return 8;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a vec3
-template <>
-inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
-{
- size_t t = Write<float>(stream,v.x);
- t += Write<float>(stream,v.y);
- t += Write<float>(stream,v.z);
- return t;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a color value
-template <>
-inline size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v)
-{
- size_t t = Write<float>(stream,v.r);
- t += Write<float>(stream,v.g);
- t += Write<float>(stream,v.b);
- return t;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a color value
-template <>
-inline size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v)
-{
- size_t t = Write<float>(stream,v.r);
- t += Write<float>(stream,v.g);
- t += Write<float>(stream,v.b);
- t += Write<float>(stream,v.a);
- return t;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a quaternion
-template <>
-inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
-{
- size_t t = Write<float>(stream,v.w);
- t += Write<float>(stream,v.x);
- t += Write<float>(stream,v.y);
- t += Write<float>(stream,v.z);
- ai_assert(t == 16);
- return 16;
-}
-
-
-// -----------------------------------------------------------------------------------
-// Serialize a vertex weight
-template <>
-inline size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v)
-{
- size_t t = Write<unsigned int>(stream,v.mVertexId);
- return t+Write<float>(stream,v.mWeight);
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize a mat4x4
-template <>
-inline size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m)
-{
- for (unsigned int i = 0; i < 4;++i) {
- for (unsigned int i2 = 0; i2 < 4;++i2) {
- Write<float>(stream,m[i][i2]);
- }
- }
- return 64;
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize an aiVectorKey
-template <>
-inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
-{
- const size_t t = Write<double>(stream,v.mTime);
- return t + Write<aiVector3D>(stream,v.mValue);
-}
-
-// -----------------------------------------------------------------------------------
-// Serialize an aiQuatKey
-template <>
-inline size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v)
-{
- const size_t t = Write<double>(stream,v.mTime);
- return t + Write<aiQuaternion>(stream,v.mValue);
-}
-
-template <typename T>
-inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
-{
- T minc,maxc;
- ArrayBounds(in,size,minc,maxc);
-
- const size_t t = Write<T>(stream,minc);
- return t + Write<T>(stream,maxc);
-}
-
-// We use this to write out non-byte arrays so that we write using the specializations.
-// This way we avoid writing out extra bytes that potentially come from struct alignment.
-template <typename T>
-inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
-{
- size_t n = 0;
- for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
- return n;
-}
-
- // ----------------------------------------------------------------------------------
- /** @class AssbinChunkWriter
- * @brief Chunk writer mechanism for the .assbin file structure
- *
- * This is a standard in-memory IOStream (most of the code is based on BlobIOStream),
- * the difference being that this takes another IOStream as a "container" in the
- * constructor, and when it is destroyed, it appends the magic number, the chunk size,
- * and the chunk contents to the container stream. This allows relatively easy chunk
- * chunk construction, even recursively.
- */
- class AssbinChunkWriter : public IOStream
- {
- private:
-
- uint8_t* buffer;
- uint32_t magic;
- IOStream * container;
- size_t cur_size, cursor, initial;
-
- private:
- // -------------------------------------------------------------------
- void Grow(size_t need = 0)
- {
- size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
-
- const uint8_t* const old = buffer;
- buffer = new uint8_t[new_size];
-
- if (old) {
- memcpy(buffer,old,cur_size);
- delete[] old;
- }
-
- cur_size = new_size;
- }
-
- public:
-
- AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
- : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
- {
- }
-
- virtual ~AssbinChunkWriter()
- {
- if (container) {
- container->Write( &magic, sizeof(uint32_t), 1 );
- container->Write( &cursor, sizeof(uint32_t), 1 );
- container->Write( buffer, 1, cursor );
- }
- if (buffer) delete[] buffer;
- }
-
- void * GetBufferPointer() { return buffer; }
-
- // -------------------------------------------------------------------
- virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }
- virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }
- virtual size_t Tell() const { return cursor; }
- virtual void Flush() { }
-
- virtual size_t FileSize() const
- {
- return cursor;
- }
-
- // -------------------------------------------------------------------
- virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount)
- {
- pSize *= pCount;
- if (cursor + pSize > cur_size) {
- Grow(cursor + pSize);
- }
-
- memcpy(buffer+cursor, pvBuffer, pSize);
- cursor += pSize;
-
- return pCount;
- }
-
- };
-
- // ----------------------------------------------------------------------------------
- /** @class AssbinExport
- * @brief Assbin exporter class
- *
- * This class performs the .assbin exporting, and is responsible for the file layout.
- */
- class AssbinExport
- {
- private:
- bool shortened;
- bool compressed;
-
- protected:
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryNode( IOStream * container, const aiNode* node)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );
-
- unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);
-
- Write<aiString>(&chunk,node->mName);
- Write<aiMatrix4x4>(&chunk,node->mTransformation);
- Write<unsigned int>(&chunk,node->mNumChildren);
- Write<unsigned int>(&chunk,node->mNumMeshes);
- Write<unsigned int>(&chunk,nb_metadata);
-
- for (unsigned int i = 0; i < node->mNumMeshes;++i) {
- Write<unsigned int>(&chunk,node->mMeshes[i]);
- }
-
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- WriteBinaryNode( &chunk, node->mChildren[i] );
- }
-
- for (unsigned int i = 0; i < nb_metadata; ++i) {
- const aiString& key = node->mMetaData->mKeys[i];
- aiMetadataType type = node->mMetaData->mValues[i].mType;
- void* value = node->mMetaData->mValues[i].mData;
-
- Write<aiString>(&chunk, key);
- Write<uint16_t>(&chunk, type);
-
- switch (type) {
- case AI_BOOL:
- Write<bool>(&chunk, *((bool*) value));
- break;
- case AI_INT32:
- Write<int32_t>(&chunk, *((int32_t*) value));
- break;
- case AI_UINT64:
- Write<uint64_t>(&chunk, *((uint64_t*) value));
- break;
- case AI_FLOAT:
- Write<float>(&chunk, *((float*) value));
- break;
- case AI_DOUBLE:
- Write<double>(&chunk, *((double*) value));
- break;
- case AI_AISTRING:
- Write<aiString>(&chunk, *((aiString*) value));
- break;
- case AI_AIVECTOR3D:
- Write<aiVector3D>(&chunk, *((aiVector3D*) value));
- break;
-#ifdef SWIG
- case FORCE_32BIT:
-#endif // SWIG
- default:
- break;
- }
- }
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE );
-
- Write<unsigned int>(&chunk,tex->mWidth);
- Write<unsigned int>(&chunk,tex->mHeight);
- chunk.Write( tex->achFormatHint, sizeof(char), 4 );
-
- if(!shortened) {
- if (!tex->mHeight) {
- chunk.Write(tex->pcData,1,tex->mWidth);
- }
- else {
- chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4);
- }
- }
-
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryBone(IOStream * container, const aiBone* b)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE );
-
- Write<aiString>(&chunk,b->mName);
- Write<unsigned int>(&chunk,b->mNumWeights);
- Write<aiMatrix4x4>(&chunk,b->mOffsetMatrix);
-
- // for the moment we write dumb min/max values for the bones, too.
- // maybe I'll add a better, hash-like solution later
- if (shortened) {
- WriteBounds(&chunk,b->mWeights,b->mNumWeights);
- } // else write as usual
- else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH );
-
- Write<unsigned int>(&chunk,mesh->mPrimitiveTypes);
- Write<unsigned int>(&chunk,mesh->mNumVertices);
- Write<unsigned int>(&chunk,mesh->mNumFaces);
- Write<unsigned int>(&chunk,mesh->mNumBones);
- Write<unsigned int>(&chunk,mesh->mMaterialIndex);
-
- // first of all, write bits for all existent vertex components
- unsigned int c = 0;
- if (mesh->mVertices) {
- c |= ASSBIN_MESH_HAS_POSITIONS;
- }
- if (mesh->mNormals) {
- c |= ASSBIN_MESH_HAS_NORMALS;
- }
- if (mesh->mTangents && mesh->mBitangents) {
- c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS;
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
- if (!mesh->mTextureCoords[n]) {
- break;
- }
- c |= ASSBIN_MESH_HAS_TEXCOORD(n);
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
- if (!mesh->mColors[n]) {
- break;
- }
- c |= ASSBIN_MESH_HAS_COLOR(n);
- }
- Write<unsigned int>(&chunk,c);
-
- aiVector3D minVec, maxVec;
- if (mesh->mVertices) {
- if (shortened) {
- WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices);
- } // else write as usual
- else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
- }
- if (mesh->mNormals) {
- if (shortened) {
- WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices);
- } // else write as usual
- else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
- }
- if (mesh->mTangents && mesh->mBitangents) {
- if (shortened) {
- WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices);
- WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices);
- } // else write as usual
- else {
- WriteArray<aiVector3D>(&chunk,mesh->mTangents,mesh->mNumVertices);
- WriteArray<aiVector3D>(&chunk,mesh->mBitangents,mesh->mNumVertices);
- }
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
- if (!mesh->mColors[n])
- break;
-
- if (shortened) {
- WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices);
- } // else write as usual
- else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
- if (!mesh->mTextureCoords[n])
- break;
-
- // write number of UV components
- Write<unsigned int>(&chunk,mesh->mNumUVComponents[n]);
-
- if (shortened) {
- WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
- } // else write as usual
- else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
- }
-
- // write faces. There are no floating-point calculations involved
- // in these, so we can write a simple hash over the face data
- // to the dump file. We generate a single 32 Bit hash for 512 faces
- // using Assimp's standard hashing function.
- if (shortened) {
- unsigned int processed = 0;
- for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) {
-
- uint32_t hash = 0;
- for (unsigned int a = 0; a < job;++a) {
-
- const aiFace& f = mesh->mFaces[processed+a];
- uint32_t tmp = f.mNumIndices;
- hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
- for (unsigned int i = 0; i < f.mNumIndices; ++i) {
- static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
- tmp = static_cast<uint32_t>( f.mIndices[i] );
- hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
- }
- }
- Write<unsigned int>(&chunk,hash);
- }
- }
- else // else write as usual
- {
- // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
- for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
- const aiFace& f = mesh->mFaces[i];
-
- static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
- Write<uint16_t>(&chunk,f.mNumIndices);
-
- for (unsigned int a = 0; a < f.mNumIndices;++a) {
- if (mesh->mNumVertices < (1u<<16)) {
- Write<uint16_t>(&chunk,f.mIndices[a]);
- }
- else Write<unsigned int>(&chunk,f.mIndices[a]);
- }
- }
- }
-
- // write bones
- if (mesh->mNumBones) {
- for (unsigned int a = 0; a < mesh->mNumBones;++a) {
- const aiBone* b = mesh->mBones[a];
- WriteBinaryBone(&chunk,b);
- }
- }
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY );
-
- Write<aiString>(&chunk,prop->mKey);
- Write<unsigned int>(&chunk,prop->mSemantic);
- Write<unsigned int>(&chunk,prop->mIndex);
-
- Write<unsigned int>(&chunk,prop->mDataLength);
- Write<unsigned int>(&chunk,(unsigned int)prop->mType);
- chunk.Write(prop->mData,1,prop->mDataLength);
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL);
-
- Write<unsigned int>(&chunk,mat->mNumProperties);
- for (unsigned int i = 0; i < mat->mNumProperties;++i) {
- WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]);
- }
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM );
-
- Write<aiString>(&chunk,nd->mNodeName);
- Write<unsigned int>(&chunk,nd->mNumPositionKeys);
- Write<unsigned int>(&chunk,nd->mNumRotationKeys);
- Write<unsigned int>(&chunk,nd->mNumScalingKeys);
- Write<unsigned int>(&chunk,nd->mPreState);
- Write<unsigned int>(&chunk,nd->mPostState);
-
- if (nd->mPositionKeys) {
- if (shortened) {
- WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
-
- } // else write as usual
- else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
- }
- if (nd->mRotationKeys) {
- if (shortened) {
- WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
-
- } // else write as usual
- else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
- }
- if (nd->mScalingKeys) {
- if (shortened) {
- WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
-
- } // else write as usual
- else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
- }
- }
-
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION );
-
- Write<aiString>(&chunk,anim->mName);
- Write<double>(&chunk,anim->mDuration);
- Write<double>(&chunk,anim->mTicksPerSecond);
- Write<unsigned int>(&chunk,anim->mNumChannels);
-
- for (unsigned int a = 0; a < anim->mNumChannels;++a) {
- const aiNodeAnim* nd = anim->mChannels[a];
- WriteBinaryNodeAnim(&chunk,nd);
- }
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryLight( IOStream * container, const aiLight* l )
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT );
-
- Write<aiString>(&chunk,l->mName);
- Write<unsigned int>(&chunk,l->mType);
-
- if (l->mType != aiLightSource_DIRECTIONAL) {
- Write<float>(&chunk,l->mAttenuationConstant);
- Write<float>(&chunk,l->mAttenuationLinear);
- Write<float>(&chunk,l->mAttenuationQuadratic);
- }
-
- Write<aiColor3D>(&chunk,l->mColorDiffuse);
- Write<aiColor3D>(&chunk,l->mColorSpecular);
- Write<aiColor3D>(&chunk,l->mColorAmbient);
-
- if (l->mType == aiLightSource_SPOT) {
- Write<float>(&chunk,l->mAngleInnerCone);
- Write<float>(&chunk,l->mAngleOuterCone);
- }
-
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA );
-
- Write<aiString>(&chunk,cam->mName);
- Write<aiVector3D>(&chunk,cam->mPosition);
- Write<aiVector3D>(&chunk,cam->mLookAt);
- Write<aiVector3D>(&chunk,cam->mUp);
- Write<float>(&chunk,cam->mHorizontalFOV);
- Write<float>(&chunk,cam->mClipPlaneNear);
- Write<float>(&chunk,cam->mClipPlaneFar);
- Write<float>(&chunk,cam->mAspect);
- }
-
- // -----------------------------------------------------------------------------------
- void WriteBinaryScene( IOStream * container, const aiScene* scene)
- {
- AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE );
-
- // basic scene information
- Write<unsigned int>(&chunk,scene->mFlags);
- Write<unsigned int>(&chunk,scene->mNumMeshes);
- Write<unsigned int>(&chunk,scene->mNumMaterials);
- Write<unsigned int>(&chunk,scene->mNumAnimations);
- Write<unsigned int>(&chunk,scene->mNumTextures);
- Write<unsigned int>(&chunk,scene->mNumLights);
- Write<unsigned int>(&chunk,scene->mNumCameras);
-
- // write node graph
- WriteBinaryNode( &chunk, scene->mRootNode );
-
- // write all meshes
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- const aiMesh* mesh = scene->mMeshes[i];
- WriteBinaryMesh( &chunk,mesh);
- }
-
- // write materials
- for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
- const aiMaterial* mat = scene->mMaterials[i];
- WriteBinaryMaterial(&chunk,mat);
- }
-
- // write all animations
- for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
- const aiAnimation* anim = scene->mAnimations[i];
- WriteBinaryAnim(&chunk,anim);
- }
-
-
- // write all textures
- for (unsigned int i = 0; i < scene->mNumTextures;++i) {
- const aiTexture* mesh = scene->mTextures[i];
- WriteBinaryTexture(&chunk,mesh);
- }
-
- // write lights
- for (unsigned int i = 0; i < scene->mNumLights;++i) {
- const aiLight* l = scene->mLights[i];
- WriteBinaryLight(&chunk,l);
- }
-
- // write cameras
- for (unsigned int i = 0; i < scene->mNumCameras;++i) {
- const aiCamera* cam = scene->mCameras[i];
- WriteBinaryCamera(&chunk,cam);
- }
-
- }
-
- public:
- AssbinExport()
- : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters
- {
- }
-
- // -----------------------------------------------------------------------------------
- // Write a binary model dump
- void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
- {
- IOStream * out = pIOSystem->Open( pFile, "wb" );
- if (!out) return;
-
- time_t tt = time(NULL);
- tm* p = gmtime(&tt);
-
- // header
- char s[64];
- memset( s, 0, 64 );
-#if _MSC_VER >= 1400
- sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
-#else
- ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
-#endif
- out->Write( s, 44, 1 );
- // == 44 bytes
-
- Write<unsigned int>( out, ASSBIN_VERSION_MAJOR );
- Write<unsigned int>( out, ASSBIN_VERSION_MINOR );
- Write<unsigned int>( out, aiGetVersionRevision() );
- Write<unsigned int>( out, aiGetCompileFlags() );
- Write<uint16_t>( out, shortened );
- Write<uint16_t>( out, compressed );
- // == 20 bytes
-
- char buff[256];
- strncpy(buff,pFile,256);
- out->Write(buff,sizeof(char),256);
-
- char cmd[] = "\0";
- strncpy(buff,cmd,128);
- out->Write(buff,sizeof(char),128);
-
- // leave 64 bytes free for future extensions
- memset(buff,0xcd,64);
- out->Write(buff,sizeof(char),64);
- // == 435 bytes
-
- // ==== total header size: 512 bytes
- ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH );
-
- // Up to here the data is uncompressed. For compressed files, the rest
- // is compressed using standard DEFLATE from zlib.
- if (compressed)
- {
- AssbinChunkWriter uncompressedStream( NULL, 0 );
- WriteBinaryScene( &uncompressedStream, pScene );
-
- uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
- uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
- uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
-
- compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );
-
- out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
- out->Write( compressedBuffer, sizeof(char), compressedSize );
-
- delete[] compressedBuffer;
- }
- else
- {
- WriteBinaryScene( out, pScene );
- }
-
- pIOSystem->Close( out );
- }
- };
-
-void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- AssbinExport exporter;
- exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
-}
-} // end of namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/AssbinExporter.h b/src/3rdparty/assimp/code/AssbinExporter.h
deleted file mode 100644
index 55bb9fc82..000000000
--- a/src/3rdparty/assimp/code/AssbinExporter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssbinExporter.h
- * ASSBIN Exporter Main Header
- */
-#ifndef AI_ASSBINEXPORTER_H_INC
-#define AI_ASSBINEXPORTER_H_INC
-
-// nothing really needed here - reserved for future use like properties
-
-#endif
diff --git a/src/3rdparty/assimp/code/AssbinLoader.cpp b/src/3rdparty/assimp/code/AssbinLoader.cpp
deleted file mode 100644
index a7044c119..000000000
--- a/src/3rdparty/assimp/code/AssbinLoader.cpp
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssbinLoader.cpp
- * @brief Implementation of the .assbin importer class
- *
- * see assbin_chunks.h
- */
-
-#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-
-// internal headers
-#include "AssbinLoader.h"
-#include "assbin_chunks.h"
-#include "MemoryIOWrapper.h"
-#include <assimp/mesh.h>
-#include <assimp/anim.h>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-#else
-# include <contrib/zlib/zlib.h>
-#endif
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- ".assbin Importer",
- "Gargaj / Conspiracy",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
- 0,
- 0,
- 0,
- 0,
- "assbin"
-};
-
-const aiImporterDesc* AssbinImporter::GetInfo() const
-{
- return &desc;
-}
-
-bool AssbinImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/ ) const
-{
- IOStream * in = pIOHandler->Open(pFile);
- if (!in)
- return false;
-
- char s[32];
- in->Read( s, sizeof(char), 32 );
-
- pIOHandler->Close(in);
-
- return strncmp( s, "ASSIMP.binary-dump.", 19 ) == 0;
-}
-
-template <typename T>
-T Read(IOStream * stream)
-{
- T t;
- stream->Read( &t, sizeof(T), 1 );
- return t;
-}
-
-template <>
-aiVector3D Read<aiVector3D>(IOStream * stream)
-{
- aiVector3D v;
- v.x = Read<float>(stream);
- v.y = Read<float>(stream);
- v.z = Read<float>(stream);
- return v;
-}
-
-template <>
-aiColor4D Read<aiColor4D>(IOStream * stream)
-{
- aiColor4D c;
- c.r = Read<float>(stream);
- c.g = Read<float>(stream);
- c.b = Read<float>(stream);
- c.a = Read<float>(stream);
- return c;
-}
-
-template <>
-aiQuaternion Read<aiQuaternion>(IOStream * stream)
-{
- aiQuaternion v;
- v.w = Read<float>(stream);
- v.x = Read<float>(stream);
- v.y = Read<float>(stream);
- v.z = Read<float>(stream);
- return v;
-}
-
-template <>
-aiString Read<aiString>(IOStream * stream)
-{
- aiString s;
- stream->Read(&s.length,4,1);
- stream->Read(s.data,s.length,1);
- s.data[s.length] = 0;
- return s;
-}
-
-template <>
-aiVertexWeight Read<aiVertexWeight>(IOStream * stream)
-{
- aiVertexWeight w;
- w.mVertexId = Read<unsigned int>(stream);
- w.mWeight = Read<float>(stream);
- return w;
-}
-
-template <>
-aiMatrix4x4 Read<aiMatrix4x4>(IOStream * stream)
-{
- aiMatrix4x4 m;
- for (unsigned int i = 0; i < 4;++i) {
- for (unsigned int i2 = 0; i2 < 4;++i2) {
- m[i][i2] = Read<float>(stream);
- }
- }
- return m;
-}
-
-template <>
-aiVectorKey Read<aiVectorKey>(IOStream * stream)
-{
- aiVectorKey v;
- v.mTime = Read<double>(stream);
- v.mValue = Read<aiVector3D>(stream);
- return v;
-}
-
-template <>
-aiQuatKey Read<aiQuatKey>(IOStream * stream)
-{
- aiQuatKey v;
- v.mTime = Read<double>(stream);
- v.mValue = Read<aiQuaternion>(stream);
- return v;
-}
-
-template <typename T>
-void ReadArray(IOStream * stream, T * out, unsigned int size)
-{
- for (unsigned int i=0; i<size; i++) out[i] = Read<T>(stream);
-}
-
-template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int n )
-{
- // not sure what to do here, the data isn't really useful.
- stream->Seek( sizeof(T) * n, aiOrigin_CUR );
-}
-
-void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node, aiNode* parent ) {
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- *node = new aiNode();
-
- (*node)->mName = Read<aiString>(stream);
- (*node)->mTransformation = Read<aiMatrix4x4>(stream);
- (*node)->mNumChildren = Read<unsigned int>(stream);
- (*node)->mNumMeshes = Read<unsigned int>(stream);
- unsigned int nb_metadata = Read<unsigned int>(stream);
-
- if(parent) {
- (*node)->mParent = parent;
- }
-
- if ((*node)->mNumMeshes) {
- (*node)->mMeshes = new unsigned int[(*node)->mNumMeshes];
- for (unsigned int i = 0; i < (*node)->mNumMeshes; ++i) {
- (*node)->mMeshes[i] = Read<unsigned int>(stream);
- }
- }
-
- if ((*node)->mNumChildren) {
- (*node)->mChildren = new aiNode*[(*node)->mNumChildren];
- for (unsigned int i = 0; i < (*node)->mNumChildren; ++i) {
- ReadBinaryNode( stream, &(*node)->mChildren[i], *node );
- }
- }
-
- if ( nb_metadata > 0 ) {
- (*node)->mMetaData = aiMetadata::Alloc(nb_metadata);
- for (unsigned int i = 0; i < nb_metadata; ++i) {
- (*node)->mMetaData->mKeys[i] = Read<aiString>(stream);
- (*node)->mMetaData->mValues[i].mType = (aiMetadataType) Read<uint16_t>(stream);
- void* data( nullptr );
-
- switch ((*node)->mMetaData->mValues[i].mType) {
- case AI_BOOL:
- data = new bool(Read<bool>(stream));
- break;
- case AI_INT32:
- data = new int32_t(Read<int32_t>(stream));
- break;
- case AI_UINT64:
- data = new uint64_t(Read<uint64_t>(stream));
- break;
- case AI_FLOAT:
- data = new float(Read<float>(stream));
- break;
- case AI_DOUBLE:
- data = new double(Read<double>(stream));
- break;
- case AI_AISTRING:
- data = new aiString(Read<aiString>(stream));
- break;
- case AI_AIVECTOR3D:
- data = new aiVector3D(Read<aiVector3D>(stream));
- break;
-#ifndef SWIG
- case FORCE_32BIT:
-#endif // SWIG
- default:
- break;
- }
-
- (*node)->mMetaData->mValues[i].mData = data;
- }
- }
-}
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- b->mName = Read<aiString>(stream);
- b->mNumWeights = Read<unsigned int>(stream);
- b->mOffsetMatrix = Read<aiMatrix4x4>(stream);
-
- // for the moment we write dumb min/max values for the bones, too.
- // maybe I'll add a better, hash-like solution later
- if (shortened)
- {
- ReadBounds(stream,b->mWeights,b->mNumWeights);
- } // else write as usual
- else
- {
- b->mWeights = new aiVertexWeight[b->mNumWeights];
- ReadArray<aiVertexWeight>(stream,b->mWeights,b->mNumWeights);
- }
-}
-
-
-void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- mesh->mPrimitiveTypes = Read<unsigned int>(stream);
- mesh->mNumVertices = Read<unsigned int>(stream);
- mesh->mNumFaces = Read<unsigned int>(stream);
- mesh->mNumBones = Read<unsigned int>(stream);
- mesh->mMaterialIndex = Read<unsigned int>(stream);
-
- // first of all, write bits for all existent vertex components
- unsigned int c = Read<unsigned int>(stream);
-
- if (c & ASSBIN_MESH_HAS_POSITIONS)
- {
- if (shortened) {
- ReadBounds(stream,mesh->mVertices,mesh->mNumVertices);
- } // else write as usual
- else
- {
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- ReadArray<aiVector3D>(stream,mesh->mVertices,mesh->mNumVertices);
- }
- }
- if (c & ASSBIN_MESH_HAS_NORMALS)
- {
- if (shortened) {
- ReadBounds(stream,mesh->mNormals,mesh->mNumVertices);
- } // else write as usual
- else
- {
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- ReadArray<aiVector3D>(stream,mesh->mNormals,mesh->mNumVertices);
- }
- }
- if (c & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS)
- {
- if (shortened) {
- ReadBounds(stream,mesh->mTangents,mesh->mNumVertices);
- ReadBounds(stream,mesh->mBitangents,mesh->mNumVertices);
- } // else write as usual
- else
- {
- mesh->mTangents = new aiVector3D[mesh->mNumVertices];
- ReadArray<aiVector3D>(stream,mesh->mTangents,mesh->mNumVertices);
- mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
- ReadArray<aiVector3D>(stream,mesh->mBitangents,mesh->mNumVertices);
- }
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n)
- {
- if (!(c & ASSBIN_MESH_HAS_COLOR(n)))
- break;
-
- if (shortened)
- {
- ReadBounds(stream,mesh->mColors[n],mesh->mNumVertices);
- } // else write as usual
- else
- {
- mesh->mColors[n] = new aiColor4D[mesh->mNumVertices];
- ReadArray<aiColor4D>(stream,mesh->mColors[n],mesh->mNumVertices);
- }
- }
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
- {
- if (!(c & ASSBIN_MESH_HAS_TEXCOORD(n)))
- break;
-
- // write number of UV components
- mesh->mNumUVComponents[n] = Read<unsigned int>(stream);
-
- if (shortened) {
- ReadBounds(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
- } // else write as usual
- else
- {
- mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
- ReadArray<aiVector3D>(stream,mesh->mTextureCoords[n],mesh->mNumVertices);
- }
- }
-
- // write faces. There are no floating-point calculations involved
- // in these, so we can write a simple hash over the face data
- // to the dump file. We generate a single 32 Bit hash for 512 faces
- // using Assimp's standard hashing function.
- if (shortened) {
- Read<unsigned int>(stream);
- }
- else // else write as usual
- {
- // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
- aiFace& f = mesh->mFaces[i];
-
- static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
- f.mNumIndices = Read<uint16_t>(stream);
- f.mIndices = new unsigned int[f.mNumIndices];
-
- for (unsigned int a = 0; a < f.mNumIndices;++a) {
- if (mesh->mNumVertices < (1u<<16))
- {
- f.mIndices[a] = Read<uint16_t>(stream);
- }
- else
- {
- f.mIndices[a] = Read<unsigned int>(stream);
- }
- }
- }
- }
-
- // write bones
- if (mesh->mNumBones) {
- mesh->mBones = new C_STRUCT aiBone*[mesh->mNumBones];
- for (unsigned int a = 0; a < mesh->mNumBones;++a) {
- mesh->mBones[a] = new aiBone();
- ReadBinaryBone(stream,mesh->mBones[a]);
- }
- }
-}
-
-void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- prop->mKey = Read<aiString>(stream);
- prop->mSemantic = Read<unsigned int>(stream);
- prop->mIndex = Read<unsigned int>(stream);
-
- prop->mDataLength = Read<unsigned int>(stream);
- prop->mType = (aiPropertyTypeInfo)Read<unsigned int>(stream);
- prop->mData = new char [ prop->mDataLength ];
- stream->Read(prop->mData,1,prop->mDataLength);
-}
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
- if (mat->mNumProperties)
- {
- if (mat->mProperties)
- {
- delete[] mat->mProperties;
- }
- mat->mProperties = new aiMaterialProperty*[mat->mNumProperties];
- for (unsigned int i = 0; i < mat->mNumProperties;++i) {
- mat->mProperties[i] = new aiMaterialProperty();
- ReadBinaryMaterialProperty( stream, mat->mProperties[i]);
- }
- }
-}
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- nd->mNodeName = Read<aiString>(stream);
- nd->mNumPositionKeys = Read<unsigned int>(stream);
- nd->mNumRotationKeys = Read<unsigned int>(stream);
- nd->mNumScalingKeys = Read<unsigned int>(stream);
- nd->mPreState = (aiAnimBehaviour)Read<unsigned int>(stream);
- nd->mPostState = (aiAnimBehaviour)Read<unsigned int>(stream);
-
- if (nd->mNumPositionKeys) {
- if (shortened) {
- ReadBounds(stream,nd->mPositionKeys,nd->mNumPositionKeys);
-
- } // else write as usual
- else {
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
- ReadArray<aiVectorKey>(stream,nd->mPositionKeys,nd->mNumPositionKeys);
- }
- }
- if (nd->mNumRotationKeys) {
- if (shortened) {
- ReadBounds(stream,nd->mRotationKeys,nd->mNumRotationKeys);
-
- } // else write as usual
- else
- {
- nd->mRotationKeys = new aiQuatKey[nd->mNumRotationKeys];
- ReadArray<aiQuatKey>(stream,nd->mRotationKeys,nd->mNumRotationKeys);
- }
- }
- if (nd->mNumScalingKeys) {
- if (shortened) {
- ReadBounds(stream,nd->mScalingKeys,nd->mNumScalingKeys);
-
- } // else write as usual
- else
- {
- nd->mScalingKeys = new aiVectorKey[nd->mNumScalingKeys];
- ReadArray<aiVectorKey>(stream,nd->mScalingKeys,nd->mNumScalingKeys);
- }
- }
-}
-
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- anim->mName = Read<aiString> (stream);
- anim->mDuration = Read<double> (stream);
- anim->mTicksPerSecond = Read<double> (stream);
- anim->mNumChannels = Read<unsigned int>(stream);
-
- if (anim->mNumChannels)
- {
- anim->mChannels = new aiNodeAnim*[ anim->mNumChannels ];
- for (unsigned int a = 0; a < anim->mNumChannels;++a) {
- anim->mChannels[a] = new aiNodeAnim();
- ReadBinaryNodeAnim(stream,anim->mChannels[a]);
- }
- }
-}
-
-void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- tex->mWidth = Read<unsigned int>(stream);
- tex->mHeight = Read<unsigned int>(stream);
- stream->Read( tex->achFormatHint, sizeof(char), 4 );
-
- if(!shortened) {
- if (!tex->mHeight) {
- tex->pcData = new aiTexel[ tex->mWidth ];
- stream->Read(tex->pcData,1,tex->mWidth);
- }
- else {
- tex->pcData = new aiTexel[ tex->mWidth*tex->mHeight ];
- stream->Read(tex->pcData,1,tex->mWidth*tex->mHeight*4);
- }
- }
-
-}
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- l->mName = Read<aiString>(stream);
- l->mType = (aiLightSourceType)Read<unsigned int>(stream);
-
- if (l->mType != aiLightSource_DIRECTIONAL) {
- l->mAttenuationConstant = Read<float>(stream);
- l->mAttenuationLinear = Read<float>(stream);
- l->mAttenuationQuadratic = Read<float>(stream);
- }
-
- l->mColorDiffuse = Read<aiColor3D>(stream);
- l->mColorSpecular = Read<aiColor3D>(stream);
- l->mColorAmbient = Read<aiColor3D>(stream);
-
- if (l->mType == aiLightSource_SPOT) {
- l->mAngleInnerCone = Read<float>(stream);
- l->mAngleOuterCone = Read<float>(stream);
- }
-
-}
-
-// -----------------------------------------------------------------------------------
-void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- cam->mName = Read<aiString>(stream);
- cam->mPosition = Read<aiVector3D>(stream);
- cam->mLookAt = Read<aiVector3D>(stream);
- cam->mUp = Read<aiVector3D>(stream);
- cam->mHorizontalFOV = Read<float>(stream);
- cam->mClipPlaneNear = Read<float>(stream);
- cam->mClipPlaneFar = Read<float>(stream);
- cam->mAspect = Read<float>(stream);
-}
-
-void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
-{
- uint32_t chunkID = Read<uint32_t>(stream);
- (void)(chunkID);
- ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
- /*uint32_t size =*/ Read<uint32_t>(stream);
-
- scene->mFlags = Read<unsigned int>(stream);
- scene->mNumMeshes = Read<unsigned int>(stream);
- scene->mNumMaterials = Read<unsigned int>(stream);
- scene->mNumAnimations = Read<unsigned int>(stream);
- scene->mNumTextures = Read<unsigned int>(stream);
- scene->mNumLights = Read<unsigned int>(stream);
- scene->mNumCameras = Read<unsigned int>(stream);
-
- // Read node graph
- scene->mRootNode = new aiNode[1];
- ReadBinaryNode( stream, &scene->mRootNode, (aiNode*)NULL );
-
- // Read all meshes
- if (scene->mNumMeshes)
- {
- scene->mMeshes = new aiMesh*[scene->mNumMeshes];
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- scene->mMeshes[i] = new aiMesh();
- ReadBinaryMesh( stream,scene->mMeshes[i]);
- }
- }
-
- // Read materials
- if (scene->mNumMaterials)
- {
- scene->mMaterials = new aiMaterial*[scene->mNumMaterials];
- for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
- scene->mMaterials[i] = new aiMaterial();
- ReadBinaryMaterial(stream,scene->mMaterials[i]);
- }
- }
-
- // Read all animations
- if (scene->mNumAnimations)
- {
- scene->mAnimations = new aiAnimation*[scene->mNumAnimations];
- for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
- scene->mAnimations[i] = new aiAnimation();
- ReadBinaryAnim(stream,scene->mAnimations[i]);
- }
- }
-
- // Read all textures
- if (scene->mNumTextures)
- {
- scene->mTextures = new aiTexture*[scene->mNumTextures];
- for (unsigned int i = 0; i < scene->mNumTextures;++i) {
- scene->mTextures[i] = new aiTexture();
- ReadBinaryTexture(stream,scene->mTextures[i]);
- }
- }
-
- // Read lights
- if (scene->mNumLights)
- {
- scene->mLights = new aiLight*[scene->mNumLights];
- for (unsigned int i = 0; i < scene->mNumLights;++i) {
- scene->mLights[i] = new aiLight();
- ReadBinaryLight(stream,scene->mLights[i]);
- }
- }
-
- // Read cameras
- if (scene->mNumCameras)
- {
- scene->mCameras = new aiCamera*[scene->mNumCameras];
- for (unsigned int i = 0; i < scene->mNumCameras;++i) {
- scene->mCameras[i] = new aiCamera();
- ReadBinaryCamera(stream,scene->mCameras[i]);
- }
- }
-
-}
-
-void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
-{
- IOStream * stream = pIOHandler->Open(pFile,"rb");
- if (!stream)
- return;
-
- stream->Seek( 44, aiOrigin_CUR ); // signature
-
- /*unsigned int versionMajor =*/ Read<unsigned int>(stream);
- /*unsigned int versionMinor =*/ Read<unsigned int>(stream);
- /*unsigned int versionRevision =*/ Read<unsigned int>(stream);
- /*unsigned int compileFlags =*/ Read<unsigned int>(stream);
-
- shortened = Read<uint16_t>(stream) > 0;
- compressed = Read<uint16_t>(stream) > 0;
-
- if (shortened)
- throw DeadlyImportError( "Shortened binaries are not supported!" );
-
- stream->Seek( 256, aiOrigin_CUR ); // original filename
- stream->Seek( 128, aiOrigin_CUR ); // options
- stream->Seek( 64, aiOrigin_CUR ); // padding
-
- if (compressed)
- {
- uLongf uncompressedSize = Read<uint32_t>(stream);
- uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
-
- unsigned char * compressedData = new unsigned char[ compressedSize ];
- stream->Read( compressedData, 1, compressedSize );
-
- unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
-
- uncompress( uncompressedData, &uncompressedSize, compressedData, compressedSize );
-
- MemoryIOStream io( uncompressedData, uncompressedSize );
-
- ReadBinaryScene(&io,pScene);
-
- delete[] uncompressedData;
- delete[] compressedData;
- }
- else
- {
- ReadBinaryScene(stream,pScene);
- }
-
- pIOHandler->Close(stream);
-}
-
-#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER
diff --git a/src/3rdparty/assimp/code/AssbinLoader.h b/src/3rdparty/assimp/code/AssbinLoader.h
deleted file mode 100644
index 2eb7a6488..000000000
--- a/src/3rdparty/assimp/code/AssbinLoader.h
+++ /dev/null
@@ -1,104 +0,0 @@
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssbinLoader.h
- * @brief .assbin File format loader
- */
-#ifndef AI_ASSBINIMPORTER_H_INC
-#define AI_ASSBINIMPORTER_H_INC
-
-#include "BaseImporter.h"
-
-struct aiMesh;
-struct aiNode;
-struct aiBone;
-struct aiMaterial;
-struct aiMaterialProperty;
-struct aiNodeAnim;
-struct aiAnimation;
-struct aiTexture;
-struct aiLight;
-struct aiCamera;
-
-#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-/** Importer class for 3D Studio r3 and r4 3DS files
- */
-class AssbinImporter : public BaseImporter
-{
-private:
- bool shortened;
- bool compressed;
-
-public:
- virtual bool CanRead(
- const std::string& pFile,
- IOSystem* pIOHandler,
- bool checkSig
- ) const;
- virtual const aiImporterDesc* GetInfo() const;
- virtual void InternReadFile(
- const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler
- );
- void ReadBinaryScene( IOStream * stream, aiScene* pScene );
- void ReadBinaryNode( IOStream * stream, aiNode** mRootNode, aiNode* parent );
- void ReadBinaryMesh( IOStream * stream, aiMesh* mesh );
- void ReadBinaryBone( IOStream * stream, aiBone* bone );
- void ReadBinaryMaterial(IOStream * stream, aiMaterial* mat);
- void ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop);
- void ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd);
- void ReadBinaryAnim( IOStream * stream, aiAnimation* anim );
- void ReadBinaryTexture(IOStream * stream, aiTexture* tex);
- void ReadBinaryLight( IOStream * stream, aiLight* l );
- void ReadBinaryCamera( IOStream * stream, aiCamera* cam );
-};
-
-} // end of namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-
-#endif // AI_ASSBINIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/Assimp.cpp b/src/3rdparty/assimp/code/Assimp.cpp
deleted file mode 100644
index 9269f905e..000000000
--- a/src/3rdparty/assimp/code/Assimp.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Assimp.cpp
- * @brief Implementation of the Plain-C API
- */
-
-#include <assimp/cimport.h>
-#include <assimp/LogStream.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-#include <assimp/scene.h>
-
-#include "GenericProperty.h"
-#include "CInterfaceIOWrapper.h"
-#include "Importer.h"
-#include "Exceptional.h"
-#include "ScenePrivate.h"
-#include "BaseImporter.h"
-#include <list>
-
-// ------------------------------------------------------------------------------------------------
-#ifndef ASSIMP_BUILD_SINGLETHREADED
-# include <thread>
-# include <mutex>
-#endif
-// ------------------------------------------------------------------------------------------------
-using namespace Assimp;
-
-namespace Assimp {
- // underlying structure for aiPropertyStore
- typedef BatchLoader::PropertyMap PropertyMap;
-
- /** Stores the LogStream objects for all active C log streams */
- struct mpred {
- bool operator () (const aiLogStream& s0, const aiLogStream& s1) const {
- return s0.callback<s1.callback&&s0.user<s1.user;
- }
- };
- typedef std::map<aiLogStream, Assimp::LogStream*, mpred> LogStreamMap;
-
- /** Stores the LogStream objects allocated by #aiGetPredefinedLogStream */
- typedef std::list<Assimp::LogStream*> PredefLogStreamMap;
-
- /** Local storage of all active log streams */
- static LogStreamMap gActiveLogStreams;
-
- /** Local storage of LogStreams allocated by #aiGetPredefinedLogStream */
- static PredefLogStreamMap gPredefinedStreams;
-
- /** Error message of the last failed import process */
- static std::string gLastErrorString;
-
- /** Verbose logging active or not? */
- static aiBool gVerboseLogging = false;
-
- /** will return all registered importers. */
- void GetImporterInstanceList(std::vector< BaseImporter* >& out);
-
- /** will delete all registered importers. */
- void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
-} // namespace assimp
-
-
-#ifndef ASSIMP_BUILD_SINGLETHREADED
-/** Global mutex to manage the access to the log-stream map */
-static std::mutex gLogStreamMutex;
-#endif
-
-
-// ------------------------------------------------------------------------------------------------
-// Custom LogStream implementation for the C-API
-class LogToCallbackRedirector : public LogStream {
-public:
- explicit LogToCallbackRedirector(const aiLogStream& s)
- : stream (s) {
- ai_assert(NULL != s.callback);
- }
-
- ~LogToCallbackRedirector() {
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(gLogStreamMutex);
-#endif
- // (HACK) Check whether the 'stream.user' pointer points to a
- // custom LogStream allocated by #aiGetPredefinedLogStream.
- // In this case, we need to delete it, too. Of course, this
- // might cause strange problems, but the chance is quite low.
-
- PredefLogStreamMap::iterator it = std::find(gPredefinedStreams.begin(),
- gPredefinedStreams.end(), (Assimp::LogStream*)stream.user);
-
- if (it != gPredefinedStreams.end()) {
- delete *it;
- gPredefinedStreams.erase(it);
- }
- }
-
- /** @copydoc LogStream::write */
- void write(const char* message) {
- stream.callback(message,stream.user);
- }
-
-private:
- aiLogStream stream;
-};
-
-// ------------------------------------------------------------------------------------------------
-void ReportSceneNotFoundError() {
- DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
- "The C-API does not accept scenes produced by the C++ API and vice versa");
-
- ai_assert(false);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the given file and returns its content.
-const aiScene* aiImportFile( const char* pFile, unsigned int pFlags) {
- return aiImportFileEx(pFile,pFlags,NULL);
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileEx( const char* pFile, unsigned int pFlags, aiFileIO* pFS) {
- return aiImportFileExWithProperties(pFile, pFlags, pFS, NULL);
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileExWithProperties( const char* pFile, unsigned int pFlags,
- aiFileIO* pFS, const aiPropertyStore* props) {
- ai_assert(NULL != pFile);
-
- const aiScene* scene = NULL;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // create an Importer for this file
- Assimp::Importer* imp = new Assimp::Importer();
-
- // copy properties
- if(props) {
- const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
- ImporterPimpl* pimpl = imp->Pimpl();
- 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) {
- imp->SetIOHandler( new CIOSystemWrapper (pFS) );
- }
-
- // and have it read the file
- scene = imp->ReadFile( pFile, pFlags);
-
- // if succeeded, store the importer in the scene and keep it alive
- if( scene) {
- ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
- priv->mOrigImporter = imp;
- } else {
- // if failed, extract error code and destroy the import
- gLastErrorString = imp->GetErrorString();
- delete imp;
- }
-
- // return imported data. If the import failed the pointer is NULL anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
-
- return scene;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileFromMemory(
- const char* pBuffer,
- unsigned int pLength,
- unsigned int pFlags,
- const char* pHint)
-{
- return aiImportFileFromMemoryWithProperties(pBuffer, pLength, pFlags, pHint, NULL);
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* aiImportFileFromMemoryWithProperties(
- const char* pBuffer,
- unsigned int pLength,
- unsigned int pFlags,
- const char* pHint,
- const aiPropertyStore* props)
-{
- ai_assert( NULL != pBuffer );
- ai_assert( 0 != pLength );
-
- const aiScene* scene = NULL;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // create an Importer for this file
- Assimp::Importer* imp = new Assimp::Importer();
-
- // copy properties
- if(props) {
- const PropertyMap* pp = reinterpret_cast<const PropertyMap*>(props);
- ImporterPimpl* pimpl = imp->Pimpl();
- 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
- scene = imp->ReadFileFromMemory( pBuffer, pLength, pFlags,pHint);
-
- // if succeeded, store the importer in the scene and keep it alive
- if( scene) {
- ScenePrivateData* priv = const_cast<ScenePrivateData*>( ScenePriv(scene) );
- priv->mOrigImporter = imp;
- }
- else {
- // if failed, extract error code and destroy the import
- gLastErrorString = imp->GetErrorString();
- delete imp;
- }
- // return imported data. If the import failed the pointer is NULL anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return scene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Releases all resources associated with the given import process.
-void aiReleaseImport( const aiScene* pScene)
-{
- if (!pScene) {
- return;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // find the importer associated with this data
- const ScenePrivateData* priv = ScenePriv(pScene);
- if( !priv || !priv->mOrigImporter) {
- delete pScene;
- }
- else {
- // deleting the Importer also deletes the scene
- // Note: the reason that this is not written as 'delete priv->mOrigImporter'
- // is a suspected bug in gcc 4.4+ (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52339)
- Importer* importer = priv->mOrigImporter;
- delete importer;
- }
-
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
- unsigned int pFlags)
-{
- const aiScene* sc = NULL;
-
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // find the importer associated with this data
- const ScenePrivateData* priv = ScenePriv(pScene);
- if( !priv || !priv->mOrigImporter) {
- ReportSceneNotFoundError();
- return NULL;
- }
-
- sc = priv->mOrigImporter->ApplyPostProcessing(pFlags);
-
- if (!sc) {
- aiReleaseImport(pScene);
- return NULL;
- }
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return sc;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene,
- BaseProcess* process,
- bool requestValidation ) {
- const aiScene* sc( NULL );
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // find the importer associated with this data
- const ScenePrivateData* priv = ScenePriv( scene );
- if ( NULL == priv || NULL == priv->mOrigImporter ) {
- ReportSceneNotFoundError();
- return NULL;
- }
-
- sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation );
-
- if ( !sc ) {
- aiReleaseImport( scene );
- return NULL;
- }
-
- ASSIMP_END_EXCEPTION_REGION( const aiScene* );
-
- return sc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void CallbackToLogRedirector (const char* msg, char* dt)
-{
- ai_assert( NULL != msg );
- ai_assert( NULL != dt );
- LogStream* s = (LogStream*)dt;
-
- s->write(msg);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiLogStream aiGetPredefinedLogStream(aiDefaultLogStream pStream,const char* file)
-{
- aiLogStream sout;
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- LogStream* stream = LogStream::createDefaultStream(pStream,file);
- if (!stream) {
- sout.callback = NULL;
- sout.user = NULL;
- }
- else {
- sout.callback = &CallbackToLogRedirector;
- sout.user = (char*)stream;
- }
- gPredefinedStreams.push_back(stream);
- ASSIMP_END_EXCEPTION_REGION(aiLogStream);
- return sout;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(gLogStreamMutex);
-#endif
-
- LogStream* lg = new LogToCallbackRedirector(*stream);
- gActiveLogStreams[*stream] = lg;
-
- if (DefaultLogger::isNullLogger()) {
- DefaultLogger::create(NULL,(gVerboseLogging == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
- }
- DefaultLogger::get()->attachStream(lg);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(gLogStreamMutex);
-#endif
- // find the log-stream associated with this data
- LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
- // it should be there... else the user is playing fools with us
- if( it == gActiveLogStreams.end()) {
- return AI_FAILURE;
- }
- DefaultLogger::get()->detatchStream( it->second );
- delete it->second;
-
- gActiveLogStreams.erase( it);
-
- if (gActiveLogStreams.empty()) {
- DefaultLogger::kill();
- }
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiDetachAllLogStreams(void)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(gLogStreamMutex);
-#endif
- Logger *logger( DefaultLogger::get() );
- if ( NULL == logger ) {
- return;
- }
-
- for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
- logger->detatchStream( it->second );
- delete it->second;
- }
- gActiveLogStreams.clear();
- DefaultLogger::kill();
-
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiEnableVerboseLogging(aiBool d)
-{
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->setLogSeverity((d == AI_TRUE ? Logger::VERBOSE : Logger::NORMAL));
- }
- gVerboseLogging = d;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the error text of the last failed import process.
-const char* aiGetErrorString()
-{
- return gLastErrorString.c_str();
-}
-
-// -----------------------------------------------------------------------------------------------
-// Return the description of a importer given its index
-const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
-{
- return Importer().GetImporterInfo(pIndex);
-}
-
-// -----------------------------------------------------------------------------------------------
-// Return the number of importers
-size_t aiGetImportFormatCount(void)
-{
- return Importer().GetImporterCount();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the error text of the last failed import process.
-aiBool aiIsExtensionSupported(const char* szExtension)
-{
- ai_assert(NULL != szExtension);
- aiBool candoit=AI_FALSE;
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // FIXME: no need to create a temporary Importer instance just for that ..
- Assimp::Importer tmp;
- candoit = tmp.IsExtensionSupported(std::string(szExtension)) ? AI_TRUE : AI_FALSE;
-
- ASSIMP_END_EXCEPTION_REGION(aiBool);
- return candoit;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all file extensions supported by ASSIMP
-void aiGetExtensionList(aiString* szOut)
-{
- ai_assert(NULL != szOut);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // FIXME: no need to create a temporary Importer instance just for that ..
- Assimp::Importer tmp;
- tmp.GetExtensionList(*szOut);
-
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the memory requirements for a particular import.
-void aiGetMemoryRequirements(const C_STRUCT aiScene* pIn,
- C_STRUCT aiMemoryInfo* in)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // find the importer associated with this data
- const ScenePrivateData* priv = ScenePriv(pIn);
- if( !priv || !priv->mOrigImporter) {
- ReportSceneNotFoundError();
- return;
- }
-
- return priv->mOrigImporter->GetMemoryRequirements(*in);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
-{
- return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
-{
- delete reinterpret_cast<PropertyMap*>(p);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyInteger
-ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szName, int value)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
- SetGenericProperty<int>(pp->ints,szName,value);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyFloat
-ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
- SetGenericProperty<ai_real>(pp->floats,szName,value);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer::SetPropertyString
-ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName,
- const C_STRUCT aiString* st)
-{
- if (!st) {
- return;
- }
- ASSIMP_BEGIN_EXCEPTION_REGION();
- PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
- SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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);
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Rotation matrix to quaternion
-ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
-{
- ai_assert( NULL != quat );
- ai_assert( NULL != mat );
- *quat = aiQuaternion(*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix decomposition
-ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
- aiQuaternion* rotation,
- aiVector3D* position)
-{
- ai_assert( NULL != rotation );
- ai_assert( NULL != position );
- ai_assert( NULL != scaling );
- ai_assert( NULL != mat );
- mat->Decompose(*scaling,*rotation,*position);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix transpose
-ASSIMP_API void aiTransposeMatrix3(aiMatrix3x3* mat)
-{
- ai_assert(NULL != mat);
- mat->Transpose();
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
-{
- ai_assert(NULL != mat);
- mat->Transpose();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Vector transformation
-ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
- const aiMatrix3x3* mat)
-{
- ai_assert( NULL != mat );
- ai_assert( NULL != vec);
- *vec *= (*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
- const aiMatrix4x4* mat)
-{
- ai_assert( NULL != mat );
- ai_assert( NULL != vec );
-
- *vec *= (*mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix multiplication
-ASSIMP_API void aiMultiplyMatrix4(
- aiMatrix4x4* dst,
- const aiMatrix4x4* src)
-{
- ai_assert( NULL != dst );
- ai_assert( NULL != src );
- *dst = (*dst) * (*src);
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiMultiplyMatrix3(
- aiMatrix3x3* dst,
- const aiMatrix3x3* src)
-{
- ai_assert( NULL != dst );
- ai_assert( NULL != src );
- *dst = (*dst) * (*src);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Matrix identity
-ASSIMP_API void aiIdentityMatrix3(
- aiMatrix3x3* mat)
-{
- ai_assert(NULL != mat);
- *mat = aiMatrix3x3();
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiIdentityMatrix4(
- aiMatrix4x4* mat)
-{
- ai_assert(NULL != mat);
- *mat = aiMatrix4x4();
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
- if( NULL == extension ) {
- return NULL;
- }
- const aiImporterDesc *desc( NULL );
- std::vector< BaseImporter* > out;
- GetImporterInstanceList( out );
- for( size_t i = 0; i < out.size(); ++i ) {
- if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
- desc = out[ i ]->GetInfo();
- break;
- }
- }
-
- DeleteImporterInstanceList(out);
-
- return desc;
-}
-
-// ------------------------------------------------------------------------------------------------
diff --git a/src/3rdparty/assimp/code/AssimpCExport.cpp b/src/3rdparty/assimp/code/AssimpCExport.cpp
deleted file mode 100644
index b8d3264a1..000000000
--- a/src/3rdparty/assimp/code/AssimpCExport.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssimpCExport.cpp
-Assimp C export interface. See Exporter.cpp for some notes.
-*/
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-
-#include "CInterfaceIOWrapper.h"
-#include <assimp/SceneCombiner.h>
-#include "ScenePrivate.h"
-#include <assimp/Exporter.hpp>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API size_t aiGetExportFormatCount(void)
-{
- return Exporter().GetExportFormatCount();
-}
-
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
-{
- // Note: this is valid as the index always pertains to a built-in exporter,
- // for which the returned structure is guaranteed to be of static storage duration.
- Exporter exporter;
- const aiExportFormatDesc* orig( exporter.GetExportFormatDescription( index ) );
- if (NULL == orig) {
- return NULL;
- }
-
- aiExportFormatDesc *desc = new aiExportFormatDesc;
- desc->description = new char[ strlen( orig->description ) + 1 ]();
- ::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
- desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
- ::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
- desc->id = new char[ strlen( orig->id ) + 1 ]();
- ::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
-
- return desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiReleaseExportFormatDescription( const aiExportFormatDesc *desc ) {
- if (NULL == desc) {
- return;
- }
-
- delete [] desc->description;
- delete [] desc->fileExtension;
- delete [] desc->id;
- delete desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
-{
- if (!pOut || !pIn) {
- return;
- }
-
- 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 )
-{
- return ::aiExportSceneEx(pScene,pFormatId,pFileName,NULL,pPreprocessing);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiReturn aiExportSceneEx( const aiScene* pScene, const char* pFormatId, const char* pFileName, aiFileIO* pIO, unsigned int pPreprocessing )
-{
- Exporter exp;
-
- if (pIO) {
- exp.SetIOHandler(new CIOSystemWrapper(pIO));
- }
- return exp.Export(pScene,pFormatId,pFileName,pPreprocessing);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing )
-{
- Exporter exp;
- if (!exp.ExportToBlob(pScene,pFormatId,pPreprocessing)) {
- return NULL;
- }
- const aiExportDataBlob* blob = exp.GetOrphanedBlob();
- ai_assert(blob);
-
- return blob;
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API C_STRUCT void aiReleaseExportBlob( const aiExportDataBlob* pData )
-{
- delete pData;
-}
-
-#endif // !ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/AssxmlExporter.cpp b/src/3rdparty/assimp/code/AssxmlExporter.cpp
deleted file mode 100644
index 90ed66701..000000000
--- a/src/3rdparty/assimp/code/AssxmlExporter.cpp
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssxmlExporter.cpp
- * ASSXML exporter main code
- */
-#include <stdarg.h>
-#include <assimp/version.h>
-#include "ProcessHelper.h"
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-#else
-# include <contrib/zlib/zlib.h>
-#endif
-
-#include <time.h>
-#include <stdio.h>
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
-
-using namespace Assimp;
-
-namespace Assimp {
-
-namespace AssxmlExport {
-
-// -----------------------------------------------------------------------------------
-static int ioprintf( IOStream * io, const char *format, ... ) {
- using namespace std;
- if ( nullptr == io ) {
- return -1;
- }
-
- static const int Size = 4096;
- char sz[ Size ];
- ::memset( sz, '\0', Size );
- va_list va;
- va_start( va, format );
- const unsigned int nSize = vsnprintf( sz, Size-1, format, va );
- ai_assert( nSize < Size );
- va_end( va );
-
- io->Write( sz, sizeof(char), nSize );
-
- return nSize;
-}
-
-// -----------------------------------------------------------------------------------
-// Convert a name to standard XML format
-static void ConvertName(aiString& out, const aiString& in) {
- out.length = 0;
- for (unsigned int i = 0; i < in.length; ++i) {
- switch (in.data[i]) {
- case '<':
- out.Append("&lt;");break;
- case '>':
- out.Append("&gt;");break;
- case '&':
- out.Append("&amp;");break;
- case '\"':
- out.Append("&quot;");break;
- case '\'':
- out.Append("&apos;");break;
- default:
- out.data[out.length++] = in.data[i];
- }
- }
- out.data[out.length] = 0;
-}
-
-// -----------------------------------------------------------------------------------
-// Write a single node as text dump
-static void WriteNode(const aiNode* node, IOStream * io, unsigned int depth) {
- char prefix[512];
- for (unsigned int i = 0; i < depth;++i)
- prefix[i] = '\t';
- prefix[depth] = '\0';
-
- const aiMatrix4x4& m = node->mTransformation;
-
- aiString name;
- ConvertName(name,node->mName);
- ioprintf(io,"%s<Node name=\"%s\"> \n"
- "%s\t<Matrix4> \n"
- "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "%s\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "%s\t</Matrix4> \n",
- prefix,name.data,prefix,
- prefix,m.a1,m.a2,m.a3,m.a4,
- prefix,m.b1,m.b2,m.b3,m.b4,
- prefix,m.c1,m.c2,m.c3,m.c4,
- prefix,m.d1,m.d2,m.d3,m.d4,prefix);
-
- if (node->mNumMeshes) {
- ioprintf(io, "%s\t<MeshRefs num=\"%i\">\n%s\t",
- prefix,node->mNumMeshes,prefix);
-
- for (unsigned int i = 0; i < node->mNumMeshes;++i) {
- ioprintf(io,"%i ",node->mMeshes[i]);
- }
- ioprintf(io,"\n%s\t</MeshRefs>\n",prefix);
- }
-
- if (node->mNumChildren) {
- ioprintf(io,"%s\t<NodeList num=\"%i\">\n",
- prefix,node->mNumChildren);
-
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- WriteNode(node->mChildren[i],io,depth+2);
- }
- ioprintf(io,"%s\t</NodeList>\n",prefix);
- }
- ioprintf(io,"%s</Node>\n",prefix);
-}
-
-
-// -----------------------------------------------------------------------------------
-// Some chuncks of text will need to be encoded for XML
-// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377
-static std::string encodeXML(const std::string& data) {
- std::string buffer;
- buffer.reserve(data.size());
- for(size_t pos = 0; pos != data.size(); ++pos) {
- switch(data[pos]) {
- case '&': buffer.append("&amp;"); break;
- case '\"': buffer.append("&quot;"); break;
- case '\'': buffer.append("&apos;"); break;
- case '<': buffer.append("&lt;"); break;
- case '>': buffer.append("&gt;"); break;
- default: buffer.append(&data[pos], 1); break;
- }
- }
- return buffer;
-}
-
-// -----------------------------------------------------------------------------------
-// Write a text model dump
-static
-void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
- time_t tt = ::time( NULL );
- tm* p = ::gmtime( &tt );
- ai_assert( nullptr != p );
-
- // write header
- std::string header(
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
- "<ASSIMP format_id=\"1\">\n\n"
- "<!-- XML Model dump produced by assimp dump\n"
- " Library version: %i.%i.%i\n"
- " %s\n"
- "-->"
- " \n\n"
- "<Scene flags=\"%d\" postprocessing=\"%i\">\n"
- );
-
- const unsigned int majorVersion( aiGetVersionMajor() );
- const unsigned int minorVersion( aiGetVersionMinor() );
- const unsigned int rev( aiGetVersionRevision() );
- const char *curtime( asctime( p ) );
- ioprintf( io, header.c_str(), majorVersion, minorVersion, rev, curtime, scene->mFlags, 0 );
-
- // write the node graph
- WriteNode(scene->mRootNode, io, 0);
-
-#if 0
- // write cameras
- for (unsigned int i = 0; i < scene->mNumCameras;++i) {
- aiCamera* cam = scene->mCameras[i];
- ConvertName(name,cam->mName);
-
- // camera header
- ioprintf(io,"\t<Camera parent=\"%s\">\n"
- "\t\t<Vector3 name=\"up\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Float name=\"fov\" > %f </Float>\n"
- "\t\t<Float name=\"aspect\" > %f </Float>\n"
- "\t\t<Float name=\"near_clip\" > %f </Float>\n"
- "\t\t<Float name=\"far_clip\" > %f </Float>\n"
- "\t</Camera>\n",
- name.data,
- cam->mUp.x,cam->mUp.y,cam->mUp.z,
- cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z,
- cam->mPosition.x,cam->mPosition.y,cam->mPosition.z,
- cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i);
- }
-
- // write lights
- for (unsigned int i = 0; i < scene->mNumLights;++i) {
- aiLight* l = scene->mLights[i];
- ConvertName(name,l->mName);
-
- // light header
- ioprintf(io,"\t<Light parent=\"%s\"> type=\"%s\"\n"
- "\t\t<Vector3 name=\"diffuse\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Vector3 name=\"specular\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Vector3 name=\"ambient\" > %0 8f %0 8f %0 8f </Vector3>\n",
- name.data,
- (l->mType == aiLightSource_DIRECTIONAL ? "directional" :
- (l->mType == aiLightSource_POINT ? "point" : "spot" )),
- l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b,
- l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b,
- l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b);
-
- if (l->mType != aiLightSource_DIRECTIONAL) {
- ioprintf(io,
- "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n"
- "\t\t<Float name=\"atten_cst\" > %f </Float>\n"
- "\t\t<Float name=\"atten_lin\" > %f </Float>\n"
- "\t\t<Float name=\"atten_sqr\" > %f </Float>\n",
- l->mPosition.x,l->mPosition.y,l->mPosition.z,
- l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic);
- }
-
- if (l->mType != aiLightSource_POINT) {
- ioprintf(io,
- "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n",
- l->mDirection.x,l->mDirection.y,l->mDirection.z);
- }
-
- if (l->mType == aiLightSource_SPOT) {
- ioprintf(io,
- "\t\t<Float name=\"cone_out\" > %f </Float>\n"
- "\t\t<Float name=\"cone_inn\" > %f </Float>\n",
- l->mAngleOuterCone,l->mAngleInnerCone);
- }
- ioprintf(io,"\t</Light>\n");
- }
-#endif
- aiString name;
-
- // write textures
- if (scene->mNumTextures) {
- ioprintf(io,"<TextureList num=\"%i\">\n",scene->mNumTextures);
- for (unsigned int i = 0; i < scene->mNumTextures;++i) {
- aiTexture* tex = scene->mTextures[i];
- bool compressed = (tex->mHeight == 0);
-
- // mesh header
- ioprintf(io,"\t<Texture width=\"%i\" height=\"%i\" compressed=\"%s\"> \n",
- (compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight),
- (compressed ? "true" : "false"));
-
- if (compressed) {
- ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth);
-
- if (!shortened) {
- for (unsigned int n = 0; n < tex->mWidth;++n) {
- ioprintf(io,"\t\t\t%2x",reinterpret_cast<uint8_t*>(tex->pcData)[n]);
- if (n && !(n % 50)) {
- ioprintf(io,"\n");
- }
- }
- }
- }
- else if (!shortened){
- ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
-
- // const unsigned int width = (unsigned int)std::log10((double)std::max(tex->mHeight,tex->mWidth))+1;
- for (unsigned int y = 0; y < tex->mHeight;++y) {
- for (unsigned int x = 0; x < tex->mWidth;++x) {
- aiTexel* tx = tex->pcData + y*tex->mWidth+x;
- unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
- ioprintf(io,"\t\t\t%2x %2x %2x %2x",r,g,b,a);
-
- // group by four for readability
- if ( 0 == ( x + y*tex->mWidth ) % 4 ) {
- ioprintf( io, "\n" );
- }
- }
- }
- }
- ioprintf(io,"\t\t</Data>\n\t</Texture>\n");
- }
- ioprintf(io,"</TextureList>\n");
- }
-
- // write materials
- if (scene->mNumMaterials) {
- ioprintf(io,"<MaterialList num=\"%i\">\n",scene->mNumMaterials);
- for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
- const aiMaterial* mat = scene->mMaterials[i];
-
- ioprintf(io,"\t<Material>\n");
- ioprintf(io,"\t\t<MatPropertyList num=\"%i\">\n",mat->mNumProperties);
- for (unsigned int n = 0; n < mat->mNumProperties;++n) {
-
- const aiMaterialProperty* prop = mat->mProperties[n];
- const char* sz = "";
- if (prop->mType == aiPTI_Float) {
- sz = "float";
- }
- else if (prop->mType == aiPTI_Integer) {
- sz = "integer";
- }
- else if (prop->mType == aiPTI_String) {
- sz = "string";
- }
- else if (prop->mType == aiPTI_Buffer) {
- sz = "binary_buffer";
- }
-
- ioprintf(io,"\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%i\"",
- prop->mKey.data, sz,
- ::TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex);
-
- if (prop->mType == aiPTI_Float) {
- ioprintf(io," size=\"%i\">\n\t\t\t\t",
- static_cast<int>(prop->mDataLength/sizeof(float)));
-
- for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) {
- ioprintf(io,"%f ",*((float*)(prop->mData+p*sizeof(float))));
- }
- }
- else if (prop->mType == aiPTI_Integer) {
- ioprintf(io," size=\"%i\">\n\t\t\t\t",
- static_cast<int>(prop->mDataLength/sizeof(int)));
-
- for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) {
- ioprintf(io,"%i ",*((int*)(prop->mData+p*sizeof(int))));
- }
- }
- else if (prop->mType == aiPTI_Buffer) {
- ioprintf(io," size=\"%i\">\n\t\t\t\t",
- static_cast<int>(prop->mDataLength));
-
- for (unsigned int p = 0; p < prop->mDataLength;++p) {
- ioprintf(io,"%2x ",prop->mData[p]);
- if (p && 0 == p%30) {
- ioprintf(io,"\n\t\t\t\t");
- }
- }
- }
- else if (prop->mType == aiPTI_String) {
- ioprintf(io,">\n\t\t\t\t\"%s\"",encodeXML(prop->mData+4).c_str() /* skip length */);
- }
- ioprintf(io,"\n\t\t\t</MatProperty>\n");
- }
- ioprintf(io,"\t\t</MatPropertyList>\n");
- ioprintf(io,"\t</Material>\n");
- }
- ioprintf(io,"</MaterialList>\n");
- }
-
- // write animations
- if (scene->mNumAnimations) {
- ioprintf(io,"<AnimationList num=\"%i\">\n",scene->mNumAnimations);
- for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
- aiAnimation* anim = scene->mAnimations[i];
-
- // anim header
- ConvertName(name,anim->mName);
- ioprintf(io,"\t<Animation name=\"%s\" duration=\"%e\" tick_cnt=\"%e\">\n",
- name.data, anim->mDuration, anim->mTicksPerSecond);
-
- // write bone animation channels
- if (anim->mNumChannels) {
- ioprintf(io,"\t\t<NodeAnimList num=\"%i\">\n",anim->mNumChannels);
- for (unsigned int n = 0; n < anim->mNumChannels;++n) {
- aiNodeAnim* nd = anim->mChannels[n];
-
- // node anim header
- ConvertName(name,nd->mNodeName);
- ioprintf(io,"\t\t\t<NodeAnim node=\"%s\">\n",name.data);
-
- if (!shortened) {
- // write position keys
- if (nd->mNumPositionKeys) {
- ioprintf(io,"\t\t\t\t<PositionKeyList num=\"%i\">\n",nd->mNumPositionKeys);
- for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) {
- aiVectorKey* vc = nd->mPositionKeys+a;
- ioprintf(io,"\t\t\t\t\t<PositionKey time=\"%e\">\n"
- "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</PositionKey>\n",
- vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
- }
- ioprintf(io,"\t\t\t\t</PositionKeyList>\n");
- }
-
- // write scaling keys
- if (nd->mNumScalingKeys) {
- ioprintf(io,"\t\t\t\t<ScalingKeyList num=\"%i\">\n",nd->mNumScalingKeys);
- for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) {
- aiVectorKey* vc = nd->mScalingKeys+a;
- ioprintf(io,"\t\t\t\t\t<ScalingKey time=\"%e\">\n"
- "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</ScalingKey>\n",
- vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z);
- }
- ioprintf(io,"\t\t\t\t</ScalingKeyList>\n");
- }
-
- // write rotation keys
- if (nd->mNumRotationKeys) {
- ioprintf(io,"\t\t\t\t<RotationKeyList num=\"%i\">\n",nd->mNumRotationKeys);
- for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) {
- aiQuatKey* vc = nd->mRotationKeys+a;
- ioprintf(io,"\t\t\t\t\t<RotationKey time=\"%e\">\n"
- "\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t</RotationKey>\n",
- vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w);
- }
- ioprintf(io,"\t\t\t\t</RotationKeyList>\n");
- }
- }
- ioprintf(io,"\t\t\t</NodeAnim>\n");
- }
- ioprintf(io,"\t\t</NodeAnimList>\n");
- }
- ioprintf(io,"\t</Animation>\n");
- }
- ioprintf(io,"</AnimationList>\n");
- }
-
- // write meshes
- if (scene->mNumMeshes) {
- ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- aiMesh* mesh = scene->mMeshes[i];
- // const unsigned int width = (unsigned int)std::log10((double)mesh->mNumVertices)+1;
-
- // mesh header
- ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
- (mesh->mPrimitiveTypes & aiPrimitiveType_POINT ? "points" : ""),
- (mesh->mPrimitiveTypes & aiPrimitiveType_LINE ? "lines" : ""),
- (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""),
- (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON ? "polygons" : ""),
- mesh->mMaterialIndex);
-
- // bones
- if (mesh->mNumBones) {
- ioprintf(io,"\t\t<BoneList num=\"%i\">\n",mesh->mNumBones);
-
- for (unsigned int n = 0; n < mesh->mNumBones;++n) {
- aiBone* bone = mesh->mBones[n];
-
- ConvertName(name,bone->mName);
- // bone header
- ioprintf(io,"\t\t\t<Bone name=\"%s\">\n"
- "\t\t\t\t<Matrix4> \n"
- "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n"
- "\t\t\t\t</Matrix4> \n",
- name.data,
- bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4,
- bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4,
- bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4,
- bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4);
-
- if (!shortened && bone->mNumWeights) {
- ioprintf(io,"\t\t\t\t<WeightList num=\"%i\">\n",bone->mNumWeights);
-
- // bone weights
- for (unsigned int a = 0; a < bone->mNumWeights;++a) {
- aiVertexWeight* wght = bone->mWeights+a;
-
- ioprintf(io,"\t\t\t\t\t<Weight index=\"%i\">\n\t\t\t\t\t\t%f\n\t\t\t\t\t</Weight>\n",
- wght->mVertexId,wght->mWeight);
- }
- ioprintf(io,"\t\t\t\t</WeightList>\n");
- }
- ioprintf(io,"\t\t\t</Bone>\n");
- }
- ioprintf(io,"\t\t</BoneList>\n");
- }
-
- // faces
- if (!shortened && mesh->mNumFaces) {
- ioprintf(io,"\t\t<FaceList num=\"%i\">\n",mesh->mNumFaces);
- for (unsigned int n = 0; n < mesh->mNumFaces; ++n) {
- aiFace& f = mesh->mFaces[n];
- ioprintf(io,"\t\t\t<Face num=\"%i\">\n"
- "\t\t\t\t",f.mNumIndices);
-
- for (unsigned int j = 0; j < f.mNumIndices;++j)
- ioprintf(io,"%i ",f.mIndices[j]);
-
- ioprintf(io,"\n\t\t\t</Face>\n");
- }
- ioprintf(io,"\t\t</FaceList>\n");
- }
-
- // vertex positions
- if (mesh->HasPositions()) {
- ioprintf(io,"\t\t<Positions num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
- if (!shortened) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
- mesh->mVertices[n].x,
- mesh->mVertices[n].y,
- mesh->mVertices[n].z);
- }
- }
- ioprintf(io,"\t\t</Positions>\n");
- }
-
- // vertex normals
- if (mesh->HasNormals()) {
- ioprintf(io,"\t\t<Normals num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
- if (!shortened) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
- mesh->mNormals[n].x,
- mesh->mNormals[n].y,
- mesh->mNormals[n].z);
- }
- }
- else {
- }
- ioprintf(io,"\t\t</Normals>\n");
- }
-
- // vertex tangents and bitangents
- if (mesh->HasTangentsAndBitangents()) {
- ioprintf(io,"\t\t<Tangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
- if (!shortened) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
- mesh->mTangents[n].x,
- mesh->mTangents[n].y,
- mesh->mTangents[n].z);
- }
- }
- ioprintf(io,"\t\t</Tangents>\n");
-
- ioprintf(io,"\t\t<Bitangents num=\"%i\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices);
- if (!shortened) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
- mesh->mBitangents[n].x,
- mesh->mBitangents[n].y,
- mesh->mBitangents[n].z);
- }
- }
- ioprintf(io,"\t\t</Bitangents>\n");
- }
-
- // texture coordinates
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
- if (!mesh->mTextureCoords[a])
- break;
-
- ioprintf(io,"\t\t<TextureCoords num=\"%i\" set=\"%i\" num_components=\"%i\"> \n",mesh->mNumVertices,
- a,mesh->mNumUVComponents[a]);
-
- if (!shortened) {
- if (mesh->mNumUVComponents[a] == 3) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f\n",
- mesh->mTextureCoords[a][n].x,
- mesh->mTextureCoords[a][n].y,
- mesh->mTextureCoords[a][n].z);
- }
- }
- else {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f\n",
- mesh->mTextureCoords[a][n].x,
- mesh->mTextureCoords[a][n].y);
- }
- }
- }
- ioprintf(io,"\t\t</TextureCoords>\n");
- }
-
- // vertex colors
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
- if (!mesh->mColors[a])
- break;
- ioprintf(io,"\t\t<Colors num=\"%i\" set=\"%i\" num_components=\"4\"> \n",mesh->mNumVertices,a);
- if (!shortened) {
- for (unsigned int n = 0; n < mesh->mNumVertices; ++n) {
- ioprintf(io,"\t\t%0 8f %0 8f %0 8f %0 8f\n",
- mesh->mColors[a][n].r,
- mesh->mColors[a][n].g,
- mesh->mColors[a][n].b,
- mesh->mColors[a][n].a);
- }
- }
- ioprintf(io,"\t\t</Colors>\n");
- }
- ioprintf(io,"\t</Mesh>\n");
- }
- ioprintf(io,"</MeshList>\n");
- }
- ioprintf(io,"</Scene>\n</ASSIMP>");
-}
-
-} // end of namespace AssxmlExport
-
-void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- IOStream * out = pIOSystem->Open( pFile, "wt" );
- if (!out) return;
-
- bool shortened = false;
- AssxmlExport::WriteDump( pScene, out, shortened );
-
- pIOSystem->Close( out );
-}
-
-} // end of namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_ASSXML_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/AssxmlExporter.h b/src/3rdparty/assimp/code/AssxmlExporter.h
deleted file mode 100644
index 9694f74a3..000000000
--- a/src/3rdparty/assimp/code/AssxmlExporter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AssxmlExporter.h
- * ASSXML Exporter Main Header
- */
-#ifndef AI_ASSXMLEXPORTER_H_INC
-#define AI_ASSXMLEXPORTER_H_INC
-
-// nothing really needed here - reserved for future use like properties
-
-#endif
diff --git a/src/3rdparty/assimp/code/B3DImporter.cpp b/src/3rdparty/assimp/code/B3DImporter.cpp
deleted file mode 100644
index bc888fb66..000000000
--- a/src/3rdparty/assimp/code/B3DImporter.cpp
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 B3DImporter.cpp
- * @brief Implementation of the b3d importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-
-// internal headers
-#include "B3DImporter.h"
-#include "TextureTransform.h"
-#include "ConvertToLHProcess.h"
-#include "StringUtils.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/anim.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-using namespace std;
-
-static const aiImporterDesc desc = {
- "BlitzBasic 3D Importer",
- "",
- "",
- "http://www.blitzbasic.com/",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "b3d"
-};
-
-// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings
-#ifdef _MSC_VER
-# pragma warning (disable: 4018)
-#endif
-
-//#define DEBUG_B3D
-
-template<typename T>
-void DeleteAllBarePointers(std::vector<T>& x)
-{
- for(auto p : x)
- {
- delete p;
- }
-}
-
-B3DImporter::~B3DImporter()
-{
- DeleteAllBarePointers(_animations);
-}
-
-// ------------------------------------------------------------------------------------------------
-bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{
-
- size_t pos=pFile.find_last_of( '.' );
- if( pos==string::npos ) return false;
-
- string ext=pFile.substr( pos+1 );
- if( ext.size()!=3 ) return false;
-
- return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader meta information
-const aiImporterDesc* B3DImporter::GetInfo () const
-{
- return &desc;
-}
-
-#ifdef DEBUG_B3D
- extern "C"{ void _stdcall AllocConsole(); }
-#endif
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){
-
-#ifdef DEBUG_B3D
- AllocConsole();
- freopen( "conin$","r",stdin );
- freopen( "conout$","w",stdout );
- freopen( "conout$","w",stderr );
- cout<<"Hello world from the B3DImporter!"<<endl;
-#endif
-
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open B3D file " + pFile + ".");
-
- // check whether the .b3d file is large enough to contain
- // at least one chunk.
- size_t fileSize = file->FileSize();
- if( fileSize<8 ) throw DeadlyImportError( "B3D File is too small.");
-
- _pos=0;
- _buf.resize( fileSize );
- file->Read( &_buf[0],1,fileSize );
- _stack.clear();
-
- ReadBB3D( pScene );
-}
-
-// ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void B3DImporter::Oops(){
- throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
-}
-
-// ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void B3DImporter::Fail( string str ){
-#ifdef DEBUG_B3D
- cout<<"Error in B3D file data: "<<str<<endl;
-#endif
- throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str );
-}
-
-// ------------------------------------------------------------------------------------------------
-int B3DImporter::ReadByte(){
- if( _pos<_buf.size() ) return _buf[_pos++];
- Fail( "EOF" );
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-int B3DImporter::ReadInt(){
- if( _pos+4<=_buf.size() ){
- int n;
- memcpy(&n, &_buf[_pos], 4);
- _pos+=4;
- return n;
- }
- Fail( "EOF" );
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-float B3DImporter::ReadFloat(){
- if( _pos+4<=_buf.size() ){
- float n;
- memcpy(&n, &_buf[_pos], 4);
- _pos+=4;
- return n;
- }
- Fail( "EOF" );
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector2D B3DImporter::ReadVec2(){
- float x=ReadFloat();
- float y=ReadFloat();
- return aiVector2D( x,y );
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector3D B3DImporter::ReadVec3(){
- float x=ReadFloat();
- float y=ReadFloat();
- float z=ReadFloat();
- return aiVector3D( x,y,z );
-}
-
-// ------------------------------------------------------------------------------------------------
-aiQuaternion B3DImporter::ReadQuat(){
- // (aramis_acg) Fix to adapt the loader to changed quat orientation
- float w=-ReadFloat();
- float x=ReadFloat();
- float y=ReadFloat();
- float z=ReadFloat();
- return aiQuaternion( w,x,y,z );
-}
-
-// ------------------------------------------------------------------------------------------------
-string B3DImporter::ReadString(){
- string str;
- while( _pos<_buf.size() ){
- char c=(char)ReadByte();
- if( !c ) return str;
- str+=c;
- }
- Fail( "EOF" );
- return string();
-}
-
-// ------------------------------------------------------------------------------------------------
-string B3DImporter::ReadChunk(){
- string tag;
- for( int i=0;i<4;++i ){
- tag+=char( ReadByte() );
- }
-#ifdef DEBUG_B3D
-// cout<<"ReadChunk:"<<tag<<endl;
-#endif
- unsigned sz=(unsigned)ReadInt();
- _stack.push_back( _pos+sz );
- return tag;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ExitChunk(){
- _pos=_stack.back();
- _stack.pop_back();
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned B3DImporter::ChunkSize(){
- return _stack.back()-_pos;
-}
-// ------------------------------------------------------------------------------------------------
-
-template<class T>
-T *B3DImporter::to_array( const vector<T> &v ){
- if( v.empty() ) {
- return 0;
- }
- T *p=new T[ v.size() ];
- for( size_t i=0;i<v.size();++i ){
- p[i]=v[i];
- }
- return p;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadTEXS(){
- while( ChunkSize() ){
- string name=ReadString();
- /*int flags=*/ReadInt();
- /*int blend=*/ReadInt();
- /*aiVector2D pos=*/ReadVec2();
- /*aiVector2D scale=*/ReadVec2();
- /*float rot=*/ReadFloat();
-
- _textures.push_back( name );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBRUS(){
- int n_texs=ReadInt();
- if( n_texs<0 || n_texs>8 ){
- Fail( "Bad texture count" );
- }
- while( ChunkSize() ){
- string name=ReadString();
- aiVector3D color=ReadVec3();
- float alpha=ReadFloat();
- float shiny=ReadFloat();
- /*int blend=**/ReadInt();
- int fx=ReadInt();
-
- aiMaterial *mat=new aiMaterial;
- _materials.push_back( mat );
-
- // Name
- aiString ainame( name );
- mat->AddProperty( &ainame,AI_MATKEY_NAME );
-
- // Diffuse color
- mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );
-
- // Opacity
- mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );
-
- // Specular color
- aiColor3D speccolor( shiny,shiny,shiny );
- mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR );
-
- // Specular power
- float specpow=shiny*128;
- mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS );
-
- // Double sided
- if( fx & 0x10 ){
- int i=1;
- mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED );
- }
-
- //Textures
- for( int i=0;i<n_texs;++i ){
- int texid=ReadInt();
- if( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){
- Fail( "Bad texture id" );
- }
- if( i==0 && texid>=0 ){
- aiString texname( _textures[texid] );
- mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadVRTS(){
- _vflags=ReadInt();
- _tcsets=ReadInt();
- _tcsize=ReadInt();
- if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
- Fail( "Bad texcoord data" );
- }
-
- int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
- int n_verts=ChunkSize()/sz;
-
- int v0=static_cast<int>(_vertices.size());
- _vertices.resize( v0+n_verts );
-
- for( int i=0;i<n_verts;++i ){
- Vertex &v=_vertices[v0+i];
-
- memset( v.bones,0,sizeof(v.bones) );
- memset( v.weights,0,sizeof(v.weights) );
-
- v.vertex=ReadVec3();
-
- if( _vflags & 1 ) v.normal=ReadVec3();
-
- if( _vflags & 2 ) ReadQuat(); //skip v 4bytes...
-
- for( int i=0;i<_tcsets;++i ){
- float t[4]={0,0,0,0};
- for( int j=0;j<_tcsize;++j ){
- t[j]=ReadFloat();
- }
- t[1]=1-t[1];
- if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadTRIS( int v0 ){
- int matid=ReadInt();
- if( matid==-1 ){
- matid=0;
- }else if( matid<0 || matid>=(int)_materials.size() ){
-#ifdef DEBUG_B3D
- cout<<"material id="<<matid<<endl;
-#endif
- Fail( "Bad material id" );
- }
-
- aiMesh *mesh=new aiMesh;
- _meshes.push_back( mesh );
-
- mesh->mMaterialIndex=matid;
- mesh->mNumFaces=0;
- mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;
-
- int n_tris=ChunkSize()/12;
- aiFace *face=mesh->mFaces=new aiFace[n_tris];
-
- for( int i=0;i<n_tris;++i ){
- int i0=ReadInt()+v0;
- int i1=ReadInt()+v0;
- int i2=ReadInt()+v0;
- if( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){
-#ifdef DEBUG_B3D
- cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
-#endif
- Fail( "Bad triangle index" );
- continue;
- }
- face->mNumIndices=3;
- face->mIndices=new unsigned[3];
- face->mIndices[0]=i0;
- face->mIndices[1]=i1;
- face->mIndices[2]=i2;
- ++mesh->mNumFaces;
- ++face;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadMESH(){
- /*int matid=*/ReadInt();
-
- int v0= static_cast<int>(_vertices.size());
-
- while( ChunkSize() ){
- string t=ReadChunk();
- if( t=="VRTS" ){
- ReadVRTS();
- }else if( t=="TRIS" ){
- ReadTRIS( v0 );
- }
- ExitChunk();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBONE( int id ){
- while( ChunkSize() ){
- int vertex=ReadInt();
- float weight=ReadFloat();
- if( vertex<0 || vertex>=(int)_vertices.size() ){
- Fail( "Bad vertex index" );
- }
-
- Vertex &v=_vertices[vertex];
- int i;
- for( i=0;i<4;++i ){
- if( !v.weights[i] ){
- v.bones[i]=id;
- v.weights[i]=weight;
- break;
- }
- }
-#ifdef DEBUG_B3D
- if( i==4 ){
- cout<<"Too many bone weights"<<endl;
- }
-#endif
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
- vector<aiVectorKey> trans,scale;
- vector<aiQuatKey> rot;
- int flags=ReadInt();
- while( ChunkSize() ){
- int frame=ReadInt();
- if( flags & 1 ){
- trans.push_back( aiVectorKey( frame,ReadVec3() ) );
- }
- if( flags & 2 ){
- scale.push_back( aiVectorKey( frame,ReadVec3() ) );
- }
- if( flags & 4 ){
- rot.push_back( aiQuatKey( frame,ReadQuat() ) );
- }
- }
-
- if( flags & 1 ){
- nodeAnim->mNumPositionKeys=static_cast<unsigned int>(trans.size());
- nodeAnim->mPositionKeys=to_array( trans );
- }
-
- if( flags & 2 ){
- nodeAnim->mNumScalingKeys=static_cast<unsigned int>(scale.size());
- nodeAnim->mScalingKeys=to_array( scale );
- }
-
- if( flags & 4 ){
- nodeAnim->mNumRotationKeys=static_cast<unsigned int>(rot.size());
- nodeAnim->mRotationKeys=to_array( rot );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadANIM(){
- /*int flags=*/ReadInt();
- int frames=ReadInt();
- float fps=ReadFloat();
-
- aiAnimation *anim=new aiAnimation;
- _animations.push_back( anim );
-
- anim->mDuration=frames;
- anim->mTicksPerSecond=fps;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode *B3DImporter::ReadNODE( aiNode *parent ){
-
- string name=ReadString();
- aiVector3D t=ReadVec3();
- aiVector3D s=ReadVec3();
- aiQuaternion r=ReadQuat();
-
- aiMatrix4x4 trans,scale,rot;
-
- aiMatrix4x4::Translation( t,trans );
- aiMatrix4x4::Scaling( s,scale );
- rot=aiMatrix4x4( r.GetMatrix() );
-
- aiMatrix4x4 tform=trans * rot * scale;
-
- int nodeid=static_cast<int>(_nodes.size());
-
- aiNode *node=new aiNode( name );
- _nodes.push_back( node );
-
- node->mParent=parent;
- node->mTransformation=tform;
-
- aiNodeAnim *nodeAnim=0;
- vector<unsigned> meshes;
- vector<aiNode*> children;
-
- while( ChunkSize() ){
- string t=ReadChunk();
- if( t=="MESH" ){
- unsigned int n= static_cast<unsigned int>(_meshes.size());
- ReadMESH();
- for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){
- meshes.push_back( i );
- }
- }else if( t=="BONE" ){
- ReadBONE( nodeid );
- }else if( t=="ANIM" ){
- ReadANIM();
- }else if( t=="KEYS" ){
- if( !nodeAnim ){
- nodeAnim=new aiNodeAnim;
- _nodeAnims.push_back( nodeAnim );
- nodeAnim->mNodeName=node->mName;
- }
- ReadKEYS( nodeAnim );
- }else if( t=="NODE" ){
- aiNode *child=ReadNODE( node );
- children.push_back( child );
- }
- ExitChunk();
- }
-
- node->mNumMeshes= static_cast<unsigned int>(meshes.size());
- node->mMeshes=to_array( meshes );
-
- node->mNumChildren=static_cast<unsigned int>(children.size());
- node->mChildren=to_array( children );
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-void B3DImporter::ReadBB3D( aiScene *scene ){
-
- _textures.clear();
-
- _materials.clear();
-
- _vertices.clear();
-
- _meshes.clear();
-
- DeleteAllBarePointers(_nodes);
- _nodes.clear();
-
- _nodeAnims.clear();
-
- DeleteAllBarePointers(_animations);
- _animations.clear();
-
- string t=ReadChunk();
- if( t=="BB3D" ){
- int version=ReadInt();
-
- if (!DefaultLogger::isNullLogger()) {
- char dmp[128];
- ai_snprintf(dmp, 128, "B3D file format version: %i",version);
- DefaultLogger::get()->info(dmp);
- }
-
- while( ChunkSize() ){
- string t=ReadChunk();
- if( t=="TEXS" ){
- ReadTEXS();
- }else if( t=="BRUS" ){
- ReadBRUS();
- }else if( t=="NODE" ){
- ReadNODE( 0 );
- }
- ExitChunk();
- }
- }
- ExitChunk();
-
- if( !_nodes.size() ) Fail( "No nodes" );
-
- if( !_meshes.size() ) Fail( "No meshes" );
-
- //Fix nodes/meshes/bones
- for(size_t i=0;i<_nodes.size();++i ){
- aiNode *node=_nodes[i];
-
- for( size_t j=0;j<node->mNumMeshes;++j ){
- aiMesh *mesh=_meshes[node->mMeshes[j]];
-
- int n_tris=mesh->mNumFaces;
- int n_verts=mesh->mNumVertices=n_tris * 3;
-
- aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
- if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
- if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];
-
- aiFace *face=mesh->mFaces;
-
- vector< vector<aiVertexWeight> > vweights( _nodes.size() );
-
- for( int i=0;i<n_verts;i+=3 ){
- for( int j=0;j<3;++j ){
- Vertex &v=_vertices[face->mIndices[j]];
-
- *mv++=v.vertex;
- if( mn ) *mn++=v.normal;
- if( mc ) *mc++=v.texcoords;
-
- face->mIndices[j]=i+j;
-
- for( int k=0;k<4;++k ){
- if( !v.weights[k] ) break;
-
- int bone=v.bones[k];
- float weight=v.weights[k];
-
- vweights[bone].push_back( aiVertexWeight(i+j,weight) );
- }
- }
- ++face;
- }
-
- vector<aiBone*> bones;
- for(size_t i=0;i<vweights.size();++i ){
- vector<aiVertexWeight> &weights=vweights[i];
- if( !weights.size() ) continue;
-
- aiBone *bone=new aiBone;
- bones.push_back( bone );
-
- aiNode *bnode=_nodes[i];
-
- bone->mName=bnode->mName;
- bone->mNumWeights= static_cast<unsigned int>(weights.size());
- bone->mWeights=to_array( weights );
-
- aiMatrix4x4 mat=bnode->mTransformation;
- while( bnode->mParent ){
- bnode=bnode->mParent;
- mat=bnode->mTransformation * mat;
- }
- bone->mOffsetMatrix=mat.Inverse();
- }
- mesh->mNumBones= static_cast<unsigned int>(bones.size());
- mesh->mBones=to_array( bones );
- }
- }
-
- //nodes
- scene->mRootNode=_nodes[0];
-
- //material
- if( !_materials.size() ){
- _materials.push_back( new aiMaterial );
- }
- scene->mNumMaterials= static_cast<unsigned int>(_materials.size());
- scene->mMaterials=to_array( _materials );
-
- //meshes
- scene->mNumMeshes= static_cast<unsigned int>(_meshes.size());
- scene->mMeshes=to_array( _meshes );
-
- //animations
- if( _animations.size()==1 && _nodeAnims.size() ){
-
- aiAnimation *anim=_animations.back();
- anim->mNumChannels=static_cast<unsigned int>(_nodeAnims.size());
- anim->mChannels=to_array( _nodeAnims );
-
- scene->mNumAnimations=static_cast<unsigned int>(_animations.size());
- scene->mAnimations=to_array( _animations );
- }
-
- // convert to RH
- MakeLeftHandedProcess makeleft;
- makeleft.Execute( scene );
-
- FlipWindingOrderProcess flip;
- flip.Execute( scene );
-}
-
-#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/B3DImporter.h b/src/3rdparty/assimp/code/B3DImporter.h
deleted file mode 100644
index 94644edd4..000000000
--- a/src/3rdparty/assimp/code/B3DImporter.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Definition of the .b3d importer class. */
-
-#ifndef AI_B3DIMPORTER_H_INC
-#define AI_B3DIMPORTER_H_INC
-
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-#include "BaseImporter.h"
-
-#include <vector>
-
-struct aiNodeAnim;
-struct aiNode;
-struct aiAnimation;
-
-namespace Assimp{
-
-class B3DImporter : public BaseImporter{
-public:
- B3DImporter() = default;
- virtual ~B3DImporter();
-
- virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-protected:
-
- virtual const aiImporterDesc* GetInfo () const;
- virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
-private:
-
- int ReadByte();
- int ReadInt();
- float ReadFloat();
- aiVector2D ReadVec2();
- aiVector3D ReadVec3();
- aiQuaternion ReadQuat();
- std::string ReadString();
- std::string ReadChunk();
- void ExitChunk();
- unsigned ChunkSize();
-
- template<class T>
- T *to_array( const std::vector<T> &v );
-
- struct Vertex{
- aiVector3D vertex;
- aiVector3D normal;
- aiVector3D texcoords;
- unsigned char bones[4];
- float weights[4];
- };
-
- AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
- AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
-
- void ReadTEXS();
- void ReadBRUS();
-
- void ReadVRTS();
- void ReadTRIS( int v0 );
- void ReadMESH();
- void ReadBONE( int id );
- void ReadKEYS( aiNodeAnim *nodeAnim );
- void ReadANIM();
-
- aiNode *ReadNODE( aiNode *parent );
-
- void ReadBB3D( aiScene *scene );
-
- unsigned _pos;
-// unsigned _size;
- std::vector<unsigned char> _buf;
- std::vector<unsigned> _stack;
-
- std::vector<std::string> _textures;
- std::vector<aiMaterial*> _materials;
-
- int _vflags,_tcsets,_tcsize;
- std::vector<Vertex> _vertices;
-
- std::vector<aiNode*> _nodes;
- std::vector<aiMesh*> _meshes;
- std::vector<aiNodeAnim*> _nodeAnims;
- std::vector<aiAnimation*> _animations;
-};
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/BVHLoader.cpp b/src/3rdparty/assimp/code/BVHLoader.cpp
deleted file mode 100644
index c20cbec4e..000000000
--- a/src/3rdparty/assimp/code/BVHLoader.cpp
+++ /dev/null
@@ -1,545 +0,0 @@
-/** Implementation of the BVH loader */
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_BVH_IMPORTER
-
-#include "BVHLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-#include <assimp/Importer.hpp>
-#include <memory>
-#include "TinyFormatter.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-
-static const aiImporterDesc desc = {
- "BVH Importer (MoCap)",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "bvh"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BVHLoader::BVHLoader()
- : mLine(),
- mAnimTickDuration(),
- mAnimNumFrames(),
- noSkeletonMesh()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BVHLoader::~BVHLoader()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool BVHLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if( extension == "bvh")
- return true;
-
- if ((!extension.length() || cs) && pIOHandler) {
- const char* tokens[] = {"HIERARCHY"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-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
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- mFileName = pFile;
-
- // read file into memory
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- size_t fileSize = file->FileSize();
- if( fileSize == 0)
- throw DeadlyImportError( "File is too small.");
-
- mBuffer.resize( fileSize);
- file->Read( &mBuffer.front(), 1, fileSize);
-
- // start reading
- mReader = mBuffer.begin();
- mLine = 1;
- ReadStructure( 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);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the file
-void BVHLoader::ReadStructure( aiScene* pScene)
-{
- // first comes hierarchy
- std::string header = GetNextToken();
- if( header != "HIERARCHY")
- ThrowException( "Expected header string \"HIERARCHY\".");
- ReadHierarchy( pScene);
-
- // then comes the motion data
- std::string motion = GetNextToken();
- if( motion != "MOTION")
- ThrowException( "Expected beginning of motion data \"MOTION\".");
- ReadMotion( pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the hierarchy
-void BVHLoader::ReadHierarchy( aiScene* pScene)
-{
- std::string root = GetNextToken();
- if( root != "ROOT")
- ThrowException( "Expected root node \"ROOT\".");
-
- // Go read the hierarchy from here
- pScene->mRootNode = ReadNode();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a node and recursively its childs and returns the created node;
-aiNode* BVHLoader::ReadNode()
-{
- // first token is name
- std::string nodeName = GetNextToken();
- if( nodeName.empty() || nodeName == "{")
- ThrowException( format() << "Expected node name, but found \"" << nodeName << "\"." );
-
- // then an opening brace should follow
- std::string openBrace = GetNextToken();
- if( openBrace != "{")
- ThrowException( format() << "Expected opening brace \"{\", but found \"" << openBrace << "\"." );
-
- // Create a node
- aiNode* node = new aiNode( nodeName);
- std::vector<aiNode*> childNodes;
-
- // and create an bone entry for it
- mNodes.push_back( Node( node));
- Node& internNode = mNodes.back();
-
- // now read the node's contents
- while( 1)
- {
- std::string token = GetNextToken();
-
- // node offset to parent node
- if( token == "OFFSET")
- ReadNodeOffset( node);
- else if( token == "CHANNELS")
- ReadNodeChannels( internNode);
- else if( token == "JOINT")
- {
- // child node follows
- aiNode* child = ReadNode();
- child->mParent = node;
- childNodes.push_back( child);
- }
- else if( token == "End")
- {
- // The real symbol is "End Site". Second part comes in a separate token
- std::string siteToken = GetNextToken();
- if( siteToken != "Site")
- ThrowException( format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\"." );
-
- aiNode* child = ReadEndSite( nodeName);
- child->mParent = node;
- childNodes.push_back( child);
- }
- else if( token == "}")
- {
- // we're done with that part of the hierarchy
- break;
- } else
- {
- // everything else is a parse error
- ThrowException( format() << "Unknown keyword \"" << token << "\"." );
- }
- }
-
- // add the child nodes if there are any
- if( childNodes.size() > 0)
- {
- node->mNumChildren = static_cast<unsigned int>(childNodes.size());
- node->mChildren = new aiNode*[node->mNumChildren];
- std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
- }
-
- // and return the sub-hierarchy we built here
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an end node and returns the created node.
-aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
-{
- // check opening brace
- std::string openBrace = GetNextToken();
- if( openBrace != "{")
- ThrowException( format() << "Expected opening brace \"{\", but found \"" << openBrace << "\".");
-
- // Create a node
- aiNode* node = new aiNode( "EndSite_" + pParentName);
-
- // now read the node's contents. Only possible entry is "OFFSET"
- while( 1)
- {
- std::string token = GetNextToken();
-
- // end node's offset
- if( token == "OFFSET")
- {
- ReadNodeOffset( node);
- }
- else if( token == "}")
- {
- // we're done with the end node
- break;
- } else
- {
- // everything else is a parse error
- ThrowException( format() << "Unknown keyword \"" << token << "\"." );
- }
- }
-
- // and return the sub-hierarchy we built here
- return node;
-}
-// ------------------------------------------------------------------------------------------------
-// Reads a node offset for the given node
-void BVHLoader::ReadNodeOffset( aiNode* pNode)
-{
- // Offset consists of three floats to read
- aiVector3D offset;
- offset.x = GetNextTokenAsFloat();
- offset.y = GetNextTokenAsFloat();
- offset.z = GetNextTokenAsFloat();
-
- // build a transformation matrix from it
- pNode->mTransformation = aiMatrix4x4( 1.0f, 0.0f, 0.0f, offset.x, 0.0f, 1.0f, 0.0f, offset.y,
- 0.0f, 0.0f, 1.0f, offset.z, 0.0f, 0.0f, 0.0f, 1.0f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the animation channels for the given node
-void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
-{
- // number of channels. Use the float reader because we're lazy
- float numChannelsFloat = GetNextTokenAsFloat();
- unsigned int numChannels = (unsigned int) numChannelsFloat;
-
- for( unsigned int a = 0; a < numChannels; a++)
- {
- std::string channelToken = GetNextToken();
-
- if( channelToken == "Xposition")
- pNode.mChannels.push_back( Channel_PositionX);
- else if( channelToken == "Yposition")
- pNode.mChannels.push_back( Channel_PositionY);
- else if( channelToken == "Zposition")
- pNode.mChannels.push_back( Channel_PositionZ);
- else if( channelToken == "Xrotation")
- pNode.mChannels.push_back( Channel_RotationX);
- else if( channelToken == "Yrotation")
- pNode.mChannels.push_back( Channel_RotationY);
- else if( channelToken == "Zrotation")
- pNode.mChannels.push_back( Channel_RotationZ);
- else
- ThrowException( format() << "Invalid channel specifier \"" << channelToken << "\"." );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the motion data
-void BVHLoader::ReadMotion( aiScene* /*pScene*/)
-{
- // Read number of frames
- std::string tokenFrames = GetNextToken();
- if( tokenFrames != "Frames:")
- ThrowException( format() << "Expected frame count \"Frames:\", but found \"" << tokenFrames << "\".");
-
- float numFramesFloat = GetNextTokenAsFloat();
- mAnimNumFrames = (unsigned int) numFramesFloat;
-
- // Read frame duration
- std::string tokenDuration1 = GetNextToken();
- std::string tokenDuration2 = GetNextToken();
- if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
- ThrowException( format() << "Expected frame duration \"Frame Time:\", but found \"" << tokenDuration1 << " " << tokenDuration2 << "\"." );
-
- mAnimTickDuration = GetNextTokenAsFloat();
-
- // resize value vectors for each node
- for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
- it->mChannelValues.reserve( it->mChannels.size() * mAnimNumFrames);
-
- // now read all the data and store it in the corresponding node's value vector
- for( unsigned int frame = 0; frame < mAnimNumFrames; ++frame)
- {
- // on each line read the values for all nodes
- for( std::vector<Node>::iterator it = mNodes.begin(); it != mNodes.end(); ++it)
- {
- // get as many values as the node has channels
- for( unsigned int c = 0; c < it->mChannels.size(); ++c)
- it->mChannelValues.push_back( GetNextTokenAsFloat());
- }
-
- // after one frame worth of values for all nodes there should be a newline, but we better don't rely on it
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Retrieves the next token
-std::string BVHLoader::GetNextToken()
-{
- // skip any preceding whitespace
- while( mReader != mBuffer.end())
- {
- if( !isspace( *mReader))
- break;
-
- // count lines
- if( *mReader == '\n')
- mLine++;
-
- ++mReader;
- }
-
- // collect all chars till the next whitespace. BVH is easy in respect to that.
- std::string token;
- while( mReader != mBuffer.end())
- {
- if( isspace( *mReader))
- break;
-
- token.push_back( *mReader);
- ++mReader;
-
- // little extra logic to make sure braces are counted correctly
- if( token == "{" || token == "}")
- break;
- }
-
- // empty token means end of file, which is just fine
- return token;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the next token as a float
-float BVHLoader::GetNextTokenAsFloat()
-{
- std::string token = GetNextToken();
- if( token.empty())
- ThrowException( "Unexpected end of file while trying to read a float");
-
- // check if the float is valid by testing if the atof() function consumed every char of the token
- const char* ctoken = token.c_str();
- float result = 0.0f;
- ctoken = fast_atoreal_move<float>( ctoken, result);
-
- if( ctoken != token.c_str() + token.length())
- ThrowException( format() << "Expected a floating point number, but found \"" << token << "\"." );
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Aborts the file reading with an exception
-AI_WONT_RETURN void BVHLoader::ThrowException( const std::string& pError)
-{
- throw DeadlyImportError( format() << mFileName << ":" << mLine << " - " << pError);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs an animation for the motion data and stores it in the given scene
-void BVHLoader::CreateAnimation( aiScene* pScene)
-{
- // create the animation
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- aiAnimation* anim = new aiAnimation;
- pScene->mAnimations[0] = anim;
-
- // put down the basic parameters
- anim->mName.Set( "Motion");
- anim->mTicksPerSecond = 1.0 / double( mAnimTickDuration);
- anim->mDuration = double( mAnimNumFrames - 1);
-
- // now generate the tracks for all nodes
- anim->mNumChannels = static_cast<unsigned int>(mNodes.size());
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
-
- // FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
- for (unsigned int i = 0; i < anim->mNumChannels;++i)
- anim->mChannels[i] = NULL;
-
- for( unsigned int a = 0; a < anim->mNumChannels; a++)
- {
- const Node& node = mNodes[a];
- const std::string nodeName = std::string( node.mNode->mName.data );
- aiNodeAnim* nodeAnim = new aiNodeAnim;
- anim->mChannels[a] = nodeAnim;
- nodeAnim->mNodeName.Set( nodeName);
-
- // translational part, if given
- if( node.mChannels.size() == 6)
- {
- nodeAnim->mNumPositionKeys = mAnimNumFrames;
- nodeAnim->mPositionKeys = new aiVectorKey[mAnimNumFrames];
- aiVectorKey* poskey = nodeAnim->mPositionKeys;
- for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
- {
- poskey->mTime = double( fr);
-
- // Now compute all translations in the right order
- for( unsigned int channel = 0; channel < 3; ++channel)
- {
- switch( node.mChannels[channel])
- {
- case Channel_PositionX: poskey->mValue.x = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- case Channel_PositionY: poskey->mValue.y = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- case Channel_PositionZ: poskey->mValue.z = node.mChannelValues[fr * node.mChannels.size() + channel]; break;
- default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
- }
- }
- ++poskey;
- }
- } else
- {
- // if no translation part is given, put a default sequence
- aiVector3D nodePos( node.mNode->mTransformation.a4, node.mNode->mTransformation.b4, node.mNode->mTransformation.c4);
- nodeAnim->mNumPositionKeys = 1;
- nodeAnim->mPositionKeys = new aiVectorKey[1];
- nodeAnim->mPositionKeys[0].mTime = 0.0;
- nodeAnim->mPositionKeys[0].mValue = nodePos;
- }
-
- // rotation part. Always present. First find value offsets
- {
- unsigned int rotOffset = 0;
- if( node.mChannels.size() == 6)
- {
- // Offset all further calculations
- rotOffset = 3;
- }
-
- // Then create the number of rotation keys
- nodeAnim->mNumRotationKeys = mAnimNumFrames;
- nodeAnim->mRotationKeys = new aiQuatKey[mAnimNumFrames];
- aiQuatKey* rotkey = nodeAnim->mRotationKeys;
- for( unsigned int fr = 0; fr < mAnimNumFrames; ++fr)
- {
- aiMatrix4x4 temp;
- aiMatrix3x3 rotMatrix;
-
- for( unsigned int channel = 0; channel < 3; ++channel)
- {
- // translate ZXY euler angels into a quaternion
- const float angle = node.mChannelValues[fr * node.mChannels.size() + rotOffset + channel] * float( AI_MATH_PI) / 180.0f;
-
- // Compute rotation transformations in the right order
- switch (node.mChannels[rotOffset+channel])
- {
- case Channel_RotationX: aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- case Channel_RotationY: aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- case Channel_RotationZ: aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp); break;
- default: throw DeadlyImportError( "Unexpected animation channel setup at node " + nodeName );
- }
- }
-
- rotkey->mTime = double( fr);
- rotkey->mValue = aiQuaternion( rotMatrix);
- ++rotkey;
- }
- }
-
- // scaling part. Always just a default track
- {
- nodeAnim->mNumScalingKeys = 1;
- nodeAnim->mScalingKeys = new aiVectorKey[1];
- nodeAnim->mScalingKeys[0].mTime = 0.0;
- nodeAnim->mScalingKeys[0].mValue.Set( 1.0f, 1.0f, 1.0f);
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
diff --git a/src/3rdparty/assimp/code/BVHLoader.h b/src/3rdparty/assimp/code/BVHLoader.h
deleted file mode 100644
index 6a89e1aaf..000000000
--- a/src/3rdparty/assimp/code/BVHLoader.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/** Defines the BHV motion capturing loader class */
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BVHLoader.h
- * @brief Biovision BVH import
- */
-
-#ifndef AI_BVHLOADER_H_INC
-#define AI_BVHLOADER_H_INC
-
-#include "BaseImporter.h"
-
-struct aiNode;
-
-namespace Assimp
-{
-
-// --------------------------------------------------------------------------------
-/** Loader class to read Motion Capturing data from a .bvh file.
- *
- * This format only contains a hierarchy of joints and a series of keyframes for
- * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
- * inside the loader just to be able to see something.
-*/
-class BVHLoader : public BaseImporter
-{
-
- /** Possible animation channels for which the motion data holds the values */
- enum ChannelType
- {
- Channel_PositionX,
- Channel_PositionY,
- Channel_PositionZ,
- Channel_RotationX,
- Channel_RotationY,
- Channel_RotationZ
- };
-
- /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
- struct Node
- {
- const aiNode* mNode;
- std::vector<ChannelType> mChannels;
- std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
-
- Node() { }
- explicit Node( const aiNode* pNode) : mNode( pNode) { }
- };
-
-public:
-
- BVHLoader();
- ~BVHLoader();
-
-public:
- /** Returns whether the class can handle the format of the given file.
- * 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:
-
-
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
-protected:
- /** Reads the file */
- void ReadStructure( aiScene* pScene);
-
- /** Reads the hierarchy */
- void ReadHierarchy( aiScene* pScene);
-
- /** Reads a node and recursively its childs and returns the created node. */
- aiNode* ReadNode();
-
- /** Reads an end node and returns the created node. */
- aiNode* ReadEndSite( const std::string& pParentName);
-
- /** Reads a node offset for the given node */
- void ReadNodeOffset( aiNode* pNode);
-
- /** Reads the animation channels into the given node */
- void ReadNodeChannels( BVHLoader::Node& pNode);
-
- /** Reads the motion data */
- void ReadMotion( aiScene* pScene);
-
- /** Retrieves the next token */
- std::string GetNextToken();
-
- /** Reads the next token as a float */
- float GetNextTokenAsFloat();
-
- /** Aborts the file reading with an exception */
- AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
-
- /** Constructs an animation for the motion data and stores it in the given scene */
- void CreateAnimation( aiScene* pScene);
-
-protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** Buffer to hold the loaded file */
- std::vector<char> mBuffer;
-
- /** Next char to read from the buffer */
- std::vector<char>::const_iterator mReader;
-
- /** Current line, for error messages */
- unsigned int mLine;
-
- /** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
- * Also contain the motion data for the node's channels
- */
- std::vector<Node> mNodes;
-
- /** basic Animation parameters */
- float mAnimTickDuration;
- unsigned int mAnimNumFrames;
-
- bool noSkeletonMesh;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_BVHLOADER_H_INC
diff --git a/src/3rdparty/assimp/code/BaseImporter.cpp b/src/3rdparty/assimp/code/BaseImporter.cpp
deleted file mode 100644
index b9b9eeb71..000000000
--- a/src/3rdparty/assimp/code/BaseImporter.cpp
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BaseImporter.cpp
- * @brief Implementation of BaseImporter
- */
-
-#include "BaseImporter.h"
-#include "FileSystemFilter.h"
-#include "Importer.h"
-#include "ByteSwapper.h"
-#include <assimp/scene.h>
-#include <assimp/Importer.hpp>
-#include <assimp/postprocess.h>
-#include <assimp/importerdesc.h>
-#include <ios>
-#include <list>
-#include <memory>
-#include <sstream>
-#include <cctype>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BaseImporter::BaseImporter()
-: m_progress()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BaseImporter::~BaseImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file and returns the imported data.
-aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
-{
- m_progress = pImp->GetProgressHandler();
- ai_assert(m_progress);
-
- // Gather configuration properties for this run
- SetupProperties( pImp );
-
- // Construct a file system filter to improve our success ratio at reading external files
- FileSystemFilter filter(pFile,pIOHandler);
-
- // create a scene object to hold the data
- std::unique_ptr<aiScene> sc(new aiScene());
-
- // dispatch importing
- try
- {
- InternReadFile( pFile, sc.get(), &filter);
-
- } catch( const std::exception& err ) {
- // extract error description
- m_ErrorText = err.what();
- DefaultLogger::get()->error(m_ErrorText);
- return NULL;
- }
-
- // return what we gathered from the import.
- return sc.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // the default implementation does nothing
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
-{
- const aiImporterDesc* desc = GetInfo();
- ai_assert(desc != NULL);
-
- const char* ext = desc->mFileExtensions;
- ai_assert(ext != NULL);
-
- const char* last = ext;
- do {
- if (!*ext || *ext == ' ') {
- extensions.insert(std::string(last,ext-last));
- ai_assert(ext-last > 0);
- last = ext;
- while(*last == ' ') {
- ++last;
- }
- }
- }
- while(*ext++);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ bool BaseImporter::SearchFileHeaderForToken( IOSystem* pIOHandler,
- const std::string& pFile,
- const char** tokens,
- unsigned int numTokens,
- unsigned int searchBytes /* = 200 */,
- bool tokensSol /* false */)
-{
- ai_assert( NULL != tokens );
- ai_assert( 0 != numTokens );
- ai_assert( 0 != searchBytes);
-
- if (!pIOHandler)
- return false;
-
- std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
- if (pStream.get() ) {
- // read 200 characters from the file
- std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
- char* buffer = _buffer.get();
- if( NULL == buffer ) {
- return false;
- }
-
- const size_t read = pStream->Read(buffer,1,searchBytes);
- if( !read ) {
- return false;
- }
-
- for( size_t i = 0; i < read; ++i ) {
- buffer[ i ] = ::tolower( buffer[ i ] );
- }
-
- // It is not a proper handling of unicode files here ...
- // ehm ... but it works in most cases.
- char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
- while (cur != end) {
- if( *cur ) {
- *cur2++ = *cur;
- }
- ++cur;
- }
- *cur2 = '\0';
-
- for (unsigned int i = 0; i < numTokens;++i) {
- ai_assert(NULL != tokens[i]);
- const char* r = strstr(buffer,tokens[i]);
- if( !r ) {
- continue;
- }
- // We got a match, either we don't care where it is, or it happens to
- // be in the beginning of the file / line
- if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
- DefaultLogger::get()->debug(std::string("Found positive match for header keyword: ") + tokens[i]);
- return true;
- }
- }
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Simple check for file extension
-/*static*/ bool BaseImporter::SimpleExtensionCheck (const std::string& pFile,
- const char* ext0,
- const char* ext1,
- const char* ext2)
-{
- std::string::size_type pos = pFile.find_last_of('.');
-
- // no file extension - can't read
- if( pos == std::string::npos)
- return false;
-
- const char* ext_real = & pFile[ pos+1 ];
- if( !ASSIMP_stricmp(ext_real,ext0) )
- return true;
-
- // check for other, optional, file extensions
- if (ext1 && !ASSIMP_stricmp(ext_real,ext1))
- return true;
-
- if (ext2 && !ASSIMP_stricmp(ext_real,ext2))
- return true;
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get file extension from path
-/*static*/ std::string BaseImporter::GetExtension (const std::string& pFile)
-{
- std::string::size_type pos = pFile.find_last_of('.');
-
- // no file extension at all
- if( pos == std::string::npos)
- return "";
-
- std::string ret = pFile.substr(pos+1);
- std::transform(ret.begin(),ret.end(),ret.begin(),::tolower); // thanks to Andy Maloney for the hint
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check for magic bytes at the beginning of the file.
-/* static */ bool BaseImporter::CheckMagicToken(IOSystem* pIOHandler, const std::string& pFile,
- const void* _magic, unsigned int num, unsigned int offset, unsigned int size)
-{
- ai_assert(size <= 16 && _magic);
-
- if (!pIOHandler) {
- return false;
- }
- union {
- const char* magic;
- const uint16_t* magic_u16;
- const uint32_t* magic_u32;
- };
- magic = reinterpret_cast<const char*>(_magic);
- std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
- if (pStream.get() ) {
-
- // skip to offset
- pStream->Seek(offset,aiOrigin_SET);
-
- // read 'size' characters from the file
- union {
- char data[16];
- uint16_t data_u16[8];
- uint32_t data_u32[4];
- };
- if(size != pStream->Read(data,1,size)) {
- return false;
- }
-
- for (unsigned int i = 0; i < num; ++i) {
- // also check against big endian versions of tokens with size 2,4
- // that's just for convenience, the chance that we cause conflicts
- // is quite low and it can save some lines and prevent nasty bugs
- if (2 == size) {
- uint16_t rev = *magic_u16;
- ByteSwap::Swap(&rev);
- if (data_u16[0] == *magic_u16 || data_u16[0] == rev) {
- return true;
- }
- }
- else if (4 == size) {
- uint32_t rev = *magic_u32;
- ByteSwap::Swap(&rev);
- if (data_u32[0] == *magic_u32 || data_u32[0] == rev) {
- return true;
- }
- }
- else {
- // any length ... just compare
- if(!memcmp(magic,data,size)) {
- return true;
- }
- }
- magic += size;
- }
- }
- return false;
-}
-
-#include "../contrib/utf8cpp/source/utf8.h"
-
-// ------------------------------------------------------------------------------------------------
-// Convert to UTF8 data
-void BaseImporter::ConvertToUTF8(std::vector<char>& data)
-{
- //ConversionResult result;
- if(data.size() < 8) {
- throw DeadlyImportError("File is too small");
- }
-
- // UTF 8 with BOM
- if((uint8_t)data[0] == 0xEF && (uint8_t)data[1] == 0xBB && (uint8_t)data[2] == 0xBF) {
- DefaultLogger::get()->debug("Found UTF-8 BOM ...");
-
- std::copy(data.begin()+3,data.end(),data.begin());
- data.resize(data.size()-3);
- return;
- }
-
-
- // UTF 32 BE with BOM
- if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
-
- // swap the endianness ..
- for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
- AI_SWAP4P(p);
- }
- }
-
- // UTF 32 LE with BOM
- if(*((uint32_t*)&data.front()) == 0x0000FFFE) {
- DefaultLogger::get()->debug("Found UTF-32 BOM ...");
-
- std::vector<char> output;
- int *ptr = (int*)&data[ 0 ];
- int *end = ptr + ( data.size() / sizeof(int) ) +1;
- utf8::utf32to8( ptr, end, back_inserter(output));
- return;
- }
-
- // UTF 16 BE with BOM
- if(*((uint16_t*)&data.front()) == 0xFFFE) {
-
- // swap the endianness ..
- for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
- ByteSwap::Swap2(p);
- }
- }
-
- // UTF 16 LE with BOM
- if(*((uint16_t*)&data.front()) == 0xFEFF) {
- DefaultLogger::get()->debug("Found UTF-16 BOM ...");
-
- std::vector<unsigned char> output;
- utf8::utf16to8(data.begin(), data.end(), back_inserter(output));
- return;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert to UTF8 data to ISO-8859-1
-void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
-{
- size_t size = data.size();
- size_t i = 0, j = 0;
-
- while(i < size) {
- if ((unsigned char) data[i] < (size_t) 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,
- TextFileMode mode)
-{
- ai_assert(NULL != stream);
-
- const size_t fileSize = stream->FileSize();
- if (mode == FORBID_EMPTY) {
- if(!fileSize) {
- throw DeadlyImportError("File is empty");
- }
- }
-
- data.reserve(fileSize+1);
- data.resize(fileSize);
- if(fileSize > 0) {
- if(fileSize != stream->Read( &data[0], 1, fileSize)) {
- throw DeadlyImportError("File read error");
- }
-
- ConvertToUTF8(data);
- }
-
- // append a binary zero to simplify string parsing
- data.push_back(0);
-}
-
-// ------------------------------------------------------------------------------------------------
-namespace Assimp {
- // Represents an import request
- struct LoadRequest {
- LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
- : file(_file)
- , flags(_flags)
- , refCnt(1)
- , scene(NULL)
- , loaded(false)
- , id(_id) {
- if ( _map ) {
- map = *_map;
- }
- }
-
- bool operator== ( const std::string& f ) const {
- return file == f;
- }
-
- const std::string file;
- unsigned int flags;
- unsigned int refCnt;
- aiScene *scene;
- bool loaded;
- BatchLoader::PropertyMap map;
- unsigned int id;
- };
-}
-
-// ------------------------------------------------------------------------------------------------
-// BatchLoader::pimpl data structure
-struct Assimp::BatchData {
- BatchData( IOSystem* pIO, bool validate )
- : pIOSystem( pIO )
- , pImporter( nullptr )
- , next_id(0xffff)
- , validate( validate ) {
- ai_assert( NULL != pIO );
-
- pImporter = new Importer();
- pImporter->SetIOHandler( pIO );
- }
-
- ~BatchData() {
- pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */
- delete pImporter;
- }
-
- // IO system to be used for all imports
- IOSystem* pIOSystem;
-
- // Importer used to load all meshes
- Importer* pImporter;
-
- // List of all imports
- std::list<LoadRequest> requests;
-
- // Base path
- std::string pathBase;
-
- // Id for next item
- unsigned int next_id;
-
- // Validation enabled state
- bool validate;
-};
-
-typedef std::list<LoadRequest>::iterator LoadReqIt;
-
-// ------------------------------------------------------------------------------------------------
-BatchLoader::BatchLoader(IOSystem* pIO, bool validate )
-{
- ai_assert(NULL != pIO);
-
- m_data = new BatchData( pIO, validate );
-}
-
-// ------------------------------------------------------------------------------------------------
-BatchLoader::~BatchLoader()
-{
- // delete all scenes what have not been polled by the user
- for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
- delete (*it).scene;
- }
- delete m_data;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BatchLoader::setValidation( bool enabled ) {
- m_data->validate = enabled;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool BatchLoader::getValidation() const {
- return m_data->validate;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int BatchLoader::AddLoadRequest(const std::string& file,
- unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
-{
- ai_assert(!file.empty());
-
- // check whether we have this loading request already
- for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
- // Call IOSystem's path comparison function here
- if ( m_data->pIOSystem->ComparePaths((*it).file,file)) {
- if (map) {
- if ( !( ( *it ).map == *map ) ) {
- continue;
- }
- }
- else if ( !( *it ).map.empty() ) {
- continue;
- }
-
- (*it).refCnt++;
- return (*it).id;
- }
- }
-
- // no, we don't have it. So add it to the queue ...
- m_data->requests.push_back(LoadRequest(file,steps,map, m_data->next_id));
- return m_data->next_id++;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiScene* BatchLoader::GetImport( unsigned int which )
-{
- for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
- if ((*it).id == which && (*it).loaded) {
- aiScene* sc = (*it).scene;
- if (!(--(*it).refCnt)) {
- m_data->requests.erase(it);
- }
- return sc;
- }
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BatchLoader::LoadAll()
-{
- // no threaded implementation for the moment
- for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
- // force validation in debug builds
- unsigned int pp = (*it).flags;
- if ( m_data->validate ) {
- pp |= aiProcess_ValidateDataStructure;
- }
-
- // setup config properties if necessary
- ImporterPimpl* pimpl = m_data->pImporter->Pimpl();
- pimpl->mFloatProperties = (*it).map.floats;
- pimpl->mIntProperties = (*it).map.ints;
- pimpl->mStringProperties = (*it).map.strings;
- pimpl->mMatrixProperties = (*it).map.matrices;
-
- if (!DefaultLogger::isNullLogger())
- {
- DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
- DefaultLogger::get()->info("File: " + (*it).file);
- }
- m_data->pImporter->ReadFile((*it).file,pp);
- (*it).scene = m_data->pImporter->GetOrphanedScene();
- (*it).loaded = true;
-
- DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
- }
-}
diff --git a/src/3rdparty/assimp/code/BaseImporter.h b/src/3rdparty/assimp/code/BaseImporter.h
deleted file mode 100644
index b424d2f83..000000000
--- a/src/3rdparty/assimp/code/BaseImporter.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Definition of the base class for all importer worker classes. */
-#ifndef INCLUDED_AI_BASEIMPORTER_H
-#define INCLUDED_AI_BASEIMPORTER_H
-
-#include "Exceptional.h"
-
-#include <vector>
-#include <set>
-#include <assimp/types.h>
-#include <assimp/ProgressHandler.hpp>
-
-struct aiScene;
-struct aiImporterDesc;
-
-namespace Assimp {
-
-class Importer;
-class IOSystem;
-class BaseProcess;
-class SharedPostProcessInfo;
-class IOStream;
-
-// utility to do char4 to uint32 in a portable manner
-#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
- (string[1] << 16) + (string[2] << 8) + string[3]))
-
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: The BaseImporter defines a common interface
- * for all importer worker classes.
- *
- * The interface defines two functions: CanRead() is used to check if the
- * importer can handle the format of the given file. If an implementation of
- * this function returns true, the importer then calls ReadFile() which
- * imports the given file. ReadFile is not overridable, it just calls
- * InternReadFile() and catches any ImportErrorException that might occur.
- */
-class ASSIMP_API BaseImporter
-{
- friend class Importer;
-
-public:
-
- /** Constructor to be privately used by #Importer */
- BaseImporter();
-
- /** Destructor, private as well */
- virtual ~BaseImporter();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- *
- * The implementation should be as quick as possible. A check for
- * the file extension is enough. If no suitable loader is found with
- * this strategy, CanRead() is called again, the 'checkSig' parameter
- * set to true this time. Now the implementation is expected to
- * perform a full check of the file structure, possibly searching the
- * first bytes of the file for magic identifiers or keywords.
- *
- * @param pFile Path and file name of the file to be examined.
- * @param pIOHandler The IO handler to use for accessing any file.
- * @param checkSig Set to true if this method is called a second time.
- * This time, the implementation may take more time to examine the
- * contents of the file to be loaded for magic bytes, keywords, etc
- * to be able to load files with unknown/not existent file extensions.
- * @return true if the class can read this file, false if not.
- */
- virtual bool CanRead(
- const std::string& pFile,
- IOSystem* pIOHandler,
- bool checkSig
- ) const = 0;
-
- // -------------------------------------------------------------------
- /** Imports the given file and returns the imported data.
- * If the import succeeds, ownership of the data is transferred to
- * the caller. If the import fails, NULL is returned. The function
- * takes care that any partially constructed data is destroyed
- * beforehand.
- *
- * @param pImp #Importer object hosting this loader.
- * @param pFile Path of the file to be imported.
- * @param pIOHandler IO-Handler used to open this and possible other files.
- * @return The imported data or NULL if failed. If it failed a
- * human-readable error description can be retrieved by calling
- * GetErrorText()
- *
- * @note This function is not intended to be overridden. Implement
- * InternReadFile() to do the import. If an exception is thrown somewhere
- * in InternReadFile(), this function will catch it and transform it into
- * a suitable response to the caller.
- */
- aiScene* ReadFile(
- const Importer* pImp,
- const std::string& pFile,
- IOSystem* pIOHandler
- );
-
- // -------------------------------------------------------------------
- /** Returns the error description of the last error that occurred.
- * @return A description of the last error that occurred. An empty
- * string if there was no error.
- */
- const std::string& GetErrorText() const {
- return m_ErrorText;
- }
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- * @param pImp Importer instance
- */
- virtual void SetupProperties(
- const Importer* pImp
- );
-
- // -------------------------------------------------------------------
- /** Called by #Importer::GetImporterInfo to get a description of
- * some loader features. Importers must provide this information. */
- virtual const aiImporterDesc* GetInfo() const = 0;
-
- // -------------------------------------------------------------------
- /** Called by #Importer::GetExtensionList for each loaded importer.
- * Take the extension list contained in the structure returned by
- * #GetInfo and insert all file extensions into the given set.
- * @param extension set to collect file extensions in*/
- void GetExtensionList(std::set<std::string>& extensions);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure. The
- * function is expected to throw an ImportErrorException if there is
- * an error. If it terminates normally, the data in aiScene is
- * expected to be correct. Override this function to implement the
- * actual importing.
- * <br>
- * The output scene must meet the following requirements:<br>
- * <ul>
- * <li>At least a root node must be there, even if its only purpose
- * is to reference one mesh.</li>
- * <li>aiMesh::mPrimitiveTypes may be 0. The types of primitives
- * in the mesh are determined automatically in this case.</li>
- * <li>the vertex data is stored in a pseudo-indexed "verbose" format.
- * In fact this means that every vertex that is referenced by
- * a face is unique. Or the other way round: a vertex index may
- * not occur twice in a single aiMesh.</li>
- * <li>aiAnimation::mDuration may be -1. Assimp determines the length
- * of the animation automatically in this case as the length of
- * the longest animation channel.</li>
- * <li>aiMesh::mBitangents may be NULL if tangents and normals are
- * given. In this case bitangents are computed as the cross product
- * between normal and tangent.</li>
- * <li>There needn't be a material. If none is there a default material
- * is generated. However, it is recommended practice for loaders
- * to generate a default material for yourself that matches the
- * default material setting for the file format better than Assimp's
- * generic default material. Note that default materials *should*
- * be named AI_DEFAULT_MATERIAL_NAME if they're just color-shaded
- * or AI_DEFAULT_TEXTURED_MATERIAL_NAME if they define a (dummy)
- * texture. </li>
- * </ul>
- * If the AI_SCENE_FLAGS_INCOMPLETE-Flag is <b>not</b> set:<ul>
- * <li> at least one mesh must be there</li>
- * <li> there may be no meshes with 0 vertices or faces</li>
- * </ul>
- * This won't be checked (except by the validation step): Assimp will
- * crash if one of the conditions is not met!
- *
- * @param pFile Path of the file to be imported.
- * @param pScene The scene object to hold the imported data.
- * NULL is not a valid parameter.
- * @param pIOHandler The IO handler to use for any file access.
- * NULL is not a valid parameter. */
- virtual void InternReadFile(
- const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler
- ) = 0;
-
-public: // static utilities
-
- // -------------------------------------------------------------------
- /** A utility for CanRead().
- *
- * The function searches the header of a file for a specific token
- * and returns true if this token is found. This works for text
- * files only. There is a rudimentary handling of UNICODE files.
- * The comparison is case independent.
- *
- * @param pIOSystem IO System to work with
- * @param file File name of the file
- * @param tokens List of tokens to search for
- * @param numTokens Size of the token array
- * @param searchBytes Number of bytes to be searched for the tokens.
- */
- static bool SearchFileHeaderForToken(
- IOSystem* pIOSystem,
- const std::string& file,
- const char** tokens,
- unsigned int numTokens,
- unsigned int searchBytes = 200,
- bool tokensSol = false);
-
- // -------------------------------------------------------------------
- /** @brief Check whether a file has a specific file extension
- * @param pFile Input file
- * @param ext0 Extension to check for. Lowercase characters only, no dot!
- * @param ext1 Optional second extension
- * @param ext2 Optional third extension
- * @note Case-insensitive
- */
- static bool SimpleExtensionCheck (
- const std::string& pFile,
- const char* ext0,
- const char* ext1 = NULL,
- const char* ext2 = NULL);
-
- // -------------------------------------------------------------------
- /** @brief Extract file extension from a string
- * @param pFile Input file
- * @return Extension without trailing dot, all lowercase
- */
- static std::string GetExtension (
- const std::string& pFile);
-
- // -------------------------------------------------------------------
- /** @brief Check whether a file starts with one or more magic tokens
- * @param pFile Input file
- * @param pIOHandler IO system to be used
- * @param magic n magic tokens
- * @params num Size of magic
- * @param offset Offset from file start where tokens are located
- * @param Size of one token, in bytes. Maximally 16 bytes.
- * @return true if one of the given tokens was found
- *
- * @note For convenience, the check is also performed for the
- * byte-swapped variant of all tokens (big endian). Only for
- * tokens of size 2,4.
- */
- static bool CheckMagicToken(
- IOSystem* pIOHandler,
- const std::string& pFile,
- const void* magic,
- unsigned int num,
- unsigned int offset = 0,
- unsigned int size = 4);
-
- // -------------------------------------------------------------------
- /** An utility for all text file loaders. It converts a file to our
- * UTF8 character set. Errors are reported, but ignored.
- *
- * @param data File buffer to be converted to UTF8 data. The buffer
- * is resized as appropriate. */
- static void ConvertToUTF8(
- 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);
-
- // -------------------------------------------------------------------
- /// @brief Enum to define, if empty files are ok or not.
- enum TextFileMode {
- ALLOW_EMPTY,
- FORBID_EMPTY
- };
-
- // -------------------------------------------------------------------
- /** Utility for text file loaders which copies the contents of the
- * file into a memory buffer and converts it to our UTF8
- * representation.
- * @param stream Stream to read from.
- * @param data Output buffer to be resized and filled with the
- * converted text file data. The buffer is terminated with
- * a binary 0.
- * @param mode Whether it is OK to load empty text files. */
- static void TextFileToBuffer(
- IOStream* stream,
- std::vector<char>& data,
- TextFileMode mode = FORBID_EMPTY);
-
- // -------------------------------------------------------------------
- /** Utility function to move a std::vector into a aiScene array
- * @param vec The vector to be moved
- * @param out The output pointer to the allocated array.
- * @param numOut The output count of elements copied. */
- template<typename T>
- AI_FORCE_INLINE
- static void CopyVector(
- std::vector<T>& vec,
- T*& out,
- unsigned int& outLength)
- {
- outLength = unsigned(vec.size());
- if (outLength) {
- out = new T[outLength];
- std::swap_ranges(vec.begin(), vec.end(), out);
- }
- }
-
-protected:
- /// Error description in case there was one.
- std::string m_ErrorText;
- /// Currently set progress handler.
- ProgressHandler* m_progress;
-};
-
-
-
-} // end of namespace Assimp
-
-#endif // AI_BASEIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/BaseProcess.cpp b/src/3rdparty/assimp/code/BaseProcess.cpp
deleted file mode 100644
index 9e175d315..000000000
--- a/src/3rdparty/assimp/code/BaseProcess.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of BaseProcess */
-
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include "Importer.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BaseProcess::BaseProcess()
-: shared()
-, progress()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BaseProcess::~BaseProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseProcess::ExecuteOnScene( Importer* pImp)
-{
- ai_assert(NULL != pImp && NULL != pImp->Pimpl()->mScene);
-
- progress = pImp->GetProgressHandler();
- ai_assert(progress);
-
- SetupProperties( pImp );
-
- // catch exceptions thrown inside the PostProcess-Step
- try
- {
- Execute(pImp->Pimpl()->mScene);
-
- } catch( const std::exception& err ) {
-
- // extract error description
- pImp->Pimpl()->mErrorString = err.what();
- DefaultLogger::get()->error(pImp->Pimpl()->mErrorString);
-
- // and kill the partially imported data
- delete pImp->Pimpl()->mScene;
- pImp->Pimpl()->mScene = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BaseProcess::SetupProperties(const Importer* /*pImp*/)
-{
- // the default implementation does nothing
-}
-
-// ------------------------------------------------------------------------------------------------
-bool BaseProcess::RequireVerboseFormat() const
-{
- return true;
-}
-
diff --git a/src/3rdparty/assimp/code/BaseProcess.h b/src/3rdparty/assimp/code/BaseProcess.h
deleted file mode 100644
index aa873f717..000000000
--- a/src/3rdparty/assimp/code/BaseProcess.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Base class of all import post processing steps */
-#ifndef INCLUDED_AI_BASEPROCESS_H
-#define INCLUDED_AI_BASEPROCESS_H
-
-#include <map>
-#include "GenericProperty.h"
-
-struct aiScene;
-
-namespace Assimp {
-
-class Importer;
-
-// ---------------------------------------------------------------------------
-/** Helper class to allow post-processing steps to interact with each other.
- *
- * The class maintains a simple property list that can be used by pp-steps
- * to provide additional information to other steps. This is primarily
- * intended for cross-step optimizations.
- */
-class SharedPostProcessInfo
-{
-public:
-
- struct Base
- {
- virtual ~Base()
- {}
- };
-
- //! Represents data that is allocated on the heap, thus needs to be deleted
- template <typename T>
- struct THeapData : public Base
- {
- explicit THeapData(T* in)
- : data (in)
- {}
-
- ~THeapData()
- {
- delete data;
- }
- T* data;
- };
-
- //! Represents static, by-value data not allocated on the heap
- template <typename T>
- struct TStaticData : public Base
- {
- explicit TStaticData(T in)
- : data (in)
- {}
-
- ~TStaticData()
- {}
-
- T data;
- };
-
- // some typedefs for cleaner code
- typedef unsigned int KeyType;
- typedef std::map<KeyType, Base*> PropertyMap;
-
-public:
-
- //! Destructor
- ~SharedPostProcessInfo()
- {
- Clean();
- }
-
- //! Remove all stored properties from the table
- void Clean()
- {
- // invoke the virtual destructor for all stored properties
- for (PropertyMap::iterator it = pmap.begin(), end = pmap.end();
- it != end; ++it)
- {
- delete (*it).second;
- }
- pmap.clear();
- }
-
- //! Add a heap property to the list
- template <typename T>
- void AddProperty( const char* name, T* in ){
- AddProperty(name,(Base*)new THeapData<T>(in));
- }
-
- //! Add a static by-value property to the list
- template <typename T>
- void AddProperty( const char* name, T in ){
- AddProperty(name,(Base*)new TStaticData<T>(in));
- }
-
-
- //! Get a heap property
- template <typename T>
- bool GetProperty( const char* name, T*& out ) const
- {
- THeapData<T>* t = (THeapData<T>*)GetPropertyInternal(name);
- if(!t)
- {
- out = NULL;
- return false;
- }
- out = t->data;
- return true;
- }
-
- //! Get a static, by-value property
- template <typename T>
- bool GetProperty( const char* name, T& out ) const
- {
- TStaticData<T>* t = (TStaticData<T>*)GetPropertyInternal(name);
- if(!t)return false;
- out = t->data;
- return true;
- }
-
- //! Remove a property of a specific type
- void RemoveProperty( const char* name) {
- SetGenericPropertyPtr<Base>(pmap,name,NULL);
- }
-
-private:
-
- void AddProperty( const char* name, Base* data) {
- SetGenericPropertyPtr<Base>(pmap,name,data);
- }
-
- Base* GetPropertyInternal( const char* name) const {
- return GetGenericProperty<Base*>(pmap,name,NULL);
- }
-
-private:
-
- //! Map of all stored properties
- PropertyMap pmap;
-};
-
-#if 0
-
-// ---------------------------------------------------------------------------
-/** @brief Represents a dependency table for a postprocessing steps.
- *
- * For future use.
- */
- struct PPDependencyTable
- {
- unsigned int execute_me_before_these;
- unsigned int execute_me_after_these;
- unsigned int only_if_these_are_not_specified;
- unsigned int mutually_exclusive_with;
- };
-
-#endif
-
-
-#define AI_SPP_SPATIAL_SORT "$Spat"
-
-// ---------------------------------------------------------------------------
-/** The BaseProcess defines a common interface for all post processing steps.
- * A post processing step is run after a successful import if the caller
- * specified the corresponding flag when calling ReadFile().
- * Enum #aiPostProcessSteps defines which flags are available.
- * After a successful import the Importer iterates over its internal array
- * of processes and calls IsActive() on each process to evaluate if the step
- * should be executed. If the function returns true, the class' Execute()
- * function is called subsequently.
- */
-class ASSIMP_API_WINONLY BaseProcess
-{
- friend class Importer;
-
-public:
-
- /** Constructor to be privately used by Importer */
- BaseProcess();
-
- /** Destructor, private as well */
- virtual ~BaseProcess();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with. A
- * bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- virtual bool IsActive( unsigned int pFlags) const = 0;
-
- // -------------------------------------------------------------------
- /** Check whether this step expects its input vertex data to be
- * in verbose format. */
- virtual bool RequireVerboseFormat() const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * The function deletes the scene if the postprocess step fails (
- * the object pointer will be set to NULL).
- * @param pImp Importer instance (pImp->mScene must be valid)
- */
- void ExecuteOnScene( Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * A process should throw an ImportErrorException* if it fails.
- * This method must be implemented by deriving classes.
- * @param pScene The imported data to work at.
- */
- virtual void Execute( aiScene* pScene) = 0;
-
-
- // -------------------------------------------------------------------
- /** Assign a new SharedPostProcessInfo to the step. This object
- * allows multiple postprocess steps to share data.
- * @param sh May be NULL
- */
- inline void SetSharedData(SharedPostProcessInfo* sh) {
- shared = sh;
- }
-
- // -------------------------------------------------------------------
- /** Get the shared data that is assigned to the step.
- */
- inline SharedPostProcessInfo* GetSharedData() {
- return shared;
- }
-
-protected:
-
- /** See the doc of #SharedPostProcessInfo for more details */
- SharedPostProcessInfo* shared;
-
- /** Currently active progress handler */
- ProgressHandler* progress;
-};
-
-
-} // end of namespace Assimp
-
-#endif // AI_BASEPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/Bitmap.cpp b/src/3rdparty/assimp/code/Bitmap.cpp
deleted file mode 100644
index 76994513e..000000000
--- a/src/3rdparty/assimp/code/Bitmap.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 "Bitmap.h"
-#include <assimp/texture.h>
-#include <assimp/IOStream.hpp>
-#include "ByteSwapper.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) {
-#ifdef AI_BUILD_BIG_ENDIAN
- T field_swapped=AI_BE(field);
- std::memcpy(data, &field_swapped, sizeof(field)); return sizeof(field);
-#else
- std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
-#endif
- }
-
- 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);
- 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);
- 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
deleted file mode 100644
index 96c994dbe..000000000
--- a/src/3rdparty/assimp/code/Bitmap.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
-
-#include <stdint.h>
-#include <cstddef>
-
-struct aiTexture;
-
-namespace Assimp {
-
-class IOStream;
-
-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
deleted file mode 100644
index 8a13819a6..000000000
--- a/src/3rdparty/assimp/code/BlenderBMesh.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
-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
- */
-
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-#include "BlenderBMesh.h"
-#include "BlenderTessellator.h"
-
-namespace Assimp
-{
- template< > const char* LogFunctions< BlenderBMeshConverter >::Prefix()
- {
- static auto prefix = "BLEND_BMESH: ";
- return prefix;
- }
-}
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-using namespace Assimp::Formatter;
-
-// ------------------------------------------------------------------------------------------------
-BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
- BMesh( mesh ),
- triMesh( NULL )
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-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 );
-
- // UVs are optional, so only convert when present.
- if ( BMesh->mloopuv.size() )
- {
- if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
- {
- ThrowException( "BMesh uv loop array has incorrect size" );
- }
- const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
- AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 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 = static_cast<int>(triMesh->mface.size( ));
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
-{
- MTFace mtface;
- memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
- memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
- memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
-
- if ( uv4 )
- {
- memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
- }
-
- triMesh->mtface.push_back( mtface );
-}
-
-#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
diff --git a/src/3rdparty/assimp/code/BlenderBMesh.h b/src/3rdparty/assimp/code/BlenderBMesh.h
deleted file mode 100644
index 0d58b818c..000000000
--- a/src/3rdparty/assimp/code/BlenderBMesh.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-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 );
- void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 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.cpp b/src/3rdparty/assimp/code/BlenderDNA.cpp
deleted file mode 100644
index 23ece913f..000000000
--- a/src/3rdparty/assimp/code/BlenderDNA.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderDNA.cpp
- * @brief Implementation of the Blender `DNA`, that is its own
- * serialized set of data structures.
- */
-
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-#include "BlenderDNA.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-#include "TinyFormatter.h"
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-using namespace Assimp::Formatter;
-
-static bool match4(StreamReaderAny& stream, const char* string) {
- ai_assert( nullptr != string );
- char tmp[] = {
- (const char)(stream).GetI1(),
- (const char)(stream).GetI1(),
- (const char)(stream).GetI1(),
- (const char)(stream).GetI1()
- };
- return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
-}
-
-struct Type {
- size_t size;
- std::string name;
-};
-
-// ------------------------------------------------------------------------------------------------
-void DNAParser::Parse ()
-{
- StreamReaderAny& stream = *db.reader.get();
- DNA& dna = db.dna;
-
- if(!match4(stream,"SDNA")) {
- throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
- }
-
- // name dictionary
- if(!match4(stream,"NAME")) {
- throw DeadlyImportError("BlenderDNA: Expected NAME field");
- }
-
- std::vector<std::string> names (stream.GetI4());
- for(std::string& s : names) {
- while (char c = stream.GetI1()) {
- s += c;
- }
- }
-
- // type dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
- if(!match4(stream,"TYPE")) {
- throw DeadlyImportError("BlenderDNA: Expected TYPE field");
- }
-
- std::vector<Type> types (stream.GetI4());
- for(Type& s : types) {
- while (char c = stream.GetI1()) {
- s.name += c;
- }
- }
-
- // type length dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
- if(!match4(stream,"TLEN")) {
- throw DeadlyImportError("BlenderDNA: Expected TLEN field");
- }
-
- for(Type& s : types) {
- s.size = stream.GetI2();
- }
-
- // structures dictionary
- for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
- if(!match4(stream,"STRC")) {
- throw DeadlyImportError("BlenderDNA: Expected STRC field");
- }
-
- size_t end = stream.GetI4(), fields = 0;
-
- dna.structures.reserve(end);
- for(size_t i = 0; i != end; ++i) {
-
- uint16_t n = stream.GetI2();
- if (n >= types.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid type index in structure name" ,n,
- " (there are only ", types.size(), " entries)"
- ));
- }
-
- // maintain separate indexes
- dna.indices[types[n].name] = dna.structures.size();
-
- dna.structures.push_back(Structure());
- Structure& s = dna.structures.back();
- s.name = types[n].name;
- //s.index = dna.structures.size()-1;
-
- n = stream.GetI2();
- s.fields.reserve(n);
-
- size_t offset = 0;
- for (size_t m = 0; m < n; ++m, ++fields) {
-
- uint16_t j = stream.GetI2();
- if (j >= types.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid type index in structure field ", j,
- " (there are only ", types.size(), " entries)"
- ));
- }
- s.fields.push_back(Field());
- Field& f = s.fields.back();
- f.offset = offset;
-
- f.type = types[j].name;
- f.size = types[j].size;
-
- j = stream.GetI2();
- if (j >= names.size()) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Invalid name index in structure field ", j,
- " (there are only ", names.size(), " entries)"
- ));
- }
-
- f.name = names[j];
- f.flags = 0u;
-
- // pointers always specify the size of the pointee instead of their own.
- // The pointer asterisk remains a property of the lookup name.
- if (f.name[0] == '*') {
- f.size = db.i64bit ? 8 : 4;
- f.flags |= FieldFlag_Pointer;
- }
-
- // arrays, however, specify the size of a single element so we
- // need to parse the (possibly multi-dimensional) array declaration
- // in order to obtain the actual size of the array in the file.
- // Also we need to alter the lookup name to include no array
- // brackets anymore or size fixup won't work (if our size does
- // not match the size read from the DNA).
- if (*f.name.rbegin() == ']') {
- const std::string::size_type rb = f.name.find('[');
- if (rb == std::string::npos) {
- throw DeadlyImportError((format(),
- "BlenderDNA: Encountered invalid array declaration ",
- f.name
- ));
- }
-
- f.flags |= FieldFlag_Array;
- DNA::ExtractArraySize(f.name,f.array_sizes);
- f.name = f.name.substr(0,rb);
-
- f.size *= f.array_sizes[0] * f.array_sizes[1];
- }
-
- // maintain separate indexes
- s.indices[f.name] = s.fields.size()-1;
- offset += f.size;
- }
- s.size = offset;
- }
-
- DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
- " structures with totally ",fields," fields"));
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- dna.DumpToFile();
-#endif
-
- dna.AddPrimitiveStructures();
- dna.RegisterConverters();
-}
-
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
-
-#include <fstream>
-// ------------------------------------------------------------------------------------------------
-void DNA :: DumpToFile()
-{
- // we dont't bother using the VFS here for this is only for debugging.
- // (and all your bases are belong to us).
-
- std::ofstream f("dna.txt");
- if (f.fail()) {
- DefaultLogger::get()->error("Could not dump dna to dna.txt");
- return;
- }
- f << "Field format: type name offset size" << "\n";
- f << "Structure format: name size" << "\n";
-
- for(const Structure& s : structures) {
- f << s.name << " " << s.size << "\n\n";
- for(const Field& ff : s.fields) {
- f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << "\n";
- }
- f << "\n";
- }
- f << std::flush;
-
- DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ void DNA :: ExtractArraySize(
- const std::string& out,
- size_t array_sizes[2]
-)
-{
- array_sizes[0] = array_sizes[1] = 1;
- std::string::size_type pos = out.find('[');
- if (pos++ == std::string::npos) {
- return;
- }
- array_sizes[0] = strtoul10(&out[pos]);
-
- pos = out.find('[',pos);
- if (pos++ == std::string::npos) {
- return;
- }
- array_sizes[1] = strtoul10(&out[pos]);
-}
-
-// ------------------------------------------------------------------------------------------------
-std::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
- const Structure& structure,
- const FileDatabase& db
-) const
-{
- std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
- if (it == converters.end()) {
- return std::shared_ptr< ElemBase >();
- }
-
- std::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
- (structure.*((*it).second.second))(ret,db);
-
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-DNA::FactoryPair DNA :: GetBlobToStructureConverter(
- const Structure& structure,
- const FileDatabase& /*db*/
-) const
-{
- std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
- return it == converters.end() ? FactoryPair() : (*it).second;
-}
-
-// basing on http://www.blender.org/development/architecture/notes-on-sdna/
-// ------------------------------------------------------------------------------------------------
-void DNA :: AddPrimitiveStructures()
-{
- // NOTE: these are just dummies. Their presence enforces
- // Structure::Convert<target_type> to be called on these
- // empty structures. These converters are special
- // overloads which scan the name of the structure and
- // perform the required data type conversion if one
- // of these special names is found in the structure
- // in question.
-
- indices["int"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "int";
- structures.back().size = 4;
-
- indices["short"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "short";
- structures.back().size = 2;
-
-
- indices["char"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "char";
- structures.back().size = 1;
-
-
- indices["float"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "float";
- structures.back().size = 4;
-
-
- indices["double"] = structures.size();
- structures.push_back( Structure() );
- structures.back().name = "double";
- structures.back().size = 8;
-
- // no long, seemingly.
-}
-
-// ------------------------------------------------------------------------------------------------
-void SectionParser :: Next()
-{
- stream.SetCurrentPos(current.start + current.size);
-
- const char tmp[] = {
- (const char)stream.GetI1(),
- (const char)stream.GetI1(),
- (const char)stream.GetI1(),
- (const char)stream.GetI1()
- };
- current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
-
- current.size = stream.GetI4();
- current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
-
- current.dna_index = stream.GetI4();
- current.num = stream.GetI4();
-
- current.start = stream.GetCurrentPos();
- if (stream.GetRemainingSizeToLimit() < current.size) {
- throw DeadlyImportError("BLEND: invalid size of file block");
- }
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- DefaultLogger::get()->debug(current.id);
-#endif
-}
-
-
-
-#endif
diff --git a/src/3rdparty/assimp/code/BlenderDNA.h b/src/3rdparty/assimp/code/BlenderDNA.h
deleted file mode 100644
index bac8d78bc..000000000
--- a/src/3rdparty/assimp/code/BlenderDNA.h
+++ /dev/null
@@ -1,810 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderDNA.h
- * @brief Blender `DNA` (file format specification embedded in
- * blend file itself) loader.
- */
-#ifndef INCLUDED_AI_BLEND_DNA_H
-#define INCLUDED_AI_BLEND_DNA_H
-
-#include "BaseImporter.h"
-#include "StreamReader.h"
-#include <assimp/DefaultLogger.hpp>
-#include <stdint.h>
-#include <memory>
-#include <map>
-
-// enable verbose log output. really verbose, so be careful.
-#ifdef ASSIMP_BUILD_DEBUG
-# define ASSIMP_BUILD_BLENDER_DEBUG
-#endif
-
-// #define ASSIMP_BUILD_BLENDER_NO_STATS
-
-namespace Assimp {
-
-template <bool,bool> class StreamReader;
-typedef StreamReader<true,true> StreamReaderAny;
-
-namespace Blender {
-
-class FileDatabase;
-struct FileBlockHead;
-
-template <template <typename> class TOUT>
-class ObjectCache;
-
-// -------------------------------------------------------------------------------
-/** Exception class used by the blender loader to selectively catch exceptions
- * thrown in its own code (DeadlyImportErrors thrown in general utility
- * functions are untouched then). If such an exception is not caught by
- * the loader itself, it will still be caught by Assimp due to its
- * ancestry. */
-// -------------------------------------------------------------------------------
-struct Error : DeadlyImportError {
- Error (const std::string& s)
- : DeadlyImportError(s) {
- // empty
- }
-};
-
-// -------------------------------------------------------------------------------
-/** The only purpose of this structure is to feed a virtual dtor into its
- * descendents. It serves as base class for all data structure fields. */
-// -------------------------------------------------------------------------------
-struct ElemBase {
- ElemBase()
- : dna_type(nullptr)
- {
- // empty
- }
-
- virtual ~ElemBase() {
- // empty
- }
-
- /** Type name of the element. The type
- * string points is the `c_str` of the `name` attribute of the
- * corresponding `Structure`, that is, it is only valid as long
- * as the DNA is not modified. The dna_type is only set if the
- * data type is not static, i.e. a std::shared_ptr<ElemBase>
- * in the scene description would have its type resolved
- * at runtime, so this member is always set. */
- const char* dna_type;
-};
-
-// -------------------------------------------------------------------------------
-/** Represents a generic pointer to a memory location, which can be either 32
- * or 64 bits. These pointers are loaded from the BLEND file and finally
- * fixed to point to the real, converted representation of the objects
- * they used to point to.*/
-// -------------------------------------------------------------------------------
-struct Pointer {
- Pointer()
- : val() {
- // empty
- }
- uint64_t val;
-};
-
-// -------------------------------------------------------------------------------
-/** Represents a generic offset within a BLEND file */
-// -------------------------------------------------------------------------------
-struct FileOffset {
- FileOffset()
- : val() {
- // empty
- }
- uint64_t val;
-};
-
-// -------------------------------------------------------------------------------
-/** Dummy derivate of std::vector to be able to use it in templates simultaenously
- * with std::shared_ptr, which takes only one template argument
- * while std::vector takes three. Also we need to provide some special member
- * functions of shared_ptr */
-// -------------------------------------------------------------------------------
-template <typename T>
-class vector : public std::vector<T> {
-public:
- using std::vector<T>::resize;
- using std::vector<T>::empty;
-
- void reset() {
- resize(0);
- }
-
- operator bool () const {
- return !empty();
- }
-};
-
-// -------------------------------------------------------------------------------
-/** Mixed flags for use in #Field */
-// -------------------------------------------------------------------------------
-enum FieldFlags {
- FieldFlag_Pointer = 0x1,
- FieldFlag_Array = 0x2
-};
-
-// -------------------------------------------------------------------------------
-/** Represents a single member of a data structure in a BLEND file */
-// -------------------------------------------------------------------------------
-struct Field {
- std::string name;
- std::string type;
-
- size_t size;
- size_t offset;
-
- /** Size of each array dimension. For flat arrays,
- * the second dimension is set to 1. */
- size_t array_sizes[2];
-
- /** Any of the #FieldFlags enumerated values */
- unsigned int flags;
-};
-
-// -------------------------------------------------------------------------------
-/** Range of possible behaviours for fields absend in the input file. Some are
- * mission critical so we need them, while others can silently be default
- * initialized and no animations are harmed. */
-// -------------------------------------------------------------------------------
-enum ErrorPolicy {
- /** Substitute default value and ignore */
- ErrorPolicy_Igno,
- /** Substitute default value and write to log */
- ErrorPolicy_Warn,
- /** Substitute a massive error message and crash the whole matrix. Its time for another zion */
- ErrorPolicy_Fail
-};
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
-# define ErrorPolicy_Igno ErrorPolicy_Warn
-#endif
-
-// -------------------------------------------------------------------------------
-/** Represents a data structure in a BLEND file. A Structure defines n fields
- * and their locatios and encodings the input stream. Usually, every
- * Structure instance pertains to one equally-named data structure in the
- * BlenderScene.h header. This class defines various utilities to map a
- * binary `blob` read from the file to such a structure instance with
- * meaningful contents. */
-// -------------------------------------------------------------------------------
-class Structure {
- template <template <typename> class> friend class ObjectCache;
-
-public:
- Structure()
- : cache_idx(static_cast<size_t>(-1) ){
- // empty
- }
-
-public:
-
- // publicly accessible members
- std::string name;
- vector< Field > fields;
- std::map<std::string, size_t> indices;
-
- size_t size;
-
-public:
-
- // --------------------------------------------------------
- /** Access a field of the structure by its canonical name. The pointer version
- * returns NULL on failure while the reference version raises an import error. */
- inline const Field& operator [] (const std::string& ss) const;
- inline const Field* Get (const std::string& ss) const;
-
- // --------------------------------------------------------
- /** Access a field of the structure by its index */
- inline const Field& operator [] (const size_t i) const;
-
- // --------------------------------------------------------
- inline bool operator== (const Structure& other) const {
- return name == other.name; // name is meant to be an unique identifier
- }
-
- // --------------------------------------------------------
- inline bool operator!= (const Structure& other) const {
- return name != other.name;
- }
-
-public:
-
- // --------------------------------------------------------
- /** Try to read an instance of the structure from the stream
- * and attempt to convert to `T`. This is done by
- * an appropriate specialization. If none is available,
- * a compiler complain is the result.
- * @param dest Destination value to be written
- * @param db File database, including input stream. */
- template <typename T> void Convert (T& dest, const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // generic converter
- template <typename T>
- void Convert(std::shared_ptr<ElemBase> in,const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // generic allocator
- template <typename T> std::shared_ptr<ElemBase> Allocate() const;
-
-
-
- // --------------------------------------------------------
- // field parsing for 1d arrays
- template <int error_policy, typename T, size_t M>
- void ReadFieldArray(T (& out)[M], const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for 2d arrays
- template <int error_policy, typename T, size_t M, size_t N>
- void ReadFieldArray2(T (& out)[M][N], const char* name,
- const FileDatabase& db) const;
-
- // --------------------------------------------------------
- // field parsing for pointer or dynamic array types
- // (std::shared_ptr)
- // The return value indicates whether the data was already cached.
- template <int error_policy, template <typename> class TOUT, typename T>
- 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 (std::shared_ptr[])
- // The return value indicates whether the data was already cached.
- template <int error_policy, template <typename> class TOUT, typename T, size_t N>
- 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;
-
-private:
-
- // --------------------------------------------------------
- template <template <typename> class TOUT, typename T>
- 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>
- bool ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
- const FileDatabase& db, const Field& f, bool) const;
-
- // --------------------------------------------------------
- bool ResolvePointer( std::shared_ptr< FileOffset >& out, const Pointer & ptrval,
- const FileDatabase& db, const Field& f, bool) const;
-
- // --------------------------------------------------------
- inline const FileBlockHead* LocateFileBlockForAddress(
- const Pointer & ptrval,
- const FileDatabase& db) const;
-
-private:
-
- // ------------------------------------------------------------------------------
- template <typename T> T* _allocate(std::shared_ptr<T>& out, size_t& s) const {
- out = std::shared_ptr<T>(new T());
- s = 1;
- return out.get();
- }
-
- template <typename T> T* _allocate(vector<T>& out, size_t& s) const {
- out.resize(s);
- return s ? &out.front() : NULL;
- }
-
- // --------------------------------------------------------
- template <int error_policy>
- struct _defaultInitializer {
-
- template <typename T, unsigned int N>
- void operator ()(T (& out)[N], const char* = NULL) {
- for (unsigned int i = 0; i < N; ++i) {
- out[i] = T();
- }
- }
-
- template <typename T, unsigned int N, unsigned int M>
- void operator ()(T (& out)[N][M], const char* = NULL) {
- for (unsigned int i = 0; i < N; ++i) {
- for (unsigned int j = 0; j < M; ++j) {
- out[i][j] = T();
- }
- }
- }
-
- template <typename T>
- void operator ()(T& out, const char* = NULL) {
- out = T();
- }
- };
-
-private:
-
- mutable size_t cache_idx;
-};
-
-// --------------------------------------------------------
-template <> struct Structure :: _defaultInitializer<ErrorPolicy_Warn> {
-
- template <typename T>
- void operator ()(T& out, const char* reason = "<add reason>") {
- DefaultLogger::get()->warn(reason);
-
- // ... and let the show go on
- _defaultInitializer<0 /*ErrorPolicy_Igno*/>()(out);
- }
-};
-
-template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
-
- template <typename T>
- void operator ()(T& /*out*/,const char* = "") {
- // obviously, it is crucial that _DefaultInitializer is used
- // only from within a catch clause.
- throw;
- }
-};
-
-// -------------------------------------------------------------------------------------------------------
-template <> inline bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out,
- const Pointer & ptrval,
- const FileDatabase& db,
- const Field& f,
- bool
- ) const;
-
-
-// -------------------------------------------------------------------------------
-/** Represents the full data structure information for a single BLEND file.
- * This data is extracted from the DNA1 chunk in the file.
- * #DNAParser does the reading and represents currently the only place where
- * DNA is altered.*/
-// -------------------------------------------------------------------------------
-class DNA
-{
-public:
-
- typedef void (Structure::*ConvertProcPtr) (
- std::shared_ptr<ElemBase> in,
- const FileDatabase&
- ) const;
-
- typedef std::shared_ptr<ElemBase> (
- Structure::*AllocProcPtr) () const;
-
- typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
-
-public:
-
- std::map<std::string, FactoryPair > converters;
- vector<Structure > structures;
- std::map<std::string, size_t> indices;
-
-public:
-
- // --------------------------------------------------------
- /** Access a structure by its canonical name, the pointer version returns NULL on failure
- * while the reference version raises an error. */
- inline const Structure& operator [] (const std::string& ss) const;
- inline const Structure* Get (const std::string& ss) const;
-
- // --------------------------------------------------------
- /** Access a structure by its index */
- inline const Structure& operator [] (const size_t i) const;
-
-public:
-
- // --------------------------------------------------------
- /** Add structure definitions for all the primitive types,
- * i.e. integer, short, char, float */
- void AddPrimitiveStructures();
-
- // --------------------------------------------------------
- /** Fill the @c converters member with converters for all
- * known data types. The implementation of this method is
- * in BlenderScene.cpp and is machine-generated.
- * Converters are used to quickly handle objects whose
- * exact data type is a runtime-property and not yet
- * known at compile time (consier Object::data).*/
- void RegisterConverters();
-
-
- // --------------------------------------------------------
- /** Take an input blob from the stream, interpret it according to
- * a its structure name and convert it to the intermediate
- * representation.
- * @param structure Destination structure definition
- * @param db File database.
- * @return A null pointer if no appropriate converter is available.*/
- std::shared_ptr< ElemBase > ConvertBlobToStructure(
- const Structure& structure,
- const FileDatabase& db
- ) const;
-
- // --------------------------------------------------------
- /** Find a suitable conversion function for a given Structure.
- * Such a converter function takes a blob from the input
- * stream, reads as much as it needs, and builds up a
- * complete object in intermediate representation.
- * @param structure Destination structure definition
- * @param db File database.
- * @return A null pointer in .first if no appropriate converter is available.*/
- FactoryPair GetBlobToStructureConverter(
- const Structure& structure,
- const FileDatabase& db
- ) const;
-
-
-#ifdef ASSIMP_BUILD_BLENDER_DEBUG
- // --------------------------------------------------------
- /** Dump the DNA to a text file. This is for debugging purposes.
- * The output file is `dna.txt` in the current working folder*/
- void DumpToFile();
-#endif
-
- // --------------------------------------------------------
- /** Extract array dimensions from a C array declaration, such
- * as `...[4][6]`. Returned string would be `...[][]`.
- * @param out
- * @param array_sizes Receive maximally two array dimensions,
- * the second element is set to 1 if the array is flat.
- * Both are set to 1 if the input is not an array.
- * @throw DeadlyImportError if more than 2 dimensions are
- * encountered. */
- static void ExtractArraySize(
- const std::string& out,
- size_t array_sizes[2]
- );
-};
-
-// special converters for primitive types
-template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const;
-template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const;
-
-// -------------------------------------------------------------------------------
-/** Describes a master file block header. Each master file sections holds n
- * elements of a certain SDNA structure (or otherwise unspecified data). */
-// -------------------------------------------------------------------------------
-struct FileBlockHead
-{
- // points right after the header of the file block
- StreamReaderAny::pos start;
-
- std::string id;
- size_t size;
-
- // original memory address of the data
- Pointer address;
-
- // index into DNA
- unsigned int dna_index;
-
- // number of structure instances to follow
- size_t num;
-
-
-
- // file blocks are sorted by address to quickly locate specific memory addresses
- bool operator < (const FileBlockHead& o) const {
- return address.val < o.address.val;
- }
-
- // for std::upper_bound
- operator const Pointer& () const {
- return address;
- }
-};
-
-// for std::upper_bound
-inline bool operator< (const Pointer& a, const Pointer& b) {
- return a.val < b.val;
-}
-
-// -------------------------------------------------------------------------------
-/** Utility to read all master file blocks in turn. */
-// -------------------------------------------------------------------------------
-class SectionParser
-{
-public:
-
- // --------------------------------------------------------
- /** @param stream Inout stream, must point to the
- * first section in the file. Call Next() once
- * to have it read.
- * @param ptr64 Pointer size in file is 64 bits? */
- SectionParser(StreamReaderAny& stream,bool ptr64)
- : stream(stream)
- , ptr64(ptr64)
- {
- current.size = current.start = 0;
- }
-
-public:
-
- // --------------------------------------------------------
- const FileBlockHead& GetCurrent() const {
- return current;
- }
-
-
-public:
-
- // --------------------------------------------------------
- /** Advance to the next section.
- * @throw DeadlyImportError if the last chunk was passed. */
- void Next();
-
-public:
-
- FileBlockHead current;
- StreamReaderAny& stream;
- bool ptr64;
-};
-
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
-// -------------------------------------------------------------------------------
-/** Import statistics, i.e. number of file blocks read*/
-// -------------------------------------------------------------------------------
-class Statistics {
-
-public:
-
- Statistics ()
- : fields_read ()
- , pointers_resolved ()
- , cache_hits ()
-// , blocks_read ()
- , cached_objects ()
- {}
-
-public:
-
- /** total number of fields we read */
- unsigned int fields_read;
-
- /** total number of resolved pointers */
- unsigned int pointers_resolved;
-
- /** number of pointers resolved from the cache */
- unsigned int cache_hits;
-
- /** number of blocks (from FileDatabase::entries)
- we did actually read from. */
- // unsigned int blocks_read;
-
- /** objects in FileData::cache */
- unsigned int cached_objects;
-};
-#endif
-
-// -------------------------------------------------------------------------------
-/** The object cache - all objects addressed by pointers are added here. This
- * avoids circular references and avoids object duplication. */
-// -------------------------------------------------------------------------------
-template <template <typename> class TOUT>
-class ObjectCache
-{
-public:
-
- typedef std::map< Pointer, TOUT<ElemBase> > StructureCache;
-
-public:
-
- ObjectCache(const FileDatabase& db)
- : db(db)
- {
- // currently there are only ~400 structure records per blend file.
- // we read only a small part of them and don't cache objects
- // which we don't need, so this should suffice.
- caches.reserve(64);
- }
-
-public:
-
- // --------------------------------------------------------
- /** Check whether a specific item is in the cache.
- * @param s Data type of the item
- * @param out Output pointer. Unchanged if the
- * cache doens't know the item yet.
- * @param ptr Item address to look for. */
- template <typename T> void get (
- const Structure& s,
- TOUT<T>& out,
- const Pointer& ptr) const;
-
- // --------------------------------------------------------
- /** Add an item to the cache after the item has
- * been fully read. Do not insert anything that
- * may be faulty or might cause the loading
- * to abort.
- * @param s Data type of the item
- * @param out Item to insert into the cache
- * @param ptr address (cache key) of the item. */
- template <typename T> void set
- (const Structure& s,
- const TOUT<T>& out,
- const Pointer& ptr);
-
-private:
-
- mutable vector<StructureCache> caches;
- const FileDatabase& db;
-};
-
-// -------------------------------------------------------------------------------
-// -------------------------------------------------------------------------------
-template <> class ObjectCache<Blender::vector>
-{
-public:
-
- ObjectCache(const FileDatabase&) {}
-
- template <typename T> void get(const Structure&, vector<T>&, const Pointer&) {}
- template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {}
-};
-
-#ifdef _MSC_VER
-# pragma warning(disable:4355)
-#endif
-
-// -------------------------------------------------------------------------------
-/** Memory representation of a full BLEND file and all its dependencies. The
- * output aiScene is constructed from an instance of this data structure. */
-// -------------------------------------------------------------------------------
-class FileDatabase
-{
- template <template <typename> class TOUT> friend class ObjectCache;
-
-public:
- FileDatabase()
- : _cacheArrays(*this)
- , _cache(*this)
- , next_cache_idx()
- {}
-
-public:
- // publicly accessible fields
- bool i64bit;
- bool little;
-
- DNA dna;
- std::shared_ptr< StreamReaderAny > reader;
- vector< FileBlockHead > entries;
-
-public:
-
- Statistics& stats() const {
- return _stats;
- }
-
- // For all our templates to work on both shared_ptr's and vector's
- // using the same code, a dummy cache for arrays is provided. Actually,
- // arrays of objects are never cached because we can't easily
- // ensure their proper destruction.
- template <typename T>
- ObjectCache<std::shared_ptr>& cache(std::shared_ptr<T>& /*in*/) const {
- return _cache;
- }
-
- template <typename T>
- ObjectCache<vector>& cache(vector<T>& /*in*/) const {
- return _cacheArrays;
- }
-
-private:
-
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- mutable Statistics _stats;
-#endif
-
- mutable ObjectCache<vector> _cacheArrays;
- mutable ObjectCache<std::shared_ptr> _cache;
-
- mutable size_t next_cache_idx;
-};
-
-#ifdef _MSC_VER
-# pragma warning(default:4355)
-#endif
-
-// -------------------------------------------------------------------------------
-/** Factory to extract a #DNA from the DNA1 file block in a BLEND file. */
-// -------------------------------------------------------------------------------
-class DNAParser
-{
-
-public:
-
- /** Bind the parser to a empty DNA and an input stream */
- DNAParser(FileDatabase& db)
- : db(db)
- {}
-
-public:
-
- // --------------------------------------------------------
- /** Locate the DNA in the file and parse it. The input
- * stream is expected to point to the beginning of the DN1
- * chunk at the time this method is called and is
- * undefined afterwards.
- * @throw DeadlyImportError if the DNA cannot be read.
- * @note The position of the stream pointer is undefined
- * afterwards.*/
- void Parse ();
-
-public:
-
- /** Obtain a reference to the extracted DNA information */
- const Blender::DNA& GetDNA() const {
- return db.dna;
- }
-
-private:
-
- FileDatabase& db;
-};
-
- } // end Blend
-} // end Assimp
-
-#include "BlenderDNA.inl"
-
-#endif
diff --git a/src/3rdparty/assimp/code/BlenderDNA.inl b/src/3rdparty/assimp/code/BlenderDNA.inl
deleted file mode 100644
index c65ea81bc..000000000
--- a/src/3rdparty/assimp/code/BlenderDNA.inl
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderDNA.inl
- * @brief Blender `DNA` (file format specification embedded in
- * blend file itself) loader.
- */
-#ifndef INCLUDED_AI_BLEND_DNA_INL
-#define INCLUDED_AI_BLEND_DNA_INL
-
-#include <memory>
-#include "TinyFormatter.h"
-
-namespace Assimp {
-namespace Blender {
-
-//--------------------------------------------------------------------------------
-const Field& Structure :: operator [] (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- if (it == indices.end()) {
- throw Error((Formatter::format(),
- "BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`"
- ));
- }
-
- return fields[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Field* Structure :: Get (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- return it == indices.end() ? NULL : &fields[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Field& Structure :: operator [] (const size_t i) const
-{
- if (i >= fields.size()) {
- throw Error((Formatter::format(),
- "BlendDNA: There is no field with index `",i,"` in structure `",name,"`"
- ));
- }
-
- return fields[i];
-}
-
-//--------------------------------------------------------------------------------
-template <typename T> std::shared_ptr<ElemBase> Structure :: Allocate() const
-{
- return std::shared_ptr<T>(new T());
-}
-
-//--------------------------------------------------------------------------------
-template <typename T> void Structure :: Convert(
- std::shared_ptr<ElemBase> in,
- const FileDatabase& db) const
-{
- Convert<T> (*static_cast<T*> ( in.get() ),db);
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, typename T, size_t M>
-void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- const Structure& s = db.dna[f.type];
-
- // is the input actually an array?
- if (!(f.flags & FieldFlag_Array)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be an array of size ",M
- ));
- }
-
- db.reader->IncPtr(f.offset);
-
- // size conversions are always allowed, regardless of error_policy
- unsigned int i = 0;
- for(; i < std::min(f.array_sizes[0],M); ++i) {
- s.Convert(out[i],db);
- }
- for(; i < M; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
- }
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, typename T, size_t M, size_t N>
-void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- const Structure& s = db.dna[f.type];
-
- // is the input actually an array?
- if (!(f.flags & FieldFlag_Array)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be an array of size ",M,"*",N
- ));
- }
-
- db.reader->IncPtr(f.offset);
-
- // size conversions are always allowed, regardless of error_policy
- unsigned int i = 0;
- for(; i < std::min(f.array_sizes[0],M); ++i) {
- unsigned int j = 0;
- for(; j < std::min(f.array_sizes[1],N); ++j) {
- s.Convert(out[i][j],db);
- }
- for(; j < N; ++j) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i][j]);
- }
- }
- for(; i < M; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(out[i]);
- }
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-//--------------------------------------------------------------------------------
-template <int error_policy, template <typename> class TOUT, typename T>
-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;
- const Field* f;
- try {
- f = &(*this)[name];
-
- // sanity check, should never happen if the genblenddna script is right
- if (!(f->flags & FieldFlag_Pointer)) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be a pointer"));
- }
-
- db.reader->IncPtr(f->offset);
- Convert(ptrval,db);
- // actually it is meaningless on which Structure the Convert is called
- // because the `Pointer` argument triggers a special implementation.
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
-
- out.reset();
- return false;
- }
-
- // resolve the pointer and load the corresponding structure
- const bool res = ResolvePointer(out,ptrval,db,*f, non_recursive);
-
- 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>
-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
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- Pointer ptrval[N];
- const Field* f;
- try {
- f = &(*this)[name];
-
- // sanity check, should never happen if the genblenddna script is right
- if ((FieldFlag_Pointer|FieldFlag_Pointer) != (f->flags & (FieldFlag_Pointer|FieldFlag_Pointer))) {
- throw Error((Formatter::format(),"Field `",name,"` of structure `",
- this->name,"` ought to be a pointer AND an array"));
- }
-
- db.reader->IncPtr(f->offset);
-
- size_t i = 0;
- for(; i < std::min(f->array_sizes[0],N); ++i) {
- Convert(ptrval[i],db);
- }
- for(; i < N; ++i) {
- _defaultInitializer<ErrorPolicy_Igno>()(ptrval[i]);
- }
-
- // actually it is meaningless on which Structure the Convert is called
- // because the `Pointer` argument triggers a special implementation.
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- for(size_t i = 0; i < N; ++i) {
- out[i].reset();
- }
- return false;
- }
-
- bool res = true;
- for(size_t i = 0; i < N; ++i) {
- // resolve the pointer and load the corresponding structure
- res = ResolvePointer(out[i],ptrval[i],db,*f) && res;
- }
-
- // 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, typename T>
-void Structure :: ReadField(T& out, const char* name, const FileDatabase& db) const
-{
- const StreamReaderAny::pos old = db.reader->GetCurrentPos();
- try {
- const Field& f = (*this)[name];
- // find the structure definition pertaining to this field
- const Structure& s = db.dna[f.type];
-
- db.reader->IncPtr(f.offset);
- s.Convert(out,db);
- }
- catch (const Error& e) {
- _defaultInitializer<error_policy>()(out,e.what());
- }
-
- // and recover the previous stream position
- db.reader->SetCurrentPos(old);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().fields_read;
-#endif
-}
-
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT, typename T>
-bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db,
- const Field& f,
- bool non_recursive /*= false*/) const
-{
- out.reset(); // ensure null pointers work
- if (!ptrval.val) {
- return false;
- }
- const Structure& s = db.dna[f.type];
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- // also determine the target type from the block header
- // and check if it matches the type which we expect.
- const Structure& ss = db.dna[block->dna_index];
- if (ss != s) {
- throw Error((Formatter::format(),"Expected target to be of type `",s.name,
- "` but seemingly it is a `",ss.name,"` instead"
- ));
- }
-
- // try to retrieve the object from the cache
- db.cache(out).get(s,out,ptrval);
- if (out) {
- return true;
- }
-
- // seek to this location, but save the previous stream pointer.
- const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
- db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
- // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
- // I really ought to improve StreamReader to work with 64 bit indices exclusively.
-
- // continue conversion after allocating the required storage
- size_t num = block->size / ss.size;
- T* o = _allocate(out,num);
-
- // cache the object before we convert it to avoid cyclic recursion.
- db.cache(out).set(s,out,ptrval);
-
- // 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);
- }
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- if(out) {
- ++db.stats().pointers_resolved;
- }
-#endif
- return false;
-}
-
-
-//--------------------------------------------------------------------------------
-inline bool Structure :: ResolvePointer( std::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 false;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- out = std::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>
-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
- // for array-of-pointer inputs, i.e. Object::mats.
-
- out.reset();
- if (!ptrval.val) {
- return false;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
- const size_t num = block->size / (db.i64bit?8:4);
-
- // keep the old stream position
- 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) {
- Pointer val;
- Convert(val,db);
-
- // and resolve the pointees
- res = ResolvePointer(out[i],val,db,f) && res;
- }
-
- db.reader->SetCurrentPos(pold);
- return res;
-}
-
-//--------------------------------------------------------------------------------
-template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out,
- const Pointer & ptrval,
- const FileDatabase& db,
- const Field&,
- bool
-) const
-{
- // Special case when the data type needs to be determined at runtime.
- // Less secure than in the `strongly-typed` case.
-
- out.reset();
- if (!ptrval.val) {
- return false;
- }
-
- // find the file block the pointer is pointing to
- const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
-
- // determine the target type from the block header
- const Structure& s = db.dna[block->dna_index];
-
- // try to retrieve the object from the cache
- db.cache(out).get(s,out,ptrval);
- if (out) {
- return true;
- }
-
- // seek to this location, but save the previous stream pointer.
- const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
- db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
- // FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
- // I really ought to improve StreamReader to work with 64 bit indices exclusively.
-
- // continue conversion after allocating the required storage
- DNA::FactoryPair builders = db.dna.GetBlobToStructureConverter(s,db);
- if (!builders.first) {
- // this might happen if DNA::RegisterConverters hasn't been called so far
- // or if the target type is not contained in `our` DNA.
- out.reset();
- DefaultLogger::get()->warn((Formatter::format(),
- "Failed to find a converter for the `",s.name,"` structure"
- ));
- return false;
- }
-
- // allocate the object hull
- out = (s.*builders.first)();
-
- // cache the object immediately to prevent infinite recursion in a
- // circular list with a single element (i.e. a self-referencing element).
- db.cache(out).set(s,out,ptrval);
-
- // and do the actual conversion
- (s.*builders.second)(out,db);
- db.reader->SetCurrentPos(pold);
-
- // store a pointer to the name string of the actual type
- // in the object itself. This allows the conversion code
- // 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;
-}
-
-//--------------------------------------------------------------------------------
-const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrval, const FileDatabase& db) const
-{
- // the file blocks appear in list sorted by
- // with ascending base addresses so we can run a
- // binary search to locate the pointee quickly.
-
- // NOTE: Blender seems to distinguish between side-by-side
- // data (stored in the same data block) and far pointers,
- // which are only used for structures starting with an ID.
- // We don't need to make this distinction, our algorithm
- // works regardless where the data is stored.
- vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
- if (it == db.entries.end()) {
- // this is crucial, pointers may not be invalid.
- // this is either a corrupted file or an attempted attack.
- throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
- std::hex,ptrval.val,", no file block falls into this address range"
- ));
- }
- if (ptrval.val >= (*it).address.val + (*it).size) {
- throw DeadlyImportError((Formatter::format(),"Failure resolving pointer 0x",
- std::hex,ptrval.val,", nearest file block starting at 0x",
- (*it).address.val," ends at 0x",
- (*it).address.val + (*it).size
- ));
- }
- return &*it;
-}
-
-// ------------------------------------------------------------------------------------------------
-// NOTE: The MSVC debugger keeps showing up this annoying `a cast to a smaller data type has
-// caused a loss of data`-warning. Avoid this warning by a masking with an appropriate bitmask.
-
-template <typename T> struct signless;
-template <> struct signless<char> {typedef unsigned char type;};
-template <> struct signless<short> {typedef unsigned short type;};
-template <> struct signless<int> {typedef unsigned int type;};
-template <> struct signless<unsigned char> { typedef unsigned char type; };
-template <typename T>
-struct static_cast_silent {
- template <typename V>
- T operator()(V in) {
- return static_cast<T>(in & static_cast<typename signless<T>::type>(-1));
- }
-};
-
-template <> struct static_cast_silent<float> {
- template <typename V> float operator()(V in) {
- return static_cast<float> (in);
- }
-};
-
-template <> struct static_cast_silent<double> {
- template <typename V> double operator()(V in) {
- return static_cast<double>(in);
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,const FileDatabase& db)
-{
- if (in.name == "int") {
- out = static_cast_silent<T>()(db.reader->GetU4());
- }
- else if (in.name == "short") {
- out = static_cast_silent<T>()(db.reader->GetU2());
- }
- else if (in.name == "char") {
- out = static_cast_silent<T>()(db.reader->GetU1());
- }
- else if (in.name == "float") {
- out = static_cast<T>(db.reader->GetF4());
- }
- else if (in.name == "double") {
- out = static_cast<T>(db.reader->GetF8());
- }
- else {
- throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<int> (int& dest,const FileDatabase& db) const
-{
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template<> inline void Structure :: Convert<short> (short& dest,const FileDatabase& db) const
-{
- // automatic rescaling from short to float and vice versa (seems to be used by normals)
- if (name == "float") {
- float f = db.reader->GetF4();
- if ( f > 1.0f )
- f = 1.0f;
- dest = static_cast<short>( f * 32767.f);
- //db.reader->IncPtr(-4);
- return;
- }
- else if (name == "double") {
- dest = static_cast<short>(db.reader->GetF8() * 32767.);
- //db.reader->IncPtr(-8);
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<char> (char& dest,const FileDatabase& db) const
-{
- // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
- if (name == "float") {
- dest = static_cast<char>(db.reader->GetF4() * 255.f);
- return;
- }
- else if (name == "double") {
- dest = static_cast<char>(db.reader->GetF8() * 255.f);
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure::Convert<unsigned char>(unsigned char& dest, const FileDatabase& db) const
-{
- // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
- if (name == "float") {
- dest = static_cast<unsigned char>(db.reader->GetF4() * 255.f);
- return;
- }
- else if (name == "double") {
- dest = static_cast<unsigned char>(db.reader->GetF8() * 255.f);
- return;
- }
- ConvertDispatcher(dest, *this, db);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const
-{
- // automatic rescaling from char to float and vice versa (seems useful for RGB colors)
- if (name == "char") {
- dest = db.reader->GetI1() / 255.f;
- return;
- }
- // automatic rescaling from short to float and vice versa (used by normals)
- else if (name == "short") {
- dest = db.reader->GetI2() / 32767.f;
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const
-{
- if (name == "char") {
- dest = db.reader->GetI1() / 255.;
- return;
- }
- else if (name == "short") {
- dest = db.reader->GetI2() / 32767.;
- return;
- }
- ConvertDispatcher(dest,*this,db);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const
-{
- if (db.i64bit) {
- dest.val = db.reader->GetU8();
- //db.reader->IncPtr(-8);
- return;
- }
- dest.val = db.reader->GetU4();
- //db.reader->IncPtr(-4);
-}
-
-//--------------------------------------------------------------------------------
-const Structure& DNA :: operator [] (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- if (it == indices.end()) {
- throw Error((Formatter::format(),
- "BlendDNA: Did not find a structure named `",ss,"`"
- ));
- }
-
- return structures[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Structure* DNA :: Get (const std::string& ss) const
-{
- std::map<std::string, size_t>::const_iterator it = indices.find(ss);
- return it == indices.end() ? NULL : &structures[(*it).second];
-}
-
-//--------------------------------------------------------------------------------
-const Structure& DNA :: operator [] (const size_t i) const
-{
- if (i >= structures.size()) {
- throw Error((Formatter::format(),
- "BlendDNA: There is no structure with index `",i,"`"
- ));
- }
-
- return structures[i];
-}
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: get (
- const Structure& s,
- TOUT<T>& out,
- const Pointer& ptr
-) const {
-
- if(s.cache_idx == static_cast<size_t>(-1)) {
- s.cache_idx = db.next_cache_idx++;
- caches.resize(db.next_cache_idx);
- return;
- }
-
- typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
- if (it != caches[s.cache_idx].end()) {
- out = std::static_pointer_cast<T>( (*it).second );
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().cache_hits;
-#endif
- }
- // otherwise, out remains untouched
-}
-
-
-//--------------------------------------------------------------------------------
-template <template <typename> class TOUT> template <typename T> void ObjectCache<TOUT> :: set (
- const Structure& s,
- const TOUT<T>& out,
- const Pointer& ptr
-) {
- if(s.cache_idx == static_cast<size_t>(-1)) {
- s.cache_idx = db.next_cache_idx++;
- caches.resize(db.next_cache_idx);
- }
- caches[s.cache_idx][ptr] = std::static_pointer_cast<ElemBase>( out );
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- ++db.stats().cached_objects;
-#endif
-}
-
-}}
-#endif
diff --git a/src/3rdparty/assimp/code/BlenderIntermediate.h b/src/3rdparty/assimp/code/BlenderIntermediate.h
deleted file mode 100644
index c6f9cba1e..000000000
--- a/src/3rdparty/assimp/code/BlenderIntermediate.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderIntermediate.h
- * @brief Internal utility structures for the BlenderLoader. It also serves
- * as master include file for the whole (internal) Blender subsystem.
- */
-#ifndef INCLUDED_AI_BLEND_INTERMEDIATE_H
-#define INCLUDED_AI_BLEND_INTERMEDIATE_H
-
-#include "BlenderLoader.h"
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-#include <deque>
-#include <assimp/material.h>
-
-struct aiTexture;
-
-namespace Assimp {
-namespace Blender {
-
- // --------------------------------------------------------------------
- /** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
- // --------------------------------------------------------------------
- template <template <typename,typename> class TCLASS, typename T>
- struct TempArray {
- typedef TCLASS< T*,std::allocator<T*> > mywrap;
-
- TempArray() {
- }
-
- ~TempArray () {
- for(T* elem : arr) {
- delete elem;
- }
- }
-
- void dismiss() {
- arr.clear();
- }
-
- mywrap* operator -> () {
- return &arr;
- }
-
- operator mywrap& () {
- return arr;
- }
-
- operator const mywrap& () const {
- return arr;
- }
-
- mywrap& get () {
- return arr;
- }
-
- const mywrap& get () const {
- return arr;
- }
-
- T* operator[] (size_t idx) const {
- return arr[idx];
- }
-
- T*& operator[] (size_t idx) {
- return arr[idx];
- }
-
- private:
- // no copy semantics
- void operator= (const TempArray&) {
- }
-
- TempArray(const TempArray& /*arr*/) {
- }
-
- private:
- mywrap arr;
- };
-
-#ifdef _MSC_VER
-# pragma warning(disable:4351)
-#endif
-
- struct ObjectCompare {
- bool operator() (const Object* left, const Object* right) const {
- return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
- }
- };
-
- // When keeping objects in sets, sort them by their name.
- typedef std::set<const Object*, ObjectCompare> ObjectSet;
-
- // --------------------------------------------------------------------
- /** ConversionData acts as intermediate storage location for
- * the various ConvertXXX routines in BlenderImporter.*/
- // --------------------------------------------------------------------
- struct ConversionData
- {
- ConversionData(const FileDatabase& db)
- : sentinel_cnt()
- , next_texture()
- , db(db)
- {}
-
- struct ObjectCompare {
- bool operator() (const Object* left, const Object* right) const {
- return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
- }
- };
-
- ObjectSet objects;
-
- TempArray <std::vector, aiMesh> meshes;
- TempArray <std::vector, aiCamera> cameras;
- TempArray <std::vector, aiLight> lights;
- TempArray <std::vector, aiMaterial> materials;
- TempArray <std::vector, aiTexture> textures;
-
- // set of all materials referenced by at least one mesh in the scene
- std::deque< std::shared_ptr< Material > > materials_raw;
-
- // counter to name sentinel textures inserted as substitutes for procedural textures.
- unsigned int sentinel_cnt;
-
- // next texture ID for each texture type, respectively
- unsigned int next_texture[aiTextureType_UNKNOWN+1];
-
- // original file data
- const FileDatabase& db;
- };
-#ifdef _MSC_VER
-# pragma warning(default:4351)
-#endif
-
-// ------------------------------------------------------------------------------------------------
-inline const char* GetTextureTypeDisplayString(Tex::Type t)
-{
- switch (t) {
- case Tex::Type_CLOUDS : return "Clouds";
- case Tex::Type_WOOD : return "Wood";
- case Tex::Type_MARBLE : return "Marble";
- case Tex::Type_MAGIC : return "Magic";
- case Tex::Type_BLEND : return "Blend";
- case Tex::Type_STUCCI : return "Stucci";
- case Tex::Type_NOISE : return "Noise";
- case Tex::Type_PLUGIN : return "Plugin";
- case Tex::Type_MUSGRAVE : return "Musgrave";
- case Tex::Type_VORONOI : return "Voronoi";
- case Tex::Type_DISTNOISE : return "DistortedNoise";
- case Tex::Type_ENVMAP : return "EnvMap";
- case Tex::Type_IMAGE : return "Image";
- default:
- break;
- }
- return "<Unknown>";
-}
-
-} // ! Blender
-} // ! Assimp
-
-#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H
diff --git a/src/3rdparty/assimp/code/BlenderLoader.cpp b/src/3rdparty/assimp/code/BlenderLoader.cpp
deleted file mode 100644
index 824954f56..000000000
--- a/src/3rdparty/assimp/code/BlenderLoader.cpp
+++ /dev/null
@@ -1,1318 +0,0 @@
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderLoader.cpp
- * @brief Implementation of the Blender3D importer class.
- */
-
-
-//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
-// Uncomment this to disable support for (gzip)compressed .BLEND files
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderIntermediate.h"
-#include "BlenderModifier.h"
-#include "BlenderBMesh.h"
-#include "StringUtils.h"
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include "StringComparison.h"
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
-
-#include <cctype>
-
-
-// zlib is needed for compressed blend files
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include "../contrib/zlib/zlib.h"
-# endif
-#endif
-
-namespace Assimp {
- template<> const char* LogFunctions<BlenderImporter>::Prefix()
- {
- static auto prefix = "BLEND: ";
- return prefix;
- }
-}
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-using namespace Assimp::Formatter;
-
-static const aiImporterDesc blenderDesc = {
- "Blender 3D Importer \nhttp://www.blender3d.org",
- "",
- "",
- "No animation support yet",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 2,
- 50,
- "blend"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-BlenderImporter::BlenderImporter()
-: modifier_cache(new BlenderModifierShowcase()) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-BlenderImporter::~BlenderImporter()
-{
- delete modifier_cache;
-}
-
-static const char* Tokens[] = { "BLENDER" };
-static const char* TokensForSearch[] = { "blender" };
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "blend") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- // note: this won't catch compressed files
- return SearchFileHeaderForToken(pIOHandler,pFile, TokensForSearch,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// List all extensions handled by this loader
-void BlenderImporter::GetExtensionList(std::set<std::string>& app)
-{
- app.insert("blend");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader registry entry
-const aiImporterDesc* BlenderImporter::GetInfo () const
-{
- return &blenderDesc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void BlenderImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-struct free_it {
- free_it(void* free) : free(free) {}
- ~free_it() {
- ::free(this->free);
- }
-
- void* free;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void BlenderImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
- Bytef* dest = NULL;
- free_it free_it_really(dest);
-#endif
-
-
- FileDatabase file;
- std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
- if (!stream) {
- ThrowException("Could not open file for reading");
- }
-
- char magic[8] = {0};
- stream->Read(magic,7,1);
- if (strcmp(magic, Tokens[0] )) {
- // Check for presence of the gzip header. If yes, assume it is a
- // compressed blend file and try uncompressing it, else fail. This is to
- // avoid uncompressing random files which our loader might end up with.
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
- ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
-#else
-
- if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
- ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
- }
-
- LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
- if (magic[2] != 8) {
- ThrowException("Unsupported GZIP compression method");
- }
-
- // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
- stream->Seek(0L,aiOrigin_SET);
- std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
-
- // build a zlib stream
- 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
- inflateInit2(&zstream, 16+MAX_WBITS);
-
- zstream.next_in = reinterpret_cast<Bytef*>( reader->GetPtr() );
- zstream.avail_in = reader->GetRemainingSize();
-
- size_t total = 0l;
-
- // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
-#define MYBLOCK 1024
- Bytef block[MYBLOCK];
- int ret;
- do {
- zstream.avail_out = MYBLOCK;
- zstream.next_out = block;
- ret = inflate(&zstream, Z_NO_FLUSH);
-
- if (ret != Z_STREAM_END && ret != Z_OK) {
- ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
- }
- const size_t have = MYBLOCK - zstream.avail_out;
- total += have;
- dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
- memcpy(dest + total - have,block,have);
- }
- while (ret != Z_STREAM_END);
-
- // terminate zlib
- inflateEnd(&zstream);
-
- // replace the input stream with a memory stream
- stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
-
- // .. and retry
- stream->Read(magic,7,1);
- if (strcmp(magic,"BLENDER")) {
- ThrowException("Found no BLENDER magic word in decompressed GZIP file");
- }
-#endif
- }
-
- file.i64bit = (stream->Read(magic,1,1),magic[0]=='-');
- file.little = (stream->Read(magic,1,1),magic[0]=='v');
-
- stream->Read(magic,3,1);
- magic[3] = '\0';
-
- LogInfo((format(),"Blender version is ",magic[0],".",magic+1,
- " (64bit: ",file.i64bit?"true":"false",
- ", little endian: ",file.little?"true":"false",")"
- ));
-
- ParseBlendFile(file,stream);
-
- Scene scene;
- ExtractScene(scene,file);
-
- ConvertBlendFile(pScene,scene,file);
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ParseBlendFile(FileDatabase& out, std::shared_ptr<IOStream> stream)
-{
- out.reader = std::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream,out.little));
-
- DNAParser dna_reader(out);
- const DNA* dna = NULL;
-
- out.entries.reserve(128); { // even small BLEND files tend to consist of many file blocks
- SectionParser parser(*out.reader.get(),out.i64bit);
-
- // first parse the file in search for the DNA and insert all other sections into the database
- while ((parser.Next(),1)) {
- const FileBlockHead& head = parser.GetCurrent();
-
- if (head.id == "ENDB") {
- break; // only valid end of the file
- }
- else if (head.id == "DNA1") {
- dna_reader.Parse();
- dna = &dna_reader.GetDNA();
- continue;
- }
-
- out.entries.push_back(head);
- }
- }
- if (!dna) {
- ThrowException("SDNA not found");
- }
-
- std::sort(out.entries.begin(),out.entries.end());
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
-{
- const FileBlockHead* block = NULL;
- std::map<std::string,size_t>::const_iterator it = file.dna.indices.find("Scene");
- if (it == file.dna.indices.end()) {
- ThrowException("There is no `Scene` structure record");
- }
-
- const Structure& ss = file.dna.structures[(*it).second];
-
- // we need a scene somewhere to start with.
- for(const FileBlockHead& bl :file.entries) {
-
- // Fix: using the DNA index is more reliable to locate scenes
- //if (bl.id == "SC") {
-
- if (bl.dna_index == (*it).second) {
- block = &bl;
- break;
- }
- }
-
- if (!block) {
- ThrowException("There is not a single `Scene` record to load");
- }
-
- file.reader->SetCurrentPos(block->start);
- ss.Convert(out,file);
-
-#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
- DefaultLogger::get()->info((format(),
- "(Stats) Fields read: " ,file.stats().fields_read,
- ", pointers resolved: " ,file.stats().pointers_resolved,
- ", cache hits: " ,file.stats().cache_hits,
- ", cached objects: " ,file.stats().cached_objects
- ));
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileDatabase& file)
-{
- ConversionData conv(file);
-
- // FIXME it must be possible to take the hierarchy directly from
- // the file. This is terrible. Here, we're first looking for
- // all objects which don't have parent objects at all -
- std::deque<const Object*> no_parents;
- for (std::shared_ptr<Base> cur = std::static_pointer_cast<Base> ( in.base.first ); cur; cur = cur->next) {
- if (cur->object) {
- if(!cur->object->parent) {
- no_parents.push_back(cur->object.get());
- } else {
- conv.objects.insert( cur->object.get() );
- }
- }
- }
- for (std::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
- if (cur->object) {
- if(cur->object->parent) {
- conv.objects.insert(cur->object.get());
- }
- }
- }
-
- if (no_parents.empty()) {
- ThrowException("Expected at least one object with no parent");
- }
-
- aiNode* root = out->mRootNode = new aiNode("<BlenderRoot>");
-
- 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, aiMatrix4x4());
- root->mChildren[i]->mParent = root;
- }
-
- BuildMaterials(conv);
-
- if (conv.meshes->size()) {
- out->mMeshes = new aiMesh*[out->mNumMeshes = static_cast<unsigned int>( conv.meshes->size() )];
- std::copy(conv.meshes->begin(),conv.meshes->end(),out->mMeshes);
- conv.meshes.dismiss();
- }
-
- if (conv.lights->size()) {
- out->mLights = new aiLight*[out->mNumLights = static_cast<unsigned int>( conv.lights->size() )];
- std::copy(conv.lights->begin(),conv.lights->end(),out->mLights);
- conv.lights.dismiss();
- }
-
- if (conv.cameras->size()) {
- out->mCameras = new aiCamera*[out->mNumCameras = static_cast<unsigned int>( conv.cameras->size() )];
- std::copy(conv.cameras->begin(),conv.cameras->end(),out->mCameras);
- conv.cameras.dismiss();
- }
-
- if (conv.materials->size()) {
- out->mMaterials = new aiMaterial*[out->mNumMaterials = static_cast<unsigned int>( conv.materials->size() )];
- std::copy(conv.materials->begin(),conv.materials->end(),out->mMaterials);
- conv.materials.dismiss();
- }
-
- if (conv.textures->size()) {
- out->mTextures = new aiTexture*[out->mNumTextures = static_cast<unsigned int>( conv.textures->size() )];
- std::copy(conv.textures->begin(),conv.textures->end(),out->mTextures);
- conv.textures.dismiss();
- }
-
- // acknowledge that the scene might come out incomplete
- // by Assimp's definition of `complete`: blender scenes
- // can consist of thousands of cameras or lights with
- // not a single mesh between them.
- if (!out->mNumMeshes) {
- out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const MTex* tex, const Image* img, ConversionData& conv_data)
-{
- (void)mat; (void)tex; (void)conv_data;
- aiString name;
-
- // check if the file contents are bundled with the BLEND file
- if (img->packedfile) {
- name.data[0] = '*';
- name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size()));
-
- conv_data.textures->push_back(new aiTexture());
- aiTexture* tex = conv_data.textures->back();
-
- // usually 'img->name' will be the original file name of the embedded textures,
- // so we can extract the file extension from it.
- const size_t nlen = strlen( img->name );
- const char* s = img->name+nlen, *e = s;
- while ( s >= img->name && *s != '.' ) {
- --s;
- }
-
- tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
- tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
- tex->achFormatHint[2] = s+3>e ? '\0' : ::tolower( s[3] );
- tex->achFormatHint[3] = '\0';
-
- // tex->mHeight = 0;
- tex->mWidth = img->packedfile->size;
- uint8_t* ch = new uint8_t[tex->mWidth];
-
- conv_data.db.reader->SetCurrentPos(static_cast<size_t>( img->packedfile->data->val));
- conv_data.db.reader->CopyAndAdvance(ch,tex->mWidth);
-
- tex->pcData = reinterpret_cast<aiTexel*>(ch);
-
- LogInfo("Reading embedded texture, original file was "+std::string(img->name));
- } else {
- name = aiString( img->name );
- }
-
- 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]++));
-
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
-{
- (void)mat; (void)tex; (void)conv_data;
-
- aiString name;
- name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
- GetTextureTypeDisplayString(tex->tex->type)
- );
- out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
- conv_data.next_texture[aiTextureType_DIFFUSE]++)
- );
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const MTex* tex, ConversionData& conv_data)
-{
- const Tex* rtex = tex->tex.get();
- if(!rtex || !rtex->type) {
- return;
- }
-
- // 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 )
- {
- // these are listed in blender's UI
- case Tex::Type_CLOUDS :
- case Tex::Type_WOOD :
- case Tex::Type_MARBLE :
- case Tex::Type_MAGIC :
- case Tex::Type_BLEND :
- case Tex::Type_STUCCI :
- case Tex::Type_NOISE :
- case Tex::Type_PLUGIN :
- case Tex::Type_MUSGRAVE :
- case Tex::Type_VORONOI :
- case Tex::Type_DISTNOISE :
- case Tex::Type_ENVMAP :
-
- // these do no appear in the UI, why?
- case Tex::Type_POINTDENSITY :
- case Tex::Type_VOXELDATA :
-
- LogWarn(std::string("Encountered a texture with an unsupported type: ")+dispnam);
- AddSentinelTexture(out, mat, tex, conv_data);
- break;
-
- case Tex::Type_IMAGE :
- if (!rtex->ima) {
- LogError("A texture claims to be an Image, but no image reference is given");
- break;
- }
- ResolveImage(out, mat, tex, rtex->ima.get(),conv_data);
- break;
-
- default:
- ai_assert(false);
- };
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData& conv_data)
-{
- // add a default material if necessary
- unsigned int index = static_cast<unsigned int>( -1 );
- for( aiMesh* mesh : conv_data.meshes.get() ) {
- if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
-
- if (index == static_cast<unsigned int>( -1 )) {
- // Setup a default material.
- std::shared_ptr<Material> p(new Material());
- ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name)-2);
- strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
-
- // Note: MSVC11 does not zero-initialize Material here, although it should.
- // Thus all relevant fields should be explicitly initialized. We cannot add
- // a default constructor to Material since the DNA codegen does not support
- // parsing it.
- p->r = p->g = p->b = 0.6f;
- p->specr = p->specg = p->specb = 0.6f;
- p->ambr = p->ambg = p->ambb = 0.0f;
- p->mirr = p->mirg = p->mirb = 0.0f;
- p->emit = 0.f;
- p->alpha = 0.f;
- p->har = 0;
-
- index = static_cast<unsigned int>( conv_data.materials_raw.size() );
- conv_data.materials_raw.push_back(p);
- LogInfo("Adding default material");
- }
- mesh->mMaterialIndex = index;
- }
- }
-}
-
-void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
-{
- aiColor3D diffuseColor(source->r, source->g, source->b);
- result->AddProperty(&diffuseColor, 1, "$mat.blend.diffuse.color", 0, 0);
-
- float diffuseIntensity = source->ref;
- result->AddProperty(&diffuseIntensity, 1, "$mat.blend.diffuse.intensity", 0, 0);
-
- int diffuseShader = source->diff_shader;
- result->AddProperty(&diffuseShader, 1, "$mat.blend.diffuse.shader", 0, 0);
-
- int diffuseRamp = 0;
- result->AddProperty(&diffuseRamp, 1, "$mat.blend.diffuse.ramp", 0, 0);
-
-
- aiColor3D specularColor(source->specr, source->specg, source->specb);
- result->AddProperty(&specularColor, 1, "$mat.blend.specular.color", 0, 0);
-
- float specularIntensity = source->spec;
- result->AddProperty(&specularIntensity, 1, "$mat.blend.specular.intensity", 0, 0);
-
- int specularShader = source->spec_shader;
- result->AddProperty(&specularShader, 1, "$mat.blend.specular.shader", 0, 0);
-
- int specularRamp = 0;
- result->AddProperty(&specularRamp, 1, "$mat.blend.specular.ramp", 0, 0);
-
- int specularHardness = source->har;
- result->AddProperty(&specularHardness, 1, "$mat.blend.specular.hardness", 0, 0);
-
-
- int transparencyUse = source->mode & MA_TRANSPARENCY ? 1 : 0;
- result->AddProperty(&transparencyUse, 1, "$mat.blend.transparency.use", 0, 0);
-
- int transparencyMethod = source->mode & MA_RAYTRANSP ? 2 : (source->mode & MA_ZTRANSP ? 1 : 0);
- result->AddProperty(&transparencyMethod, 1, "$mat.blend.transparency.method", 0, 0);
-
- float transparencyAlpha = source->alpha;
- result->AddProperty(&transparencyAlpha, 1, "$mat.blend.transparency.alpha", 0, 0);
-
- float transparencySpecular = source->spectra;
- result->AddProperty(&transparencySpecular, 1, "$mat.blend.transparency.specular", 0, 0);
-
- float transparencyFresnel = source->fresnel_tra;
- result->AddProperty(&transparencyFresnel, 1, "$mat.blend.transparency.fresnel", 0, 0);
-
- float transparencyBlend = source->fresnel_tra_i;
- result->AddProperty(&transparencyBlend, 1, "$mat.blend.transparency.blend", 0, 0);
-
- float transparencyIor = source->ang;
- result->AddProperty(&transparencyIor, 1, "$mat.blend.transparency.ior", 0, 0);
-
- float transparencyFilter = source->filter;
- result->AddProperty(&transparencyFilter, 1, "$mat.blend.transparency.filter", 0, 0);
-
- float transparencyFalloff = source->tx_falloff;
- result->AddProperty(&transparencyFalloff, 1, "$mat.blend.transparency.falloff", 0, 0);
-
- float transparencyLimit = source->tx_limit;
- result->AddProperty(&transparencyLimit, 1, "$mat.blend.transparency.limit", 0, 0);
-
- int transparencyDepth = source->ray_depth_tra;
- result->AddProperty(&transparencyDepth, 1, "$mat.blend.transparency.depth", 0, 0);
-
- float transparencyGlossAmount = source->gloss_tra;
- result->AddProperty(&transparencyGlossAmount, 1, "$mat.blend.transparency.glossAmount", 0, 0);
-
- float transparencyGlossThreshold = source->adapt_thresh_tra;
- result->AddProperty(&transparencyGlossThreshold, 1, "$mat.blend.transparency.glossThreshold", 0, 0);
-
- int transparencyGlossSamples = source->samp_gloss_tra;
- result->AddProperty(&transparencyGlossSamples, 1, "$mat.blend.transparency.glossSamples", 0, 0);
-
-
- int mirrorUse = source->mode & MA_RAYMIRROR ? 1 : 0;
- result->AddProperty(&mirrorUse, 1, "$mat.blend.mirror.use", 0, 0);
-
- float mirrorReflectivity = source->ray_mirror;
- result->AddProperty(&mirrorReflectivity, 1, "$mat.blend.mirror.reflectivity", 0, 0);
-
- aiColor3D mirrorColor(source->mirr, source->mirg, source->mirb);
- result->AddProperty(&mirrorColor, 1, "$mat.blend.mirror.color", 0, 0);
-
- float mirrorFresnel = source->fresnel_mir;
- result->AddProperty(&mirrorFresnel, 1, "$mat.blend.mirror.fresnel", 0, 0);
-
- float mirrorBlend = source->fresnel_mir_i;
- result->AddProperty(&mirrorBlend, 1, "$mat.blend.mirror.blend", 0, 0);
-
- int mirrorDepth = source->ray_depth;
- result->AddProperty(&mirrorDepth, 1, "$mat.blend.mirror.depth", 0, 0);
-
- float mirrorMaxDist = source->dist_mir;
- result->AddProperty(&mirrorMaxDist, 1, "$mat.blend.mirror.maxDist", 0, 0);
-
- int mirrorFadeTo = source->fadeto_mir;
- result->AddProperty(&mirrorFadeTo, 1, "$mat.blend.mirror.fadeTo", 0, 0);
-
- float mirrorGlossAmount = source->gloss_mir;
- result->AddProperty(&mirrorGlossAmount, 1, "$mat.blend.mirror.glossAmount", 0, 0);
-
- float mirrorGlossThreshold = source->adapt_thresh_mir;
- result->AddProperty(&mirrorGlossThreshold, 1, "$mat.blend.mirror.glossThreshold", 0, 0);
-
- int mirrorGlossSamples = source->samp_gloss_mir;
- result->AddProperty(&mirrorGlossSamples, 1, "$mat.blend.mirror.glossSamples", 0, 0);
-
- float mirrorGlossAnisotropic = source->aniso_gloss_mir;
- result->AddProperty(&mirrorGlossAnisotropic, 1, "$mat.blend.mirror.glossAnisotropic", 0, 0);
-}
-
-void BlenderImporter::BuildMaterials(ConversionData& conv_data)
-{
- conv_data.materials->reserve(conv_data.materials_raw.size());
-
- BuildDefaultMaterial(conv_data);
-
- for(std::shared_ptr<Material> mat : conv_data.materials_raw) {
-
- // reset per material global counters
- for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
- conv_data.next_texture[i] = 0 ;
- }
-
- aiMaterial* mout = new aiMaterial();
- conv_data.materials->push_back(mout);
- // For any new material field handled here, the default material above must be updated with an appropriate default value.
-
- // set material name
- aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
- mout->AddProperty(&name,AI_MATKEY_NAME);
-
- // basic material colors
- aiColor3D col(mat->r,mat->g,mat->b);
- if (mat->r || mat->g || mat->b ) {
-
- // 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);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_SPECULAR);
-
- // is hardness/shininess set?
- if( mat->har ) {
- const float har = mat->har;
- mout->AddProperty(&har,1,AI_MATKEY_SHININESS);
- }
-
- col = aiColor3D(mat->ambr,mat->ambg,mat->ambb);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
-
- // is mirror enabled?
- if( mat->mode & MA_RAYMIRROR ) {
- const float ray_mirror = mat->ray_mirror;
- mout->AddProperty(&ray_mirror,1,AI_MATKEY_REFLECTIVITY);
- }
-
- col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
- mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
-
- for(size_t i = 0; i < sizeof(mat->mtex) / sizeof(mat->mtex[0]); ++i) {
- if (!mat->mtex[i]) {
- continue;
- }
-
- ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
- }
-
- AddBlendParams(mout, mat.get());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
-{
- ai_assert(dt);
- if (strcmp(dt->dna_type,check)) {
- ThrowException((format(),
- "Expected object at ",std::hex,dt," to be of type `",check,
- "`, but it claims to be a `",dt->dna_type,"`instead"
- ));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::NotSupportedObjectType(const Object* obj, const char* type)
-{
- LogWarn((format(), "Object `",obj->id.name,"` - type is unsupported: `",type, "`, skipping" ));
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, const Mesh* mesh,
- ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
- )
-{
- // TODO: Resolve various problems with BMesh triangulation before re-enabling.
- // See issues #400, #373, #318 #315 and #132.
-#if defined(TODO_FIX_BMESH_CONVERSION)
- BlenderBMeshConverter BMeshConverter( mesh );
- if ( BMeshConverter.ContainsBMesh( ) )
- {
- mesh = BMeshConverter.TriangulateBMesh( );
- }
-#endif
-
- typedef std::pair<const int,size_t> MyPair;
- if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
- return;
- }
-
- // some sanity checks
- if (static_cast<size_t> ( mesh->totface ) > mesh->mface.size() ){
- ThrowException("Number of faces is larger than the corresponding array");
- }
-
- if (static_cast<size_t> ( mesh->totvert ) > mesh->mvert.size()) {
- 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
- const size_t old = temp->size();
- temp->reserve(temp->size() + per_mat.size());
-
- std::map<size_t,size_t> mat_num_to_mesh_idx;
- for(MyPair& it : per_mat) {
-
- mat_num_to_mesh_idx[it.first] = temp->size();
- temp->push_back(new aiMesh());
-
- aiMesh* out = temp->back();
- out->mVertices = new aiVector3D[per_mat_verts[it.first]];
- out->mNormals = new aiVector3D[per_mat_verts[it.first]];
-
- //out->mNumFaces = 0
- //out->mNumVertices = 0
- out->mFaces = new aiFace[it.second]();
-
- // all sub-meshes created from this mesh are named equally. this allows
- // curious users to recover the original adjacency.
- out->mName = aiString(mesh->id.name+2);
- // skip over the name prefix 'ME'
-
- // resolve the material reference and add this material to the set of
- // output materials. The (temporary) material index is the index
- // of the material entry within the list of resolved materials.
- if (mesh->mat) {
-
- if (static_cast<size_t> ( it.first ) >= mesh->mat.size() ) {
- ThrowException("Material index is out of range");
- }
-
- std::shared_ptr<Material> mat = mesh->mat[it.first];
- const std::deque< std::shared_ptr<Material> >::iterator has = std::find(
- conv_data.materials_raw.begin(),
- conv_data.materials_raw.end(),mat
- );
-
- if (has != conv_data.materials_raw.end()) {
- out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
- }
- else {
- out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
- conv_data.materials_raw.push_back(mat);
- }
- }
- else out->mMaterialIndex = static_cast<unsigned int>( -1 );
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
-
- const MFace& mf = mesh->mface[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.v4?4:3 ];
- 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.
-
- if (mf.v1 >= mesh->totvert) {
- ThrowException("Vertex index v1 out of range");
- }
- const MVert* v = &mesh->mvert[mf.v1];
- 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[0] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- // if (f.mNumIndices >= 2) {
- if (mf.v2 >= mesh->totvert) {
- ThrowException("Vertex index v2 out of range");
- }
- v = &mesh->mvert[mf.v2];
- 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[1] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- if (mf.v3 >= mesh->totvert) {
- ThrowException("Vertex index v3 out of range");
- }
- // if (f.mNumIndices >= 3) {
- v = &mesh->mvert[mf.v3];
- 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[2] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- if (mf.v4 >= mesh->totvert) {
- ThrowException("Vertex index v4 out of range");
- }
- // if (f.mNumIndices >= 4) {
- if (mf.v4) {
- v = &mesh->mvert[mf.v4];
- 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[3] = out->mNumVertices++;
- ++vo;
- ++vn;
-
- out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
- else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
-
- // }
- // }
- // }
- }
-
- 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 || 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)");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
- const MTFace* v = &mesh->mtface[i];
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
- for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
- vo->x = v->uv[i][0];
- 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)
- if (mesh->tface) {
- if (mesh->totface > static_cast<int> ( mesh->tface.size())) {
- ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
- const TFace* v = &mesh->tface[i];
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
- for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
- vo->x = v->uv[i][0];
- vo->y = v->uv[i][1];
- }
- }
- }
-
- // collect vertex colors, stored separately as well
- 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");
- }
- for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
- ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
-
- (*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
- (*it)->mNumFaces = (*it)->mNumVertices = 0;
- }
-
- for (int i = 0; i < mesh->totface; ++i) {
-
- aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
- const aiFace& f = out->mFaces[out->mNumFaces++];
-
- aiColor4D* vo = &out->mColors[0][out->mNumVertices];
- for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
- const MCol* col = &mesh->mcol[(i<<2)+n];
-
- vo->r = col->r;
- vo->g = col->g;
- vo->b = col->b;
- vo->a = col->a;
- }
- 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];
- const ai_real scaleZeroToOne = 1.f/255.f;
- for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
- const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
- vo->r = ai_real(col.r) * scaleZeroToOne;
- vo->g = ai_real(col.g) * scaleZeroToOne;
- vo->b = ai_real(col.b) * scaleZeroToOne;
- vo->a = ai_real(col.a) * scaleZeroToOne;
- }
-
- }
-
- }
-
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* cam, ConversionData& /*conv_data*/)
-{
- std::unique_ptr<aiCamera> out(new aiCamera());
- 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);
- if (cam->sensor_x && cam->lens) {
- out->mHorizontalFOV = std::atan2(cam->sensor_x, 2.f * cam->lens);
- }
- out->mClipPlaneNear = cam->clipsta;
- out->mClipPlaneFar = cam->clipend;
-
- return out.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, const Lamp* lamp, ConversionData& /*conv_data*/)
-{
- std::unique_ptr<aiLight> out(new aiLight());
- out->mName = obj->id.name+2;
-
- 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);
- out->mUp = aiVector3D(0.f, 1.f, 0.f);
- break;
-
- case Lamp::Type_Area:
- out->mType = aiLightSource_AREA;
-
- if (lamp->area_shape == 0) {
- out->mSize = aiVector2D(lamp->area_size, lamp->area_size);
- }
- else {
- out->mSize = aiVector2D(lamp->area_size, lamp->area_sizey);
- }
-
- // blender orients directional lights as facing toward -z
- out->mDirection = aiVector3D(0.f, 0.f, -1.f);
- out->mUp = aiVector3D(0.f, 1.f, 0.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.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
-{
- std::deque<const Object*> children;
- for(ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
- const Object* object = *it;
- if (object->parent == obj) {
- children.push_back(object);
-
- conv_data.objects.erase(it++);
- continue;
- }
- ++it;
- }
-
- std::unique_ptr<aiNode> node(new aiNode(obj->id.name+2)); // skip over the name prefix 'OB'
- if (obj->data) {
- switch (obj->type)
- {
- case Object :: Type_EMPTY:
- break; // do nothing
-
-
- // supported object types
- case Object :: Type_MESH: {
- const size_t old = conv_data.meshes->size();
-
- CheckActualType(obj->data.get(),"Mesh");
- ConvertMesh(in,obj,static_cast<const Mesh*>(obj->data.get()),conv_data,conv_data.meshes);
-
- if (conv_data.meshes->size() > old) {
- node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
- for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
- node->mMeshes[i] = static_cast<unsigned int>(i + old);
- }
- }}
- break;
- case Object :: Type_LAMP: {
- CheckActualType(obj->data.get(),"Lamp");
- aiLight* mesh = ConvertLight(in,obj,static_cast<const Lamp*>(
- obj->data.get()),conv_data);
-
- if (mesh) {
- conv_data.lights->push_back(mesh);
- }}
- break;
- case Object :: Type_CAMERA: {
- CheckActualType(obj->data.get(),"Camera");
- aiCamera* mesh = ConvertCamera(in,obj,static_cast<const Camera*>(
- obj->data.get()),conv_data);
-
- if (mesh) {
- conv_data.cameras->push_back(mesh);
- }}
- break;
-
-
- // unsupported object types / log, but do not break
- case Object :: Type_CURVE:
- NotSupportedObjectType(obj,"Curve");
- break;
- case Object :: Type_SURF:
- NotSupportedObjectType(obj,"Surface");
- break;
- case Object :: Type_FONT:
- NotSupportedObjectType(obj,"Font");
- break;
- case Object :: Type_MBALL:
- NotSupportedObjectType(obj,"MetaBall");
- break;
- case Object :: Type_WAVE:
- NotSupportedObjectType(obj,"Wave");
- break;
- case Object :: Type_LATTICE:
- NotSupportedObjectType(obj,"Lattice");
- break;
-
- // invalid or unknown type
- default:
- break;
- }
- }
-
- for(unsigned int x = 0; x < 4; ++x) {
- for(unsigned int y = 0; y < 4; ++y) {
- node->mTransformation[y][x] = obj->obmat[x][y];
- }
- }
-
- aiMatrix4x4 m = parentTransform;
- m = m.Inverse();
-
- node->mTransformation = m*node->mTransformation;
-
- if (children.size()) {
- node->mNumChildren = static_cast<unsigned int>(children.size());
- aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
- for (const Object* nobj :children) {
- *nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform);
- (*nd++)->mParent = node.get();
- }
- }
-
- // apply modifiers
- modifier_cache->ApplyModifiers(*node,conv_data,in,*obj);
-
- return node.release();
-}
-
-#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
diff --git a/src/3rdparty/assimp/code/BlenderLoader.h b/src/3rdparty/assimp/code/BlenderLoader.h
deleted file mode 100644
index 66fff594b..000000000
--- a/src/3rdparty/assimp/code/BlenderLoader.h
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderLoader.h
- * @brief Declaration of the Blender 3D (*.blend) importer class.
- */
-#ifndef INCLUDED_AI_BLEND_LOADER_H
-#define INCLUDED_AI_BLEND_LOADER_H
-
-#include "BaseImporter.h"
-#include "LogAux.h"
-#include <memory>
-
-struct aiNode;
-struct aiMesh;
-struct aiLight;
-struct aiCamera;
-struct aiMaterial;
-
-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;
- }
-
- // BlenderDNA.h
- namespace Blender {
- class FileDatabase;
- struct ElemBase;
- }
-
- // BlenderScene.h
- namespace Blender {
- struct Scene;
- struct Object;
- struct Mesh;
- struct Camera;
- struct Lamp;
- struct MTex;
- struct Image;
- struct Material;
- }
-
- // BlenderIntermediate.h
- namespace Blender {
- struct ConversionData;
- template <template <typename,typename> class TCLASS, typename T> struct TempArray;
- }
-
- // BlenderModifier.h
- namespace Blender {
- class BlenderModifierShowcase;
- class BlenderModifier;
- }
-
-
-
-// -------------------------------------------------------------------------------------------
-/** Load blenders official binary format. The actual file structure (the `DNA` how they
- * call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
- * conversion from intermediate format to aiScene. */
-// -------------------------------------------------------------------------------------------
-class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
-{
-public:
- BlenderImporter();
- ~BlenderImporter();
-
-public:
-
- // --------------------
- bool CanRead( const std::string& pFile,
- IOSystem* pIOHandler,
- bool checkSig
- ) const;
-
-protected:
-
- // --------------------
- const aiImporterDesc* GetInfo () const;
-
- // --------------------
- void GetExtensionList(std::set<std::string>& app);
-
- // --------------------
- void SetupProperties(const Importer* pImp);
-
- // --------------------
- void InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler
- );
-
- // --------------------
- void ParseBlendFile(Blender::FileDatabase& out,
- std::shared_ptr<IOStream> stream
- );
-
- // --------------------
- void ExtractScene(Blender::Scene& out,
- const Blender::FileDatabase& file
- );
-
- // --------------------
- void ConvertBlendFile(aiScene* out,
- const Blender::Scene& in,
- const Blender::FileDatabase& file
- );
-
-private:
-
- // --------------------
- aiNode* ConvertNode(const Blender::Scene& in,
- const Blender::Object* obj,
- Blender::ConversionData& conv_info,
- const aiMatrix4x4& parentTransform
- );
-
- // --------------------
- void ConvertMesh(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Mesh* mesh,
- Blender::ConversionData& conv_data,
- Blender::TempArray<std::vector,aiMesh>& temp
- );
-
- // --------------------
- aiLight* ConvertLight(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Lamp* mesh,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- aiCamera* ConvertCamera(const Blender::Scene& in,
- const Blender::Object* obj,
- const Blender::Camera* mesh,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- void BuildDefaultMaterial(
- Blender::ConversionData& conv_data
- );
-
- void AddBlendParams(
- aiMaterial* result,
- const Blender::Material* source
- );
-
- void BuildMaterials(
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- void ResolveTexture(
- aiMaterial* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- Blender::ConversionData& conv_data
- );
-
- // --------------------
- void ResolveImage(
- aiMaterial* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- const Blender::Image* img,
- Blender::ConversionData& conv_data
- );
-
- void AddSentinelTexture(
- aiMaterial* out,
- const Blender::Material* mat,
- const Blender::MTex* tex,
- Blender::ConversionData& conv_data
- );
-
-private: // static stuff, mostly logging and error reporting.
-
- // --------------------
- static void CheckActualType(const Blender::ElemBase* dt,
- const char* check
- );
-
- // --------------------
- static void NotSupportedObjectType(const Blender::Object* obj,
- const char* type
- );
-
-
-private:
-
- Blender::BlenderModifierShowcase* modifier_cache;
-
-}; // !class BlenderImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/BlenderModifier.cpp b/src/3rdparty/assimp/code/BlenderModifier.cpp
deleted file mode 100644
index 348df1f48..000000000
--- a/src/3rdparty/assimp/code/BlenderModifier.cpp
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderModifier.cpp
- * @brief Implementation of some blender modifiers (i.e subdivision, mirror).
- */
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderModifier.h"
-#include <assimp/SceneCombiner.h>
-#include "Subdivision.h"
-#include <assimp/scene.h>
-#include <memory>
-
-#include <functional>
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-
-template <typename T> BlenderModifier* god() {
- return new T();
-}
-
-// add all available modifiers here
-typedef BlenderModifier* (*fpCreateModifier)();
-static const fpCreateModifier creators[] = {
- &god<BlenderModifier_Mirror>,
- &god<BlenderModifier_Subdivision>,
-
- NULL // sentinel
-};
-
-// ------------------------------------------------------------------------------------------------
-// just testing out some new macros to simplify logging
-#define ASSIMP_LOG_WARN_F(string,...)\
- DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_ERROR_F(string,...)\
- DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_DEBUG_F(string,...)\
- DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
-
-#define ASSIMP_LOG_INFO_F(string,...)\
- DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
-
-
-#define ASSIMP_LOG_WARN(string)\
- DefaultLogger::get()->warn(string)
-
-#define ASSIMP_LOG_ERROR(string)\
- DefaultLogger::get()->error(string)
-
-#define ASSIMP_LOG_DEBUG(string)\
- DefaultLogger::get()->debug(string)
-
-#define ASSIMP_LOG_INFO(string)\
- DefaultLogger::get()->info(string)
-
-
-// ------------------------------------------------------------------------------------------------
-struct SharedModifierData : ElemBase
-{
- ModifierData modifier;
-};
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
-{
- size_t cnt = 0u, ful = 0u;
-
- // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
- // we're allowed to dereference the pointers without risking to crash. We might still be
- // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
- // structures is at offset sizeof(vftable) with no padding.
- const SharedModifierData* cur = static_cast<const SharedModifierData *> ( orig_object.modifiers.first.get() );
- for (; cur; cur = static_cast<const SharedModifierData *> ( cur->modifier.next.get() ), ++ful) {
- ai_assert(cur->dna_type);
-
- const Structure* s = conv_data.db.dna.Get( cur->dna_type );
- if (!s) {
- ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
- continue;
- }
-
- // this is a common trait of all XXXMirrorData structures in BlenderDNA
- const Field* f = s->Get("modifier");
- if (!f || f->offset != 0) {
- ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
- continue;
- }
-
- s = conv_data.db.dna.Get( f->type );
- if (!s || s->name != "ModifierData") {
- ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
- continue;
- }
-
- // now, we can be sure that we should be fine to dereference *cur* as
- // ModifierData (with the above note).
- const ModifierData& dat = cur->modifier;
-
- const fpCreateModifier* curgod = creators;
- std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
-
- for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
- if (curmod == endmod) {
- cached_modifiers->push_back((*curgod)());
-
- endmod = cached_modifiers->end();
- curmod = endmod-1;
- }
-
- BlenderModifier* const modifier = *curmod;
- if(modifier->IsActive(dat)) {
- modifier->DoIt(out,conv_data,*static_cast<const ElemBase *>(cur),in,orig_object);
- cnt++;
-
- curgod = NULL;
- break;
- }
- }
- if (curgod) {
- ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
- }
- }
-
- // Even though we managed to resolve some or all of the modifiers on this
- // object, we still can't say whether our modifier implementations were
- // able to fully do their job.
- if (ful) {
- ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
- "`, check log messages above for errors");
- }
-}
-
-
-
-// ------------------------------------------------------------------------------------------------
-bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
-{
- return modin.type == ModifierData::eModifierType_Mirror;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
- const Scene& /*in*/,
- const Object& orig_object )
-{
- // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
- const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
- ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
-
- conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
-
- // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
-
- // take all input meshes and clone them
- for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
- aiMesh* mesh;
- SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
-
- const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
- const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
- const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
-
- if (mir.mirror_ob) {
- const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mVertices[i];
-
- v.x = center.x + xs*(center.x - v.x);
- v.y = center.y + ys*(center.y - v.y);
- v.z = center.z + zs*(center.z - v.z);
- }
- }
- else {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mVertices[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mNormals) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mNormals[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mTangents) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mTangents[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- if (mesh->mBitangents) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mBitangents[i];
- v.x *= xs;v.y *= ys;v.z *= zs;
- }
- }
-
- const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
- const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
-
- for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- aiVector3D& v = mesh->mTextureCoords[n][i];
- v.x *= us;v.y *= vs;
- }
- }
-
- // Only reverse the winding order if an odd number of axes were mirrored.
- if (xs * ys * zs < 0) {
- for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
- aiFace& face = mesh->mFaces[i];
- for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
- std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
- }
- }
-
- conv_data.meshes->push_back(mesh);
- }
- unsigned int* nind = new unsigned int[out.mNumMeshes*2];
-
- std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
- std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
- [&out](unsigned int n) { return out.mNumMeshes + n; });
-
- delete[] out.mMeshes;
- out.mMeshes = nind;
- out.mNumMeshes *= 2;
-
- ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
- orig_object.id.name,"`");
-}
-
-// ------------------------------------------------------------------------------------------------
-bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
-{
- return modin.type == ModifierData::eModifierType_Subsurf;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
- const Scene& /*in*/,
- const Object& orig_object )
-{
- // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
- const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
- ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
-
- Subdivider::Algorithm algo;
- switch (mir.subdivType)
- {
- case SubsurfModifierData::TYPE_CatmullClarke:
- algo = Subdivider::CATMULL_CLARKE;
- break;
-
- case SubsurfModifierData::TYPE_Simple:
- ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
- algo = Subdivider::CATMULL_CLARKE;
- break;
-
- default:
- ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
- return;
- };
-
- std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
- ai_assert(subd);
- if ( conv_data.meshes->empty() ) {
- return;
- }
- aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
- std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
-
- subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
- std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
-
- ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
- orig_object.id.name,"`");
-}
-
-#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
diff --git a/src/3rdparty/assimp/code/BlenderModifier.h b/src/3rdparty/assimp/code/BlenderModifier.h
deleted file mode 100644
index 9fa8c74ee..000000000
--- a/src/3rdparty/assimp/code/BlenderModifier.h
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderModifier.h
- * @brief Declare dedicated helper classes to simulate some blender modifiers (i.e. mirror)
- */
-#ifndef INCLUDED_AI_BLEND_MODIFIER_H
-#define INCLUDED_AI_BLEND_MODIFIER_H
-
-#include "BlenderIntermediate.h"
-#include "TinyFormatter.h"
-
-namespace Assimp {
-namespace Blender {
-
-// -------------------------------------------------------------------------------------------
-/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
- * they should be stateless and not try to cache model data. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier
-{
-public:
- virtual ~BlenderModifier() {
- // empty
- }
-
-public:
-
- // --------------------
- /** Check if *this* modifier is active, given a ModifierData& block.*/
- virtual bool IsActive( const ModifierData& /*modin*/) {
- return false;
- }
-
- // --------------------
- /** Apply the modifier to a given output node. The original data used
- * to construct the node is given as well. Not called unless IsActive()
- * was called and gave positive response. */
- virtual void DoIt(aiNode& /*out*/,
- ConversionData& /*conv_data*/,
- const ElemBase& orig_modifier,
- const Scene& /*in*/,
- const Object& /*orig_object*/
- ) {
- DefaultLogger::get()->warn((Formatter::format("This modifier is not supported, skipping: "),orig_modifier.dna_type));
- return;
- }
-};
-
-
-// -------------------------------------------------------------------------------------------
-/** Manage all known modifiers and instance and apply them if necessary */
-// -------------------------------------------------------------------------------------------
-class BlenderModifierShowcase
-{
-public:
-
- // --------------------
- /** Apply all requested modifiers provided we support them. */
- void ApplyModifiers(aiNode& out,
- ConversionData& conv_data,
- const Scene& in,
- const Object& orig_object
- );
-
-private:
-
- TempArray< std::vector,BlenderModifier > cached_modifiers;
-};
-
-
-
-
-
-// MODIFIERS
-
-
-
-// -------------------------------------------------------------------------------------------
-/** Mirror modifier. Status: implemented. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier_Mirror : public BlenderModifier
-{
-public:
-
- // --------------------
- virtual bool IsActive( const ModifierData& modin);
-
- // --------------------
- virtual void DoIt(aiNode& out,
- ConversionData& conv_data,
- const ElemBase& orig_modifier,
- const Scene& in,
- const Object& orig_object
- ) ;
-};
-
-// -------------------------------------------------------------------------------------------
-/** Subdivision modifier. Status: dummy. */
-// -------------------------------------------------------------------------------------------
-class BlenderModifier_Subdivision : public BlenderModifier
-{
-public:
-
- // --------------------
- virtual bool IsActive( const ModifierData& modin);
-
- // --------------------
- virtual void DoIt(aiNode& out,
- ConversionData& conv_data,
- const ElemBase& orig_modifier,
- const Scene& in,
- const Object& orig_object
- ) ;
-};
-
-
-}}
-#endif // !INCLUDED_AI_BLEND_MODIFIER_H
diff --git a/src/3rdparty/assimp/code/BlenderScene.cpp b/src/3rdparty/assimp/code/BlenderScene.cpp
deleted file mode 100644
index 0e1dec7f3..000000000
--- a/src/3rdparty/assimp/code/BlenderScene.cpp
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, ASSIMP Development 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 Development 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 BlenderScene.cpp
- * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
- */
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderScene.h"
-#include "BlenderSceneGen.h"
-#include "BlenderDNA.h"
-
-using namespace Assimp;
-using namespace Assimp::Blender;
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Object> (
- Object& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- int temp = 0;
- ReadField<ErrorPolicy_Fail>(temp,"type",db);
- dest.type = static_cast<Assimp::Blender::Object::Type>(temp);
- ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
- ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
- ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
- {
- std::shared_ptr<Object> parent;
- ReadFieldPtr<ErrorPolicy_Warn>(parent,"*parent",db);
- dest.parent = parent.get();
- }
- ReadFieldPtr<ErrorPolicy_Warn>(dest.track,"*track",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy,"*proxy",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_from,"*proxy_from",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_group,"*proxy_group",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.dup_group,"*dup_group",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
- ReadField<ErrorPolicy_Igno>(dest.modifiers,"modifiers",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Group> (
- Group& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MTex> (
- MTex& dest,
- const FileDatabase& db
- ) const
-{
-
- int temp_short = 0;
- ReadField<ErrorPolicy_Igno>(temp_short,"mapto",db);
- dest.mapto = static_cast<Assimp::Blender::MTex::MapType>(temp_short);
- int temp = 0;
- ReadField<ErrorPolicy_Igno>(temp,"blendtype",db);
- dest.blendtype = static_cast<Assimp::Blender::MTex::BlendType>(temp);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
- ReadField<ErrorPolicy_Igno>(temp,"projx",db);
- dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
- ReadField<ErrorPolicy_Igno>(temp,"projy",db);
- dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
- ReadField<ErrorPolicy_Igno>(temp,"projz",db);
- dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
- ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
- ReadField<ErrorPolicy_Igno>(dest.rot,"rot",db);
- ReadField<ErrorPolicy_Igno>(dest.texflag,"texflag",db);
- ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
- ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
- ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
- ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
- ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
- ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
- ReadField<ErrorPolicy_Igno>(dest.difffac,"difffac",db);
- 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);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<TFace> (
- TFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.col,"col",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
- ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<SubsurfModifierData> (
- SubsurfModifierData& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
- ReadField<ErrorPolicy_Warn>(dest.subdivType,"subdivType",db);
- ReadField<ErrorPolicy_Fail>(dest.levels,"levels",db);
- ReadField<ErrorPolicy_Igno>(dest.renderLevels,"renderLevels",db);
- ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MFace> (
- MFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
- ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
- ReadField<ErrorPolicy_Fail>(dest.v3,"v3",db);
- ReadField<ErrorPolicy_Fail>(dest.v4,"v4",db);
- ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Lamp> (
- Lamp& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- int temp = 0;
- ReadField<ErrorPolicy_Fail>(temp,"type",db);
- dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
- ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
- ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
- ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
- ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
- ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
- ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
- ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
- ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
- ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
- ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
- dest.falloff_type = static_cast<Assimp::Blender::Lamp::FalloffType>(temp);
- ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
- ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
- ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
- ReadField<ErrorPolicy_Igno>(dest.area_sizez,"area_sizez",db);
- ReadField<ErrorPolicy_Igno>(dest.area_shape,"area_shape",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MDeformWeight> (
- MDeformWeight& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
- ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<PackedFile> (
- PackedFile& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Warn>(dest.size,"size",db);
- ReadField<ErrorPolicy_Warn>(dest.seek,"seek",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.data,"*data",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Base> (
- Base& dest,
- const FileDatabase& db
- ) const
-{
- // 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);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MTFace> (
- MTFace& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
- ReadField<ErrorPolicy_Igno>(dest.unwrap,"unwrap",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Material> (
- Material& dest,
- const FileDatabase& db
- ) const
-{
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
- ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
- ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
- ReadField<ErrorPolicy_Warn>(dest.specr,"specr",db);
- ReadField<ErrorPolicy_Warn>(dest.specg,"specg",db);
- ReadField<ErrorPolicy_Warn>(dest.specb,"specb",db);
- ReadField<ErrorPolicy_Igno>(dest.har,"har",db);
- ReadField<ErrorPolicy_Warn>(dest.ambr,"ambr",db);
- ReadField<ErrorPolicy_Warn>(dest.ambg,"ambg",db);
- ReadField<ErrorPolicy_Warn>(dest.ambb,"ambb",db);
- ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
- ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
- ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
- ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
- ReadField<ErrorPolicy_Igno>(dest.ray_mirror,"ray_mirror",db);
- ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
- ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
- ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
- ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
- ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
- ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
- ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
-
-
- ReadField<ErrorPolicy_Igno>(dest.amb, "amb", db);
- ReadField<ErrorPolicy_Igno>(dest.ang, "ang", db);
- ReadField<ErrorPolicy_Igno>(dest.spectra, "spectra", db);
- ReadField<ErrorPolicy_Igno>(dest.spec, "spec", db);
- ReadField<ErrorPolicy_Igno>(dest.zoffs, "zoffs", db);
- ReadField<ErrorPolicy_Igno>(dest.add, "add", db);
- ReadField<ErrorPolicy_Igno>(dest.fresnel_mir, "fresnel_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.fresnel_mir_i, "fresnel_mir_i", db);
- ReadField<ErrorPolicy_Igno>(dest.fresnel_tra, "fresnel_tra", db);
- ReadField<ErrorPolicy_Igno>(dest.fresnel_tra_i, "fresnel_tra_i", db);
- ReadField<ErrorPolicy_Igno>(dest.filter, "filter", db);
- ReadField<ErrorPolicy_Igno>(dest.tx_limit, "tx_limit", db);
- ReadField<ErrorPolicy_Igno>(dest.tx_falloff, "tx_falloff", db);
- ReadField<ErrorPolicy_Igno>(dest.gloss_mir, "gloss_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.gloss_tra, "gloss_tra", db);
- ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_mir, "adapt_thresh_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_tra, "adapt_thresh_tra", db);
- ReadField<ErrorPolicy_Igno>(dest.aniso_gloss_mir, "aniso_gloss_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.dist_mir, "dist_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.hasize, "hasize", db);
- ReadField<ErrorPolicy_Igno>(dest.flaresize, "flaresize", db);
- ReadField<ErrorPolicy_Igno>(dest.subsize, "subsize", db);
- ReadField<ErrorPolicy_Igno>(dest.flareboost, "flareboost", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_sta, "strand_sta", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_end, "strand_end", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_ease, "strand_ease", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_surfnor, "strand_surfnor", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_min, "strand_min", db);
- ReadField<ErrorPolicy_Igno>(dest.strand_widthfade, "strand_widthfade", db);
- ReadField<ErrorPolicy_Igno>(dest.sbias, "sbias", db);
- ReadField<ErrorPolicy_Igno>(dest.lbias, "lbias", db);
- ReadField<ErrorPolicy_Igno>(dest.shad_alpha, "shad_alpha", db);
- ReadField<ErrorPolicy_Igno>(dest.param, "param", db);
- ReadField<ErrorPolicy_Igno>(dest.rms, "rms", db);
- ReadField<ErrorPolicy_Igno>(dest.rampfac_col, "rampfac_col", db);
- ReadField<ErrorPolicy_Igno>(dest.rampfac_spec, "rampfac_spec", db);
- ReadField<ErrorPolicy_Igno>(dest.friction, "friction", db);
- ReadField<ErrorPolicy_Igno>(dest.fh, "fh", db);
- ReadField<ErrorPolicy_Igno>(dest.reflect, "reflect", db);
- ReadField<ErrorPolicy_Igno>(dest.fhdist, "fhdist", db);
- ReadField<ErrorPolicy_Igno>(dest.xyfrict, "xyfrict", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_radius, "sss_radius", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_col, "sss_col", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_error, "sss_error", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_scale, "sss_scale", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_ior, "sss_ior", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_colfac, "sss_colfac", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_texfac, "sss_texfac", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_front, "sss_front", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_back, "sss_back", db);
-
- ReadField<ErrorPolicy_Igno>(dest.material_type, "material_type", db);
- ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
- ReadField<ErrorPolicy_Igno>(dest.ray_depth, "ray_depth", db);
- ReadField<ErrorPolicy_Igno>(dest.ray_depth_tra, "ray_depth_tra", db);
- ReadField<ErrorPolicy_Igno>(dest.samp_gloss_mir, "samp_gloss_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.samp_gloss_tra, "samp_gloss_tra", db);
- ReadField<ErrorPolicy_Igno>(dest.fadeto_mir, "fadeto_mir", db);
- ReadField<ErrorPolicy_Igno>(dest.shade_flag, "shade_flag", db);
- ReadField<ErrorPolicy_Igno>(dest.flarec, "flarec", db);
- ReadField<ErrorPolicy_Igno>(dest.starc, "starc", db);
- ReadField<ErrorPolicy_Igno>(dest.linec, "linec", db);
- ReadField<ErrorPolicy_Igno>(dest.ringc, "ringc", db);
- ReadField<ErrorPolicy_Igno>(dest.pr_lamp, "pr_lamp", db);
- ReadField<ErrorPolicy_Igno>(dest.pr_texture, "pr_texture", db);
- ReadField<ErrorPolicy_Igno>(dest.ml_flag, "ml_flag", db);
- ReadField<ErrorPolicy_Igno>(dest.diff_shader, "diff_shader", db);
- ReadField<ErrorPolicy_Igno>(dest.spec_shader, "spec_shader", db);
- ReadField<ErrorPolicy_Igno>(dest.texco, "texco", db);
- ReadField<ErrorPolicy_Igno>(dest.mapto, "mapto", db);
- ReadField<ErrorPolicy_Igno>(dest.ramp_show, "ramp_show", db);
- ReadField<ErrorPolicy_Igno>(dest.pad3, "pad3", db);
- ReadField<ErrorPolicy_Igno>(dest.dynamode, "dynamode", db);
- ReadField<ErrorPolicy_Igno>(dest.pad2, "pad2", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_flag, "sss_flag", db);
- ReadField<ErrorPolicy_Igno>(dest.sss_preset, "sss_preset", db);
- ReadField<ErrorPolicy_Igno>(dest.shadowonly_flag, "shadowonly_flag", db);
- ReadField<ErrorPolicy_Igno>(dest.index, "index", db);
- ReadField<ErrorPolicy_Igno>(dest.vcol_alpha, "vcol_alpha", db);
- ReadField<ErrorPolicy_Igno>(dest.pad4, "pad4", db);
-
- ReadField<ErrorPolicy_Igno>(dest.seed1, "seed1", db);
- ReadField<ErrorPolicy_Igno>(dest.seed2, "seed2", db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MTexPoly> (
- MTexPoly& dest,
- const FileDatabase& db
- ) const
-{
-
- {
- std::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
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- 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);
- ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.mface,"*mface",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
- 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);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MDeformVert> (
- MDeformVert& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
- ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<World> (
- World& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-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
- ) const
-{
-
- ReadFieldArray<ErrorPolicy_Fail>(dest.co,"co",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- //ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
- ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MEdge> (
- MEdge& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
- ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
- ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
- ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-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
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Fail>(dest.prev,"*prev",db);
- ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<ListBase> (
- ListBase& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Igno>(dest.first,"*first",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.last,"*last",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-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
- ) const
-{
-
- ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
- ReadField<ErrorPolicy_Igno>(dest.type,"type",db);
- ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
- ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<ID> (
- ID& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MCol> (
- MCol& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.r,"r",db);
- ReadField<ErrorPolicy_Fail>(dest.g,"g",db);
- ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
- ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MPoly> (
- MPoly& dest,
- const FileDatabase& db
- ) const
-{
-
- 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);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Scene> (
- Scene& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.camera,"*camera",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.world,"*world",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
- ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Library> (
- Library& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
- ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Tex> (
- Tex& dest,
- const FileDatabase& db
- ) const
-{
- short temp_short = 0;
- ReadField<ErrorPolicy_Igno>(temp_short,"imaflag",db);
- dest.imaflag = static_cast<Assimp::Blender::Tex::ImageFlags>(temp_short);
- int temp = 0;
- ReadField<ErrorPolicy_Fail>(temp,"type",db);
- dest.type = static_cast<Assimp::Blender::Tex::Type>(temp);
- ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<Camera> (
- Camera& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
- int temp = 0;
- ReadField<ErrorPolicy_Warn>(temp,"type",db);
- dest.type = static_cast<Assimp::Blender::Camera::Type>(temp);
- ReadField<ErrorPolicy_Warn>(temp,"flag",db);
- dest.flag = static_cast<Assimp::Blender::Camera::Type>(temp);
- ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
- ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
- ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
- ReadField<ErrorPolicy_Igno>(dest.clipend,"clipend",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-template <> void Structure :: Convert<MirrorModifierData> (
- MirrorModifierData& dest,
- const FileDatabase& db
- ) const
-{
-
- ReadField<ErrorPolicy_Fail>(dest.modifier,"modifier",db);
- ReadField<ErrorPolicy_Igno>(dest.axis,"axis",db);
- ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
- ReadField<ErrorPolicy_Igno>(dest.tolerance,"tolerance",db);
- ReadFieldPtr<ErrorPolicy_Igno>(dest.mirror_ob,"*mirror_ob",db);
-
- db.reader->IncPtr(size);
-}
-
-//--------------------------------------------------------------------------------
-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> );
- converters["Group"] = DNA::FactoryPair( &Structure::Allocate<Group>, &Structure::Convert<Group> );
- converters["MTex"] = DNA::FactoryPair( &Structure::Allocate<MTex>, &Structure::Convert<MTex> );
- converters["TFace"] = DNA::FactoryPair( &Structure::Allocate<TFace>, &Structure::Convert<TFace> );
- converters["SubsurfModifierData"] = DNA::FactoryPair( &Structure::Allocate<SubsurfModifierData>, &Structure::Convert<SubsurfModifierData> );
- converters["MFace"] = DNA::FactoryPair( &Structure::Allocate<MFace>, &Structure::Convert<MFace> );
- converters["Lamp"] = DNA::FactoryPair( &Structure::Allocate<Lamp>, &Structure::Convert<Lamp> );
- converters["MDeformWeight"] = DNA::FactoryPair( &Structure::Allocate<MDeformWeight>, &Structure::Convert<MDeformWeight> );
- converters["PackedFile"] = DNA::FactoryPair( &Structure::Allocate<PackedFile>, &Structure::Convert<PackedFile> );
- 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["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> );
-}
-
-#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
-
diff --git a/src/3rdparty/assimp/code/BlenderScene.h b/src/3rdparty/assimp/code/BlenderScene.h
deleted file mode 100644
index 86ab1f30c..000000000
--- a/src/3rdparty/assimp/code/BlenderScene.h
+++ /dev/null
@@ -1,900 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 BlenderScene.h
- * @brief Intermediate representation of a BLEND scene.
- */
-#ifndef INCLUDED_AI_BLEND_SCENE_H
-#define INCLUDED_AI_BLEND_SCENE_H
-
-#include "BlenderDNA.h"
-
-namespace Assimp {
-namespace Blender {
-
-// Minor parts of this file are extracts from blender data structures,
-// declared in the ./source/blender/makesdna directory.
-// Stuff that is not used by Assimp is commented.
-
-
-// NOTE
-// this file serves as input data to the `./scripts/genblenddna.py`
-// script. This script generates the actual binding code to read a
-// blender file with a possibly different DNA into our structures.
-// Only `struct` declarations are considered and the following
-// rules must be obeyed in order for the script to work properly:
-//
-// * C++ style comments only
-//
-// * Structures may include the primitive types char, int, short,
-// float, double. Signed specifiers are not allowed on
-// integers. Enum types are allowed, but they must have been
-// defined in this header.
-//
-// * Structures may aggregate other structures, unless not defined
-// in this header.
-//
-// * Pointers to other structures or primitive types are allowed.
-// No references or double pointers or arrays of pointers.
-// A pointer to a T is normally written as std::shared_ptr, while a
-// pointer to an array of elements is written as boost::
-// shared_array. To avoid cyclic pointers, use raw pointers in
-// one direction.
-//
-// * Arrays can have maximally two-dimensions. Any non-pointer
-// type can form them.
-//
-// * Multiple fields can be declare in a single line (i.e `int a,b;`)
-// provided they are neither pointers nor arrays.
-//
-// * One of WARN, FAIL can be appended to the declaration (
-// prior to the semicolon to specify the error handling policy if
-// this field is missing in the input DNA). If none of those
-// is specified the default policy is to substitute a default
-// value for the field.
-//
-
-// warn if field is missing, substitute default value
-#ifdef WARN
-# undef WARN
-#endif
-#define WARN
-
-// fail the import if the field does not exist
-#ifdef FAIL
-# undef FAIL
-#endif
-#define FAIL
-
-struct Object;
-struct MTex;
-struct Image;
-
-#include <memory>
-
-#define AI_BLEND_MESH_MAX_VERTS 2000000000L
-
-static const size_t MaxNameLen = 1024;
-
-// -------------------------------------------------------------------------------
-struct ID : ElemBase {
- char name[ MaxNameLen ] WARN;
- short flag;
-};
-
-// -------------------------------------------------------------------------------
-struct ListBase : ElemBase {
- std::shared_ptr<ElemBase> first;
- std::shared_ptr<ElemBase> last;
-};
-
-
-// -------------------------------------------------------------------------------
-struct PackedFile : ElemBase {
- int size WARN;
- int seek WARN;
- std::shared_ptr< FileOffset > data WARN;
-};
-
-// -------------------------------------------------------------------------------
-struct GroupObject : ElemBase {
- std::shared_ptr<GroupObject> prev,next FAIL;
- std::shared_ptr<Object> ob;
-};
-
-// -------------------------------------------------------------------------------
-struct Group : ElemBase {
- ID id FAIL;
- int layer;
-
- std::shared_ptr<GroupObject> gobject;
-};
-
-// -------------------------------------------------------------------------------
-struct World : ElemBase {
- ID id FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct MVert : ElemBase {
- float co[3] FAIL;
- float no[3] FAIL;
- char flag;
- int mat_nr WARN;
- int bweight;
-};
-
-// -------------------------------------------------------------------------------
-struct MEdge : ElemBase {
- int v1, v2 FAIL;
- char crease, bweight;
- short flag;
-};
-
-// -------------------------------------------------------------------------------
-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 {
- unsigned 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;
-};
-
-// -------------------------------------------------------------------------------
-struct MFace : ElemBase {
- int v1,v2,v3,v4 FAIL;
- int mat_nr FAIL;
- char flag;
-};
-
-// -------------------------------------------------------------------------------
-struct TFace : ElemBase {
- float uv[4][2] FAIL;
- int col[4] FAIL;
- char flag;
- short mode;
- short tile;
- short unwrap;
-};
-
-// -------------------------------------------------------------------------------
-struct MTFace : ElemBase {
- MTFace()
- : flag(0)
- , mode(0)
- , tile(0)
- , unwrap(0)
- {
- }
-
- float uv[4][2] FAIL;
- char flag;
- short mode;
- short tile;
- short unwrap;
-
- // std::shared_ptr<Image> tpage;
-};
-
-// -------------------------------------------------------------------------------
-struct MDeformWeight : ElemBase {
- int def_nr FAIL;
- float weight FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct MDeformVert : ElemBase {
- vector<MDeformWeight> dw WARN;
- int totweight;
-};
-
-// -------------------------------------------------------------------------------
-#define MA_RAYMIRROR 0x40000
-#define MA_TRANSPARENCY 0x10000
-#define MA_RAYTRANSP 0x20000
-#define MA_ZTRANSP 0x00040
-
-struct Material : ElemBase {
- ID id FAIL;
-
- float r,g,b WARN;
- float specr,specg,specb WARN;
- short har;
- float ambr,ambg,ambb WARN;
- float mirr,mirg,mirb;
- float emit WARN;
- float ray_mirror;
- float alpha WARN;
- float ref;
- float translucency;
- int mode;
- float roughness;
- float darkness;
- float refrac;
-
- float amb;
- float ang;
- float spectra;
- float spec;
- float zoffs;
- float add;
- float fresnel_mir;
- float fresnel_mir_i;
- float fresnel_tra;
- float fresnel_tra_i;
- float filter;
- float tx_limit;
- float tx_falloff;
- float gloss_mir;
- float gloss_tra;
- float adapt_thresh_mir;
- float adapt_thresh_tra;
- float aniso_gloss_mir;
- float dist_mir;
- float hasize;
- float flaresize;
- float subsize;
- float flareboost;
- float strand_sta;
- float strand_end;
- float strand_ease;
- float strand_surfnor;
- float strand_min;
- float strand_widthfade;
- float sbias;
- float lbias;
- float shad_alpha;
- float param;
- float rms;
- float rampfac_col;
- float rampfac_spec;
- float friction;
- float fh;
- float reflect;
- float fhdist;
- float xyfrict;
- float sss_radius;
- float sss_col;
- float sss_error;
- float sss_scale;
- float sss_ior;
- float sss_colfac;
- float sss_texfac;
- float sss_front;
- float sss_back;
-
- short material_type;
- short flag;
- short ray_depth;
- short ray_depth_tra;
- short samp_gloss_mir;
- short samp_gloss_tra;
- short fadeto_mir;
- short shade_flag;
- short flarec;
- short starc;
- short linec;
- short ringc;
- short pr_lamp;
- short pr_texture;
- short ml_flag;
- short texco;
- short mapto;
- short ramp_show;
- short pad3;
- short dynamode;
- short pad2;
- short sss_flag;
- short sss_preset;
- short shadowonly_flag;
- short index;
- short vcol_alpha;
- short pad4;
-
- char seed1;
- char seed2;
-
- std::shared_ptr<Group> group;
-
- short diff_shader WARN;
- short spec_shader WARN;
-
- std::shared_ptr<MTex> mtex[18];
-};
-
-// -------------------------------------------------------------------------------
-struct Mesh : ElemBase {
- ID id FAIL;
-
- int totface FAIL;
- int totedge FAIL;
- int totvert FAIL;
- int totloop;
- int totpoly;
-
- short subdiv;
- short subdivr;
- short subsurftype;
- short smoothresh;
-
- vector<MFace> mface FAIL;
- vector<MTFace> mtface;
- 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;
-
- vector< std::shared_ptr<Material> > mat FAIL;
-};
-
-// -------------------------------------------------------------------------------
-struct Library : ElemBase {
- ID id FAIL;
-
- char name[240] WARN;
- char filename[240] FAIL;
- std::shared_ptr<Library> parent WARN;
-};
-
-// -------------------------------------------------------------------------------
-struct Camera : ElemBase {
- enum Type {
- Type_PERSP = 0
- ,Type_ORTHO = 1
- };
-
- ID id FAIL;
-
- Type type,flag WARN;
- float lens WARN;
- float sensor_x WARN;
- float clipsta, clipend;
-};
-
-
-// -------------------------------------------------------------------------------
-struct Lamp : ElemBase {
-
- enum FalloffType {
- FalloffType_Constant = 0x0
- ,FalloffType_InvLinear = 0x1
- ,FalloffType_InvSquare = 0x2
- //,FalloffType_Curve = 0x3
- //,FalloffType_Sliders = 0x4
- };
-
- enum Type {
- Type_Local = 0x0
- ,Type_Sun = 0x1
- ,Type_Spot = 0x2
- ,Type_Hemi = 0x3
- ,Type_Area = 0x4
- //,Type_YFPhoton = 0x5
- };
-
- ID id FAIL;
- //AnimData *adt;
-
- Type type FAIL;
- short flags;
-
- //int mode;
-
- short colormodel, totex;
- float r,g,b,k WARN;
- //float shdwr, shdwg, shdwb;
-
- float energy, dist, spotsize, spotblend;
- //float haint;
-
- float att1, att2;
- //struct CurveMapping *curfalloff;
- FalloffType falloff_type;
-
- //float clipsta, clipend, shadspotsize;
- //float bias, soft, compressthresh;
- //short bufsize, samp, buffers, filtertype;
- //char bufflag, buftype;
-
- //short ray_samp, ray_sampy, ray_sampz;
- //short ray_samp_type;
- short area_shape;
- float area_size, area_sizey, area_sizez;
- //float adapt_thresh;
- //short ray_samp_method;
-
- //short texact, shadhalostep;
-
- //short sun_effect_type;
- //short skyblendtype;
- //float horizon_brightness;
- //float spread;
- float sun_brightness;
- //float sun_size;
- //float backscattered_light;
- //float sun_intensity;
- //float atm_turbidity;
- //float atm_inscattering_factor;
- //float atm_extinction_factor;
- //float atm_distance_factor;
- //float skyblendfac;
- //float sky_exposure;
- //short sky_colorspace;
-
- // int YF_numphotons, YF_numsearch;
- // short YF_phdepth, YF_useqmc, YF_bufsize, YF_pad;
- // float YF_causticblur, YF_ltradius;
-
- // float YF_glowint, YF_glowofs;
- // short YF_glowtype, YF_pad2;
-
- //struct Ipo *ipo;
- //struct MTex *mtex[18];
- // short pr_texture;
-
- //struct PreviewImage *preview;
-};
-
-// -------------------------------------------------------------------------------
-struct ModifierData : ElemBase {
- enum ModifierType {
- eModifierType_None = 0,
- eModifierType_Subsurf,
- eModifierType_Lattice,
- eModifierType_Curve,
- eModifierType_Build,
- eModifierType_Mirror,
- eModifierType_Decimate,
- eModifierType_Wave,
- eModifierType_Armature,
- eModifierType_Hook,
- eModifierType_Softbody,
- eModifierType_Boolean,
- eModifierType_Array,
- eModifierType_EdgeSplit,
- eModifierType_Displace,
- eModifierType_UVProject,
- eModifierType_Smooth,
- eModifierType_Cast,
- eModifierType_MeshDeform,
- eModifierType_ParticleSystem,
- eModifierType_ParticleInstance,
- eModifierType_Explode,
- eModifierType_Cloth,
- eModifierType_Collision,
- eModifierType_Bevel,
- eModifierType_Shrinkwrap,
- eModifierType_Fluidsim,
- eModifierType_Mask,
- eModifierType_SimpleDeform,
- eModifierType_Multires,
- eModifierType_Surface,
- eModifierType_Smoke,
- eModifierType_ShapeKey
- };
-
- std::shared_ptr<ElemBase> next WARN;
- std::shared_ptr<ElemBase> prev WARN;
-
- int type, mode;
- char name[32];
-};
-
-// -------------------------------------------------------------------------------
-struct SubsurfModifierData : ElemBase {
-
- enum Type {
-
- TYPE_CatmullClarke = 0x0,
- TYPE_Simple = 0x1
- };
-
- enum Flags {
- // some omitted
- FLAGS_SubsurfUV =1<<3
- };
-
- ModifierData modifier FAIL;
- short subdivType WARN;
- short levels FAIL;
- short renderLevels ;
- short flags;
-};
-
-// -------------------------------------------------------------------------------
-struct MirrorModifierData : ElemBase {
-
- enum Flags {
- Flags_CLIPPING =1<<0,
- Flags_MIRROR_U =1<<1,
- Flags_MIRROR_V =1<<2,
- Flags_AXIS_X =1<<3,
- Flags_AXIS_Y =1<<4,
- Flags_AXIS_Z =1<<5,
- Flags_VGROUP =1<<6
- };
-
- ModifierData modifier FAIL;
-
- short axis, flag;
- float tolerance;
- std::shared_ptr<Object> mirror_ob;
-};
-
-// -------------------------------------------------------------------------------
-struct Object : ElemBase {
- ID id FAIL;
-
- enum Type {
- Type_EMPTY = 0
- ,Type_MESH = 1
- ,Type_CURVE = 2
- ,Type_SURF = 3
- ,Type_FONT = 4
- ,Type_MBALL = 5
-
- ,Type_LAMP = 10
- ,Type_CAMERA = 11
-
- ,Type_WAVE = 21
- ,Type_LATTICE = 22
- };
-
- Type type FAIL;
- float obmat[4][4] WARN;
- float parentinv[4][4] WARN;
- char parsubstr[32] WARN;
-
- Object* parent WARN;
- std::shared_ptr<Object> track WARN;
-
- std::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
- std::shared_ptr<Group> dup_group WARN;
- std::shared_ptr<ElemBase> data FAIL;
-
- ListBase modifiers;
-
- Object()
- : ElemBase()
- , type( Type_EMPTY )
- , parent( nullptr )
- , track()
- , proxy()
- , proxy_from()
- , data() {
- // empty
- }
-};
-
-
-// -------------------------------------------------------------------------------
-struct Base : ElemBase {
- Base* prev WARN;
- std::shared_ptr<Base> next WARN;
- std::shared_ptr<Object> object WARN;
-
- Base()
- : ElemBase()
- , prev( nullptr )
- , next()
- , object() {
- // empty
- // empty
- }
-};
-
-// -------------------------------------------------------------------------------
-struct Scene : ElemBase {
- ID id FAIL;
-
- std::shared_ptr<Object> camera WARN;
- std::shared_ptr<World> world WARN;
- std::shared_ptr<Base> basact WARN;
-
- ListBase base;
-
- Scene()
- : ElemBase()
- , camera()
- , world()
- , basact() {
- // empty
- }
-};
-
-// -------------------------------------------------------------------------------
-struct Image : ElemBase {
- ID id FAIL;
-
- char name[240] WARN;
-
- //struct anim *anim;
-
- short ok, flag;
- short source, type, pad, pad1;
- int lastframe;
-
- short tpageflag, totbind;
- short xrep, yrep;
- short twsta, twend;
- //unsigned int bindcode;
- //unsigned int *repbind;
-
- std::shared_ptr<PackedFile> packedfile;
- //struct PreviewImage * preview;
-
- float lastupdate;
- int lastused;
- short animspeed;
-
- short gen_x, gen_y, gen_type;
-
- Image()
- : ElemBase() {
- // empty
- }
-};
-
-// -------------------------------------------------------------------------------
-struct Tex : ElemBase {
-
- // actually, the only texture type we support is Type_IMAGE
- enum Type {
- Type_CLOUDS = 1
- ,Type_WOOD = 2
- ,Type_MARBLE = 3
- ,Type_MAGIC = 4
- ,Type_BLEND = 5
- ,Type_STUCCI = 6
- ,Type_NOISE = 7
- ,Type_IMAGE = 8
- ,Type_PLUGIN = 9
- ,Type_ENVMAP = 10
- ,Type_MUSGRAVE = 11
- ,Type_VORONOI = 12
- ,Type_DISTNOISE = 13
- ,Type_POINTDENSITY = 14
- ,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;
-
- //float noisesize, turbul;
- //float bright, contrast, rfac, gfac, bfac;
- //float filtersize;
-
- //float mg_H, mg_lacunarity, mg_octaves, mg_offset, mg_gain;
- //float dist_amount, ns_outscale;
-
- //float vn_w1;
- //float vn_w2;
- //float vn_w3;
- //float vn_w4;
- //float vn_mexp;
- //short vn_distm, vn_coltype;
-
- //short noisedepth, noisetype;
- //short noisebasis, noisebasis2;
-
- //short flag;
- ImageFlags imaflag;
- Type type FAIL;
- //short stype;
-
- //float cropxmin, cropymin, cropxmax, cropymax;
- //int texfilter;
- //int afmax;
- //short xrepeat, yrepeat;
- //short extend;
-
- //short fie_ima;
- //int len;
- //int frames, offset, sfra;
-
- //float checkerdist, nabla;
- //float norfac;
-
- //ImageUser iuser;
-
- //bNodeTree *nodetree;
- //Ipo *ipo;
- std::shared_ptr<Image> ima WARN;
- //PluginTex *plugin;
- //ColorBand *coba;
- //EnvMap *env;
- //PreviewImage * preview;
- //PointDensity *pd;
- //VoxelData *vd;
-
- //char use_nodes;
-
- Tex()
- : ElemBase()
- , imaflag( ImageFlags_INTERPOL )
- , type( Type_CLOUDS )
- , ima() {
- // empty
- }
-};
-
-// -------------------------------------------------------------------------------
-struct MTex : ElemBase {
-
- enum Projection {
- Proj_N = 0
- ,Proj_X = 1
- ,Proj_Y = 2
- ,Proj_Z = 3
- };
-
- enum Flag {
- Flag_RGBTOINT = 0x1
- ,Flag_STENCIL = 0x2
- ,Flag_NEGATIVE = 0x4
- ,Flag_ALPHAMIX = 0x8
- ,Flag_VIEWSPACE = 0x10
- };
-
- enum BlendType {
- BlendType_BLEND = 0
- ,BlendType_MUL = 1
- ,BlendType_ADD = 2
- ,BlendType_SUB = 3
- ,BlendType_DIV = 4
- ,BlendType_DARK = 5
- ,BlendType_DIFF = 6
- ,BlendType_LIGHT = 7
- ,BlendType_SCREEN = 8
- ,BlendType_OVERLAY = 9
- ,BlendType_BLEND_HUE = 10
- ,BlendType_BLEND_SAT = 11
- ,BlendType_BLEND_VAL = 12
- ,BlendType_BLEND_COLOR = 13
- };
-
- 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;
- std::shared_ptr<Object> object;
- std::shared_ptr<Tex> tex;
- char uvname[32];
-
- Projection projx,projy,projz;
- char mapping;
- float ofs[3], size[3], rot;
-
- int texflag;
- short colormodel, pmapto, pmaptoneg;
- //short normapspace, which_output;
- //char brush_map_mode;
- float r,g,b,k WARN;
- //float def_var, rt;
-
- //float colfac, varfac;
-
- float norfac;
- //float dispfac, warpfac;
- float colspecfac, mirrfac, alphafac;
- float difffac, specfac, emitfac, hardfac;
- //float raymirrfac, translfac, ambfac;
- //float colemitfac, colreflfac, coltransfac;
- //float densfac, scatterfac, reflfac;
-
- //float timefac, lengthfac, clumpfac;
- //float kinkfac, roughfac, padensfac;
- //float lifefac, sizefac, ivelfac, pvelfac;
- //float shadowfac;
- //float zenupfac, zendownfac, blendfac;
-
- MTex()
- : ElemBase() {
- // empty
- }
-};
-
-}
-}
-#endif
diff --git a/src/3rdparty/assimp/code/BlenderSceneGen.h b/src/3rdparty/assimp/code/BlenderSceneGen.h
deleted file mode 100644
index 92c727eb2..000000000
--- a/src/3rdparty/assimp/code/BlenderSceneGen.h
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, ASSIMP Development 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 Development 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 BlenderSceneGen.h
- * @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
- */
-#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
-#define INCLUDED_AI_BLEND_SCENEGEN_H
-
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-
-namespace Assimp {
-namespace Blender {
-
-template <> void Structure :: Convert<Object> (
- Object& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Group> (
- Group& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MTex> (
- MTex& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<TFace> (
- TFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<SubsurfModifierData> (
- SubsurfModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MFace> (
- MFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Lamp> (
- Lamp& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MDeformWeight> (
- MDeformWeight& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<PackedFile> (
- PackedFile& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Base> (
- Base& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MTFace> (
- MTFace& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Material> (
- Material& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MTexPoly> (
- MTexPoly& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Mesh> (
- Mesh& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MDeformVert> (
- MDeformVert& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<World> (
- World& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MLoopCol> (
- MLoopCol& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MVert> (
- MVert& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MEdge> (
- MEdge& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MLoopUV> (
- MLoopUV& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<GroupObject> (
- GroupObject& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ListBase> (
- ListBase& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MLoop> (
- MLoop& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ModifierData> (
- ModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<ID> (
- ID& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MCol> (
- MCol& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MPoly> (
- MPoly& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Scene> (
- Scene& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Library> (
- Library& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Tex> (
- Tex& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Camera> (
- Camera& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<MirrorModifierData> (
- MirrorModifierData& dest,
- const FileDatabase& db
- ) const
-;
-
-template <> void Structure :: Convert<Image> (
- Image& dest,
- const FileDatabase& db
- ) const
-;
-
-
- }
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/BlenderTessellator.cpp b/src/3rdparty/assimp/code/BlenderTessellator.cpp
deleted file mode 100644
index 9f4c51048..000000000
--- a/src/3rdparty/assimp/code/BlenderTessellator.cpp
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-
-#include "BlenderDNA.h"
-#include "BlenderScene.h"
-#include "BlenderBMesh.h"
-#include "BlenderTessellator.h"
-
-#include <stddef.h>
-
-static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
-
-#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
-
-namspace Assimp
-{
- template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
- {
- static auto prefix = "BLEND_TESS_GL: ";
- return prefix;
- }
-}
-
-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 tri-strips 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 )
-{
- const 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 )
-{
- const 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 )
-{
- const 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 char* LogFunctions< BlenderTessellatorP2T >::Prefix()
- {
- static auto prefix = "BLEND_TESS_P2T: ";
- return prefix;
- }
-}
-
-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 ( std::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 ( size_t 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 ( size_t i = 0; i < points.size( ); ++i )
- {
- pointRefs[ i ] = &points[ i ].point2D;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-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 ( size_t 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 ( unsigned int x = 0; x < 3; ++x )
- {
- for ( unsigned int y = 0; y < 3; ++y )
- {
- result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
- }
- }
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apparently Assimp doesn't have matrix scaling
-aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
-{
- aiMatrix3x3 result;
-
- for ( unsigned int x = 0; x < 3; ++x )
- {
- for ( unsigned 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
-{
- 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.0 );
- for ( size_t i = 0; i < points.size( ); ++i )
- {
- sum += points[ i ].point3D;
- }
- result.centre = sum * (ai_real)( 1.0 / points.size( ) );
-
- ai_real sumXX = 0.0;
- ai_real sumXY = 0.0;
- ai_real sumXZ = 0.0;
- ai_real sumYY = 0.0;
- ai_real sumYZ = 0.0;
- ai_real sumZZ = 0.0;
- for ( size_t 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 );
-
- const ai_real 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
deleted file mode 100644
index 47d3a4665..000000000
--- a/src/3rdparty/assimp/code/BlenderTessellator.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
deleted file mode 100644
index f406ea0fe..000000000
--- a/src/3rdparty/assimp/code/BlobIOSystem.h
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Provides cheat implementations for IOSystem and IOStream to
- * redirect exporter output to a blob chain.*/
-
-#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
-#define AI_BLOBIOSYSTEM_H_INCLUDED
-
-#include <assimp/IOStream.hpp>
-#include <assimp/cexport.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <stdint.h>
-#include <set>
-#include <vector>
-
-namespace Assimp {
- class BlobIOSystem;
-
-// --------------------------------------------------------------------------------------------
-/** Redirect IOStream to a blob */
-// --------------------------------------------------------------------------------------------
-class BlobIOStream : public IOStream
-{
-public:
-
- BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
- : buffer()
- , cur_size()
- , file_size()
- , cursor()
- , initial(initial)
- , file(file)
- , creator(creator)
- {
- }
-
-
- virtual ~BlobIOStream();
-
-public:
-
- // -------------------------------------------------------------------
- aiExportDataBlob* GetBlob()
- {
- aiExportDataBlob* blob = new aiExportDataBlob();
- blob->size = file_size;
- blob->data = buffer;
-
- buffer = NULL;
-
- return blob;
- }
-
-
-public:
-
-
- // -------------------------------------------------------------------
- virtual size_t Read( void *,
- size_t,
- size_t )
- {
- return 0;
- }
-
- // -------------------------------------------------------------------
- virtual size_t Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount)
- {
- pSize *= pCount;
- if (cursor + pSize > cur_size) {
- Grow(cursor + pSize);
- }
-
- memcpy(buffer+cursor, pvBuffer, pSize);
- cursor += pSize;
-
- file_size = std::max(file_size,cursor);
- return pCount;
- }
-
- // -------------------------------------------------------------------
- virtual aiReturn Seek(size_t pOffset,
- aiOrigin pOrigin)
- {
- switch(pOrigin)
- {
- case aiOrigin_CUR:
- cursor += pOffset;
- break;
-
- case aiOrigin_END:
- cursor = file_size - pOffset;
- break;
-
- case aiOrigin_SET:
- cursor = pOffset;
- break;
-
- default:
- return AI_FAILURE;
- }
-
- if (cursor > file_size) {
- Grow(cursor);
- }
-
- file_size = std::max(cursor,file_size);
- return AI_SUCCESS;
- }
-
- // -------------------------------------------------------------------
- virtual size_t Tell() const
- {
- return cursor;
- }
-
- // -------------------------------------------------------------------
- virtual size_t FileSize() const
- {
- return file_size;
- }
-
- // -------------------------------------------------------------------
- virtual void Flush()
- {
- // ignore
- }
-
-
-
-private:
-
- // -------------------------------------------------------------------
- void Grow(size_t need = 0)
- {
- // 1.5 and phi are very heap-friendly growth factors (the first
- // allows for frequent re-use of heap blocks, the second
- // forms a fibonacci sequence with similar characteristics -
- // since this heavily depends on the heap implementation
- // and other factors as well, i'll just go with 1.5 since
- // it is quicker to compute).
- size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
-
- const uint8_t* const old = buffer;
- buffer = new uint8_t[new_size];
-
- if (old) {
- memcpy(buffer,old,cur_size);
- delete[] old;
- }
-
- cur_size = new_size;
- }
-
-private:
-
- uint8_t* buffer;
- size_t cur_size,file_size, cursor, initial;
-
- const std::string file;
- BlobIOSystem* const creator;
-};
-
-
-#define AI_BLOBIO_MAGIC "$blobfile"
-
-// --------------------------------------------------------------------------------------------
-/** Redirect IOSystem to a blob */
-// --------------------------------------------------------------------------------------------
-class BlobIOSystem : public IOSystem
-{
-
- friend class BlobIOStream;
- typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
-
-public:
-
- BlobIOSystem()
- {
- }
-
- virtual ~BlobIOSystem()
- {
- for(BlobEntry& blobby : blobs) {
- delete blobby.second;
- }
- }
-
-public:
-
- // -------------------------------------------------------------------
- const char* GetMagicFileName() const
- {
- return AI_BLOBIO_MAGIC;
- }
-
-
- // -------------------------------------------------------------------
- aiExportDataBlob* GetBlobChain()
- {
- // one must be the master
- aiExportDataBlob* master = NULL, *cur;
- for(const BlobEntry& blobby : blobs) {
- if (blobby.first == AI_BLOBIO_MAGIC) {
- master = blobby.second;
- break;
- }
- }
- if (!master) {
- DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
- return NULL;
- }
-
- master->name.Set("");
-
- cur = master;
- for(const BlobEntry& blobby : blobs) {
- if (blobby.second == master) {
- continue;
- }
-
- cur->next = blobby.second;
- cur = cur->next;
-
- // extract the file extension from the file written
- const std::string::size_type s = blobby.first.find_first_of('.');
- cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
- }
-
- // give up blob ownership
- blobs.clear();
- return master;
- }
-
-public:
-
- // -------------------------------------------------------------------
- virtual bool Exists( const char* pFile) const {
- return created.find(std::string(pFile)) != created.end();
- }
-
-
- // -------------------------------------------------------------------
- virtual char getOsSeparator() const {
- return '/';
- }
-
-
- // -------------------------------------------------------------------
- virtual IOStream* Open(const char* pFile,
- const char* pMode)
- {
- if (pMode[0] != 'w') {
- return NULL;
- }
-
- created.insert(std::string(pFile));
- return new BlobIOStream(this,std::string(pFile));
- }
-
- // -------------------------------------------------------------------
- virtual void Close( IOStream* pFile)
- {
- delete pFile;
- }
-
-private:
-
- // -------------------------------------------------------------------
- void OnDestruct(const std::string& filename, BlobIOStream* child)
- {
- // we don't know in which the files are closed, so we
- // can't reliably say that the first must be the master
- // file ...
- blobs.push_back( BlobEntry(filename,child->GetBlob()) );
- }
-
-private:
- std::set<std::string> created;
- std::vector< BlobEntry > blobs;
-};
-
-
-// --------------------------------------------------------------------------------------------
-BlobIOStream :: ~BlobIOStream()
-{
- creator->OnDestruct(file,this);
- delete[] buffer;
-}
-
-
-} // end Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/ByteSwapper.h b/src/3rdparty/assimp/code/ByteSwapper.h
deleted file mode 100644
index e5c7569f1..000000000
--- a/src/3rdparty/assimp/code/ByteSwapper.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Helper class tp perform various byte oder swappings
- (e.g. little to big endian) */
-#ifndef AI_BYTESWAPPER_H_INC
-#define AI_BYTESWAPPER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/types.h>
-#include <stdint.h>
-
-#if _MSC_VER >= 1400
-#include <stdlib.h>
-#endif
-
-namespace Assimp {
-// --------------------------------------------------------------------------------------
-/** Defines some useful byte order swap routines.
- *
- * This is required to read big-endian model formats on little-endian machines,
- * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
-// --------------------------------------------------------------------------------------
-class ByteSwap
-{
- ByteSwap() {}
-
-public:
-
- // ----------------------------------------------------------------------
- /** Swap two bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap2(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
- *szOut = _byteswap_ushort(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[1]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** Swap four bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap4(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
- *szOut = _byteswap_ulong(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[3]);
- std::swap(szOut[1],szOut[2]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** Swap eight bytes of data
- * @param[inout] _szOut A void* to save the reintcasts for the caller. */
- static inline void Swap8(void* _szOut)
- {
- ai_assert(_szOut);
-
-#if _MSC_VER >= 1400
- uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
- *szOut = _byteswap_uint64(*szOut);
-#else
- uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
- std::swap(szOut[0],szOut[7]);
- std::swap(szOut[1],szOut[6]);
- std::swap(szOut[2],szOut[5]);
- std::swap(szOut[3],szOut[4]);
-#endif
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap a float. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(float* fOut) {
- Swap4(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap a double. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(double* fOut) {
- Swap8(fOut);
- }
-
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int16t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int16_t* fOut) {
- Swap2(fOut);
- }
-
- static inline void Swap(uint16_t* fOut) {
- Swap2(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int32t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int32_t* fOut){
- Swap4(fOut);
- }
-
- static inline void Swap(uint32_t* fOut){
- Swap4(fOut);
- }
-
- // ----------------------------------------------------------------------
- /** ByteSwap an int64t. Not a joke.
- * @param[inout] fOut ehm. .. */
- static inline void Swap(int64_t* fOut) {
- Swap8(fOut);
- }
-
- static inline void Swap(uint64_t* fOut) {
- Swap8(fOut);
- }
-
- // ----------------------------------------------------------------------
- //! Templatized ByteSwap
- //! \returns param tOut as swapped
- template<typename Type>
- static inline Type Swapped(Type tOut)
- {
- return _swapper<Type,sizeof(Type)>()(tOut);
- }
-
-private:
-
- template <typename T, size_t size> struct _swapper;
-};
-
-template <typename T> struct ByteSwap::_swapper<T,2> {
- T operator() (T tOut) {
- Swap2(&tOut);
- return tOut;
- }
-};
-
-template <typename T> struct ByteSwap::_swapper<T,4> {
- T operator() (T tOut) {
- Swap4(&tOut);
- return tOut;
- }
-};
-
-template <typename T> struct ByteSwap::_swapper<T,8> {
- T operator() (T tOut) {
- Swap8(&tOut);
- return tOut;
- }
-};
-
-
-// --------------------------------------------------------------------------------------
-// ByteSwap macros for BigEndian/LittleEndian support
-// --------------------------------------------------------------------------------------
-#if (defined AI_BUILD_BIG_ENDIAN)
-# define AI_LE(t) (t)
-# define AI_BE(t) ByteSwap::Swapped(t)
-# define AI_LSWAP2(p)
-# define AI_LSWAP4(p)
-# define AI_LSWAP8(p)
-# define AI_LSWAP2P(p)
-# define AI_LSWAP4P(p)
-# define AI_LSWAP8P(p)
-# define LE_NCONST const
-# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
-# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
-# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
-# define AI_SWAP2P(p) ByteSwap::Swap2((p))
-# define AI_SWAP4P(p) ByteSwap::Swap4((p))
-# define AI_SWAP8P(p) ByteSwap::Swap8((p))
-# define BE_NCONST
-#else
-# define AI_BE(t) (t)
-# define AI_LE(t) ByteSwap::Swapped(t)
-# define AI_SWAP2(p)
-# define AI_SWAP4(p)
-# define AI_SWAP8(p)
-# define AI_SWAP2P(p)
-# define AI_SWAP4P(p)
-# define AI_SWAP8P(p)
-# define BE_NCONST const
-# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
-# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
-# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
-# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
-# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
-# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
-# define LE_NCONST
-#endif
-
-
-namespace Intern {
-
-// --------------------------------------------------------------------------------------------
-template <typename T, bool doit>
-struct ByteSwapper {
- void operator() (T* inout) {
- ByteSwap::Swap(inout);
- }
-};
-
-template <typename T>
-struct ByteSwapper<T,false> {
- void operator() (T*) {
- }
-};
-
-// --------------------------------------------------------------------------------------------
-template <bool SwapEndianess, typename T, bool RuntimeSwitch>
-struct Getter {
- void operator() (T* inout, bool le) {
-#ifdef AI_BUILD_BIG_ENDIAN
- le = le;
-#else
- le = !le;
-#endif
- if (le) {
- ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
- }
- else ByteSwapper<T,false> () (inout);
- }
-};
-
-template <bool SwapEndianess, typename T>
-struct Getter<SwapEndianess,T,false> {
-
- void operator() (T* inout, bool /*le*/) {
- // static branch
- ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
- }
-};
-} // end Intern
-} // end Assimp
-
-#endif //!! AI_BYTESWAPPER_H_INC
diff --git a/src/3rdparty/assimp/code/C4DImporter.cpp b/src/3rdparty/assimp/code/C4DImporter.cpp
deleted file mode 100644
index 1344f32fb..000000000
--- a/src/3rdparty/assimp/code/C4DImporter.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-/*
-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 C4DImporter.cpp
- * @brief Implementation of the Cinema4D importer class.
- */
-#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
-
-// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
-// where it is turned on in the CMake settings.
-
-#ifndef _MSC_VER
-# error C4D support is currently MSVC only
-#endif
-
-#include "C4DImporter.h"
-#include "TinyFormatter.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-
-#if defined(_M_X64) || defined(__amd64__)
-# define __C4D_64BIT
-#endif
-
-#define __PC
-#include "c4d_file.h"
-#include "default_alien_overloads.h"
-
-using namespace melange;
-
-// overload this function and fill in your own unique data
-void GetWriterInfo(int &id, String &appname)
-{
- id = 2424226;
- appname = "Open Asset Import Library";
-}
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-
-namespace Assimp {
- template<> const std::string LogFunctions<C4DImporter>::log_prefix = "C4D: ";
-}
-
-static const aiImporterDesc desc = {
- "Cinema4D Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "c4d"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-C4DImporter::C4DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-C4DImporter::~C4DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "c4d") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- // TODO
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* C4DImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void C4DImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void C4DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- if( file.get() == NULL) {
- ThrowException("failed to open file " + pFile);
- }
-
- const size_t file_size = file->FileSize();
-
- std::vector<uint8_t> mBuffer(file_size);
- file->Read(&mBuffer[0], 1, file_size);
-
- Filename f;
- f.SetMemoryReadMode(&mBuffer[0], file_size);
-
- // open document first
- BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
- if(doc == NULL) {
- ThrowException("failed to read document " + pFile);
- }
-
- pScene->mRootNode = new aiNode("<C4DRoot>");
-
- // first convert all materials
- ReadMaterials(doc->GetFirstMaterial());
-
- // process C4D scenegraph recursively
- try {
- RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
- }
- catch(...) {
- for(aiMesh* mesh : meshes) {
- delete mesh;
- }
- BaseDocument::Free(doc);
- throw;
- }
- BaseDocument::Free(doc);
-
- // copy meshes over
- pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- std::copy(meshes.begin(), meshes.end(), pScene->mMeshes);
-
- // copy materials over, adding a default material if necessary
- unsigned int mat_count = static_cast<unsigned int>(materials.size());
- for(aiMesh* mesh : meshes) {
- ai_assert(mesh->mMaterialIndex <= mat_count);
- if(mesh->mMaterialIndex >= mat_count) {
- ++mat_count;
-
- std::unique_ptr<aiMaterial> def_material(new aiMaterial());
- const aiString name(AI_DEFAULT_MATERIAL_NAME);
- def_material->AddProperty(&name, AI_MATKEY_NAME);
-
- materials.push_back(def_material.release());
- break;
- }
- }
-
- pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
- std::copy(materials.begin(), materials.end(), pScene->mMaterials);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
-{
- // based on Melange sample code (C4DImportExport.cpp)
- while(shader) {
- if(shader->GetType() == Xlayer) {
- BaseContainer* container = shader->GetDataInstance();
- GeData blend = container->GetData(SLA_LAYER_BLEND);
- iBlendDataType* blend_list = reinterpret_cast<iBlendDataType*>(blend.GetCustomDataType(CUSTOMDATA_BLEND_LIST));
- if (!blend_list)
- {
- LogWarn("ignoring XLayer shader: no blend list given");
- continue;
- }
-
- LayerShaderLayer *lsl = dynamic_cast<LayerShaderLayer*>(blend_list->m_BlendLayers.GetObject(0));
-
- // Ignore the actual layer blending - models for real-time rendering should not
- // use them in a non-trivial way. Just try to find textures that we can apply
- // to the model.
- while (lsl)
- {
- if (lsl->GetType() == TypeFolder)
- {
- BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
- LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
-
- while (subLsl)
- {
- if (subLsl->GetType() == TypeShader) {
- BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
- if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
- return true;
- }
- }
-
- subLsl = subLsl->GetNext();
- }
- }
- else if (lsl->GetType() == TypeShader) {
- BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
- if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
- return true;
- }
- }
-
- lsl = lsl->GetNext();
- }
- }
- else if ( shader->GetType() == Xbitmap )
- {
- aiString path;
- shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
- path.length = ::strlen(path.data);
- out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
- return true;
- }
- else {
- LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
- }
- shader = shader->GetNext();
- }
- return false;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
-{
- // based on Melange sample code
- while (mat)
- {
- const String& name = mat->GetName();
- if (mat->GetType() == Mmaterial)
- {
- aiMaterial* out = new aiMaterial();
- material_mapping[mat] = static_cast<unsigned int>(materials.size());
- materials.push_back(out);
-
- aiString ai_name;
- name.GetCString(ai_name.data, MAXLEN-1);
- ai_name.length = ::strlen(ai_name.data);
- out->AddProperty(&ai_name, AI_MATKEY_NAME);
-
- Material& m = dynamic_cast<Material&>(*mat);
-
- if (m.GetChannelState(CHANNEL_COLOR))
- {
- GeData data;
- mat->GetParameter(MATERIAL_COLOR_COLOR, data);
- Vector color = data.GetVector();
- mat->GetParameter(MATERIAL_COLOR_BRIGHTNESS, data);
- const Float brightness = data.GetFloat();
-
- color *= brightness;
-
- aiVector3D v;
- v.x = color.x;
- v.y = color.y;
- v.z = color.z;
- out->AddProperty(&v, 1, AI_MATKEY_COLOR_DIFFUSE);
- }
-
- BaseShader* const shader = m.GetShader(MATERIAL_COLOR_SHADER);
- if(shader) {
- ReadShader(out, shader);
- }
- }
- else
- {
- LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
- }
- mat = mat->GetNext();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
-{
- ai_assert(parent != NULL);
- std::vector<aiNode*> nodes;
-
- // based on Melange sample code
- while (object)
- {
- const String& name = object->GetName();
- const LONG type = object->GetType();
- const Matrix& ml = object->GetMl();
-
- aiString string;
- name.GetCString(string.data, MAXLEN-1);
- string.length = ::strlen(string.data);
- aiNode* const nd = new aiNode();
-
- nd->mParent = parent;
- nd->mName = string;
-
- nd->mTransformation.a1 = ml.v1.x;
- nd->mTransformation.b1 = ml.v1.y;
- nd->mTransformation.c1 = ml.v1.z;
-
- nd->mTransformation.a2 = ml.v2.x;
- nd->mTransformation.b2 = ml.v2.y;
- nd->mTransformation.c2 = ml.v2.z;
-
- nd->mTransformation.a3 = ml.v3.x;
- nd->mTransformation.b3 = ml.v3.y;
- nd->mTransformation.c3 = ml.v3.z;
-
- nd->mTransformation.a4 = ml.off.x;
- nd->mTransformation.b4 = ml.off.y;
- nd->mTransformation.c4 = ml.off.z;
-
- nodes.push_back(nd);
-
- GeData data;
- if (type == Ocamera)
- {
- object->GetParameter(CAMERAOBJECT_FOV, data);
- // TODO: read camera
- }
- else if (type == Olight)
- {
- // TODO: read light
- }
- else if (type == Opolygon)
- {
- aiMesh* const mesh = ReadMesh(object);
- if(mesh != NULL) {
- nd->mNumMeshes = 1;
- nd->mMeshes = new unsigned int[1];
- nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
- meshes.push_back(mesh);
- }
- }
- else {
- LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
- }
-
- RecurseHierarchy(object->GetDown(), nd);
- object = object->GetNext();
- }
-
- // copy nodes over to parent
- parent->mNumChildren = static_cast<unsigned int>(nodes.size());
- parent->mChildren = new aiNode*[parent->mNumChildren]();
- std::copy(nodes.begin(), nodes.end(), parent->mChildren);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-aiMesh* C4DImporter::ReadMesh(BaseObject* object)
-{
- ai_assert(object != NULL && object->GetType() == Opolygon);
-
- // based on Melange sample code
- PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
- ai_assert(polyObject != NULL);
-
- const LONG pointCount = polyObject->GetPointCount();
- const LONG polyCount = polyObject->GetPolygonCount();
- if(!polyObject || !pointCount) {
- LogWarn("ignoring mesh with zero vertices or faces");
- return NULL;
- }
-
- const Vector* points = polyObject->GetPointR();
- ai_assert(points != NULL);
-
- const CPolygon* polys = polyObject->GetPolygonR();
- ai_assert(polys != NULL);
-
- std::unique_ptr<aiMesh> mesh(new aiMesh());
- mesh->mNumFaces = static_cast<unsigned int>(polyCount);
- aiFace* face = mesh->mFaces = new aiFace[mesh->mNumFaces]();
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- mesh->mMaterialIndex = 0;
-
- unsigned int vcount = 0;
-
- // first count vertices
- for (LONG i = 0; i < polyCount; i++)
- {
- vcount += 3;
-
- // TODO: do we also need to handle lines or points with similar checks?
- if (polys[i].c != polys[i].d)
- {
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- ++vcount;
- }
- }
-
- ai_assert(vcount > 0);
-
- mesh->mNumVertices = vcount;
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiVector3D* normals, *uvs, *tangents, *bitangents;
- unsigned int n = 0;
-
- // check if there are normals, tangents or UVW coordinates
- BaseTag* tag = object->GetTag(Tnormal);
- NormalTag* normals_src = NULL;
- if(tag) {
- normals_src = dynamic_cast<NormalTag*>(tag);
- normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
- }
-
- tag = object->GetTag(Ttangent);
- TangentTag* tangents_src = NULL;
- if(tag) {
- tangents_src = dynamic_cast<TangentTag*>(tag);
- tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
- bitangents = mesh->mBitangents = new aiVector3D[mesh->mNumVertices]();
- }
-
- tag = object->GetTag(Tuvw);
- UVWTag* uvs_src = NULL;
- if(tag) {
- uvs_src = dynamic_cast<UVWTag*>(tag);
- uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
- }
-
- // copy vertices and extra channels over and populate faces
- for (LONG i = 0; i < polyCount; ++i, ++face)
- {
- ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
- const Vector& pointA = points[polys[i].a];
- verts->x = pointA.x;
- verts->y = pointA.y;
- verts->z = pointA.z;
- ++verts;
-
- ai_assert(polys[i].b < pointCount && polys[i].b >= 0);
- const Vector& pointB = points[polys[i].b];
- verts->x = pointB.x;
- verts->y = pointB.y;
- verts->z = pointB.z;
- ++verts;
-
- ai_assert(polys[i].c < pointCount && polys[i].c >= 0);
- const Vector& pointC = points[polys[i].c];
- verts->x = pointC.x;
- verts->y = pointC.y;
- verts->z = pointC.z;
- ++verts;
-
- // TODO: do we also need to handle lines or points with similar checks?
- if (polys[i].c != polys[i].d)
- {
- ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
-
- face->mNumIndices = 4;
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- const Vector& pointD = points[polys[i].d];
- verts->x = pointD.x;
- verts->y = pointD.y;
- verts->z = pointD.z;
- ++verts;
- }
- else {
- face->mNumIndices = 3;
- }
- face->mIndices = new unsigned int[face->mNumIndices];
- for(unsigned int j = 0; j < face->mNumIndices; ++j) {
- face->mIndices[j] = n++;
- }
-
- // copy normals
- if (normals_src) {
- if(i >= normals_src->GetDataCount()) {
- LogError("unexpected number of normals, ignoring");
- }
- else {
- ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
- NormalStruct nor;
- NormalTag::Get(normal_handle, i, nor);
- normals->x = nor.a.x;
- normals->y = nor.a.y;
- normals->z = nor.a.z;
- ++normals;
-
- normals->x = nor.b.x;
- normals->y = nor.b.y;
- normals->z = nor.b.z;
- ++normals;
-
- normals->x = nor.c.x;
- normals->y = nor.c.y;
- normals->z = nor.c.z;
- ++normals;
-
- if(face->mNumIndices == 4) {
- normals->x = nor.d.x;
- normals->y = nor.d.y;
- normals->z = nor.d.z;
- ++normals;
- }
- }
- }
-
- // copy tangents and bitangents
- if (tangents_src) {
-
- for(unsigned int k = 0; k < face->mNumIndices; ++k) {
- LONG l;
- switch(k) {
- case 0:
- l = polys[i].a;
- break;
- case 1:
- l = polys[i].b;
- break;
- case 2:
- l = polys[i].c;
- break;
- case 3:
- l = polys[i].d;
- break;
- default:
- ai_assert(false);
- }
- if(l >= tangents_src->GetDataCount()) {
- LogError("unexpected number of tangents, ignoring");
- break;
- }
-
- Tangent tan = tangents_src->GetDataR()[l];
- tangents->x = tan.vl.x;
- tangents->y = tan.vl.y;
- tangents->z = tan.vl.z;
- ++tangents;
-
- bitangents->x = tan.vr.x;
- bitangents->y = tan.vr.y;
- bitangents->z = tan.vr.z;
- ++bitangents;
- }
- }
-
- // copy UVs
- if (uvs_src) {
- if(i >= uvs_src->GetDataCount()) {
- LogError("unexpected number of UV coordinates, ignoring");
- }
- else {
- UVWStruct uvw;
- uvs_src->Get(uvs_src->GetDataAddressR(),i,uvw);
-
- uvs->x = uvw.a.x;
- uvs->y = 1.0f-uvw.a.y;
- uvs->z = uvw.a.z;
- ++uvs;
-
- uvs->x = uvw.b.x;
- uvs->y = 1.0f-uvw.b.y;
- uvs->z = uvw.b.z;
- ++uvs;
-
- uvs->x = uvw.c.x;
- uvs->y = 1.0f-uvw.c.y;
- uvs->z = uvw.c.z;
- ++uvs;
-
- if(face->mNumIndices == 4) {
- uvs->x = uvw.d.x;
- uvs->y = 1.0f-uvw.d.y;
- uvs->z = uvw.d.z;
- ++uvs;
- }
- }
- }
- }
-
- mesh->mMaterialIndex = ResolveMaterial(polyObject);
- return mesh.release();
-}
-
-
-// ------------------------------------------------------------------------------------------------
-unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
-{
- ai_assert(obj != NULL);
-
- const unsigned int mat_count = static_cast<unsigned int>(materials.size());
-
- BaseTag* tag = obj->GetTag(Ttexture);
- if(tag == NULL) {
- return mat_count;
- }
-
- TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
-
- BaseMaterial* const mat = ttag.GetMaterial();
- ai_assert(mat != NULL);
-
- const MaterialMap::const_iterator it = material_mapping.find(mat);
- if(it == material_mapping.end()) {
- return mat_count;
- }
-
- ai_assert((*it).second < mat_count);
- return (*it).second;
-}
-
-#endif // ASSIMP_BUILD_NO_C4D_IMPORTER
-
diff --git a/src/3rdparty/assimp/code/C4DImporter.h b/src/3rdparty/assimp/code/C4DImporter.h
deleted file mode 100644
index 4dea82161..000000000
--- a/src/3rdparty/assimp/code/C4DImporter.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-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 C4DImporter.h
- * @brief Declaration of the Cinema4D (*.c4d) importer class.
- */
-#ifndef INCLUDED_AI_CINEMA_4D_LOADER_H
-#define INCLUDED_AI_CINEMA_4D_LOADER_H
-
-#include "BaseImporter.h"
-#include "LogAux.h"
-
-#include <map>
-struct aiNode;
-struct aiMesh;
-struct aiMaterial;
-
-struct aiImporterDesc;
-
-namespace melange {
- class BaseObject; // c4d_file.h
- class PolygonObject;
- class BaseMaterial;
- class BaseShader;
-}
-
-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;
- }
-
-// -------------------------------------------------------------------------------------------
-/** Importer class to load Cinema4D files using the Melange library to be obtained from
- * www.plugincafe.com
- *
- * Note that Melange is not free software. */
-// -------------------------------------------------------------------------------------------
-class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
-{
-public:
-
- C4DImporter();
- ~C4DImporter();
-
-
-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:
-
- void ReadMaterials(melange::BaseMaterial* mat);
- void RecurseHierarchy(melange::BaseObject* object, aiNode* parent);
- aiMesh* ReadMesh(melange::BaseObject* object);
- unsigned int ResolveMaterial(melange::PolygonObject* obj);
-
- bool ReadShader(aiMaterial* out, melange::BaseShader* shader);
-
- std::vector<aiMesh*> meshes;
- std::vector<aiMaterial*> materials;
-
- typedef std::map<melange::BaseMaterial*, unsigned int> MaterialMap;
- MaterialMap material_mapping;
-
-}; // !class C4DImporter
-
-} // end of namespace Assimp
-#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
-
diff --git a/src/3rdparty/assimp/code/CInterfaceIOWrapper.cpp b/src/3rdparty/assimp/code/CInterfaceIOWrapper.cpp
deleted file mode 100644
index 9de75b683..000000000
--- a/src/3rdparty/assimp/code/CInterfaceIOWrapper.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 aiFileIO -> IOSystem wrapper*/
-
-#include "CInterfaceIOWrapper.h"
-
-namespace Assimp {
-
-CIOStreamWrapper::~CIOStreamWrapper(void)
-{
- /* Various places depend on this destructor to close the file */
- if (mFile) {
- mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
- mFile = nullptr;
- }
-}
-
-// ...................................................................
-size_t CIOStreamWrapper::Read(void* pvBuffer,
- size_t pSize,
- size_t pCount
-){
- // need to typecast here as C has no void*
- return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
-}
-
-// ...................................................................
-size_t CIOStreamWrapper::Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount
-){
- // need to typecast here as C has no void*
- return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
-}
-
-// ...................................................................
-aiReturn CIOStreamWrapper::Seek(size_t pOffset,
- aiOrigin pOrigin
-){
- return mFile->SeekProc(mFile,pOffset,pOrigin);
-}
-
-// ...................................................................
-size_t CIOStreamWrapper::Tell(void) const {
- return mFile->TellProc(mFile);
-}
-
-// ...................................................................
-size_t CIOStreamWrapper::FileSize() const {
- return mFile->FileSizeProc(mFile);
-}
-
-// ...................................................................
-void CIOStreamWrapper::Flush () {
- return mFile->FlushProc(mFile);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Custom IOStream implementation for the C-API
-bool CIOSystemWrapper::Exists( const char* pFile) const {
- aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
- if (p){
- mFileSystem->CloseProc(mFileSystem,p);
- return true;
- }
- return false;
-}
-
-// ...................................................................
-char CIOSystemWrapper::getOsSeparator() const {
-#ifndef _WIN32
- return '/';
-#else
- return '\\';
-#endif
-}
-
-// ...................................................................
-IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
- aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
- if (!p) {
- return NULL;
- }
- return new CIOStreamWrapper(p, this);
-}
-
-// ...................................................................
-void CIOSystemWrapper::Close( IOStream* pFile) {
- if (!pFile) {
- return;
- }
- delete pFile;
-}
-
-}
diff --git a/src/3rdparty/assimp/code/CInterfaceIOWrapper.h b/src/3rdparty/assimp/code/CInterfaceIOWrapper.h
deleted file mode 100644
index 78cac0cf9..000000000
--- a/src/3rdparty/assimp/code/CInterfaceIOWrapper.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 aiFileIO -> IOSystem wrapper*/
-
-#ifndef AI_CIOSYSTEM_H_INCLUDED
-#define AI_CIOSYSTEM_H_INCLUDED
-
-#include <assimp/cfileio.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-
-namespace Assimp {
-
-class CIOSystemWrapper;
-
-// ------------------------------------------------------------------------------------------------
-// Custom IOStream implementation for the C-API
-class CIOStreamWrapper : public IOStream
-{
-public:
- explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io)
- : mFile(pFile),
- mIO(io)
- {}
- ~CIOStreamWrapper(void);
-
- size_t Read(void* pvBuffer, size_t pSize, size_t pCount);
- size_t Write(const void* pvBuffer, size_t pSize, size_t pCount);
- aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
- size_t Tell(void) const;
- size_t FileSize() const;
- void Flush();
-
-private:
- aiFile* mFile;
- CIOSystemWrapper* mIO;
-};
-
-class CIOSystemWrapper : public IOSystem
-{
- friend class CIOStreamWrapper;
-public:
- explicit CIOSystemWrapper(aiFileIO* pFile)
- : mFileSystem(pFile)
- {}
-
- bool Exists( const char* pFile) const;
- char getOsSeparator() const;
- IOStream* Open(const char* pFile,const char* pMode = "rb");
- void Close( IOStream* pFile);
-private:
- aiFileIO* mFileSystem;
-};
-
-}
-
-#endif
-
diff --git a/src/3rdparty/assimp/code/CMakeLists.txt b/src/3rdparty/assimp/code/CMakeLists.txt
deleted file mode 100644
index 4d02240da..000000000
--- a/src/3rdparty/assimp/code/CMakeLists.txt
+++ /dev/null
@@ -1,1012 +0,0 @@
-# Open Asset Import Library (assimp)
-# ----------------------------------------------------------------------
-#
-# Copyright (c) 2006-2017, 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.
-#
-#----------------------------------------------------------------------
-
-# Listing and grouping of all the source files.
-# 1) Set the file lists for each component
-# 2) Create a Source Group for each component, for IDE project orginization
-# 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
- ${HEADER_PATH}/Compiler/pushpack1.h
- ${HEADER_PATH}/Compiler/poppack1.h
- ${HEADER_PATH}/Compiler/pstdint.h
-)
-SOURCE_GROUP( Compiler FILES ${COMPILER_HEADERS})
-
-SET( PUBLIC_HEADERS
- ${HEADER_PATH}/anim.h
- ${HEADER_PATH}/ai_assert.h
- ${HEADER_PATH}/camera.h
- ${HEADER_PATH}/color4.h
- ${HEADER_PATH}/color4.inl
- ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
- ${HEADER_PATH}/defs.h
- ${HEADER_PATH}/Defines.h
- ${HEADER_PATH}/cfileio.h
- ${HEADER_PATH}/light.h
- ${HEADER_PATH}/material.h
- ${HEADER_PATH}/material.inl
- ${HEADER_PATH}/matrix3x3.h
- ${HEADER_PATH}/matrix3x3.inl
- ${HEADER_PATH}/matrix4x4.h
- ${HEADER_PATH}/matrix4x4.inl
- ${HEADER_PATH}/mesh.h
- ${HEADER_PATH}/postprocess.h
- ${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
- ${HEADER_PATH}/vector2.inl
- ${HEADER_PATH}/vector3.h
- ${HEADER_PATH}/vector3.inl
- ${HEADER_PATH}/version.h
- ${HEADER_PATH}/cimport.h
- ${HEADER_PATH}/importerdesc.h
- ${HEADER_PATH}/Importer.hpp
- ${HEADER_PATH}/DefaultLogger.hpp
- ${HEADER_PATH}/ProgressHandler.hpp
- ${HEADER_PATH}/IOStream.hpp
- ${HEADER_PATH}/IOSystem.hpp
- ${HEADER_PATH}/Logger.hpp
- ${HEADER_PATH}/LogStream.hpp
- ${HEADER_PATH}/NullLogger.hpp
- ${HEADER_PATH}/cexport.h
- ${HEADER_PATH}/Exporter.hpp
- ${HEADER_PATH}/DefaultIOStream.h
- ${HEADER_PATH}/DefaultIOSystem.h
- ${HEADER_PATH}/SceneCombiner.h
-)
-
-SET( Core_SRCS
- Assimp.cpp
-)
-
-SET( Logging_SRCS
- ${HEADER_PATH}/DefaultLogger.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})
-
-SET( Common_SRCS
- fast_atof.h
- qnan.h
- BaseImporter.cpp
- BaseImporter.h
- BaseProcess.cpp
- BaseProcess.h
- Importer.h
- ScenePrivate.h
- PostStepRegistry.cpp
- ImporterRegistry.cpp
- ByteSwapper.h
- DefaultProgressHandler.h
- DefaultIOStream.cpp
- DefaultIOSystem.cpp
- CInterfaceIOWrapper.cpp
- CInterfaceIOWrapper.h
- Hash.h
- Importer.cpp
- IFF.h
- MemoryIOWrapper.h
- ParsingUtils.h
- StreamReader.h
- StreamWriter.h
- StringComparison.h
- StringUtils.h
- SGSpatialSort.cpp
- SGSpatialSort.h
- VertexTriangleAdjacency.cpp
- VertexTriangleAdjacency.h
- GenericProperty.h
- SpatialSort.cpp
- SpatialSort.h
- SceneCombiner.cpp
- ScenePreprocessor.cpp
- ScenePreprocessor.h
- SkeletonMeshBuilder.cpp
- SkeletonMeshBuilder.h
- SplitByBoneCountProcess.cpp
- SplitByBoneCountProcess.h
- ScaleProcess.cpp
- ScaleProcess.h
- SmoothingGroups.h
- StandardShapes.cpp
- StandardShapes.h
- TargetAnimation.cpp
- TargetAnimation.h
- RemoveComments.cpp
- RemoveComments.h
- Subdivision.cpp
- Subdivision.h
- scene.cpp
- Vertex.h
- LineSplitter.h
- TinyFormatter.h
- Profiler.h
- LogAux.h
- Bitmap.cpp
- Bitmap.h
- XMLTools.h
- Version.cpp
- IOStreamBuffer.h
- CreateAnimMesh.h
- CreateAnimMesh.cpp
-)
-SOURCE_GROUP(Common FILES ${Common_SRCS})
-
-IF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER )
- SET( C4D_SRCS
- C4DImporter.cpp
- C4DImporter.h
- )
- SOURCE_GROUP( C4D FILES ${C4D_SRCS})
-ENDIF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER )
-
-# if this variable is set to TRUE, the user can manually disable importers by setting
-# ASSIMP_BUILD_XXX_IMPORTER to FALSE for each importer
-# if this variable is set to FALSE, the user can manually enable importers by setting
-# ASSIMP_BUILD_XXX_IMPORTER to TRUE for each importer
-OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_XXX_IMPORTER value" TRUE)
-
-# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
-# this way selective loaders can be compiled (reduces filesize + compile time)
-MACRO(ADD_ASSIMP_IMPORTER name)
- OPTION(ASSIMP_BUILD_${name}_IMPORTER "build the ${name} importer" ${ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT})
- IF(ASSIMP_BUILD_${name}_IMPORTER)
- LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
- SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
- SET(${name}_SRCS ${ARGN})
- SOURCE_GROUP(${name} FILES ${ARGN})
- ELSE()
- SET(${name}_SRC "")
- SET(ASSIMP_IMPORTERS_DISABLED "${ASSIMP_IMPORTERS_DISABLED} ${name}")
- add_definitions(-DASSIMP_BUILD_NO_${name}_IMPORTER)
- add_definitions(-DASSIMP_BUILD_NO_${name}_EXPORTER)
- ENDIF()
-ENDMACRO()
-
-SET(ASSIMP_LOADER_SRCS "")
-SET(ASSIMP_IMPORTERS_ENABLED "") # list of enabled importers
-SET(ASSIMP_IMPORTERS_DISABLED "") # disabled list (used to print)
-
-ADD_ASSIMP_IMPORTER( AMF
- AMFImporter.hpp
- AMFImporter_Macro.hpp
- AMFImporter_Node.hpp
- AMFImporter.cpp
- AMFImporter_Geometry.cpp
- AMFImporter_Material.cpp
- AMFImporter_Postprocess.cpp
-)
-
-ADD_ASSIMP_IMPORTER( 3DS
- 3DSConverter.cpp
- 3DSHelper.h
- 3DSLoader.cpp
- 3DSLoader.h
- 3DSExporter.h
- 3DSExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( AC
- ACLoader.cpp
- ACLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( ASE
- ASELoader.cpp
- ASELoader.h
- ASEParser.cpp
- ASEParser.h
-)
-
-ADD_ASSIMP_IMPORTER( ASSBIN
- AssbinExporter.h
- AssbinExporter.cpp
- AssbinLoader.h
- AssbinLoader.cpp
-)
-
-ADD_ASSIMP_IMPORTER( ASSXML
- AssxmlExporter.h
- AssxmlExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( B3D
- B3DImporter.cpp
- B3DImporter.h
-)
-
-ADD_ASSIMP_IMPORTER( BVH
- BVHLoader.cpp
- BVHLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( COLLADA
- ColladaHelper.h
- ColladaLoader.cpp
- ColladaLoader.h
- ColladaParser.cpp
- ColladaParser.h
- ColladaExporter.h
- ColladaExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( DXF
- DXFLoader.cpp
- DXFLoader.h
- DXFHelper.h
-)
-
-ADD_ASSIMP_IMPORTER( CSM
- CSMLoader.cpp
- CSMLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( HMP
- HMPFileData.h
- HMPLoader.cpp
- HMPLoader.h
- HalfLifeFileData.h
-)
-
-ADD_ASSIMP_IMPORTER( IRRMESH
- IRRMeshLoader.cpp
- IRRMeshLoader.h
- IRRShared.cpp
- IRRShared.h
-)
-
-ADD_ASSIMP_IMPORTER( IRR
- IRRLoader.cpp
- IRRLoader.h
- IRRShared.cpp
- IRRShared.h
-)
-
-ADD_ASSIMP_IMPORTER( LWO
- LWOAnimation.cpp
- LWOAnimation.h
- LWOBLoader.cpp
- LWOFileData.h
- LWOLoader.cpp
- LWOLoader.h
- LWOMaterial.cpp
-)
-
-ADD_ASSIMP_IMPORTER( LWS
- LWSLoader.cpp
- LWSLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( MD2
- MD2FileData.h
- MD2Loader.cpp
- MD2Loader.h
- MD2NormalTable.h
-)
-
-ADD_ASSIMP_IMPORTER( MD3
- MD3FileData.h
- MD3Loader.cpp
- MD3Loader.h
-)
-
-ADD_ASSIMP_IMPORTER( MD5
- MD5Loader.cpp
- MD5Loader.h
- MD5Parser.cpp
- MD5Parser.h
-)
-
-ADD_ASSIMP_IMPORTER( MDC
- MDCFileData.h
- MDCLoader.cpp
- MDCLoader.h
- MDCNormalTable.h
-)
-
-ADD_ASSIMP_IMPORTER( MDL
- MDLDefaultColorMap.h
- MDLFileData.h
- MDLLoader.cpp
- MDLLoader.h
- MDLMaterialLoader.cpp
-)
-
-SET( MaterialSystem_SRCS
- MaterialSystem.cpp
- MaterialSystem.h
-)
-SOURCE_GROUP( MaterialSystem FILES ${MaterialSystem_SRCS})
-
-ADD_ASSIMP_IMPORTER( NFF
- NFFLoader.cpp
- NFFLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( NDO
- NDOLoader.cpp
- NDOLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( OFF
- OFFLoader.cpp
- OFFLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( OBJ
- ObjFileData.h
- ObjFileImporter.cpp
- ObjFileImporter.h
- ObjFileMtlImporter.cpp
- ObjFileMtlImporter.h
- ObjFileParser.cpp
- ObjFileParser.h
- ObjTools.h
- ObjExporter.h
- ObjExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( OGRE
- OgreImporter.h
- OgreStructs.h
- OgreParsingUtils.h
- OgreBinarySerializer.h
- OgreXmlSerializer.h
- OgreImporter.cpp
- OgreStructs.cpp
- OgreBinarySerializer.cpp
- OgreXmlSerializer.cpp
- OgreMaterial.cpp
-)
-
-ADD_ASSIMP_IMPORTER( OPENGEX
- OpenGEXExporter.cpp
- OpenGEXExporter.h
- OpenGEXImporter.cpp
- OpenGEXImporter.h
- OpenGEXStructs.h
-)
-
-ADD_ASSIMP_IMPORTER( PLY
- PlyLoader.cpp
- PlyLoader.h
- PlyParser.cpp
- PlyParser.h
- PlyExporter.cpp
- PlyExporter.h
-)
-
-ADD_ASSIMP_IMPORTER( MS3D
- MS3DLoader.cpp
- MS3DLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( COB
- COBLoader.cpp
- COBLoader.h
- COBScene.h
-)
-
-ADD_ASSIMP_IMPORTER( BLEND
- BlenderLoader.cpp
- BlenderLoader.h
- BlenderDNA.cpp
- BlenderDNA.h
- BlenderDNA.inl
- BlenderScene.cpp
- BlenderScene.h
- BlenderSceneGen.h
- BlenderIntermediate.h
- BlenderModifier.h
- BlenderModifier.cpp
- BlenderBMesh.h
- BlenderBMesh.cpp
- BlenderTessellator.h
- BlenderTessellator.cpp
-)
-
-ADD_ASSIMP_IMPORTER( IFC
- IFCLoader.cpp
- IFCLoader.h
- IFCReaderGen1.cpp
- IFCReaderGen2.cpp
- IFCReaderGen.h
- IFCUtil.h
- IFCUtil.cpp
- IFCGeometry.cpp
- IFCMaterial.cpp
- IFCProfile.cpp
- IFCCurve.cpp
- IFCBoolean.cpp
- IFCOpenings.cpp
- STEPFile.h
- STEPFileReader.h
- STEPFileReader.cpp
- STEPFileEncoding.cpp
- STEPFileEncoding.h
-)
-if (ASSIMP_BUILD_IFC_IMPORTER)
- if (MSVC)
- set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "/bigobj")
- elseif(CMAKE_COMPILER_IS_MINGW)
- set_source_files_properties(IFCReaderGen1.cpp IFCReaderGen2.cpp PROPERTIES COMPILE_FLAGS "-O2 -Wa,-mbig-obj")
- endif()
-endif (ASSIMP_BUILD_IFC_IMPORTER)
-
-ADD_ASSIMP_IMPORTER( XGL
- XGLLoader.cpp
- XGLLoader.h
-)
-
-
-ADD_ASSIMP_IMPORTER( FBX
- 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.h
- FBXMeshGeometry.cpp
- FBXMaterial.cpp
- FBXModel.cpp
- FBXAnimation.cpp
- FBXNodeAttribute.cpp
- FBXDeformer.cpp
- FBXBinaryTokenizer.cpp
- FBXDocumentUtil.cpp
-)
-
-SET( PostProcessing_SRCS
- CalcTangentsProcess.cpp
- CalcTangentsProcess.h
- ComputeUVMappingProcess.cpp
- ComputeUVMappingProcess.h
- ConvertToLHProcess.cpp
- ConvertToLHProcess.h
- FindDegenerates.cpp
- FindDegenerates.h
- FindInstancesProcess.cpp
- FindInstancesProcess.h
- FindInvalidDataProcess.cpp
- FindInvalidDataProcess.h
- FixNormalsStep.cpp
- FixNormalsStep.h
- GenFaceNormalsProcess.cpp
- GenFaceNormalsProcess.h
- GenVertexNormalsProcess.cpp
- GenVertexNormalsProcess.h
- PretransformVertices.cpp
- PretransformVertices.h
- ImproveCacheLocality.cpp
- ImproveCacheLocality.h
- JoinVerticesProcess.cpp
- JoinVerticesProcess.h
- LimitBoneWeightsProcess.cpp
- LimitBoneWeightsProcess.h
- RemoveRedundantMaterials.cpp
- RemoveRedundantMaterials.h
- RemoveVCProcess.cpp
- RemoveVCProcess.h
- SortByPTypeProcess.cpp
- SortByPTypeProcess.h
- SplitLargeMeshes.cpp
- SplitLargeMeshes.h
- TextureTransform.cpp
- TextureTransform.h
- TriangulateProcess.cpp
- TriangulateProcess.h
- ValidateDataStructure.cpp
- ValidateDataStructure.h
- OptimizeGraph.cpp
- OptimizeGraph.h
- OptimizeMeshes.cpp
- OptimizeMeshes.h
- DeboneProcess.cpp
- DeboneProcess.h
- ProcessHelper.h
- ProcessHelper.cpp
- PolyTools.h
- MakeVerboseFormat.cpp
- MakeVerboseFormat.h
-)
-SOURCE_GROUP( PostProcessing FILES ${PostProcessing_SRCS})
-
-SET( IrrXML_SRCS irrXMLWrapper.h )
-SOURCE_GROUP( IrrXML FILES ${IrrXML_SRCS})
-
-ADD_ASSIMP_IMPORTER( Q3D
- Q3DLoader.cpp
- Q3DLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( Q3BSP
- Q3BSPFileData.h
- Q3BSPFileParser.h
- Q3BSPFileParser.cpp
- Q3BSPFileImporter.h
- Q3BSPFileImporter.cpp
- Q3BSPZipArchive.h
- Q3BSPZipArchive.cpp
-)
-
-ADD_ASSIMP_IMPORTER( RAW
- RawLoader.cpp
- RawLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( SIB
- SIBImporter.cpp
- SIBImporter.h
-)
-
-ADD_ASSIMP_IMPORTER( SMD
- SMDLoader.cpp
- SMDLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( STL
- STLLoader.cpp
- STLLoader.h
- STLExporter.h
- STLExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( TERRAGEN
- TerragenLoader.cpp
- TerragenLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( 3D
- UnrealLoader.cpp
- UnrealLoader.h
-)
-
-ADD_ASSIMP_IMPORTER( X
- XFileHelper.h
- XFileImporter.cpp
- XFileImporter.h
- XFileParser.cpp
- XFileParser.h
- XFileExporter.h
- XFileExporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER(X3D
- X3DExporter.cpp
- X3DExporter.hpp
- X3DImporter.cpp
- X3DImporter.hpp
- X3DImporter_Geometry2D.cpp
- X3DImporter_Geometry3D.cpp
- X3DImporter_Group.cpp
- X3DImporter_Light.cpp
- X3DImporter_Macro.hpp
- X3DImporter_Metadata.cpp
- X3DImporter_Networking.cpp
- X3DImporter_Node.hpp
- X3DImporter_Postprocess.cpp
- X3DImporter_Rendering.cpp
- X3DImporter_Shape.cpp
- X3DImporter_Texturing.cpp
- FIReader.hpp
- FIReader.cpp
- X3DVocabulary.cpp
-)
-
-ADD_ASSIMP_IMPORTER( GLTF
- glTFAsset.h
- glTFAsset.inl
- glTFAssetWriter.h
- glTFAssetWriter.inl
- glTFImporter.cpp
- glTFImporter.h
- glTFExporter.h
- glTFExporter.cpp
- glTF2Asset.h
- glTF2Asset.inl
- glTF2AssetWriter.h
- glTF2AssetWriter.inl
- glTF2Importer.cpp
- glTF2Importer.h
- glTF2Exporter.h
- glTF2Exporter.cpp
-)
-
-ADD_ASSIMP_IMPORTER( 3MF
- D3MFImporter.h
- D3MFImporter.cpp
- D3MFExporter.h
- D3MFExporter.cpp
- D3MFOpcPackage.h
- D3MFOpcPackage.cpp
- 3MFXmlTags.h
-)
-
-ADD_ASSIMP_IMPORTER( MMD
- MMDCpp14.h
- MMDImporter.cpp
- MMDImporter.h
- MMDPmdParser.h
- MMDPmxParser.h
- MMDPmxParser.cpp
- MMDVmdParser.h
-)
-
-SET( Step_SRCS
- StepExporter.h
- StepExporter.cpp
-)
-SOURCE_GROUP( Step FILES ${Step_SRCS})
-
-SET( Exporter_SRCS
- Exporter.cpp
- AssimpCExport.cpp
- BlobIOSystem.h
-)
-SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
-
-SET( Extra_SRCS
- MD4FileData.h
-)
-SOURCE_GROUP( Extra FILES ${Extra_SRCS})
-
-
-SET( Clipper_SRCS
- ../contrib/clipper/clipper.hpp
- ../contrib/clipper/clipper.cpp
-)
-SOURCE_GROUP( Clipper FILES ${Clipper_SRCS})
-
-SET( Poly2Tri_SRCS
- ../contrib/poly2tri/poly2tri/common/shapes.cc
- ../contrib/poly2tri/poly2tri/common/shapes.h
- ../contrib/poly2tri/poly2tri/common/utils.h
- ../contrib/poly2tri/poly2tri/sweep/advancing_front.h
- ../contrib/poly2tri/poly2tri/sweep/advancing_front.cc
- ../contrib/poly2tri/poly2tri/sweep/cdt.cc
- ../contrib/poly2tri/poly2tri/sweep/cdt.h
- ../contrib/poly2tri/poly2tri/sweep/sweep.cc
- ../contrib/poly2tri/poly2tri/sweep/sweep.h
- ../contrib/poly2tri/poly2tri/sweep/sweep_context.cc
- ../contrib/poly2tri/poly2tri/sweep/sweep_context.h
-)
-SOURCE_GROUP( Poly2Tri FILES ${Poly2Tri_SRCS})
-
-SET( unzip_SRCS
- ../contrib/unzip/crypt.h
- ../contrib/unzip/ioapi.c
- ../contrib/unzip/ioapi.h
- ../contrib/unzip/unzip.c
- ../contrib/unzip/unzip.h
-)
-SOURCE_GROUP( unzip FILES ${unzip_SRCS})
-
-SET( ziplib_SRCS
- ../contrib/zip/src/miniz.h
- ../contrib/zip/src/zip.c
- ../contrib/zip/src/zip.h
-)
-
-SOURCE_GROUP( ziplib FILES ${ziplib_SRCS} )
-
-SET ( openddl_parser_SRCS
- ../contrib/openddlparser/code/OpenDDLParser.cpp
- ../contrib/openddlparser/code/DDLNode.cpp
- ../contrib/openddlparser/code/OpenDDLCommon.cpp
- ../contrib/openddlparser/code/OpenDDLExport.cpp
- ../contrib/openddlparser/code/Value.cpp
- ../contrib/openddlparser/code/OpenDDLStream.cpp
- ../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
- ../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
- ../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
- ../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
- ../contrib/openddlparser/include/openddlparser/OpenDDLStream.h
- ../contrib/openddlparser/include/openddlparser/DDLNode.h
- ../contrib/openddlparser/include/openddlparser/Value.h
-)
-SOURCE_GROUP( openddl_parser FILES ${openddl_parser_SRCS})
-
-SET ( open3dgc_SRCS
- ../contrib/Open3DGC/o3dgcAdjacencyInfo.h
- ../contrib/Open3DGC/o3dgcArithmeticCodec.cpp
- ../contrib/Open3DGC/o3dgcArithmeticCodec.h
- ../contrib/Open3DGC/o3dgcBinaryStream.h
- ../contrib/Open3DGC/o3dgcCommon.h
- ../contrib/Open3DGC/o3dgcDVEncodeParams.h
- ../contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp
- ../contrib/Open3DGC/o3dgcDynamicVectorDecoder.h
- ../contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
- ../contrib/Open3DGC/o3dgcDynamicVectorEncoder.h
- ../contrib/Open3DGC/o3dgcDynamicVector.h
- ../contrib/Open3DGC/o3dgcFIFO.h
- ../contrib/Open3DGC/o3dgcIndexedFaceSet.h
- ../contrib/Open3DGC/o3dgcIndexedFaceSet.inl
- ../contrib/Open3DGC/o3dgcSC3DMCDecoder.h
- ../contrib/Open3DGC/o3dgcSC3DMCDecoder.inl
- ../contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h
- ../contrib/Open3DGC/o3dgcSC3DMCEncoder.h
- ../contrib/Open3DGC/o3dgcSC3DMCEncoder.inl
- ../contrib/Open3DGC/o3dgcTimer.h
- ../contrib/Open3DGC/o3dgcTools.cpp
- ../contrib/Open3DGC/o3dgcTriangleFans.cpp
- ../contrib/Open3DGC/o3dgcTriangleFans.h
- ../contrib/Open3DGC/o3dgcTriangleListDecoder.h
- ../contrib/Open3DGC/o3dgcTriangleListDecoder.inl
- ../contrib/Open3DGC/o3dgcTriangleListEncoder.h
- ../contrib/Open3DGC/o3dgcTriangleListEncoder.inl
- ../contrib/Open3DGC/o3dgcVector.h
- ../contrib/Open3DGC/o3dgcVector.inl
-)
-SOURCE_GROUP( open3dgc FILES ${open3dgc_SRCS})
-
-# Check dependencies for glTF importer with Open3DGC-compression.
-# RT-extensions is used in "contrib/Open3DGC/o3dgcTimer.h" for collecting statistics. Pointed file
-# has implementation for different platforms: WIN32, __MACH__ and other ("else" block).
-FIND_PACKAGE(RT QUIET)
-IF (RT_FOUND OR MSVC)
- SET( ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC 1 )
- ADD_DEFINITIONS( -DASSIMP_IMPORTER_GLTF_USE_OPEN3DGC=1 )
-ELSE ()
- SET (open3dgc_SRCS "")
- MESSAGE (INFO " RT-extension not found. glTF import/export will be built without Open3DGC-compression.")
- #!TODO: off course is better to remove statistics timers from o3dgc codec. Or propose to choose what to use.
-ENDIF ()
-
-INCLUDE_DIRECTORIES( "../contrib/rapidjson/include" )
-INCLUDE_DIRECTORIES( "../contrib" )
-
-# VC2010 fixes
-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 ( MSVC )
- ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
- ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
-endif ( MSVC )
-
-if (UNZIP_FOUND)
- SET (unzip_compile_SRCS "")
-else (UNZIP_FOUND)
- SET (unzip_compile_SRCS ${unzip_SRCS})
- INCLUDE_DIRECTORIES( "../contrib/unzip/" )
-endif (UNZIP_FOUND)
-
-MESSAGE(STATUS "Enabled formats:${ASSIMP_IMPORTERS_ENABLED}")
-MESSAGE(STATUS "Disabled formats:${ASSIMP_IMPORTERS_DISABLED}")
-
-SET( assimp_src
- # Assimp Files
- ${Core_SRCS}
- ${Common_SRCS}
- ${Logging_SRCS}
- ${Exporter_SRCS}
- ${PostProcessing_SRCS}
- ${MaterialSystem_SRCS}
- ${Step_SRCS}
-
- # Model Support
- ${ASSIMP_LOADER_SRCS}
-
- # Third-party libraries
- ${IrrXML_SRCS}
- ${unzip_compile_SRCS}
- ${Poly2Tri_SRCS}
- ${Clipper_SRCS}
- ${openddl_parser_SRCS}
- ${open3dgc_SRCS}
- ${ziplib_SRCS}
- # Necessary to show the headers in the project when using the VC++ generator:
-
- ${PUBLIC_HEADERS}
- ${COMPILER_HEADERS}
-
-)
-ADD_DEFINITIONS( -DOPENDDLPARSER_BUILD )
-
-INCLUDE_DIRECTORIES(
- ${IRRXML_INCLUDE_DIR}
- ../contrib/openddlparser/include
-)
-
-IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
- SET( assimp_src ${assimp_src} ${C4D_SRCS})
- INCLUDE_DIRECTORIES(${C4D_INCLUDES})
-ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
-
-ADD_LIBRARY( assimp ${assimp_src} )
-
-TARGET_LINK_LIBRARIES(assimp ${ZLIB_LIBRARIES} ${OPENDDL_PARSER_LIBRARIES} ${IRRXML_LIBRARY} )
-
-if(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
- set(ASSIMP_ANDROID_JNIIOSYSTEM_PATH port/AndroidJNI)
- add_subdirectory(../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/ ../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/)
- target_link_libraries(assimp android_jniiosystem)
-endif(ANDROID AND ASSIMP_ANDROID_JNIIOSYSTEM)
-
-IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
- TARGET_LINK_LIBRARIES(assimp optimized ${C4D_RELEASE_LIBRARIES})
- TARGET_LINK_LIBRARIES(assimp debug ${C4D_DEBUG_LIBRARIES})
- TARGET_LINK_LIBRARIES(assimp ${C4D_EXTRA_LIBRARIES})
-ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
-
-if( MSVC )
- # in order to prevent DLL hell, each of the DLLs have to be suffixed with the major version and msvc prefix
- if( MSVC70 OR MSVC71 )
- set(MSVC_PREFIX "vc70")
- elseif( MSVC80 )
- set(MSVC_PREFIX "vc80")
- elseif( MSVC90 )
- set(MSVC_PREFIX "vc90")
- elseif( MSVC10 )
- set(MSVC_PREFIX "vc100")
- elseif( MSVC11 )
- set(MSVC_PREFIX "vc110")
- elseif( MSVC12 )
- set(MSVC_PREFIX "vc120")
- elseif( MSVC14 )
- set(MSVC_PREFIX "vc140")
- else()
- set(MSVC_PREFIX "vc150")
- endif()
- set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library")
-endif()
-
-SET_TARGET_PROPERTIES( assimp PROPERTIES
- VERSION ${ASSIMP_VERSION}
- SOVERSION ${ASSIMP_SOVERSION} # use full version
- OUTPUT_NAME assimp${LIBRARY_SUFFIX}
-)
-
-if (APPLE)
- SET_TARGET_PROPERTIES( assimp PROPERTIES
- INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}"
- )
-
- if (BUILD_FRAMEWORK)
- SET_TARGET_PROPERTIES( assimp PROPERTIES
- FRAMEWORK TRUE
- FRAMEWORK_VERSION C
- MACOSX_FRAMEWORK_IDENTIFIER net.sf.assimp
- PUBLIC_HEADER "${PUBLIC_HEADERS}"
- )
-
- # PUBLIC_HEADER option does not support directory structure creation
- # add ./Compiler/*.h to assimp.framework via copy command
- ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
- COMMAND "${CMAKE_COMMAND}" -E copy_directory
- "../${HEADER_PATH}/Compiler"
- assimp.framework/Headers/Compiler
- COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
- endif(BUILD_FRAMEWORK)
-endif(APPLE)
-
-# Build against external unzip, or add ../contrib/unzip so
-# assimp can #include "unzip.h"
-if (UNZIP_FOUND)
- INCLUDE_DIRECTORIES(${UNZIP_INCLUDE_DIRS})
- TARGET_LINK_LIBRARIES(assimp ${UNZIP_LIBRARIES})
-else (UNZIP_FOUND)
- INCLUDE_DIRECTORIES("../")
-endif (UNZIP_FOUND)
-
-# Add RT-extension library for glTF importer with Open3DGC-compression.
-IF (RT_FOUND AND ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC)
- TARGET_LINK_LIBRARIES(assimp ${RT_LIBRARY})
-ENDIF (RT_FOUND AND ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC)
-
-INSTALL( TARGETS assimp
- LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
- FRAMEWORK DESTINATION ${ASSIMP_LIB_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 (ASSIMP_ANDROID_JNIIOSYSTEM)
- INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
- DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
- COMPONENT assimp-dev)
-endif(ASSIMP_ANDROID_JNIIOSYSTEM)
-
-if(MSVC AND ASSIMP_INSTALL_PDB)
- IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
- install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
- DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- CONFIGURATIONS Debug
- )
- install(FILES ${Assimp_BINARY_DIR}/code/RelWithDebInfo/assimp${LIBRARY_SUFFIX}.pdb
- DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- CONFIGURATIONS RelWithDebInfo
- )
- ELSE()
- install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
- DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- CONFIGURATIONS Debug
- )
- install(FILES ${Assimp_BINARY_DIR}/code/assimp${LIBRARY_SUFFIX}.pdb
- DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
- CONFIGURATIONS RelWithDebInfo
- )
- ENDIF()
-endif ()
-
-if (ASSIMP_COVERALLS)
- include(Coveralls)
-
- set(COVERAGE_SRCS ${assimp_src} ${TEST_SRCS} )
-
- # Create the coveralls target.
- coveralls_setup(
- "${COVERAGE_SRCS}" # The source files.
- ON # If we should upload.
- "${PROJECT_SOURCE_DIR}/cmake-modules/") # (Optional) Alternate project cmake module path.
-endif()
diff --git a/src/3rdparty/assimp/code/COBLoader.cpp b/src/3rdparty/assimp/code/COBLoader.cpp
deleted file mode 100644
index a92e231a5..000000000
--- a/src/3rdparty/assimp/code/COBLoader.cpp
+++ /dev/null
@@ -1,1300 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 COBLoader.cpp
- * @brief Implementation of the TrueSpace COB/SCN importer class.
- */
-
-
-#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-#include "COBLoader.h"
-#include "COBScene.h"
-
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-using namespace Assimp::COB;
-using namespace Assimp::Formatter;
-
-
-static const float units[] = {
- 1000.f,
- 100.f,
- 1.f,
- 0.001f,
- 1.f/0.0254f,
- 1.f/0.3048f,
- 1.f/0.9144f,
- 1.f/1609.344f
-};
-
-static const aiImporterDesc desc = {
- "TrueSpace Object Importer",
- "",
- "",
- "little-endian files only",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "cob scn"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-COBImporter::COBImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-COBImporter::~COBImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "cob" || extension == "scn") {
- return true;
- }
-
- else if ((!extension.length() || checkSig) && pIOHandler) {
- const char* tokens[] = {"Caligary"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Loader meta information
-const aiImporterDesc* COBImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void COBImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string& msg)
-{
- throw DeadlyImportError("COB: "+msg);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void COBImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- COB::Scene scene;
- std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );
-
- // check header
- char head[32];
- stream->CopyAndAdvance(head,32);
- if (strncmp(head,"Caligari ",9)) {
- ThrowException("Could not found magic id: `Caligari`");
- }
-
- DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
- if (head[16]!='L') {
- ThrowException("File is big-endian, which is not supported");
- }
-
- // load data into intermediate structures
- if (head[15]=='A') {
- ReadAsciiFile(scene, stream.get());
- }
- else {
- ReadBinaryFile(scene, stream.get());
- }
- if(scene.nodes.empty()) {
- ThrowException("No nodes loaded");
- }
-
- // sort faces by material indices
- for(std::shared_ptr< Node >& n : scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- for(Face& f : mesh.faces) {
- mesh.temp_map[f.material].push_back(&f);
- }
- }
- }
-
- // count meshes
- for(std::shared_ptr< Node >& n : scene.nodes) {
- if (n->type == Node::TYPE_MESH) {
- Mesh& mesh = (Mesh&)(*n.get());
- if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
- pScene->mNumMeshes += static_cast<unsigned int>(mesh.temp_map.size());
- }
- }
- }
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
- pScene->mNumMeshes = 0;
-
- // count lights and cameras
- for(std::shared_ptr< Node >& n : scene.nodes) {
- if (n->type == Node::TYPE_LIGHT) {
- ++pScene->mNumLights;
- }
- else if (n->type == Node::TYPE_CAMERA) {
- ++pScene->mNumCameras;
- }
- }
-
- if (pScene->mNumLights) {
- pScene->mLights = new aiLight*[pScene->mNumLights]();
- }
- if (pScene->mNumCameras) {
- pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
- }
- pScene->mNumLights = pScene->mNumCameras = 0;
-
- // resolve parents by their IDs and build the output graph
- std::unique_ptr<Node> root(new Group());
- for(size_t n = 0; n < scene.nodes.size(); ++n) {
- const Node& nn = *scene.nodes[n].get();
- if(nn.parent_id==0) {
- root->temp_children.push_back(&nn);
- }
-
- for(size_t m = n; m < scene.nodes.size(); ++m) {
- const Node& mm = *scene.nodes[m].get();
- if (mm.parent_id == nn.id) {
- nn.temp_children.push_back(&mm);
- }
- }
- }
-
- pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertTexture(std::shared_ptr< Texture > tex, aiMaterial* out, aiTextureType type)
-{
- const aiString path( tex->path );
- out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
- out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill)
-{
- aiNode* nd = new aiNode();
- nd->mName.Set(root.name);
- nd->mTransformation = root.transform;
-
- // Note to everybody believing Voodoo is appropriate here:
- // I know polymorphism, run as fast as you can ;-)
- if (Node::TYPE_MESH == root.type) {
- const Mesh& ndmesh = (const Mesh&)(root);
- if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
-
- typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
- for(const Entry& reflist : ndmesh.temp_map) {
- { // create mesh
- size_t n = 0;
- for(Face* f : reflist.second) {
- n += f->indices.size();
- }
- if (!n) {
- continue;
- }
- aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
- ++nd->mNumMeshes;
-
- outmesh->mVertices = new aiVector3D[n];
- outmesh->mTextureCoords[0] = new aiVector3D[n];
-
- outmesh->mFaces = new aiFace[reflist.second.size()]();
- for(Face* f : reflist.second) {
- if (f->indices.empty()) {
- continue;
- }
-
- aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
- fout.mIndices = new unsigned int[f->indices.size()];
-
- for(VertexIndex& v : f->indices) {
- if (v.pos_idx >= ndmesh.vertex_positions.size()) {
- ThrowException("Position index out of range");
- }
- if (v.uv_idx >= ndmesh.texture_coords.size()) {
- ThrowException("UV index out of range");
- }
- outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ];
- outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D(
- ndmesh.texture_coords[ v.uv_idx ].x,
- ndmesh.texture_coords[ v.uv_idx ].y,
- 0.f
- );
-
- fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
- }
- }
- outmesh->mMaterialIndex = fill->mNumMaterials;
- }{ // create material
- const Material* min = NULL;
- for(const Material& m : scin.materials) {
- if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
- min = &m;
- break;
- }
- }
- std::unique_ptr<const Material> defmat;
- if(!min) {
- DefaultLogger::get()->debug(format()<<"Could not resolve material index "
- <<reflist.first<<" - creating default material for this slot");
-
- defmat.reset(min=new Material());
- }
-
- aiMaterial* mat = new aiMaterial();
- fill->mMaterials[fill->mNumMaterials++] = mat;
-
- const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- if(int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
- mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- { int shader;
- switch(min->shader)
- {
- case Material::FLAT:
- shader = aiShadingMode_Gouraud;
- break;
-
- case Material::PHONG:
- shader = aiShadingMode_Phong;
- break;
-
- case Material::METAL:
- shader = aiShadingMode_CookTorrance;
- break;
-
- default:
- ai_assert(false); // shouldn't be here
- }
- mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
- if(shader != aiShadingMode_Gouraud) {
- mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
- }
- }
-
- mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
- mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);
-
- aiColor3D c = aiColor3D(min->rgb)*min->ks;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
-
- c = aiColor3D(min->rgb)*min->ka;
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
-
- // convert textures if some exist.
- if(min->tex_color) {
- ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
- }
- if(min->tex_env) {
- ConvertTexture(min->tex_env ,mat,aiTextureType_UNKNOWN);
- }
- if(min->tex_bump) {
- ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
- }
- }
- }
- }
- }
- else if (Node::TYPE_LIGHT == root.type) {
- const Light& ndlight = (const Light&)(root);
- aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();
-
- outlight->mName.Set(ndlight.name);
- outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;
-
- outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
- outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);
-
- // XXX
- outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
- }
- else if (Node::TYPE_CAMERA == root.type) {
- const Camera& ndcam = (const Camera&)(root);
- aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();
-
- outcam->mName.Set(ndcam.name);
- }
-
- // add meshes
- if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for(unsigned int i = 0; i < nd->mNumMeshes;++i) {
- nd->mMeshes[i] = fill->mNumMeshes-i-1;
- }
- }
-
- // add children recursively
- nd->mChildren = new aiNode*[root.temp_children.size()]();
- for(const Node* n : root.temp_children) {
- (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
- }
-
- return nd;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read an ASCII file into the given scene data structure
-void COBImporter::ReadAsciiFile(Scene& out, StreamReaderLE* stream)
-{
- ChunkInfo ci;
- for(LineSplitter splitter(*stream);splitter;++splitter) {
-
- // add all chunks to be recognized here. /else ../ omitted intentionally.
- if (splitter.match_start("PolH ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadPolH_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("BitM ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBitM_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Mat1 ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadMat1_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Grou ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadGrou_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Lght ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadLght_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Came ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadCame_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Bone ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadBone_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Chan ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadChan_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("Unit ")) {
- ReadChunkInfo_Ascii(ci,splitter);
- ReadUnit_Ascii(out,splitter,ci);
- }
- if (splitter.match_start("END ")) {
- // we don't need this, but I guess there is a reason this
- // chunk has been implemented into COB for.
- return;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
-{
- const char* all_tokens[8];
- splitter.get_tokens(all_tokens);
-
- out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
- out.id = strtoul10(all_tokens[3]);
- out.parent_id = strtoul10(all_tokens[5]);
- out.size = strtol10(all_tokens[7]);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
-{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if(nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
-
- // (HACK) - our current position in the stream is the beginning of the
- // head line of the next chunk. That's fine, but the caller is going
- // to call ++ on `splitter`, which we need to swallow to avoid
- // missing the next line.
- splitter.get_stream().IncPtr(nfo.size);
- splitter.swallow_next_increment();
- }
- else ThrowException(error);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message) {
- LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message) {
- LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message) {
- LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message) {
- LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogWarn_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->warn(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogError_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->error(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogInfo_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->info(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::LogDebug_Ascii(const Formatter::format& message) {
- DefaultLogger::get()->debug(std::string("COB: ")+=message);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
-{
- for(;splitter;++splitter) {
- if (splitter.match_start("Name")) {
- msh.name = std::string(splitter[1]);
-
- // make nice names by merging the dupe count
- std::replace(msh.name.begin(),msh.name.end(),
- ',','_');
- }
- else if (splitter.match_start("Transform")) {
- for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
- const char* s = splitter->c_str();
- for(unsigned int x = 0; x < 4; ++x) {
- SkipSpaces(&s);
- msh.transform[y][x] = fast_atof(&s);
- }
- }
- // we need the transform chunk, so we won't return until we have it.
- return;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in)
-{
- const char* rgb = *in;
- for(unsigned int i = 0; i < 3; ++i) {
- SkipSpaces(&rgb);
- if (*rgb == ',')++rgb;
- SkipSpaces(&rgb);
-
- fill[i] = fast_atof(&rgb);
- }
- *in = rgb;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
- }
-
- ++splitter;
- if (!splitter.match_start("mat# ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = strtoul10(splitter[1]);
- ++splitter;
-
- if (!splitter.match_start("shader: ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
- return;
- }
- std::string shader = std::string(splitter[1]);
- shader = shader.substr(0,shader.find_first_of(" \t"));
-
- if (shader == "metal") {
- mat.shader = Material::METAL;
- }
- else if (shader == "phong") {
- mat.shader = Material::PHONG;
- }
- else if (shader != "flat") {
- LogWarn_Ascii(splitter,format()<<
- "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
- }
-
- ++splitter;
- if (!splitter.match_start("rgb ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(mat.rgb,&rgb);
-
- ++splitter;
- if (!splitter.match_start("alpha ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
- }
-
- const char* tokens[10];
- splitter.get_tokens(tokens);
-
- mat.alpha = fast_atof( tokens[1] );
- mat.ka = fast_atof( tokens[3] );
- mat.ks = fast_atof( tokens[5] );
- mat.exp = fast_atof( tokens[7] );
- mat.ior = fast_atof( tokens[9] );
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
- }
- ++splitter;
- if (!splitter.match_start("Units ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `Units` line in `Unit` chunk "<<nfo.id);
- return;
- }
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for(std::shared_ptr< Node >& nd : out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=strtoul10(splitter[1]);
-
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
- return;
- }
- }
- LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadChan_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
- }
-
- out.nodes.push_back(std::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- if (splitter.match_start("Infinite ")) {
- msh.ltype = Light::INFINITE;
- }
- else if (splitter.match_start("Local ")) {
- msh.ltype = Light::LOCAL;
- }
- else if (splitter.match_start("Spot ")) {
- msh.ltype = Light::SPOT;
- }
- else {
- LogWarn_Ascii(splitter,format()<<
- "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
- msh.ltype = Light::SPOT;
- }
-
- ++splitter;
- if (!splitter.match_start("color ")) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `color` line in `Lght` chunk "<<nfo.id);
- }
-
- const char* rgb = splitter[1];
- ReadFloat3Tuple_Ascii(msh.color ,&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"cone angle",10)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+10,&rgb);
- msh.angle = fast_atof(&rgb);
-
- SkipSpaces(&rgb);
- if (strncmp(rgb,"inner angle",11)) {
- LogWarn_Ascii(splitter,format()<<
- "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
- }
- SkipSpaces(rgb+11,&rgb);
- msh.inner_angle = fast_atof(&rgb);
-
- // skip the rest for we can't handle this kind of physically-based lighting information.
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadCame_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 2) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Came");
- }
-
- out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // skip the next line, we don't know this differenciation between a
- // standard camera and a panoramic camera.
- ++splitter;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBone_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 5) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
- }
-
- out.nodes.push_back(std::shared_ptr<Bone>(new Bone()));
- Bone& msh = (Bone&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // TODO
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadGrou_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
- }
-
- out.nodes.push_back(std::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
- }
-
- out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
-
- // the chunk has a fixed order of components, but some are not interesting of us so
- // we're just looking for keywords in arbitrary order. The end of the chunk is
- // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
- for(;splitter;++splitter) {
- if (splitter.match_start("World Vertices")) {
- const unsigned int cnt = strtoul10(splitter[2]);
- msh.vertex_positions.resize(cnt);
-
- for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector3D& v = msh.vertex_positions[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- SkipSpaces(&s);
- v.z = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Texture Vertices")) {
- const unsigned int cnt = strtoul10(splitter[2]);
- msh.texture_coords.resize(cnt);
-
- for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
- const char* s = splitter->c_str();
-
- aiVector2D& v = msh.texture_coords[cur];
-
- SkipSpaces(&s);
- v.x = fast_atof(&s);
- SkipSpaces(&s);
- v.y = fast_atof(&s);
- }
- }
- else if (splitter.match_start("Faces")) {
- const unsigned int cnt = strtoul10(splitter[1]);
- msh.faces.reserve(cnt);
-
- for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
- if (splitter.match_start("Hole")) {
- LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
- continue;
- }
-
- if (!splitter.match_start("Face")) {
- ThrowException("Expected Face line");
- }
-
- msh.faces.push_back(Face());
- Face& face = msh.faces.back();
-
- face.indices.resize(strtoul10(splitter[2]));
- face.flags = strtoul10(splitter[4]);
- face.material = strtoul10(splitter[6]);
-
- const char* s = (++splitter)->c_str();
- for(size_t i = 0; i < face.indices.size(); ++i) {
- if(!SkipSpaces(&s)) {
- ThrowException("Expected EOL token in Face entry");
- }
- if ('<' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- face.indices[i].pos_idx = strtoul10(s,&s);
- if (',' != *s++) {
- ThrowException("Expected , token in Face entry");
- }
- face.indices[i].uv_idx = strtoul10(s,&s);
- if ('>' != *s++) {
- ThrowException("Expected < token in Face entry");
- }
- }
- }
- if (nfo.version <= 4) {
- break;
- }
- }
- else if (splitter.match_start("DrawFlags")) {
- msh.draw_flags = strtoul10(splitter[1]);
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
-{
- if(nfo.version > 1) {
- return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
- }
-/*
- "\nThumbNailHdrSize %ld"
- "\nThumbHeader: %02hx 02hx %02hx "
- "\nColorBufSize %ld"
- "\nColorBufZipSize %ld"
- "\nZippedThumbnail: %02hx 02hx %02hx "
-*/
-
- const unsigned int head = strtoul10((++splitter)[1]);
- if (head != sizeof(Bitmap::BitmapHeader)) {
- LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
- return;
- }
-
- /*union {
- Bitmap::BitmapHeader data;
- char opaq[sizeof Bitmap::BitmapHeader()];
- };*/
-// ReadHexOctets(opaq,head,(++splitter)[1]);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadString_Binary(std::string& out, StreamReaderLE& reader)
-{
- out.resize( reader.GetI2());
- for(char& c : out) {
- c = reader.GetI1();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBasicNodeInfo_Binary(Node& msh, StreamReaderLE& reader, const ChunkInfo& /*nfo*/)
-{
- const unsigned int dupes = reader.GetI2();
- ReadString_Binary(msh.name,reader);
-
- msh.name = format(msh.name)<<'_'<<dupes;
-
- // skip local axes for the moment
- reader.IncPtr(48);
-
- msh.transform = aiMatrix4x4();
- for(unsigned int y = 0; y < 3; ++y) {
- for(unsigned int x =0; x < 4; ++x) {
- msh.transform[y][x] = reader.GetF4();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkInfo& nfo, const char* name)
-{
- const std::string error = format("Encountered unsupported chunk: ") << name <<
- " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";
-
- // we can recover if the chunk size was specified.
- if(nfo.size != static_cast<unsigned int>(-1)) {
- DefaultLogger::get()->error(error);
- reader.IncPtr(nfo.size);
- }
- else ThrowException(error);
-}
-
-// ------------------------------------------------------------------------------------------------
-// tiny utility guard to aid me at staying within chunk boundaries.
-class chunk_guard {
-public:
- chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
- : nfo(nfo)
- , reader(reader)
- , cur(reader.GetCurrentPos()) {
- }
-
- ~chunk_guard() {
- // don't do anything if the size is not given
- if(nfo.size != static_cast<unsigned int>(-1)) {
- try {
- reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
- } catch ( DeadlyImportError e ) {
- // out of limit so correct the value
- reader.IncPtr( reader.GetReadLimit() );
- }
- }
- }
-
-private:
-
- const COB::ChunkInfo& nfo;
- StreamReaderLE& reader;
- long cur;
-};
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
-{
- while(1) {
- std::string type;
- type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ,type += reader -> GetI1()
- ;
-
- ChunkInfo nfo;
- nfo.version = reader -> GetI2()*10;
- nfo.version += reader -> GetI2();
-
- nfo.id = reader->GetI4();
- nfo.parent_id = reader->GetI4();
- nfo.size = reader->GetI4();
-
- if (type == "PolH") {
- ReadPolH_Binary(out,*reader,nfo);
- }
- else if (type == "BitM") {
- ReadBitM_Binary(out,*reader,nfo);
- }
- else if (type == "Grou") {
- ReadGrou_Binary(out,*reader,nfo);
- }
- else if (type == "Lght") {
- ReadLght_Binary(out,*reader,nfo);
- }
- else if (type == "Came") {
- ReadCame_Binary(out,*reader,nfo);
- }
- else if (type == "Mat1") {
- ReadMat1_Binary(out,*reader,nfo);
- }
- /* else if (type == "Bone") {
- ReadBone_Binary(out,*reader,nfo);
- }
- else if (type == "Chan") {
- ReadChan_Binary(out,*reader,nfo);
- }*/
- else if (type == "Unit") {
- ReadUnit_Binary(out,*reader,nfo);
- }
- else if (type == "OLay") {
- // ignore layer index silently.
- if(nfo.size != static_cast<unsigned int>(-1) ) {
- reader->IncPtr(nfo.size);
- }
- else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
- else if (type == "END ") {
- return;
- }
- else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"PolH");
- }
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
- Mesh& msh = (Mesh&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-
- msh.vertex_positions.resize(reader.GetI4());
- for(aiVector3D& v : msh.vertex_positions) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- v.z = reader.GetF4();
- }
-
- msh.texture_coords.resize(reader.GetI4());
- for(aiVector2D& v : msh.texture_coords) {
- v.x = reader.GetF4();
- v.y = reader.GetF4();
- }
-
- 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?
- bool hole;
- if ((hole = (reader.GetI1() & 0x08) != 0)) {
- // XXX Basically this should just work fine - then triangulator
- // should output properly triangulated data even for polygons
- // with holes. Test data specific to COB is needed to confirm it.
- if (msh.faces.empty()) {
- ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
- }
- }
- else msh.faces.push_back(Face());
- Face& f = msh.faces.back();
-
- const size_t num = reader.GetI2();
- f.indices.reserve(f.indices.size() + num);
-
- if(!hole) {
- f.material = reader.GetI2();
- f.flags = 0;
- }
-
- for(size_t x = 0; x < num; ++x) {
- f.indices.push_back(VertexIndex());
-
- VertexIndex& v = f.indices.back();
- v.pos_idx = reader.GetI4();
- v.uv_idx = reader.GetI4();
- }
-
- if(hole) {
- std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
- }
- }
- if (nfo.version>4) {
- msh.draw_flags = reader.GetI4();
- }
- nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadBitM_Binary(COB::Scene& /*out*/, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"BitM");
- }
-
- const chunk_guard cn(nfo,reader);
-
- const uint32_t len = reader.GetI4();
- reader.IncPtr(len);
-
- reader.GetI4();
- reader.IncPtr(reader.GetI4());
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 8) {
- return UnsupportedChunk_Binary(reader,nfo,"Mat1");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.materials.push_back(Material());
- Material& mat = out.materials.back();
- mat = nfo;
-
- mat.matnum = reader.GetI2();
- switch(reader.GetI1()) {
- case 'f':
- mat.type = Material::FLAT;
- break;
- case 'p':
- mat.type = Material::PHONG;
- break;
- case 'm':
- mat.type = Material::METAL;
- break;
- default:
- LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
- mat.type = Material::FLAT;
- }
-
- switch(reader.GetI1()) {
- case 'f':
- mat.autofacet = Material::FACETED;
- break;
- case 'a':
- mat.autofacet = Material::AUTOFACETED;
- break;
- case 's':
- mat.autofacet = Material::SMOOTH;
- break;
- default:
- LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
- mat.autofacet = Material::FACETED;
- }
- mat.autofacet_angle = static_cast<float>(reader.GetI1());
-
- mat.rgb.r = reader.GetF4();
- mat.rgb.g = reader.GetF4();
- mat.rgb.b = reader.GetF4();
-
- mat.alpha = reader.GetF4();
- mat.ka = reader.GetF4();
- mat.ks = reader.GetF4();
- mat.exp = reader.GetF4();
- mat.ior = reader.GetF4();
-
- char id[2];
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
-
- if (id[0] == 'e' && id[1] == ':') {
- mat.tex_env.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_env->path,reader);
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 't' && id[1] == ':') {
- mat.tex_color.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_color->path,reader);
-
- mat.tex_color->transform.mTranslation.x = reader.GetF4();
- mat.tex_color->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_color->transform.mScaling.x = reader.GetF4();
- mat.tex_color->transform.mScaling.y = reader.GetF4();
-
- // advance to next texture-id
- id[0] = reader.GetI1(),id[1] = reader.GetI1();
- }
-
- if (id[0] == 'b' && id[1] == ':') {
- mat.tex_bump.reset(new Texture());
-
- reader.GetI1();
- ReadString_Binary(mat.tex_bump->path,reader);
-
- mat.tex_bump->transform.mTranslation.x = reader.GetF4();
- mat.tex_bump->transform.mTranslation.y = reader.GetF4();
-
- mat.tex_bump->transform.mScaling.x = reader.GetF4();
- mat.tex_bump->transform.mScaling.y = reader.GetF4();
-
- // skip amplitude for I don't know its purpose.
- reader.GetF4();
- }
- reader.IncPtr(-2);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Came");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
- Camera& msh = (Camera&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-
- // the rest is not interesting for us, so we skip over it.
- if(nfo.version > 1) {
- if (reader.GetI2()==512) {
- reader.IncPtr(42);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Lght");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(std::shared_ptr<Light>(new Light()));
- Light& msh = (Light&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 2) {
- return UnsupportedChunk_Binary(reader,nfo,"Grou");
- }
-
- const chunk_guard cn(nfo,reader);
-
- out.nodes.push_back(std::shared_ptr<Group>(new Group()));
- Group& msh = (Group&)(*out.nodes.back().get());
- msh = nfo;
-
- ReadBasicNodeInfo_Binary(msh,reader,nfo);
-}
-
-// ------------------------------------------------------------------------------------------------
-void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
-{
- if(nfo.version > 1) {
- return UnsupportedChunk_Binary(reader,nfo,"Unit");
- }
-
- const chunk_guard cn(nfo,reader);
-
- // parent chunks preceede their childs, so we should have the
- // corresponding chunk already.
- for(std::shared_ptr< Node >& nd : out.nodes) {
- if (nd->id == nfo.parent_id) {
- const unsigned int t=reader.GetI2();
- nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
- LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
- ,1.f):units[t];
-
- return;
- }
- }
- LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
- <<nfo.parent_id<<" which does not exist");
-}
-
-
-#endif
diff --git a/src/3rdparty/assimp/code/COBLoader.h b/src/3rdparty/assimp/code/COBLoader.h
deleted file mode 100644
index 46dc86f62..000000000
--- a/src/3rdparty/assimp/code/COBLoader.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 COBLoader.h
- * @brief Declaration of the TrueSpace (*.cob,*.scn) importer class.
- */
-#ifndef INCLUDED_AI_COB_LOADER_H
-#define INCLUDED_AI_COB_LOADER_H
-
-#include "BaseImporter.h"
-#include "StreamReader.h"
-
-struct aiNode;
-
-namespace Assimp {
- class LineSplitter;
-
- // 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;
- }
-
- // COBScene.h
- namespace COB {
- struct ChunkInfo;
- struct Node;
- struct Scene;
- }
-
-// -------------------------------------------------------------------------------------------
-/** Importer class to load TrueSpace files (cob,scn) up to v6.
- *
- * Currently relatively limited, loads only ASCII files and needs more test coverage. */
-// -------------------------------------------------------------------------------------------
-class COBImporter : public BaseImporter
-{
-public:
- COBImporter();
- ~COBImporter();
-
-
-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:
-
- // -------------------------------------------------------------------
- /** Prepend 'COB: ' and throw msg.*/
- AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
-
- // -------------------------------------------------------------------
- /** @brief Read from an ascii scene/object file
- * @param out Receives output data.
- * @param stream Stream to read from. */
- void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
-
- // -------------------------------------------------------------------
- /** @brief Read from a binary scene/object file
- * @param out Receives output data.
- * @param stream Stream to read from. */
- void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
-
-
-private:
-
- // Conversion to Assimp output format
-
- aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
-
-private:
-
- // ASCII file support
-
- void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
- void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
- void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
-
- void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
- void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
-
-
- // ASCII file logging stuff to add proper line numbers to messages
-
- static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
- static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
- static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
- static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
-
- static void LogWarn_Ascii (const Formatter::format& message);
- static void LogError_Ascii (const Formatter::format& message);
- static void LogInfo_Ascii (const Formatter::format& message);
- static void LogDebug_Ascii (const Formatter::format& message);
-
-
- // Binary file support
-
- void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
- void ReadString_Binary(std::string& out, StreamReaderLE& reader);
- void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
-
- void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
- void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
-
-
-}; // !class COBImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/COBScene.h b/src/3rdparty/assimp/code/COBScene.h
deleted file mode 100644
index a1d6ebc27..000000000
--- a/src/3rdparty/assimp/code/COBScene.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 COBScene.h
-* @brief Utilities for the COB importer.
-*/
-#ifndef INCLUDED_AI_COB_SCENE_H
-#define INCLUDED_AI_COB_SCENE_H
-
-#include <memory>
-#include <deque>
-#include <map>
-
-#include "BaseImporter.h"
-#include <assimp/material.h>
-
-namespace Assimp {
-namespace COB {
-
-// ------------------
-/** Represents a single vertex index in a face */
-struct VertexIndex
-{
- // intentionally uninitialized
- unsigned int pos_idx,uv_idx;
-};
-
-// ------------------
-/** COB Face data structure */
-struct Face
-{
- // intentionally uninitialized
- unsigned int material, flags;
- std::vector<VertexIndex> indices;
-};
-
-// ------------------
-/** COB chunk header information */
-struct ChunkInfo
-{
- enum {NO_SIZE=UINT_MAX};
-
- ChunkInfo ()
- : id (0)
- , parent_id (0)
- , version (0)
- , size (NO_SIZE)
- {}
-
- // Id of this chunk, unique within file
- unsigned int id;
-
- // and the corresponding parent
- unsigned int parent_id;
-
- // version. v1.23 becomes 123
- unsigned int version;
-
- // chunk size in bytes, only relevant for binary files
- // NO_SIZE is also valid.
- unsigned int size;
-};
-
-// ------------------
-/** A node in the scenegraph */
-struct Node : public ChunkInfo
-{
- enum Type {
- TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
- };
-
- virtual ~Node() {}
- Node(Type type) : type(type), unit_scale(1.f){}
-
- Type type;
-
- // used during resolving
- typedef std::deque<const Node*> ChildList;
- mutable ChildList temp_children;
-
- // unique name
- std::string name;
-
- // local mesh transformation
- aiMatrix4x4 transform;
-
- // scaling for this node to get to the metric system
- float unit_scale;
-};
-
-// ------------------
-/** COB Mesh data structure */
-struct Mesh : public Node
-{
- using ChunkInfo::operator=;
- enum DrawFlags {
- SOLID = 0x1,
- TRANS = 0x2,
- WIRED = 0x4,
- BBOX = 0x8,
- HIDE = 0x10
- };
-
- Mesh()
- : Node(TYPE_MESH)
- , draw_flags(SOLID)
- {}
-
- // vertex elements
- std::vector<aiVector2D> texture_coords;
- std::vector<aiVector3D> vertex_positions;
-
- // face data
- std::vector<Face> faces;
-
- // misc. drawing flags
- unsigned int draw_flags;
-
- // used during resolving
- typedef std::deque<Face*> FaceRefList;
- typedef std::map< unsigned int,FaceRefList > TempMap;
- TempMap temp_map;
-};
-
-// ------------------
-/** COB Group data structure */
-struct Group : public Node
-{
- using ChunkInfo::operator=;
- Group() : Node(TYPE_GROUP) {}
-};
-
-// ------------------
-/** COB Bone data structure */
-struct Bone : public Node
-{
- using ChunkInfo::operator=;
- Bone() : Node(TYPE_BONE) {}
-};
-
-// ------------------
-/** COB Light data structure */
-struct Light : public Node
-{
- enum LightType {
- SPOT,LOCAL,INFINITE
- };
-
- using ChunkInfo::operator=;
- Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
-
- aiColor3D color;
- float angle,inner_angle;
-
- LightType ltype;
-};
-
-// ------------------
-/** COB Camera data structure */
-struct Camera : public Node
-{
- using ChunkInfo::operator=;
- Camera() : Node(TYPE_CAMERA) {}
-};
-
-// ------------------
-/** COB Texture data structure */
-struct Texture
-{
- std::string path;
- aiUVTransform transform;
-};
-
-// ------------------
-/** COB Material data structure */
-struct Material : ChunkInfo
-{
- using ChunkInfo::operator=;
- enum Shader {
- FLAT,PHONG,METAL
- };
-
- enum AutoFacet {
- FACETED,AUTOFACETED,SMOOTH
- };
-
- Material() : alpha(),exp(),ior(),ka(),ks(1.f),
- matnum(UINT_MAX),
- shader(FLAT),autofacet(FACETED),
- autofacet_angle()
- {}
-
- std::string type;
-
- aiColor3D rgb;
- float alpha, exp, ior,ka,ks;
-
- unsigned int matnum;
- Shader shader;
-
- AutoFacet autofacet;
- float autofacet_angle;
-
- std::shared_ptr<Texture> tex_env,tex_bump,tex_color;
-};
-
-// ------------------
-/** Embedded bitmap, for instance for the thumbnail image */
-struct Bitmap : ChunkInfo
-{
- Bitmap() : orig_size() {}
- struct BitmapHeader
- {
- };
-
- BitmapHeader head;
- size_t orig_size;
- std::vector<char> buff_zipped;
-};
-
-typedef std::deque< std::shared_ptr<Node> > NodeList;
-typedef std::vector< Material > MaterialList;
-
-// ------------------
-/** Represents a master COB scene, even if we loaded just a single COB file */
-struct Scene
-{
- NodeList nodes;
- MaterialList materials;
-
- // becomes *0 later
- Bitmap thumbnail;
-};
-
- } // end COB
-} // end Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/CSMLoader.cpp b/src/3rdparty/assimp/code/CSMLoader.cpp
deleted file mode 100644
index eeb6986b0..000000000
--- a/src/3rdparty/assimp/code/CSMLoader.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 CSMLoader.cpp
- * Implementation of the CSM importer class.
- */
-
-
-
-#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-
-#include "CSMLoader.h"
-#include "SkeletonMeshBuilder.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include <assimp/Importer.hpp>
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/anim.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "CharacterStudio Motion Importer (MoCap)",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "csm"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-CSMImporter::CSMImporter()
-: noSkeletonMesh()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CSMImporter::~CSMImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if( extension == "csm")
- return true;
-
- if ((checkSig || !extension.length()) && pIOHandler) {
- const char* tokens[] = {"$Filename"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-const aiImporterDesc* CSMImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void CSMImporter::SetupProperties(const Importer* pImp)
-{
- noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void CSMImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- aiAnimation* anim = new aiAnimation();
- int first = 0, last = 0x00ffffff;
-
- // now process the file and look out for '$' sections
- while (1) {
- SkipSpaces(&buffer);
- if ('\0' == *buffer)
- break;
-
- if ('$' == *buffer) {
- ++buffer;
- if (TokenMatchI(buffer,"firstframe",10)) {
- SkipSpaces(&buffer);
- first = strtol10(buffer,&buffer);
- }
- else if (TokenMatchI(buffer,"lastframe",9)) {
- SkipSpaces(&buffer);
- last = strtol10(buffer,&buffer);
- }
- else if (TokenMatchI(buffer,"rate",4)) {
- SkipSpaces(&buffer);
- float d;
- buffer = fast_atoreal_move<float>(buffer,d);
- anim->mTicksPerSecond = d;
- }
- else if (TokenMatchI(buffer,"order",5)) {
- std::vector< aiNodeAnim* > anims_temp;
- anims_temp.reserve(30);
- while (1) {
- SkipSpaces(&buffer);
- if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
- break; // next section
-
- // Construct a new node animation channel and setup its name
- anims_temp.push_back(new aiNodeAnim());
- aiNodeAnim* nda = anims_temp.back();
-
- char* ot = nda->mNodeName.data;
- while (!IsSpaceOrNewLine(*buffer))
- *ot++ = *buffer++;
-
- *ot = '\0';
- nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
- }
-
- anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
- if (!anim->mNumChannels)
- throw DeadlyImportError("CSM: Empty $order section");
-
- // copy over to the output animation
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
- ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
- }
- else if (TokenMatchI(buffer,"points",6)) {
- if (!anim->mNumChannels)
- throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
-
- // If we know how many frames we'll read, we can preallocate some storage
- unsigned int alloc = 100;
- if (last != 0x00ffffff)
- {
- alloc = last-first;
- alloc += alloc>>2u; // + 25%
- for (unsigned int i = 0; i < anim->mNumChannels;++i)
- anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
- }
-
- unsigned int filled = 0;
-
- // Now read all point data.
- while (1) {
- SkipSpaces(&buffer);
- if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
- break; // next section
- }
-
- // read frame
- const int frame = ::strtoul10(buffer,&buffer);
- last = std::max(frame,last);
- first = std::min(frame,last);
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
-
- aiNodeAnim* s = anim->mChannels[i];
- if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
-
- aiVectorKey* old = s->mPositionKeys;
- s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
- ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
- delete[] old;
- }
-
- // read x,y,z
- if(!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
-
- if (TokenMatchI(buffer, "DROPOUT", 7)) {
- // seems this is invalid marker data; at least the doc says it's possible
- DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
- }
- else {
- aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
- sub->mTime = (double)frame;
- buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
-
- if(!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
- buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
-
- if(!SkipSpacesAndLineEnd(&buffer))
- throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
- buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
-
- ++s->mNumPositionKeys;
- }
- }
-
- // update allocation granularity
- if (filled == alloc)
- alloc *= 2;
-
- ++filled;
- }
- // all channels must be complete in order to continue safely.
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
-
- if (!anim->mChannels[i]->mNumPositionKeys)
- throw DeadlyImportError("CSM: Invalid marker track");
- }
- }
- }
- else {
- // advance to the next line
- SkipLine(&buffer);
- }
- }
-
- // Setup a proper animation duration
- anim->mDuration = last - std::min( first, 0 );
-
- // build a dummy root node with the tiny markers as children
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("$CSM_DummyRoot");
-
- pScene->mRootNode->mNumChildren = anim->mNumChannels;
- pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
-
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* na = anim->mChannels[i];
-
- aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
- nd->mName = anim->mChannels[i]->mNodeName;
- nd->mParent = pScene->mRootNode;
-
- aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
- }
-
- // Store the one and only animation in the scene
- pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
- pScene->mAnimations[0] = anim;
- anim->mName.Set("$CSM_MasterAnim");
-
- // mark the scene as incomplete and run SkeletonMeshBuilder on it
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
-
- 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
deleted file mode 100644
index 55a632dc6..000000000
--- a/src/3rdparty/assimp/code/CSMLoader.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 CSMLoader.h
- * Declaration of the CharacterStudio Motion importer class.
- */
-#ifndef INCLUDED_AI_CSM_LOADER_H
-#define INCLUDED_AI_CSM_LOADER_H
-
-#include "BaseImporter.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class to load MOCAPs in CharacterStudio Motion format.
- *
- * A very rudimentary loader for the moment. No support for the hierarchy,
- * every marker is returned as child of root.
- *
- * Link to file format specification:
- * <max_8_dvd>\samples\Motion\Docs\CSM.rtf
-*/
-class CSMImporter : public BaseImporter
-{
-public:
- CSMImporter();
- ~CSMImporter();
-
-
-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:
-
- 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
deleted file mode 100644
index 2af16fcc0..000000000
--- a/src/3rdparty/assimp/code/CalcTangentsProcess.cpp
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to calculate
- * tangents and bitangents for all imported meshes
- */
-
-// internal headers
-#include "CalcTangentsProcess.h"
-#include "ProcessHelper.h"
-#include "TinyFormatter.h"
-#include "qnan.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-CalcTangentsProcess::CalcTangentsProcess()
-: configMaxAngle( AI_DEG_TO_RAD(45.f) )
-, configSourceUV( 0 ) {
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CalcTangentsProcess::~CalcTangentsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool CalcTangentsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_CalcTangentSpace) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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);
- configMaxAngle = AI_DEG_TO_RAD(configMaxAngle);
-
- configSourceUV = pImp->GetPropertyInteger(AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX,0);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void CalcTangentsProcess::Execute( aiScene* pScene)
-{
- ai_assert( NULL != pScene );
-
- DefaultLogger::get()->debug("CalcTangentsProcess begin");
-
- bool bHas = false;
- 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");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Calculates tangents and bi-tangents for the given mesh
-bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
-{
- // we assume that the mesh is still in the verbose vertex format where each face has its own set
- // of vertices and no vertices are shared between faces. Sadly I don't know any quick test to
- // assert() it here.
- // assert( must be verbose, dammit);
-
- if (pMesh->mTangents) // this implies that mBitangents is also there
- return false;
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
- {
- DefaultLogger::get()->info("Tangents are undefined for line and point meshes");
- return false;
- }
-
- // what we can check, though, is if the mesh has normals and texture coordinates. That's a requirement
- if( pMesh->mNormals == NULL)
- {
- DefaultLogger::get()->error("Failed to compute tangents; need normals");
- return false;
- }
- if( configSourceUV >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !pMesh->mTextureCoords[configSourceUV] )
- {
- DefaultLogger::get()->error((Formatter::format("Failed to compute tangents; need UV data in channel"),configSourceUV));
- return false;
- }
-
- const float angleEpsilon = 0.9999f;
-
- std::vector<bool> vertexDone( pMesh->mNumVertices, false);
- const float qnan = get_qnan();
-
- // create space for the tangents and bitangents
- pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
- pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
-
- const aiVector3D* meshPos = pMesh->mVertices;
- const aiVector3D* meshNorm = pMesh->mNormals;
- const aiVector3D* meshTex = pMesh->mTextureCoords[configSourceUV];
- aiVector3D* meshTang = pMesh->mTangents;
- aiVector3D* meshBitang = pMesh->mBitangents;
-
- // calculate the tangent and bitangent for every face
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3)
- {
- // There are less than three indices, thus the tangent vector
- // is not defined. We are finished with these vertices now,
- // their tangent vectors are set to qnan.
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- unsigned int idx = face.mIndices[i];
- vertexDone [idx] = true;
- meshTang [idx] = aiVector3D(qnan);
- meshBitang [idx] = aiVector3D(qnan);
- }
-
- continue;
- }
-
- // triangle or polygon... we always use only the first three indices. A polygon
- // is supposed to be planar anyways....
- // FIXME: (thom) create correct calculation for multi-vertex polygons maybe?
- const unsigned int p0 = face.mIndices[0], p1 = face.mIndices[1], p2 = face.mIndices[2];
-
- // position differences p1->p2 and p1->p3
- aiVector3D v = meshPos[p1] - meshPos[p0], w = meshPos[p2] - meshPos[p0];
-
- // texture offset p1->p2 and p1->p3
- 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;
- // 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;
- tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
- bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
- bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
- 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 ) {
- unsigned int p = face.mIndices[b];
-
- // project tangent and bitangent into the plane formed by the vertex' normal
- aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
- aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
- localTangent.Normalize(); localBitangent.Normalize();
-
- // 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;
- }
- }
-
-
- // create a helper to quickly find locally close vertices among the vertex array
- // FIX: check whether we can reuse the SpatialSort of a previous step
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
- float posEpsilon;
- if (shared)
- {
- std::vector<std::pair<SpatialSort,float> >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf)
- {
- std::pair<SpatialSort,float>& blubb = avf->operator [] (meshIndex);
- vertexFinder = &blubb.first;
- posEpsilon = blubb.second;;
- }
- }
- if (!vertexFinder)
- {
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- posEpsilon = ComputePositionEpsilon(pMesh);
- }
- std::vector<unsigned int> verticesFound;
-
- const float fLimit = std::cos(configMaxAngle);
- std::vector<unsigned int> closeVertices;
-
- // in the second pass we now smooth out all tangents and bitangents at the same local position
- // if they are not too far off.
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- {
- if( vertexDone[a])
- continue;
-
- const aiVector3D& origPos = pMesh->mVertices[a];
- const aiVector3D& origNorm = pMesh->mNormals[a];
- const aiVector3D& origTang = pMesh->mTangents[a];
- const aiVector3D& origBitang = pMesh->mBitangents[a];
- closeVertices.resize( 0 );
-
- // find all vertices close to that position
- vertexFinder->FindPositions( origPos, posEpsilon, verticesFound);
-
- closeVertices.reserve (verticesFound.size()+5);
- closeVertices.push_back( a);
-
- // look among them for other vertices sharing the same normal and a close-enough tangent/bitangent
- for( unsigned int b = 0; b < verticesFound.size(); b++)
- {
- unsigned int idx = verticesFound[b];
- if( vertexDone[idx])
- continue;
- if( meshNorm[idx] * origNorm < angleEpsilon)
- continue;
- if( meshTang[idx] * origTang < fLimit)
- continue;
- if( meshBitang[idx] * origBitang < fLimit)
- continue;
-
- // it's similar enough -> add it to the smoothing group
- closeVertices.push_back( idx);
- vertexDone[idx] = true;
- }
-
- // smooth the tangents and bitangents of all vertices that were found to be close enough
- aiVector3D smoothTangent( 0, 0, 0), smoothBitangent( 0, 0, 0);
- for( unsigned int b = 0; b < closeVertices.size(); ++b)
- {
- smoothTangent += meshTang[ closeVertices[b] ];
- smoothBitangent += meshBitang[ closeVertices[b] ];
- }
- smoothTangent.Normalize();
- smoothBitangent.Normalize();
-
- // and write it back into all affected tangents
- for( unsigned int b = 0; b < closeVertices.size(); ++b)
- {
- meshTang[ closeVertices[b] ] = smoothTangent;
- meshBitang[ closeVertices[b] ] = smoothBitangent;
- }
- }
- return true;
-}
diff --git a/src/3rdparty/assimp/code/CalcTangentsProcess.h b/src/3rdparty/assimp/code/CalcTangentsProcess.h
deleted file mode 100644
index a22785639..000000000
--- a/src/3rdparty/assimp/code/CalcTangentsProcess.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to calculate tangents and
- bitangents on all imported meshes.*/
-#ifndef AI_CALCTANGENTSPROCESS_H_INC
-#define AI_CALCTANGENTSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The CalcTangentsProcess calculates the tangent and bitangent for any vertex
- * of all meshes. It is expected to be run before the JoinVerticesProcess runs
- * because the joining of vertices also considers tangents and bitangents for
- * uniqueness.
- */
-class ASSIMP_API_WINONLY CalcTangentsProcess : public BaseProcess
-{
-public:
-
- CalcTangentsProcess();
- ~CalcTangentsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-
- // setter for configMaxAngle
- inline void SetMaxSmoothAngle(float f)
- {
- configMaxAngle =f;
- }
-
-protected:
-
- // -------------------------------------------------------------------
- /** Calculates tangents and bitangents for a specific mesh.
- * @param pMesh The mesh to process.
- * @param meshIndex Index of the mesh
- */
- bool ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-private:
-
- /** Configuration option: maximum smoothing angle, in radians*/
- float configMaxAngle;
- unsigned int configSourceUV;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/ColladaExporter.cpp b/src/3rdparty/assimp/code/ColladaExporter.cpp
deleted file mode 100644
index 4a10d5845..000000000
--- a/src/3rdparty/assimp/code/ColladaExporter.cpp
+++ /dev/null
@@ -1,1625 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
-
-#include "ColladaExporter.h"
-#include "Bitmap.h"
-#include "fast_atof.h"
-#include <assimp/SceneCombiner.h>
-#include "StringUtils.h"
-#include "XMLTools.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/scene.h>
-
-#include "Exceptional.h"
-
-#include <memory>
-#include <ctime>
-#include <set>
-#include <vector>
-#include <iostream>
-
-using namespace Assimp;
-
-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, const ExportProperties* /*pProperties*/)
-{
- std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
- std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
-
- // invoke the exporter
- ColladaExporter iDoTheExportThing( pScene, pIOSystem, path, file);
-
- if (iDoTheExportThing.mOutput.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write result to the given IOSYstem
- std::unique_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);
-}
-
-} // end of namespace Assimp
-
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor for a specific scene to export
-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") );
- mOutput.precision(16);
-
- mScene = pScene;
- mSceneOwned = false;
-
- // set up strings
- endstr = "\n";
-
- // start writing the file
- WriteFile();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor
-ColladaExporter::~ColladaExporter()
-{
- if(mSceneOwned) {
- delete mScene;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Starts writing the contents
-void ColladaExporter::WriteFile()
-{
- // write the DTD
- mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
- // COLLADA element start
- mOutput << "<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">" << endstr;
- PushTag();
-
- WriteTextures();
- WriteHeader();
-
- WriteCamerasLibrary();
- WriteLightsLibrary();
- WriteMaterials();
- WriteGeometryLibrary();
- WriteControllerLibrary();
-
- WriteSceneLibrary();
-
- // customized, Writes the animation library
- WriteAnimationsLibrary();
-
- // 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=\"#" + XMLEscape(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr;
- PopTag();
- mOutput << startstr << "</scene>" << endstr;
- PopTag();
- mOutput << "</COLLADA>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the asset header
-void ColladaExporter::WriteHeader()
-{
- static const ai_real epsilon = ai_real( 0.00001 );
- 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));
-
- aiVector3D scaling;
- aiQuaternion rotation;
- aiVector3D position;
- mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
- rotation.Normalize();
-
- bool add_root_node = false;
-
- ai_real 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 = (ai_real) ((((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();
-
- aiMetadata* meta = mScene->mRootNode->mMetaData;
- aiString value;
- if (!meta || !meta->Get("Author", value))
- mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
- else
- mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
-
- if (!meta || !meta->Get("AuthoringTool", value))
- mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
- else
- mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
-
- //mOutput << startstr << "<author>" << mScene->author.C_Str() << "</author>" << endstr;
- //mOutput << startstr << "<authoring_tool>" << mScene->authoringTool.C_Str() << "</authoring_tool>" << endstr;
-
- PopTag();
- mOutput << startstr << "</contributor>" << 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);
-
- std::unique_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));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Write the embedded textures
-void ColladaExporter::WriteCamerasLibrary() {
- if(mScene->HasCameras()) {
-
- mOutput << startstr << "<library_cameras>" << endstr;
- PushTag();
-
- for( size_t a = 0; a < mScene->mNumCameras; ++a)
- WriteCamera( a);
-
- PopTag();
- mOutput << startstr << "</library_cameras>" << endstr;
-
- }
-}
-
-void ColladaExporter::WriteCamera(size_t pIndex){
-
- const aiCamera *cam = mScene->mCameras[pIndex];
- const std::string idstrEscaped = XMLEscape(cam->mName.C_Str());
-
- mOutput << startstr << "<camera id=\"" << idstrEscaped << "-camera\" name=\"" << idstrEscaped << "_name\" >" << endstr;
- PushTag();
- mOutput << startstr << "<optics>" << endstr;
- PushTag();
- mOutput << startstr << "<technique_common>" << endstr;
- PushTag();
- //assimp doesn't support the import of orthographic cameras! se we write
- //always perspective
- mOutput << startstr << "<perspective>" << endstr;
- PushTag();
- mOutput << startstr << "<xfov sid=\"xfov\">"<<
- AI_RAD_TO_DEG(cam->mHorizontalFOV)
- <<"</xfov>" << endstr;
- mOutput << startstr << "<aspect_ratio>"
- << cam->mAspect
- << "</aspect_ratio>" << endstr;
- mOutput << startstr << "<znear sid=\"znear\">"
- << cam->mClipPlaneNear
- << "</znear>" << endstr;
- mOutput << startstr << "<zfar sid=\"zfar\">"
- << cam->mClipPlaneFar
- << "</zfar>" << endstr;
- PopTag();
- mOutput << startstr << "</perspective>" << endstr;
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
- PopTag();
- mOutput << startstr << "</optics>" << endstr;
- PopTag();
- mOutput << startstr << "</camera>" << endstr;
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Write the embedded textures
-void ColladaExporter::WriteLightsLibrary() {
- if(mScene->HasLights()) {
-
- mOutput << startstr << "<library_lights>" << endstr;
- PushTag();
-
- for( size_t a = 0; a < mScene->mNumLights; ++a)
- WriteLight( a);
-
- PopTag();
- mOutput << startstr << "</library_lights>" << endstr;
-
- }
-}
-
-void ColladaExporter::WriteLight(size_t pIndex){
-
- const aiLight *light = mScene->mLights[pIndex];
- const std::string idstrEscaped = XMLEscape(light->mName.C_Str());
-
- mOutput << startstr << "<light id=\"" << idstrEscaped << "-light\" name=\""
- << idstrEscaped << "_name\" >" << endstr;
- PushTag();
- mOutput << startstr << "<technique_common>" << endstr;
- PushTag();
- switch(light->mType){
- case aiLightSource_AMBIENT:
- WriteAmbienttLight(light);
- break;
- case aiLightSource_DIRECTIONAL:
- WriteDirectionalLight(light);
- break;
- case aiLightSource_POINT:
- WritePointLight(light);
- break;
- case aiLightSource_SPOT:
- WriteSpotLight(light);
- break;
- case aiLightSource_AREA:
- case aiLightSource_UNDEFINED:
- case _aiLightSource_Force32Bit:
- break;
- }
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
-
- PopTag();
- mOutput << startstr << "</light>" << endstr;
-
-}
-
-void ColladaExporter::WritePointLight(const aiLight *const light){
- const aiColor3D &color= light->mColorDiffuse;
- mOutput << startstr << "<point>" << endstr;
- PushTag();
- mOutput << startstr << "<color sid=\"color\">"
- << color.r<<" "<<color.g<<" "<<color.b
- <<"</color>" << endstr;
- mOutput << startstr << "<constant_attenuation>"
- << light->mAttenuationConstant
- <<"</constant_attenuation>" << endstr;
- mOutput << startstr << "<linear_attenuation>"
- << light->mAttenuationLinear
- <<"</linear_attenuation>" << endstr;
- mOutput << startstr << "<quadratic_attenuation>"
- << light->mAttenuationQuadratic
- <<"</quadratic_attenuation>" << endstr;
-
- PopTag();
- mOutput << startstr << "</point>" << endstr;
-
-}
-void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
- const aiColor3D &color= light->mColorDiffuse;
- mOutput << startstr << "<directional>" << endstr;
- PushTag();
- mOutput << startstr << "<color sid=\"color\">"
- << color.r<<" "<<color.g<<" "<<color.b
- <<"</color>" << endstr;
-
- PopTag();
- mOutput << startstr << "</directional>" << endstr;
-
-}
-void ColladaExporter::WriteSpotLight(const aiLight *const light){
-
- const aiColor3D &color= light->mColorDiffuse;
- mOutput << startstr << "<spot>" << endstr;
- PushTag();
- mOutput << startstr << "<color sid=\"color\">"
- << color.r<<" "<<color.g<<" "<<color.b
- <<"</color>" << endstr;
- mOutput << startstr << "<constant_attenuation>"
- << light->mAttenuationConstant
- <<"</constant_attenuation>" << endstr;
- mOutput << startstr << "<linear_attenuation>"
- << light->mAttenuationLinear
- <<"</linear_attenuation>" << endstr;
- mOutput << startstr << "<quadratic_attenuation>"
- << light->mAttenuationQuadratic
- <<"</quadratic_attenuation>" << endstr;
- /*
- out->mAngleOuterCone = AI_DEG_TO_RAD (std::acos(std::pow(0.1f,1.f/srcLight->mFalloffExponent))+
- srcLight->mFalloffAngle);
- */
-
- const ai_real fallOffAngle = AI_RAD_TO_DEG(light->mAngleInnerCone);
- mOutput << startstr <<"<falloff_angle sid=\"fall_off_angle\">"
- << fallOffAngle
- <<"</falloff_angle>" << endstr;
- double temp = light->mAngleOuterCone-light->mAngleInnerCone;
-
- temp = std::cos(temp);
- temp = std::log(temp)/std::log(0.1);
- temp = 1/temp;
- mOutput << startstr << "<falloff_exponent sid=\"fall_off_exponent\">"
- << temp
- <<"</falloff_exponent>" << endstr;
-
-
- PopTag();
- mOutput << startstr << "</spot>" << endstr;
-
-}
-
-void ColladaExporter::WriteAmbienttLight(const aiLight *const light){
-
- const aiColor3D &color= light->mColorAmbient;
- mOutput << startstr << "<ambient>" << endstr;
- PushTag();
- mOutput << startstr << "<color sid=\"color\">"
- << color.r<<" "<<color.g<<" "<<color.b
- <<"</color>" << endstr;
-
- PopTag();
- mOutput << startstr << "</ambient>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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)
-{
- if( pSrcMat->GetTextureCount( pTexture) > 0 )
- {
- aiString texfile;
- unsigned int uvChannel = 0;
- pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
-
- 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 )
- poSurface.exist = pSrcMat->Get( pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
-static bool isalnum_C(char c)
-{
- return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes an image entry for the given surface
-void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
-{
- if( !pSurface.texture.empty() )
- {
- mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
- PushTag();
- mOutput << startstr << "<init_from>";
-
- // URL encode image file name first, then XML encode on top
- std::stringstream imageUrlEncoded;
- for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it )
- {
- if( isalnum_C( (unsigned char) *it) || *it == ':' || *it == '_' || *it == '-' || *it == '.' || *it == '/' || *it == '\\' )
- imageUrlEncoded << *it;
- else
- imageUrlEncoded << '%' << std::hex << size_t( (unsigned char) *it) << std::dec;
- }
- mOutput << XMLEscape(imageUrlEncoded.str());
- mOutput << "</init_from>" << endstr;
- PopTag();
- mOutput << startstr << "</image>" << endstr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes a color-or-texture entry into an effect definition
-void ColladaExporter::WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName)
-{
- 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=\"" << XMLEscape(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
- }
- PopTag();
- mOutput << startstr << "</" << pTypeName << ">" << endstr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the two parameters necessary for referencing a texture in an effect entry
-void ColladaExporter::WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName)
-{
- // if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
- if( !pSurface.texture.empty() )
- {
- mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-surface\">" << endstr;
- PushTag();
- mOutput << startstr << "<surface type=\"2D\">" << endstr;
- PushTag();
- mOutput << startstr << "<init_from>" << XMLEscape(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr;
- PopTag();
- mOutput << startstr << "</surface>" << endstr;
- PopTag();
- mOutput << startstr << "</newparam>" << endstr;
-
- mOutput << startstr << "<newparam sid=\"" << XMLEscape(pMatName) << "-" << pTypeName << "-sampler\">" << endstr;
- PushTag();
- mOutput << startstr << "<sampler2D>" << endstr;
- PushTag();
- mOutput << startstr << "<source>" << XMLEscape(pMatName) << "-" << pTypeName << "-surface</source>" << endstr;
- PopTag();
- mOutput << startstr << "</sampler2D>" << endstr;
- PopTag();
- mOutput << startstr << "</newparam>" << endstr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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);
-
- /// collect all materials from the scene
- size_t numTextures = 0;
- for( size_t a = 0; a < mScene->mNumMaterials; ++a )
- {
- const aiMaterial* mat = mScene->mMaterials[a];
-
- aiString name;
- if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS ) {
- name = "mat";
- materials[a].name = std::string( "m") + to_string(a) + name.C_Str();
- } else {
- // try to use the material's name if no other material has already taken it, else append #
- std::string testName = name.C_Str();
- size_t materialCountWithThisName = 0;
- for( size_t i = 0; i < a; i ++ ) {
- if( materials[i].name == testName ) {
- materialCountWithThisName ++;
- }
- }
- if( materialCountWithThisName == 0 ) {
- materials[a].name = name.C_Str();
- } else {
- materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
- }
- }
- for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
- if( !isalnum_C( *it ) ) {
- *it = '_';
- }
- }
-
- aiShadingMode shading = aiShadingMode_Flat;
- 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++;
- ReadMaterialSurface( materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
- if( !materials[a].diffuse.texture.empty() ) numTextures++;
- ReadMaterialSurface( materials[a].specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
- if( !materials[a].specular.texture.empty() ) numTextures++;
- ReadMaterialSurface( materials[a].emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE);
- 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++;
-
- 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].index_refraction.exist = mat->Get( AI_MATKEY_REFRACTI, materials[a].index_refraction.value) == aiReturn_SUCCESS;
- }
-
- // output textures if present
- if( numTextures > 0 )
- {
- mOutput << startstr << "<library_images>" << endstr;
- PushTag();
- for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
- {
- const Material& mat = *it;
- 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 + "-emission-image");
- WriteImageEntry( mat.reflective, mat.name + "-reflective-image");
- WriteImageEntry( mat.transparent, mat.name + "-transparent-image");
- WriteImageEntry( mat.normal, mat.name + "-normal-image");
- }
- PopTag();
- mOutput << startstr << "</library_images>" << endstr;
- }
-
- // output effects - those are the actual carriers of information
- if( !materials.empty() )
- {
- mOutput << startstr << "<library_effects>" << endstr;
- PushTag();
- for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
- {
- const Material& mat = *it;
- // this is so ridiculous it must be right
- mOutput << startstr << "<effect id=\"" << XMLEscape(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr;
- PushTag();
- mOutput << startstr << "<profile_COMMON>" << endstr;
- PushTag();
-
- // write sampler- and surface params for the texture entries
- 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 << "<" << mat.shading_model << ">" << endstr;
- PushTag();
-
- 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");
- 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");
-
- if(! mat.normal.texture.empty()) {
- WriteTextureColorEntry( mat.normal, "bump", mat.name + "-normal-sampler");
- }
-
- PopTag();
- mOutput << startstr << "</" << mat.shading_model << ">" << endstr;
- PopTag();
- mOutput << startstr << "</technique>" << endstr;
- PopTag();
- mOutput << startstr << "</profile_COMMON>" << endstr;
- PopTag();
- mOutput << startstr << "</effect>" << endstr;
- }
- PopTag();
- mOutput << startstr << "</library_effects>" << endstr;
-
- // write materials - they're just effect references
- mOutput << startstr << "<library_materials>" << endstr;
- PushTag();
- for( std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it )
- {
- const Material& mat = *it;
- mOutput << startstr << "<material id=\"" << XMLEscape(mat.name) << "\" name=\"" << mat.name << "\">" << endstr;
- PushTag();
- mOutput << startstr << "<instance_effect url=\"#" << XMLEscape(mat.name) << "-fx\"/>" << endstr;
- PopTag();
- mOutput << startstr << "</material>" << endstr;
- }
- PopTag();
- mOutput << startstr << "</library_materials>" << endstr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the controller library
-void ColladaExporter::WriteControllerLibrary()
-{
- mOutput << startstr << "<library_controllers>" << endstr;
- PushTag();
-
- for( size_t a = 0; a < mScene->mNumMeshes; ++a)
- WriteController( a);
-
- PopTag();
- mOutput << startstr << "</library_controllers>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes a skin controller of the given mesh
-void ColladaExporter::WriteController( size_t pIndex)
-{
- const aiMesh* mesh = mScene->mMeshes[pIndex];
- const std::string idstr = GetMeshId( pIndex);
- const std::string idstrEscaped = XMLEscape(idstr);
-
- if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
- return;
-
- if ( mesh->mNumBones == 0 )
- return;
-
- mOutput << startstr << "<controller id=\"" << idstrEscaped << "-skin\" ";
- mOutput << "name=\"skinCluster" << pIndex << "\">"<< endstr;
- PushTag();
-
- mOutput << startstr << "<skin source=\"#" << idstrEscaped << "\">" << endstr;
- PushTag();
-
- // bind pose matrix
- mOutput << startstr << "<bind_shape_matrix>" << endstr;
- PushTag();
-
- // I think it is identity in general cases.
- aiMatrix4x4 mat;
- mOutput << startstr << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << endstr;
- mOutput << startstr << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << endstr;
- mOutput << startstr << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << endstr;
- mOutput << startstr << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4 << endstr;
-
- PopTag();
- mOutput << startstr << "</bind_shape_matrix>" << endstr;
-
- mOutput << startstr << "<source id=\"" << idstrEscaped << "-skin-joints\" name=\"" << idstrEscaped << "-skin-joints\">" << endstr;
- PushTag();
-
- mOutput << startstr << "<Name_array id=\"" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
-
- for( size_t i = 0; i < mesh->mNumBones; ++i )
- mOutput << XMLEscape(mesh->mBones[i]->mName.C_Str()) << " ";
-
- mOutput << "</Name_array>" << endstr;
-
- mOutput << startstr << "<technique_common>" << endstr;
- PushTag();
-
- mOutput << startstr << "<accessor source=\"#" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\" stride=\"" << 1 << "\">" << endstr;
- PushTag();
-
- mOutput << startstr << "<param name=\"JOINT\" type=\"Name\"></param>" << endstr;
-
- PopTag();
- mOutput << startstr << "</accessor>" << endstr;
-
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
-
- PopTag();
- mOutput << startstr << "</source>" << endstr;
-
- std::vector<ai_real> bind_poses;
- bind_poses.reserve(mesh->mNumBones * 16);
- for(unsigned int i = 0; i < mesh->mNumBones; ++i)
- for( unsigned int j = 0; j < 4; ++j)
- bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4);
-
- WriteFloatArray( idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real*) bind_poses.data(), bind_poses.size() / 16);
-
- bind_poses.clear();
-
- std::vector<ai_real> skin_weights;
- skin_weights.reserve(mesh->mNumVertices * mesh->mNumBones);
- for( size_t i = 0; i < mesh->mNumBones; ++i)
- for( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
- skin_weights.push_back(mesh->mBones[i]->mWeights[j].mWeight);
-
- WriteFloatArray( idstr + "-skin-weights", FloatType_Weight, (const ai_real*) skin_weights.data(), skin_weights.size());
-
- skin_weights.clear();
-
- mOutput << startstr << "<joints>" << endstr;
- PushTag();
-
- mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\"></input>" << endstr;
- mOutput << startstr << "<input semantic=\"INV_BIND_MATRIX\" source=\"#" << idstrEscaped << "-skin-bind_poses\"></input>" << endstr;
-
- PopTag();
- mOutput << startstr << "</joints>" << endstr;
-
- mOutput << startstr << "<vertex_weights count=\"" << mesh->mNumVertices << "\">" << endstr;
- PushTag();
-
- mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\" offset=\"0\"></input>" << endstr;
- mOutput << startstr << "<input semantic=\"WEIGHT\" source=\"#" << idstrEscaped << "-skin-weights\" offset=\"1\"></input>" << endstr;
-
- mOutput << startstr << "<vcount>";
-
- std::vector<ai_uint> num_influences(mesh->mNumVertices, (ai_uint)0);
- for( size_t i = 0; i < mesh->mNumBones; ++i)
- for( size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
- ++num_influences[mesh->mBones[i]->mWeights[j].mVertexId];
-
- for( size_t i = 0; i < mesh->mNumVertices; ++i)
- mOutput << num_influences[i] << " ";
-
- mOutput << "</vcount>" << endstr;
-
- mOutput << startstr << "<v>";
-
- ai_uint joint_weight_indices_length = 0;
- std::vector<ai_uint> accum_influences;
- accum_influences.reserve(num_influences.size());
- for( size_t i = 0; i < num_influences.size(); ++i)
- {
- accum_influences.push_back(joint_weight_indices_length);
- joint_weight_indices_length += num_influences[i];
- }
-
- ai_uint weight_index = 0;
- std::vector<ai_int> joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1);
- for( unsigned int i = 0; i < mesh->mNumBones; ++i)
- for( unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
- {
- unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId;
- for( ai_uint k = 0; k < num_influences[vId]; ++k)
- {
- if (joint_weight_indices[2 * (accum_influences[vId] + k)] == -1)
- {
- joint_weight_indices[2 * (accum_influences[vId] + k)] = i;
- joint_weight_indices[2 * (accum_influences[vId] + k) + 1] = weight_index;
- break;
- }
- }
- ++weight_index;
- }
-
- for( size_t i = 0; i < joint_weight_indices.size(); ++i)
- mOutput << joint_weight_indices[i] << " ";
-
- num_influences.clear();
- accum_influences.clear();
- joint_weight_indices.clear();
-
- mOutput << "</v>" << endstr;
-
- PopTag();
- mOutput << startstr << "</vertex_weights>" << endstr;
-
- PopTag();
- mOutput << startstr << "</skin>" << endstr;
-
- PopTag();
- mOutput << startstr << "</controller>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the geometry library
-void ColladaExporter::WriteGeometryLibrary()
-{
- mOutput << startstr << "<library_geometries>" << endstr;
- PushTag();
-
- for( size_t a = 0; a < mScene->mNumMeshes; ++a)
- WriteGeometry( a);
-
- PopTag();
- mOutput << startstr << "</library_geometries>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the given mesh
-void ColladaExporter::WriteGeometry( size_t pIndex)
-{
- const aiMesh* mesh = mScene->mMeshes[pIndex];
- const std::string idstr = GetMeshId( pIndex);
- const std::string idstrEscaped = XMLEscape(idstr);
-
- if ( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
- return;
-
- // opening tag
- mOutput << startstr << "<geometry id=\"" << idstrEscaped << "\" name=\"" << idstrEscaped << "_name\" >" << endstr;
- PushTag();
-
- mOutput << startstr << "<mesh>" << endstr;
- PushTag();
-
- // Positions
- WriteFloatArray( idstr + "-positions", FloatType_Vector, (ai_real*) mesh->mVertices, mesh->mNumVertices);
- // Normals, if any
- if( mesh->HasNormals() )
- WriteFloatArray( idstr + "-normals", FloatType_Vector, (ai_real*) mesh->mNormals, mesh->mNumVertices);
-
- // texture coords
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
- {
- if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
- {
- WriteFloatArray( idstr + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
- (ai_real*) mesh->mTextureCoords[a], mesh->mNumVertices);
- }
- }
-
- // vertex colors
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a)
- {
- if( mesh->HasVertexColors(static_cast<unsigned int>(a)) )
- WriteFloatArray( idstr + "-color" + to_string(a), FloatType_Color, (ai_real*) mesh->mColors[a], mesh->mNumVertices);
- }
-
- // assemble vertex structure
- // Only write input for POSITION since we will write other as shared inputs in polygon definition
- mOutput << startstr << "<vertices id=\"" << idstrEscaped << "-vertices" << "\">" << endstr;
- PushTag();
- mOutput << startstr << "<input semantic=\"POSITION\" source=\"#" << idstrEscaped << "-positions\" />" << endstr;
- PopTag();
- mOutput << startstr << "</vertices>" << endstr;
-
- // count the number of lines, triangles and polygon meshes
- int countLines = 0;
- int countPoly = 0;
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- if (mesh->mFaces[a].mNumIndices == 2) countLines++;
- else if (mesh->mFaces[a].mNumIndices >= 3) countPoly++;
- }
-
- // lines
- if (countLines)
- {
- mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
- PushTag();
- mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
- if( mesh->HasNormals() )
- mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << idstrEscaped << "-normals\" />" << endstr;
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
- {
- if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
- mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
- }
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
- {
- if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
- mOutput << startstr << "<input semantic=\"COLOR\" source=\"#" << idstrEscaped << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
- }
-
- mOutput << startstr << "<p>";
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- const aiFace& face = mesh->mFaces[a];
- if (face.mNumIndices != 2) continue;
- for( size_t b = 0; b < face.mNumIndices; ++b )
- mOutput << face.mIndices[b] << " ";
- }
- mOutput << "</p>" << endstr;
- PopTag();
- mOutput << startstr << "</lines>" << endstr;
- }
-
- // triangle - don't use it, because compatibility problems
-
- // polygons
- if (countPoly)
- {
- mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
- PushTag();
- mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
- if( mesh->HasNormals() )
- mOutput << startstr << "<input offset=\"0\" semantic=\"NORMAL\" source=\"#" << idstrEscaped << "-normals\" />" << endstr;
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
- {
- if( mesh->HasTextureCoords(static_cast<unsigned int>(a)) )
- mOutput << startstr << "<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
- }
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
- {
- if( mesh->HasVertexColors(static_cast<unsigned int>(a) ) )
- mOutput << startstr << "<input offset=\"0\" semantic=\"COLOR\" source=\"#" << idstrEscaped << "-color" << a << "\" " << "set=\"" << a << "\"" << " />" << endstr;
- }
-
- mOutput << startstr << "<vcount>";
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- if (mesh->mFaces[a].mNumIndices < 3) continue;
- mOutput << mesh->mFaces[a].mNumIndices << " ";
- }
- mOutput << "</vcount>" << endstr;
-
- mOutput << startstr << "<p>";
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- const aiFace& face = mesh->mFaces[a];
- if (face.mNumIndices < 3) continue;
- for( size_t b = 0; b < face.mNumIndices; ++b )
- mOutput << face.mIndices[b] << " ";
- }
- mOutput << "</p>" << endstr;
- PopTag();
- mOutput << startstr << "</polylist>" << endstr;
- }
-
- // closing tags
- PopTag();
- mOutput << startstr << "</mesh>" << endstr;
- PopTag();
- mOutput << startstr << "</geometry>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes a float array of the given type
-void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount)
-{
- size_t floatsPerElement = 0;
- switch( pType )
- {
- case FloatType_Vector: floatsPerElement = 3; break;
- case FloatType_TexCoord2: floatsPerElement = 2; break;
- case FloatType_TexCoord3: floatsPerElement = 3; break;
- case FloatType_Color: floatsPerElement = 3; break;
- case FloatType_Mat4x4: floatsPerElement = 16; break;
- case FloatType_Weight: floatsPerElement = 1; break;
- case FloatType_Time: floatsPerElement = 1; break;
- default:
- return;
- }
-
- std::string arrayId = pIdString + "-array";
-
- mOutput << startstr << "<source id=\"" << XMLEscape(pIdString) << "\" name=\"" << XMLEscape(pIdString) << "\">" << endstr;
- PushTag();
-
- // source array
- mOutput << startstr << "<float_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << pElementCount * floatsPerElement << "\"> ";
- PushTag();
-
- if( pType == FloatType_TexCoord2 )
- {
- for( size_t a = 0; a < pElementCount; ++a )
- {
- mOutput << pData[a*3+0] << " ";
- mOutput << pData[a*3+1] << " ";
- }
- }
- else if( pType == FloatType_Color )
- {
- for( size_t a = 0; a < pElementCount; ++a )
- {
- mOutput << pData[a*4+0] << " ";
- mOutput << pData[a*4+1] << " ";
- mOutput << pData[a*4+2] << " ";
- }
- }
- else
- {
- for( size_t a = 0; a < pElementCount * floatsPerElement; ++a )
- mOutput << pData[a] << " ";
- }
- mOutput << "</float_array>" << endstr;
- PopTag();
-
- // 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;
- PushTag();
-
- switch( pType )
- {
- case FloatType_Vector:
- mOutput << startstr << "<param name=\"X\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"Y\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"Z\" type=\"float\" />" << endstr;
- break;
-
- case FloatType_TexCoord2:
- mOutput << startstr << "<param name=\"S\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"T\" type=\"float\" />" << endstr;
- break;
-
- case FloatType_TexCoord3:
- mOutput << startstr << "<param name=\"S\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"T\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"P\" type=\"float\" />" << endstr;
- break;
-
- case FloatType_Color:
- mOutput << startstr << "<param name=\"R\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"G\" type=\"float\" />" << endstr;
- mOutput << startstr << "<param name=\"B\" type=\"float\" />" << endstr;
- break;
-
- case FloatType_Mat4x4:
- mOutput << startstr << "<param name=\"TRANSFORM\" type=\"float4x4\" />" << endstr;
- break;
-
- case FloatType_Weight:
- mOutput << startstr << "<param name=\"WEIGHT\" type=\"float\" />" << endstr;
- break;
-
- // customized, add animation related
- case FloatType_Time:
- mOutput << startstr << "<param name=\"TIME\" type=\"float\" />" << endstr;
- break;
-
- }
-
- PopTag();
- mOutput << startstr << "</accessor>" << endstr;
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
- PopTag();
- mOutput << startstr << "</source>" << endstr;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the scene library
-void ColladaExporter::WriteSceneLibrary()
-{
- const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
-
- mOutput << startstr << "<library_visual_scenes>" << endstr;
- PushTag();
- mOutput << startstr << "<visual_scene id=\"" + scene_name_escaped + "\" name=\"" + scene_name_escaped + "\">" << endstr;
- PushTag();
-
- // start recursive write at the root node
- for( size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a )
- WriteNode( mScene, mScene->mRootNode->mChildren[a]);
-
- PopTag();
- mOutput << startstr << "</visual_scene>" << endstr;
- PopTag();
- mOutput << startstr << "</library_visual_scenes>" << endstr;
-}
-// ------------------------------------------------------------------------------------------------
-void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
-{
- const aiAnimation * anim = mScene->mAnimations[pIndex];
-
- if ( anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels ==0 )
- return;
-
- const std::string animation_name_escaped = XMLEscape( anim->mName.C_Str() );
- std::string idstr = anim->mName.C_Str();
- std::string ending = std::string( "AnimId" ) + to_string(pIndex);
- if (idstr.length() >= ending.length()) {
- if (0 != idstr.compare (idstr.length() - ending.length(), ending.length(), ending)) {
- idstr = idstr + ending;
- }
- } else {
- idstr = idstr + ending;
- }
-
- const std::string idstrEscaped = XMLEscape(idstr);
-
- mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
- PushTag();
-
- for (size_t a = 0; a < anim->mNumChannels; ++a) {
- const aiNodeAnim * nodeAnim = anim->mChannels[a];
-
- // sanity check
- if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
-
- {
- const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input");
-
- std::vector<ai_real> frames;
- for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
- frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime));
- }
-
- WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
- frames.clear();
- }
-
- {
- const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output");
-
- std::vector<ai_real> keyframes;
- keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
- for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
-
- aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
- aiMatrix4x4 ScalingM; // identity
- ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
-
- aiQuaternion RotationQ = nodeAnim->mRotationKeys[i].mValue;
- aiMatrix4x4 s = aiMatrix4x4( RotationQ.GetMatrix() );
- aiMatrix4x4 RotationM(s.a1, s.a2, s.a3, 0, s.b1, s.b2, s.b3, 0, s.c1, s.c2, s.c3, 0, 0, 0, 0, 1);
-
- aiVector3D Translation = nodeAnim->mPositionKeys[i].mValue;
- aiMatrix4x4 TranslationM; // identity
- TranslationM[0][3] = Translation.x; TranslationM[1][3] = Translation.y; TranslationM[2][3] = Translation.z;
-
- // Combine the above transformations
- aiMatrix4x4 mat = TranslationM * RotationM * ScalingM;
-
- for( unsigned int j = 0; j < 4; ++j) {
- keyframes.insert(keyframes.end(), mat[j], mat[j] + 4);
- }
- }
-
- WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16);
- }
-
- {
- std::vector<std::string> names;
- for ( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
- if ( nodeAnim->mPreState == aiAnimBehaviour_DEFAULT
- || nodeAnim->mPreState == aiAnimBehaviour_LINEAR
- || nodeAnim->mPreState == aiAnimBehaviour_REPEAT
- ) {
- names.push_back( "LINEAR" );
- } else if (nodeAnim->mPostState == aiAnimBehaviour_CONSTANT) {
- names.push_back( "STEP" );
- }
- }
-
- const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
- std::string arrayId = node_idstr + "-array";
-
- mOutput << startstr << "<source id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
- PushTag();
-
- // source array
- mOutput << startstr << "<Name_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\"> ";
- for( size_t a = 0; a < names.size(); ++a ) {
- mOutput << names[a] << " ";
- }
- mOutput << "</Name_array>" << endstr;
-
- mOutput << startstr << "<technique_common>" << endstr;
- PushTag();
-
- mOutput << startstr << "<accessor source=\"#" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
- PushTag();
-
- mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
-
- PopTag();
- mOutput << startstr << "</accessor>" << endstr;
-
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
-
- PopTag();
- mOutput << startstr << "</source>" << endstr;
- }
-
- }
-
- for (size_t a = 0; a < anim->mNumChannels; ++a) {
- const aiNodeAnim * nodeAnim = anim->mChannels[a];
-
- {
- // samplers
- const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
- mOutput << startstr << "<sampler id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
- PushTag();
-
- mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
- mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
- mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
-
- PopTag();
- mOutput << startstr << "</sampler>" << endstr;
- }
- }
-
- for (size_t a = 0; a < anim->mNumChannels; ++a) {
- const aiNodeAnim * nodeAnim = anim->mChannels[a];
-
- {
- // channels
- mOutput << startstr << "<channel source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
- }
- }
-
- PopTag();
- mOutput << startstr << "</animation>" << endstr;
-
-}
-// ------------------------------------------------------------------------------------------------
-void ColladaExporter::WriteAnimationsLibrary()
-{
- const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
-
- if ( mScene->mNumAnimations > 0 ) {
- mOutput << startstr << "<library_animations>" << endstr;
- PushTag();
-
- // start recursive write at the root node
- for( size_t a = 0; a < mScene->mNumAnimations; ++a)
- WriteAnimationLibrary( a );
-
- PopTag();
- mOutput << startstr << "</library_animations>" << endstr;
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Helper to find a bone by name in the scene
-aiBone* findBone( const aiScene* scene, const char * name) {
- for (size_t m=0; m<scene->mNumMeshes; m++) {
- aiMesh * mesh = scene->mMeshes[m];
- for (size_t b=0; b<mesh->mNumBones; b++) {
- aiBone * bone = mesh->mBones[b];
- if (0 == strcmp(name, bone->mName.C_Str())) {
- return bone;
- }
- }
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiNode * findBoneNode( const aiNode* aNode, const aiBone* bone)
-{
- if ( aNode && bone && aNode->mName == bone->mName ) {
- return aNode;
- }
-
- if ( aNode && bone ) {
- for (unsigned int i=0; i < aNode->mNumChildren; ++i) {
- aiNode * aChild = aNode->mChildren[i];
- const aiNode * foundFromChild = 0;
- if ( aChild ) {
- foundFromChild = findBoneNode( aChild, bone );
- if ( foundFromChild ) return foundFromChild;
- }
- }
- }
-
- return NULL;
-}
-
-const aiNode * findSkeletonRootNode( const aiScene* scene, const aiMesh * mesh)
-{
- std::set<const aiNode*> topParentBoneNodes;
- if ( mesh && mesh->mNumBones > 0 ) {
- for (unsigned int i=0; i < mesh->mNumBones; ++i) {
- aiBone * bone = mesh->mBones[i];
-
- const aiNode * node = findBoneNode( scene->mRootNode, bone);
- if ( node ) {
- while ( node->mParent && findBone(scene, node->mParent->mName.C_Str() ) != 0 ) {
- node = node->mParent;
- }
- topParentBoneNodes.insert( node );
- }
- }
- }
-
- if ( !topParentBoneNodes.empty() ) {
- const aiNode * parentBoneNode = *topParentBoneNodes.begin();
- if ( topParentBoneNodes.size() == 1 ) {
- return parentBoneNode;
- } else {
- for (auto it : topParentBoneNodes) {
- if ( it->mParent ) return it->mParent;
- }
- return parentBoneNode;
- }
- }
-
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively writes the given node
-void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
-{
- // the node must have a name
- if (pNode->mName.length == 0)
- {
- std::stringstream ss;
- ss << "Node_" << pNode;
- pNode->mName.Set(ss.str());
- }
-
- // If the node is associated with a bone, it is a joint node (JOINT)
- // otherwise it is a normal node (NODE)
- const char * node_type;
- bool is_joint, is_skeleton_root = false;
- if (NULL == findBone(pScene, pNode->mName.C_Str())) {
- node_type = "NODE";
- is_joint = false;
- } else {
- node_type = "JOINT";
- is_joint = true;
- if(!pNode->mParent || NULL == findBone(pScene, pNode->mParent->mName.C_Str()))
- is_skeleton_root = true;
- }
-
- const std::string node_name_escaped = XMLEscape(pNode->mName.data);
- /* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
- mOutput << startstr
- << "<node ";
- if(is_skeleton_root)
- mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
- mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
- */
- mOutput << startstr << "<node ";
- if(is_skeleton_root) {
- mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
- mFoundSkeletonRootNodeID = node_name_escaped;
- } else {
- mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"": "") ;
- }
-
- mOutput << " name=\"" << node_name_escaped
- << "\" type=\"" << node_type
- << "\">" << endstr;
- PushTag();
-
- // write transformation - we can directly put the matrix there
- // TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
- const aiMatrix4x4& mat = pNode->mTransformation;
-
- // customized, sid should be 'matrix' to match with loader code.
- //mOutput << startstr << "<matrix sid=\"transform\">";
- mOutput << startstr << "<matrix sid=\"matrix\">";
-
- mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
- mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
- mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
- mOutput << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4;
- mOutput << "</matrix>" << endstr;
-
- if(pNode->mNumMeshes==0){
- //check if it is a camera node
- for(size_t i=0; i<mScene->mNumCameras; i++){
- if(mScene->mCameras[i]->mName == pNode->mName){
- mOutput << startstr <<"<instance_camera url=\"#" << node_name_escaped << "-camera\"/>" << endstr;
- break;
- }
- }
- //check if it is a light node
- for(size_t i=0; i<mScene->mNumLights; i++){
- if(mScene->mLights[i]->mName == pNode->mName){
- mOutput << startstr <<"<instance_light url=\"#" << node_name_escaped << "-light\"/>" << endstr;
- break;
- }
- }
-
- }else
- // instance every geometry
- for( size_t a = 0; a < pNode->mNumMeshes; ++a )
- {
- const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
- // do not instantiate mesh if empty. I wonder how this could happen
- if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
- continue;
-
- if( mesh->mNumBones == 0 )
- {
- mOutput << startstr << "<instance_geometry url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "\">" << endstr;
- PushTag();
- }
- else
- {
- mOutput << startstr
- << "<instance_controller url=\"#" << XMLEscape(GetMeshId( pNode->mMeshes[a])) << "-skin\">"
- << endstr;
- PushTag();
-
- // note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
- // use the first bone to find skeleton root
- const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
- if ( skeletonRootBoneNode ) {
- mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
- }
- mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
- }
- mOutput << startstr << "<bind_material>" << endstr;
- PushTag();
- mOutput << startstr << "<technique_common>" << endstr;
- PushTag();
- mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLEscape(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
- PushTag();
- for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
- {
- if( mesh->HasTextureCoords( static_cast<unsigned int>(a) ) )
- // semantic as in <texture texcoord=...>
- // input_semantic as in <input semantic=...>
- // input_set as in <input set=...>
- mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << a << "\" input_semantic=\"TEXCOORD\" input_set=\"" << a << "\"/>" << endstr;
- }
- PopTag();
- mOutput << startstr << "</instance_material>" << endstr;
- PopTag();
- mOutput << startstr << "</technique_common>" << endstr;
- PopTag();
- mOutput << startstr << "</bind_material>" << endstr;
-
- PopTag();
- if( mesh->mNumBones == 0)
- mOutput << startstr << "</instance_geometry>" << endstr;
- else
- mOutput << startstr << "</instance_controller>" << endstr;
- }
-
- // recurse into subnodes
- for( size_t a = 0; a < pNode->mNumChildren; ++a )
- WriteNode( pScene, pNode->mChildren[a]);
-
- PopTag();
- mOutput << startstr << "</node>" << endstr;
-}
-
-#endif
-#endif
diff --git a/src/3rdparty/assimp/code/ColladaExporter.h b/src/3rdparty/assimp/code/ColladaExporter.h
deleted file mode 100644
index e7a4a9b5d..000000000
--- a/src/3rdparty/assimp/code/ColladaExporter.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ColladaExporter.h
- * Declares the exporter class to write a scene to a Collada file
- */
-#ifndef AI_COLLADAEXPORTER_H_INC
-#define AI_COLLADAEXPORTER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/material.h>
-#include <assimp/mesh.h>
-#include <assimp/light.h>
-#include <assimp/Exporter.hpp>
-#include <sstream>
-#include <vector>
-#include <map>
-
-#include "StringUtils.h"
-
-struct aiScene;
-struct aiNode;
-
-namespace Assimp
-{
-
-/// Helper class to export a given scene to a Collada file. Just for my personal
-/// comfort when implementing it.
-class ColladaExporter
-{
-public:
- /// Constructor for a specific scene to export
- ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
-
- /// Destructor
- virtual ~ColladaExporter();
-
-protected:
- /// Starts writing the contents
- void WriteFile();
-
- /// Writes the asset header
- void WriteHeader();
-
- /// Writes the embedded textures
- void WriteTextures();
-
- /// Writes the material setup
- void WriteMaterials();
-
- /// Writes the cameras library
- void WriteCamerasLibrary();
-
- // Write a camera entry
- void WriteCamera(size_t pIndex);
-
- /// Writes the cameras library
- void WriteLightsLibrary();
-
- // Write a camera entry
- void WriteLight(size_t pIndex);
- void WritePointLight(const aiLight *const light);
- void WriteDirectionalLight(const aiLight *const light);
- void WriteSpotLight(const aiLight *const light);
- void WriteAmbienttLight(const aiLight *const light);
-
- /// Writes the controller library
- void WriteControllerLibrary();
-
- /// Writes a skin controller of the given mesh
- void WriteController( size_t pIndex);
-
- /// Writes the geometry library
- void WriteGeometryLibrary();
-
- /// Writes the given mesh
- void WriteGeometry( size_t pIndex);
-
- //enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
- // customized to add animation related type
- enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time };
-
- /// Writes a float array of the given type
- void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
-
- /// Writes the scene library
- void WriteSceneLibrary();
-
- // customized, Writes the animation library
- void WriteAnimationsLibrary();
- void WriteAnimationLibrary( size_t pIndex);
- std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
-
- /// Recursively writes the given node
- void WriteNode( const aiScene* scene, aiNode* pNode);
-
- /// Enters a new xml element, which increases the indentation
- void PushTag() { startstr.append( " "); }
- /// Leaves an element, decreasing the indentation
- void PopTag() {
- ai_assert( startstr.length() > 1);
- startstr.erase( startstr.length() - 2);
- }
-
- /// Creates a mesh ID for the given mesh
- std::string GetMeshId( size_t pIndex) const {
- return std::string( "meshId" ) + to_string(pIndex);
- }
-
-public:
- /// Stringstream to write all output into
- 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;
- /// current line end string for simple stream insertion
- std::string endstr;
-
- // pair of color and texture - texture precedences color
- struct Surface
- {
- bool exist;
- aiColor4D color;
- std::string texture;
- size_t channel;
- Surface() { exist = false; channel = 0; }
- };
-
- struct Property
- {
- bool exist;
- ai_real value;
- Property()
- : exist(false)
- , value(0.0)
- {}
- };
-
- // summarize a material in an convinient way.
- struct Material
- {
- std::string name;
- std::string shading_model;
- Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
- Property shininess, transparency, index_refraction;
-
- 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
- void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex);
- /// Writes an image entry for the given surface
- void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
- /// Writes the two parameters necessary for referencing a texture in an effect entry
- 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);
-};
-
-}
-
-#endif // !! AI_COLLADAEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/ColladaHelper.h b/src/3rdparty/assimp/code/ColladaHelper.h
deleted file mode 100644
index e691a6062..000000000
--- a/src/3rdparty/assimp/code/ColladaHelper.h
+++ /dev/null
@@ -1,703 +0,0 @@
-/** Helper structures for the Collada loader */
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_COLLADAHELPER_H_INC
-#define AI_COLLADAHELPER_H_INC
-
-#include <map>
-#include <vector>
-#include <stdint.h>
-#include <assimp/light.h>
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-
-struct aiMaterial;
-
-namespace Assimp {
-namespace Collada {
-
-/** Collada file versions which evolved during the years ... */
-enum FormatVersion
-{
- FV_1_5_n,
- FV_1_4_n,
- FV_1_3_n
-};
-
-
-/** Transformation types that can be applied to a node */
-enum TransformType
-{
- TF_LOOKAT,
- TF_ROTATE,
- TF_TRANSLATE,
- TF_SCALE,
- TF_SKEW,
- TF_MATRIX
-};
-
-/** Different types of input data to a vertex or face */
-enum InputType
-{
- IT_Invalid,
- IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
- IT_Position,
- IT_Normal,
- IT_Texcoord,
- IT_Color,
- IT_Tangent,
- IT_Bitangent
-};
-
-/** Supported controller types */
-enum ControllerType
-{
- Skin,
- Morph
-};
-
-/** Supported morph methods */
-enum MorphMethod
-{
- Normalized,
- Relative
-};
-
-
-/** Contains all data for one of the different transformation types */
-struct Transform
-{
- std::string mID; ///< SID of the transform step, by which anim channels address their target node
- TransformType mType;
- ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
-};
-
-/** A collada camera. */
-struct Camera
-{
- Camera()
- : mOrtho (false)
- , mHorFov (10e10f)
- , mVerFov (10e10f)
- , mAspect (10e10f)
- , mZNear (0.1f)
- , mZFar (1000.f)
- {}
-
- // Name of camera
- std::string mName;
-
- // True if it is an orthografic camera
- bool mOrtho;
-
- //! Horizontal field of view in degrees
- ai_real mHorFov;
-
- //! Vertical field of view in degrees
- ai_real mVerFov;
-
- //! Screen aspect
- ai_real mAspect;
-
- //! Near& far z
- ai_real mZNear, mZFar;
-};
-
-#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
-
-/** A collada light source. */
-struct Light
-{
- Light()
- : mType (aiLightSource_UNDEFINED)
- , mAttConstant (1.f)
- , mAttLinear (0.f)
- , mAttQuadratic (0.f)
- , mFalloffAngle (180.f)
- , mFalloffExponent (0.f)
- , mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
- , mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET)
- , mIntensity (1.f)
- {}
-
- //! Type of the light source aiLightSourceType + ambient
- unsigned int mType;
-
- //! Color of the light
- aiColor3D mColor;
-
- //! Light attenuation
- ai_real mAttConstant,mAttLinear,mAttQuadratic;
-
- //! Spot light falloff
- ai_real mFalloffAngle;
- ai_real mFalloffExponent;
-
- // -----------------------------------------------------
- // FCOLLADA extension from here
-
- //! ... related stuff from maja and max extensions
- ai_real mPenumbraAngle;
- ai_real mOuterAngle;
-
- //! Common light intensity
- ai_real mIntensity;
-};
-
-/** Short vertex index description */
-struct InputSemanticMapEntry
-{
- InputSemanticMapEntry()
- : mSet(0)
- , mType(IT_Invalid)
- {}
-
- //! Index of set, optional
- unsigned int mSet;
-
- //! Type of referenced vertex input
- InputType mType;
-};
-
-/** Table to map from effect to vertex input semantics */
-struct SemanticMappingTable
-{
- //! Name of material
- std::string mMatName;
-
- //! List of semantic map commands, grouped by effect semantic name
- std::map<std::string, InputSemanticMapEntry> mMap;
-
- //! For std::find
- bool operator == (const std::string& s) const {
- return s == mMatName;
- }
-};
-
-/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
- * The ID refers to either a mesh or a controller which specifies the mesh
- */
-struct MeshInstance
-{
- ///< ID of the mesh or controller to be instanced
- std::string mMeshOrController;
-
- ///< Map of materials by the subgroup ID they're applied to
- std::map<std::string, SemanticMappingTable> mMaterials;
-};
-
-/** A reference to a camera inside a node*/
-struct CameraInstance
-{
- ///< ID of the camera
- std::string mCamera;
-};
-
-/** A reference to a light inside a node*/
-struct LightInstance
-{
- ///< ID of the camera
- std::string mLight;
-};
-
-/** A reference to a node inside a node*/
-struct NodeInstance
-{
- ///< ID of the node
- std::string mNode;
-};
-
-/** A node in a scene hierarchy */
-struct Node
-{
- std::string mName;
- std::string mID;
- std::string mSID;
- Node* mParent;
- std::vector<Node*> mChildren;
-
- /** Operations in order to calculate the resulting transformation to parent. */
- std::vector<Transform> mTransforms;
-
- /** Meshes at this node */
- std::vector<MeshInstance> mMeshes;
-
- /** Lights at this node */
- std::vector<LightInstance> mLights;
-
- /** Cameras at this node */
- std::vector<CameraInstance> mCameras;
-
- /** Node instances at this node */
- std::vector<NodeInstance> mNodeInstances;
-
- /** Rootnodes: Name of primary camera, if any */
- std::string mPrimaryCamera;
-
- //! Constructor. Begin with a zero parent
- Node() {
- mParent = NULL;
- }
-
- //! Destructor: delete all children subsequently
- ~Node() {
- for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
- delete *it;
- }
-};
-
-/** Data source array: either floats or strings */
-struct Data
-{
- bool mIsStringArray;
- std::vector<ai_real> mValues;
- std::vector<std::string> mStrings;
-};
-
-/** Accessor to a data array */
-struct Accessor
-{
- size_t mCount; // in number of objects
- size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
- size_t mOffset; // in number of values
- size_t mStride; // Stride in number of values
- std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
- size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
- // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
- std::string mSource; // URL of the source array
- mutable const Data* mData; // Pointer to the source array, if resolved. NULL else
-
- Accessor()
- {
- mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL;
- mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
- }
-};
-
-/** A single face in a mesh */
-struct Face
-{
- std::vector<size_t> mIndices;
-};
-
-/** An input channel for mesh data, referring to a single accessor */
-struct InputChannel
-{
- InputType mType; // Type of the data
- size_t mIndex; // Optional index, if multiple sets of the same data type are given
- size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
- std::string mAccessor; // ID of the accessor where to read the actual values from.
- mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else
-
- InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; }
-};
-
-/** Subset of a mesh with a certain material */
-struct SubMesh
-{
- std::string mMaterial; ///< subgroup identifier
- size_t mNumFaces; ///< number of faces in this submesh
-};
-
-/** Contains data for a single mesh */
-struct Mesh
-{
- 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.
- std::string mVertexID;
-
- // Vertex data addressed by vertex indices
- std::vector<InputChannel> mPerVertexData;
-
- // actual mesh data, assembled on encounter of a <p> element. Verbose format, not indexed
- std::vector<aiVector3D> mPositions;
- std::vector<aiVector3D> mNormals;
- std::vector<aiVector3D> mTangents;
- std::vector<aiVector3D> mBitangents;
- std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- // Faces. Stored are only the number of vertices for each face.
- // 1 == point, 2 == line, 3 == triangle, 4+ == poly
- std::vector<size_t> mFaceSize;
-
- // Position indices for all faces in the sequence given in mFaceSize -
- // necessary for bone weight assignment
- std::vector<size_t> mFacePosIndices;
-
- // Submeshes in this mesh, each with a given material
- std::vector<SubMesh> mSubMeshes;
-};
-
-/** Which type of primitives the ReadPrimitives() function is going to read */
-enum PrimitiveType
-{
- Prim_Invalid,
- Prim_Lines,
- Prim_LineStrip,
- Prim_Triangles,
- Prim_TriStrips,
- Prim_TriFans,
- Prim_Polylist,
- Prim_Polygon
-};
-
-/** A skeleton controller to deform a mesh with the use of joints */
-struct Controller
-{
- // controller type
- ControllerType mType;
-
- // Morphing method if type is Morph
- MorphMethod mMethod;
-
- // the URL of the mesh deformed by the controller.
- std::string mMeshId;
-
- // accessor URL of the joint names
- std::string mJointNameSource;
-
- ///< The bind shape matrix, as array of floats. I'm not sure what this matrix actually describes, but it can't be ignored in all cases
- ai_real mBindShapeMatrix[16];
-
- // accessor URL of the joint inverse bind matrices
- std::string mJointOffsetMatrixSource;
-
- // input channel: joint names.
- InputChannel mWeightInputJoints;
- // input channel: joint weights
- InputChannel mWeightInputWeights;
-
- // Number of weights per vertex.
- std::vector<size_t> mWeightCounts;
-
- // JointIndex-WeightIndex pairs for all vertices
- std::vector< std::pair<size_t, size_t> > mWeights;
-
- std::string mMorphTarget;
- std::string mMorphWeight;
-};
-
-/** A collada material. Pretty much the only member is a reference to an effect. */
-struct Material
-{
- std::string mName;
- std::string mEffect;
-};
-
-/** Type of the effect param */
-enum ParamType
-{
- Param_Sampler,
- Param_Surface
-};
-
-/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
-struct EffectParam
-{
- ParamType mType;
- std::string mReference; // to which other thing the param is referring to.
-};
-
-/** Shading type supported by the standard effect spec of Collada */
-enum ShadeType
-{
- Shade_Invalid,
- Shade_Constant,
- Shade_Lambert,
- Shade_Phong,
- Shade_Blinn
-};
-
-/** Represents a texture sampler in collada */
-struct Sampler
-{
- Sampler()
- : mWrapU (true)
- , mWrapV (true)
- , mMirrorU ()
- , mMirrorV ()
- , mOp (aiTextureOp_Multiply)
- , mUVId (UINT_MAX)
- , mWeighting (1.f)
- , mMixWithPrevious (1.f)
- {}
-
- /** Name of image reference
- */
- std::string mName;
-
- /** Wrap U?
- */
- bool mWrapU;
-
- /** Wrap V?
- */
- bool mWrapV;
-
- /** Mirror U?
- */
- bool mMirrorU;
-
- /** Mirror V?
- */
- bool mMirrorV;
-
- /** Blend mode
- */
- aiTextureOp mOp;
-
- /** UV transformation
- */
- aiUVTransform mTransform;
-
- /** Name of source UV channel
- */
- std::string mUVChannel;
-
- /** Resolved UV channel index or UINT_MAX if not known
- */
- unsigned int mUVId;
-
- // OKINO/MAX3D extensions from here
- // -------------------------------------------------------
-
- /** Weighting factor
- */
- ai_real mWeighting;
-
- /** Mixing factor from OKINO
- */
- ai_real mMixWithPrevious;
-};
-
-/** A collada effect. Can contain about anything according to the Collada spec,
- but we limit our version to a reasonable subset. */
-struct Effect
-{
- // Shading mode
- ShadeType mShadeType;
-
- // Colors
- aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
- mTransparent, mReflective;
-
- // Textures
- Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
- mTexTransparent, mTexBump, mTexReflective;
-
- // Scalar factory
- ai_real mShininess, mRefractIndex, mReflectivity;
- ai_real mTransparency;
- bool mHasTransparency;
- bool mRGBTransparency;
- bool mInvertTransparency;
-
- // local params referring to each other by their SID
- typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
- ParamLibrary mParams;
-
- // MAX3D extensions
- // ---------------------------------------------------------
- // Double-sided?
- bool mDoubleSided, mWireframe, mFaceted;
-
- Effect()
- : mShadeType (Shade_Phong)
- , mEmissive ( 0, 0, 0, 1)
- , mAmbient ( 0.1f, 0.1f, 0.1f, 1)
- , mDiffuse ( 0.6f, 0.6f, 0.6f, 1)
- , mSpecular ( 0.4f, 0.4f, 0.4f, 1)
- , mTransparent ( 0, 0, 0, 1)
- , mShininess (10.0f)
- , mRefractIndex (1.f)
- , mReflectivity (0.f)
- , mTransparency (1.f)
- , mHasTransparency (false)
- , mRGBTransparency(false)
- , mInvertTransparency(false)
- , mDoubleSided (false)
- , mWireframe (false)
- , mFaceted (false)
- {
- }
-};
-
-/** An image, meaning texture */
-struct Image
-{
- std::string mFileName;
-
- /** If image file name is zero, embedded image data
- */
- std::vector<uint8_t> mImageData;
-
- /** If image file name is zero, file format of
- * embedded image data.
- */
- std::string mEmbeddedFormat;
-
-};
-
-/** An animation channel. */
-struct AnimationChannel
-{
- /** URL of the data to animate. Could be about anything, but we support only the
- * "NodeID/TransformID.SubElement" notation
- */
- std::string mTarget;
-
- /** Source URL of the time values. Collada calls them "input". Meh. */
- std::string mSourceTimes;
- /** Source URL of the value values. Collada calls them "output". */
- std::string mSourceValues;
- /** Source URL of the IN_TANGENT semantic values. */
- std::string mInTanValues;
- /** Source URL of the OUT_TANGENT semantic values. */
- std::string mOutTanValues;
- /** Source URL of the INTERPOLATION semantic values. */
- std::string mInterpolationValues;
-};
-
-/** An animation. Container for 0-x animation channels or 0-x animations */
-struct Animation
-{
- /** Anim name */
- std::string mName;
-
- /** the animation channels, if any */
- std::vector<AnimationChannel> mChannels;
-
- /** the sub-animations, if any */
- std::vector<Animation*> mSubAnims;
-
- /** Destructor */
- ~Animation()
- {
- for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
- delete *it;
- }
-
- /** Collect all channels in the animation hierarchy into a single channel list. */
- void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
- {
- channels.insert(channels.end(), mChannels.begin(), mChannels.end());
-
- for (std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
- {
- Animation *pAnim = (*it);
-
- pAnim->CollectChannelsRecursively(channels);
- }
- }
-
- /** Combine all single-channel animations' channel into the same (parent) animation channel list. */
- void CombineSingleChannelAnimations()
- {
- CombineSingleChannelAnimationsRecursively(this);
- }
-
- void CombineSingleChannelAnimationsRecursively(Animation *pParent)
- {
- for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
- {
- Animation *anim = *it;
-
- CombineSingleChannelAnimationsRecursively(anim);
-
- if (anim->mChannels.size() == 1)
- {
- pParent->mChannels.push_back(anim->mChannels[0]);
-
- it = pParent->mSubAnims.erase(it);
-
- delete anim;
- }
- else
- {
- ++it;
- }
- }
- }
-};
-
-/** Description of a collada animation channel which has been determined to affect the current node */
-struct ChannelEntry
-{
- const Collada::AnimationChannel* mChannel; ///> the source channel
- std::string mTargetId;
- std::string mTransformId; // the ID of the transformation step of the node which is influenced
- size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
- size_t mSubElement; // starting index inside the transform data
-
- // resolved data references
- const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values
- const Collada::Data* mTimeData; ///> Source data array for the time values
- const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values
- const Collada::Data* mValueData; ///> Source datat array for the key value values
-
- ChannelEntry()
- : mChannel()
- , mTransformIndex()
- , mSubElement()
- , mTimeAccessor()
- , mTimeData()
- , mValueAccessor()
- , mValueData()
- {}
-};
-
-} // end of namespace Collada
-} // end of namespace Assimp
-
-#endif // AI_COLLADAHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/ColladaLoader.cpp b/src/3rdparty/assimp/code/ColladaLoader.cpp
deleted file mode 100644
index d2141c374..000000000
--- a/src/3rdparty/assimp/code/ColladaLoader.cpp
+++ /dev/null
@@ -1,1924 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the Collada loader */
-
-
-#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-
-#include "ColladaLoader.h"
-#include <assimp/anim.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-
-#include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "SkeletonMeshBuilder.h"
-#include "CreateAnimMesh.h"
-
-#include "time.h"
-#include "math.h"
-#include <algorithm>
-#include <numeric>
-#include <assimp/Defines.h>
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-
-static const aiImporterDesc desc = {
- "Collada Importer",
- "",
- "",
- "http://collada.org",
- aiImporterFlags_SupportTextFlavour,
- 1,
- 3,
- 1,
- 5,
- "dae"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ColladaLoader::ColladaLoader()
- : mFileName()
- , mMeshIndexByID()
- , mMaterialIndexByName()
- , mMeshes()
- , newMats()
- , mCameras()
- , mLights()
- , mTextures()
- , mAnims()
- , noSkeletonMesh( false )
- , ignoreUpDirection(false)
- , mNodeNameCounter( 0 )
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ColladaLoader::~ColladaLoader()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- std::string extension = GetExtension(pFile);
-
- if( extension == "dae")
- return true;
-
- // XML - too generic, we need to open the file and search for typical keywords
- if( extension == "xml" || !extension.length() || checkSig) {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"<collada"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-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
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- mFileName = pFile;
-
- // clean all member arrays - just for safety, it should work even if we did not
- mMeshIndexByID.clear();
- mMaterialIndexByName.clear();
- mMeshes.clear();
- mTargetMeshes.clear();
- newMats.clear();
- mLights.clear();
- mCameras.clear();
- mTextures.clear();
- mAnims.clear();
-
- // parse the input file
- ColladaParser parser( pIOHandler, pFile);
-
- if( !parser.mRootNode)
- throw DeadlyImportError( "Collada: File came out empty. Something is wrong here.");
-
- // reserve some storage to avoid unnecessary reallocs
- newMats.reserve(parser.mMaterialLibrary.size()*2);
- mMeshes.reserve(parser.mMeshLibrary.size()*2);
-
- mCameras.reserve(parser.mCameraLibrary.size());
- mLights.reserve(parser.mLightLibrary.size());
-
- // create the materials first, for the meshes to find
- BuildMaterials( parser, pScene);
-
- // build the node hierarchy from it
- pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
-
- // ... then fill the materials with the now adjusted settings
- FillMaterials(parser, pScene);
-
- // 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);
-
- // store all materials
- StoreSceneMaterials( pScene);
-
- // store all lights
- StoreSceneLights( pScene);
-
- // store all cameras
- StoreSceneCameras( pScene);
-
- // store all animations
- StoreAnimations( pScene, parser);
-
-
- // If no meshes have been loaded, it's probably just an animated skeleton.
- if (!pScene->mNumMeshes) {
-
- if (!noSkeletonMesh) {
- SkeletonMeshBuilder hero(pScene);
- }
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively constructs a scene node for the given parser node and returns it.
-aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode)
-{
- // create a node for it
- aiNode* node = new aiNode();
-
- // find a name for the new node. It's more complicated than you might think
- node->mName.Set( FindNameForNode( pNode));
-
- // calculate the transformation matrix for it
- node->mTransformation = pParser.CalculateResultTransform( pNode->mTransforms);
-
- // now resolve node instances
- std::vector<const Collada::Node*> instances;
- ResolveNodeInstances(pParser,pNode,instances);
-
- // add children. first the *real* ones
- node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size()+instances.size());
- node->mChildren = new aiNode*[node->mNumChildren];
-
- for( size_t a = 0; a < pNode->mChildren.size(); a++)
- {
- node->mChildren[a] = BuildHierarchy( pParser, pNode->mChildren[a]);
- node->mChildren[a]->mParent = node;
- }
-
- // ... and finally the resolved node instances
- for( size_t a = 0; a < instances.size(); a++)
- {
- node->mChildren[pNode->mChildren.size() + a] = BuildHierarchy( pParser, instances[a]);
- node->mChildren[pNode->mChildren.size() + a]->mParent = node;
- }
-
- // construct meshes
- BuildMeshesForNode( pParser, pNode, node);
-
- // construct cameras
- BuildCamerasForNode(pParser, pNode, node);
-
- // construct lights
- BuildLightsForNode(pParser, pNode, node);
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Resolve node instances
-void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
- std::vector<const Collada::Node*>& resolved)
-{
- // reserve enough storage
- resolved.reserve(pNode->mNodeInstances.size());
-
- // ... and iterate through all nodes to be instanced as children of pNode
- for (const auto &nodeInst: pNode->mNodeInstances)
- {
- // find the corresponding node in the library
- const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
- const Collada::Node* nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second;
-
- // FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
- // need to check for both name and ID to catch all. To avoid breaking valid files,
- // the workaround is only enabled when the first attempt to resolve the node has failed.
- if (!nd) {
- nd = FindNode(pParser.mRootNode, nodeInst.mNode);
- }
- if (!nd)
- DefaultLogger::get()->error("Collada: Unable to resolve reference to instanced node " + nodeInst.mNode);
-
- else {
- // attach this node to the list of children
- resolved.push_back(nd);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Resolve UV channels
-void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
- const Collada::SemanticMappingTable& table)
-{
- std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
- if (it != table.mMap.end()) {
- if (it->second.mType != Collada::IT_Texcoord)
- DefaultLogger::get()->error("Collada: Unexpected effect input mapping");
-
- sampler.mUVId = it->second.mSet;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds lights for the given node and references them
-void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
-{
- for( const Collada::LightInstance& lid : pNode->mLights)
- {
- // find the referred light
- ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight);
- if( srcLightIt == pParser.mLightLibrary.end())
- {
- DefaultLogger::get()->warn("Collada: Unable to find light for ID \"" + lid.mLight + "\". Skipping.");
- continue;
- }
- const Collada::Light* srcLight = &srcLightIt->second;
-
- // now fill our ai data structure
- aiLight* out = new aiLight();
- out->mName = pTarget->mName;
- out->mType = (aiLightSourceType)srcLight->mType;
-
- // collada lights point in -Z by default, rest is specified in node transform
- out->mDirection = aiVector3D(0.f,0.f,-1.f);
-
- out->mAttenuationConstant = srcLight->mAttConstant;
- out->mAttenuationLinear = srcLight->mAttLinear;
- out->mAttenuationQuadratic = srcLight->mAttQuadratic;
-
- out->mColorDiffuse = out->mColorSpecular = out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
- if (out->mType == aiLightSource_AMBIENT) {
- out->mColorDiffuse = out->mColorSpecular = aiColor3D(0, 0, 0);
- out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
- }
- else {
- // collada doesn't differentiate between these color types
- out->mColorDiffuse = out->mColorSpecular = srcLight->mColor*srcLight->mIntensity;
- out->mColorAmbient = aiColor3D(0, 0, 0);
- }
-
- // convert falloff angle and falloff exponent in our representation, if given
- if (out->mType == aiLightSource_SPOT) {
-
- out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle );
-
- // ... some extension magic.
- if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
- {
- // ... 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
- out->mAngleOuterCone = std::acos(std::pow(0.1f,1.f/srcLight->mFalloffExponent))+
- out->mAngleInnerCone;
- }
- else {
- out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD( srcLight->mPenumbraAngle );
- if (out->mAngleOuterCone < out->mAngleInnerCone)
- std::swap(out->mAngleInnerCone,out->mAngleOuterCone);
- }
- }
- else out->mAngleOuterCone = AI_DEG_TO_RAD( srcLight->mOuterAngle );
- }
-
- // add to light list
- mLights.push_back(out);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds cameras for the given node and references them
-void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
-{
- for( const Collada::CameraInstance& cid : pNode->mCameras)
- {
- // find the referred light
- ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera);
- if( srcCameraIt == pParser.mCameraLibrary.end())
- {
- DefaultLogger::get()->warn("Collada: Unable to find camera for ID \"" + cid.mCamera + "\". Skipping.");
- continue;
- }
- const Collada::Camera* srcCamera = &srcCameraIt->second;
-
- // orthographic cameras not yet supported in Assimp
- if (srcCamera->mOrtho) {
- DefaultLogger::get()->warn("Collada: Orthographic cameras are not supported.");
- }
-
- // now fill our ai data structure
- aiCamera* out = new aiCamera();
- out->mName = pTarget->mName;
-
- // collada cameras point in -Z by default, rest is specified in node transform
- out->mLookAt = aiVector3D(0.f,0.f,-1.f);
-
- // near/far z is already ok
- out->mClipPlaneFar = srcCamera->mZFar;
- out->mClipPlaneNear = srcCamera->mZNear;
-
- // ... but for the rest some values are optional
- // and we need to compute the others in any combination.
- if (srcCamera->mAspect != 10e10f)
- out->mAspect = srcCamera->mAspect;
-
- if (srcCamera->mHorFov != 10e10f) {
- out->mHorizontalFOV = srcCamera->mHorFov;
-
- if (srcCamera->mVerFov != 10e10f && srcCamera->mAspect == 10e10f) {
- out->mAspect = std::tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
- std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
- }
- }
- else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
- out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(std::atan(srcCamera->mAspect *
- std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
- }
-
- // Collada uses degrees, we use radians
- out->mHorizontalFOV = AI_DEG_TO_RAD(out->mHorizontalFOV);
-
- // add to camera list
- mCameras.push_back(out);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Builds meshes for the given node and references them
-void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
-{
- // accumulated mesh references by this node
- std::vector<size_t> newMeshRefs;
- newMeshRefs.reserve(pNode->mMeshes.size());
-
- // add a mesh for each subgroup in each collada mesh
- for( const Collada::MeshInstance& mid : pNode->mMeshes)
- {
- const Collada::Mesh* srcMesh = NULL;
- const Collada::Controller* srcController = NULL;
-
- // find the referred mesh
- ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid.mMeshOrController);
- if( srcMeshIt == pParser.mMeshLibrary.end())
- {
- // if not found in the mesh-library, it might also be a controller referring to a mesh
- ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find( mid.mMeshOrController);
- if( srcContrIt != pParser.mControllerLibrary.end())
- {
- srcController = &srcContrIt->second;
- srcMeshIt = pParser.mMeshLibrary.find( srcController->mMeshId);
- if( srcMeshIt != pParser.mMeshLibrary.end())
- srcMesh = srcMeshIt->second;
- }
-
- if( !srcMesh)
- {
- DefaultLogger::get()->warn( format() << "Collada: Unable to find geometry for ID \"" << mid.mMeshOrController << "\". Skipping." );
- continue;
- }
- } else
- {
- // ID found in the mesh library -> direct reference to an unskinned mesh
- srcMesh = srcMeshIt->second;
- }
-
- // build a mesh for each of its subgroups
- size_t vertexStart = 0, faceStart = 0;
- for( size_t sm = 0; sm < srcMesh->mSubMeshes.size(); ++sm)
- {
- const Collada::SubMesh& submesh = srcMesh->mSubMeshes[sm];
- if( submesh.mNumFaces == 0)
- continue;
-
- // find material assigned to this submesh
- std::string meshMaterial;
- std::map<std::string, Collada::SemanticMappingTable >::const_iterator meshMatIt = mid.mMaterials.find( submesh.mMaterial);
-
- const Collada::SemanticMappingTable* table = NULL;
- if( meshMatIt != mid.mMaterials.end())
- {
- table = &meshMatIt->second;
- meshMaterial = table->mMatName;
- }
- else
- {
- DefaultLogger::get()->warn( format() << "Collada: No material specified for subgroup <" << submesh.mMaterial << "> in geometry <" << mid.mMeshOrController << ">." );
- if( !mid.mMaterials.empty() )
- meshMaterial = mid.mMaterials.begin()->second.mMatName;
- }
-
- // OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
- // given. The only mapping stuff which we do actually support is the UV channel.
- std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find( meshMaterial);
- unsigned int matIdx;
- if( matIt != mMaterialIndexByName.end())
- matIdx = static_cast<unsigned int>(matIt->second);
- else
- matIdx = 0;
-
- if (table && !table->mMap.empty() ) {
- std::pair<Collada::Effect*, aiMaterial*>& mat = newMats[matIdx];
-
- // Iterate through all texture channels assigned to the effect and
- // check whether we have mapping information for it.
- ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent,*table);
- ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
- }
-
- // built lookup index of the Mesh-Submesh-Material combination
- ColladaMeshIndex index( mid.mMeshOrController, sm, meshMaterial);
-
- // if we already have the mesh at the library, just add its index to the node's array
- std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find( index);
- if( dstMeshIt != mMeshIndexByID.end()) {
- newMeshRefs.push_back( dstMeshIt->second);
- }
- else
- {
- // else we have to add the mesh to the collection and store its newly assigned index at the node
- aiMesh* dstMesh = CreateMesh( pParser, srcMesh, submesh, srcController, vertexStart, faceStart);
-
- // store the mesh, and store its new index in the node
- newMeshRefs.push_back( mMeshes.size());
- mMeshIndexByID[index] = mMeshes.size();
- mMeshes.push_back( dstMesh);
- vertexStart += dstMesh->mNumVertices; faceStart += submesh.mNumFaces;
-
- // assign the material index
- dstMesh->mMaterialIndex = matIdx;
- if(dstMesh->mName.length == 0)
- {
- dstMesh->mName = mid.mMeshOrController;
- }
- }
- }
- }
-
- // now place all mesh references we gathered in the target node
- pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
- if( newMeshRefs.size())
- {
- struct UIntTypeConverter
- {
- unsigned int operator()(const size_t& v) const
- {
- return static_cast<unsigned int>(v);
- }
- };
-
- pTarget->mMeshes = new unsigned int[pTarget->mNumMeshes];
- std::transform( newMeshRefs.begin(), newMeshRefs.end(), pTarget->mMeshes, UIntTypeConverter());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find mesh from either meshes or morph target meshes
-aiMesh *ColladaLoader::findMesh(std::string meshid)
-{
- for (unsigned int i = 0; i < mMeshes.size(); i++)
- if (std::string(mMeshes[i]->mName.data) == meshid)
- return mMeshes[i];
-
- for (unsigned int i = 0; i < mTargetMeshes.size(); i++)
- if (std::string(mTargetMeshes[i]->mName.data) == meshid)
- return mTargetMeshes[i];
-
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
-aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
- 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,
- pSrcMesh->mFaceSize.begin() + pStartFace + pSubMesh.mNumFaces, size_t(0));
-
- // copy positions
- dstMesh->mNumVertices = static_cast<unsigned int>(numVertices);
- dstMesh->mVertices = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mPositions.begin() + pStartVertex, pSrcMesh->mPositions.begin() +
- pStartVertex + numVertices, dstMesh->mVertices);
-
- // 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)
- {
- dstMesh->mNormals = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
- pStartVertex + numVertices, dstMesh->mNormals);
- }
-
- // tangents, if given.
- if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
- {
- dstMesh->mTangents = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() +
- pStartVertex + numVertices, dstMesh->mTangents);
- }
-
- // bitangents, if given.
- if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
- {
- dstMesh->mBitangents = new aiVector3D[numVertices];
- std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() +
- pStartVertex + numVertices, dstMesh->mBitangents);
- }
-
- // same for texturecoords, as many as we have
- // empty slots are not allowed, need to pack and adjust UV indexes accordingly
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
- {
- if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices)
- {
- dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
- for( size_t b = 0; b < numVertices; ++b)
- dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
-
- dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
- ++real;
- }
- }
-
- // same for vertex colors, as many as we have. again the same packing to avoid empty slots
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
- {
- if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices)
- {
- dstMesh->mColors[real] = new aiColor4D[numVertices];
- std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
- ++real;
- }
- }
-
- // create faces. Due to the fact that each face uses unique vertices, we can simply count up on each vertex
- size_t vertex = 0;
- dstMesh->mNumFaces = static_cast<unsigned int>(pSubMesh.mNumFaces);
- dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
- for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
- {
- size_t s = pSrcMesh->mFaceSize[ pStartFace + a];
- aiFace& face = dstMesh->mFaces[a];
- face.mNumIndices = static_cast<unsigned int>(s);
- face.mIndices = new unsigned int[s];
- for( size_t b = 0; b < s; ++b)
- face.mIndices[b] = static_cast<unsigned int>(vertex++);
- }
-
- // create morph target meshes if any
- std::vector<aiMesh*> targetMeshes;
- std::vector<float> targetWeights;
- Collada::MorphMethod method = Collada::Normalized;
-
- for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
- it != pParser.mControllerLibrary.end(); it++)
- {
- const Collada::Controller &c = it->second;
- const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference( pParser.mMeshLibrary, c.mMeshId);
-
- if (c.mType == Collada::Morph && baseMesh->mName == pSrcMesh->mName)
- {
- const Collada::Accessor& targetAccessor = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, c.mMorphTarget);
- const Collada::Accessor& weightAccessor = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, c.mMorphWeight);
- const Collada::Data& targetData = pParser.ResolveLibraryReference( pParser.mDataLibrary, targetAccessor.mSource);
- const Collada::Data& weightData = pParser.ResolveLibraryReference( pParser.mDataLibrary, weightAccessor.mSource);
-
- // take method
- method = c.mMethod;
-
- if (!targetData.mIsStringArray)
- throw DeadlyImportError( "target data must contain id. ");
- if (weightData.mIsStringArray)
- throw DeadlyImportError( "target weight data must not be textual ");
-
- for (unsigned int i = 0; i < targetData.mStrings.size(); ++i)
- {
- const Collada::Mesh* targetMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, targetData.mStrings.at(i));
-
- aiMesh *aimesh = findMesh(targetMesh->mName);
- if (!aimesh)
- {
- if (targetMesh->mSubMeshes.size() > 1)
- throw DeadlyImportError( "Morhing target mesh must be a single");
- aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), NULL, 0, 0);
- mTargetMeshes.push_back(aimesh);
- }
- targetMeshes.push_back(aimesh);
- }
- for (unsigned int i = 0; i < weightData.mValues.size(); ++i)
- targetWeights.push_back(weightData.mValues.at(i));
- }
- }
- if (targetMeshes.size() > 0 && targetWeights.size() == targetMeshes.size())
- {
- std::vector<aiAnimMesh*> animMeshes;
- for (unsigned int i = 0; i < targetMeshes.size(); i++)
- {
- aiAnimMesh *animMesh = aiCreateAnimMesh(targetMeshes.at(i));
- animMesh->mWeight = targetWeights[i];
- animMeshes.push_back(animMesh);
- }
- dstMesh->mMethod = (method == Collada::Relative)
- ? aiMorphingMethod_MORPH_RELATIVE
- : aiMorphingMethod_MORPH_NORMALIZED;
- dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
- dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
- for (unsigned int i = 0; i < animMeshes.size(); i++)
- dstMesh->mAnimMeshes[i] = animMeshes.at(i);
- }
-
- // create bones if given
- if( pSrcController && pSrcController->mType == Collada::Skin)
- {
- // refuse if the vertex count does not match
-// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
-// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
-
- // resolve references - joint names
- const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
- const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
- // joint offset matrices
- const Collada::Accessor& jointMatrixAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointOffsetMatrixSource);
- const Collada::Data& jointMatrices = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointMatrixAcc.mSource);
- // joint vertex_weight name list - should refer to the same list as the joint names above. If not, report and reconsider
- const Collada::Accessor& weightNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputJoints.mAccessor);
- if( &weightNamesAcc != &jointNamesAcc)
- throw DeadlyImportError( "Temporary implementational laziness. If you read this, please report to the author.");
- // vertex weights
- const Collada::Accessor& weightsAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mWeightInputWeights.mAccessor);
- const Collada::Data& weights = pParser.ResolveLibraryReference( pParser.mDataLibrary, weightsAcc.mSource);
-
- if( !jointNames.mIsStringArray || jointMatrices.mIsStringArray || weights.mIsStringArray)
- 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 addressing scheme. ");
-
- // create containers to collect the weights for each bone
- size_t numBones = jointNames.mStrings.size();
- std::vector<std::vector<aiVertexWeight> > dstBones( numBones);
-
- // build a temporary array of pointers to the start of each vertex's weights
- typedef std::vector< std::pair<size_t, size_t> > IndexPairVector;
- std::vector<IndexPairVector::const_iterator> weightStartPerVertex;
- weightStartPerVertex.resize(pSrcController->mWeightCounts.size(),pSrcController->mWeights.end());
-
- IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
- for( size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a)
- {
- weightStartPerVertex[a] = pit;
- pit += pSrcController->mWeightCounts[a];
- }
-
- // now for each vertex put the corresponding vertex weights into each bone's weight collection
- for( size_t a = pStartVertex; a < pStartVertex + numVertices; ++a)
- {
- // which position index was responsible for this vertex? that's also the index by which
- // the controller assigns the vertex weights
- size_t orgIndex = pSrcMesh->mFacePosIndices[a];
- // find the vertex weights for this vertex
- IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
- size_t pairCount = pSrcController->mWeightCounts[orgIndex];
-
- for( size_t b = 0; b < pairCount; ++b, ++iit)
- {
- size_t jointIndex = iit->first;
- size_t vertexIndex = iit->second;
-
- ai_real weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
-
- // one day I gonna kill that XSI Collada exporter
- if( weight > 0.0f)
- {
- aiVertexWeight w;
- w.mVertexId = static_cast<unsigned int>(a - pStartVertex);
- w.mWeight = weight;
- dstBones[jointIndex].push_back( w);
- }
- }
- }
-
- // count the number of bones which influence vertices of the current submesh
- size_t numRemainingBones = 0;
- for( std::vector<std::vector<aiVertexWeight> >::const_iterator it = dstBones.begin(); it != dstBones.end(); ++it)
- if( it->size() > 0)
- numRemainingBones++;
-
- // create bone array and copy bone weights one by one
- dstMesh->mNumBones = static_cast<unsigned int>(numRemainingBones);
- dstMesh->mBones = new aiBone*[numRemainingBones];
- size_t boneCount = 0;
- for( size_t a = 0; a < numBones; ++a)
- {
- // omit bones without weights
- if( dstBones[a].size() == 0)
- continue;
-
- // create bone with its weights
- aiBone* bone = new aiBone;
- bone->mName = ReadString( jointNamesAcc, jointNames, a);
- bone->mOffsetMatrix.a1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 0);
- bone->mOffsetMatrix.a2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 1);
- bone->mOffsetMatrix.a3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 2);
- bone->mOffsetMatrix.a4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 3);
- bone->mOffsetMatrix.b1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 4);
- bone->mOffsetMatrix.b2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 5);
- bone->mOffsetMatrix.b3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 6);
- bone->mOffsetMatrix.b4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 7);
- bone->mOffsetMatrix.c1 = ReadFloat( jointMatrixAcc, jointMatrices, a, 8);
- bone->mOffsetMatrix.c2 = ReadFloat( jointMatrixAcc, jointMatrices, a, 9);
- bone->mOffsetMatrix.c3 = ReadFloat( jointMatrixAcc, jointMatrices, a, 10);
- bone->mOffsetMatrix.c4 = ReadFloat( jointMatrixAcc, jointMatrices, a, 11);
- bone->mNumWeights = static_cast<unsigned int>(dstBones[a].size());
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- std::copy( dstBones[a].begin(), dstBones[a].end(), bone->mWeights);
-
- // apply bind shape matrix to offset matrix
- aiMatrix4x4 bindShapeMatrix;
- bindShapeMatrix.a1 = pSrcController->mBindShapeMatrix[0];
- bindShapeMatrix.a2 = pSrcController->mBindShapeMatrix[1];
- bindShapeMatrix.a3 = pSrcController->mBindShapeMatrix[2];
- bindShapeMatrix.a4 = pSrcController->mBindShapeMatrix[3];
- bindShapeMatrix.b1 = pSrcController->mBindShapeMatrix[4];
- bindShapeMatrix.b2 = pSrcController->mBindShapeMatrix[5];
- bindShapeMatrix.b3 = pSrcController->mBindShapeMatrix[6];
- bindShapeMatrix.b4 = pSrcController->mBindShapeMatrix[7];
- bindShapeMatrix.c1 = pSrcController->mBindShapeMatrix[8];
- bindShapeMatrix.c2 = pSrcController->mBindShapeMatrix[9];
- bindShapeMatrix.c3 = pSrcController->mBindShapeMatrix[10];
- bindShapeMatrix.c4 = pSrcController->mBindShapeMatrix[11];
- bindShapeMatrix.d1 = pSrcController->mBindShapeMatrix[12];
- bindShapeMatrix.d2 = pSrcController->mBindShapeMatrix[13];
- bindShapeMatrix.d3 = pSrcController->mBindShapeMatrix[14];
- bindShapeMatrix.d4 = pSrcController->mBindShapeMatrix[15];
- bone->mOffsetMatrix *= bindShapeMatrix;
-
- // HACK: (thom) Some exporters address the bone nodes by SID, others address them by ID or even name.
- // Therefore I added a little name replacement here: I search for the bone's node by either name, ID or SID,
- // and replace the bone's name by the node's name so that the user can use the standard
- // find-by-name method to associate nodes with bones.
- const Collada::Node* bnode = FindNode( pParser.mRootNode, bone->mName.data);
- if( !bnode)
- bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data);
-
- // assign the name that we would have assigned for the source node
- if( bnode)
- bone->mName.Set( FindNameForNode( bnode));
- else
- DefaultLogger::get()->warn( format() << "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"" << bone->mName.data << "\"." );
-
- // and insert bone
- dstMesh->mBones[boneCount++] = bone;
- }
- }
-
- return dstMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all meshes in the given scene
-void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
-{
- pScene->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
- if( mMeshes.size() > 0)
- {
- pScene->mMeshes = new aiMesh*[mMeshes.size()];
- std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
- mMeshes.clear();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all cameras in the given scene
-void ColladaLoader::StoreSceneCameras( aiScene* pScene)
-{
- pScene->mNumCameras = static_cast<unsigned int>(mCameras.size());
- if( mCameras.size() > 0)
- {
- pScene->mCameras = new aiCamera*[mCameras.size()];
- std::copy( mCameras.begin(), mCameras.end(), pScene->mCameras);
- mCameras.clear();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all lights in the given scene
-void ColladaLoader::StoreSceneLights( aiScene* pScene)
-{
- pScene->mNumLights = static_cast<unsigned int>(mLights.size());
- if( mLights.size() > 0)
- {
- pScene->mLights = new aiLight*[mLights.size()];
- std::copy( mLights.begin(), mLights.end(), pScene->mLights);
- mLights.clear();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all textures in the given scene
-void ColladaLoader::StoreSceneTextures( aiScene* pScene)
-{
- pScene->mNumTextures = static_cast<unsigned int>(mTextures.size());
- if( mTextures.size() > 0)
- {
- pScene->mTextures = new aiTexture*[mTextures.size()];
- std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures);
- mTextures.clear();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all materials in the given scene
-void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
-{
- pScene->mNumMaterials = static_cast<unsigned int>(newMats.size());
-
- if (newMats.size() > 0) {
- pScene->mMaterials = new aiMaterial*[newMats.size()];
- for (unsigned int i = 0; i < newMats.size();++i)
- pScene->mMaterials[i] = newMats[i].second;
-
- newMats.clear();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Stores all animations
-void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
-{
- // recursivly collect all animations from the collada scene
- StoreAnimations( pScene, pParser, &pParser.mAnims, "");
-
- // catch special case: many animations with the same length, each affecting only a single node.
- // we need to unite all those single-node-anims to a proper combined animation
- for( size_t a = 0; a < mAnims.size(); ++a)
- {
- aiAnimation* templateAnim = mAnims[a];
- if( templateAnim->mNumChannels == 1)
- {
- // search for other single-channel-anims with the same duration
- std::vector<size_t> collectedAnimIndices;
- for( size_t b = a+1; b < mAnims.size(); ++b)
- {
- aiAnimation* other = mAnims[b];
- if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
- collectedAnimIndices.push_back( b);
- }
-
- // if there are other animations which fit the template anim, combine all channels into a single anim
- if( !collectedAnimIndices.empty() )
- {
- aiAnimation* combinedAnim = new aiAnimation();
- combinedAnim->mName = aiString( std::string( "combinedAnim_") + char( '0' + a));
- combinedAnim->mDuration = templateAnim->mDuration;
- combinedAnim->mTicksPerSecond = templateAnim->mTicksPerSecond;
- combinedAnim->mNumChannels = static_cast<unsigned int>(collectedAnimIndices.size() + 1);
- combinedAnim->mChannels = new aiNodeAnim*[combinedAnim->mNumChannels];
- // add the template anim as first channel by moving its aiNodeAnim to the combined animation
- combinedAnim->mChannels[0] = templateAnim->mChannels[0];
- templateAnim->mChannels[0] = NULL;
- delete templateAnim;
- // combined animation replaces template animation in the anim array
- mAnims[a] = combinedAnim;
-
- // move the memory of all other anims to the combined anim and erase them from the source anims
- for( size_t b = 0; b < collectedAnimIndices.size(); ++b)
- {
- aiAnimation* srcAnimation = mAnims[collectedAnimIndices[b]];
- combinedAnim->mChannels[1 + b] = srcAnimation->mChannels[0];
- srcAnimation->mChannels[0] = NULL;
- delete srcAnimation;
- }
-
- // in a second go, delete all the single-channel-anims that we've stripped from their channels
- // back to front to preserve indices - you know, removing an element from a vector moves all elements behind the removed one
- while( !collectedAnimIndices.empty() )
- {
- mAnims.erase( mAnims.begin() + collectedAnimIndices.back());
- collectedAnimIndices.pop_back();
- }
- }
- }
- }
-
- // now store all anims in the scene
- if( !mAnims.empty())
- {
- pScene->mNumAnimations = static_cast<unsigned int>(mAnims.size());
- pScene->mAnimations = new aiAnimation*[mAnims.size()];
- std::copy( mAnims.begin(), mAnims.end(), pScene->mAnimations);
- }
-
- mAnims.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the animations for the given source anim
-void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string &pPrefix)
-{
- std::string animName = pPrefix.empty() ? pSrcAnim->mName : pPrefix + "_" + pSrcAnim->mName;
-
- // create nested animations, if given
- for( std::vector<Collada::Animation*>::const_iterator it = pSrcAnim->mSubAnims.begin(); it != pSrcAnim->mSubAnims.end(); ++it)
- StoreAnimations( pScene, pParser, *it, animName);
-
- // create animation channels, if any
- if( !pSrcAnim->mChannels.empty())
- CreateAnimation( pScene, pParser, pSrcAnim, animName);
-}
-
-struct MorphTimeValues
-{
- float mTime;
- struct key
- {
- float mWeight;
- unsigned int mValue;
- };
- std::vector<key> mKeys;
-};
-
-void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, float weight, unsigned int value)
-{
- MorphTimeValues::key k;
- k.mValue = value;
- k.mWeight = weight;
- if (values.size() == 0 || time < values[0].mTime)
- {
- MorphTimeValues val;
- val.mTime = time;
- val.mKeys.push_back(k);
- values.insert(values.begin(), val);
- return;
- }
- if (time > values.back().mTime)
- {
- MorphTimeValues val;
- val.mTime = time;
- val.mKeys.push_back(k);
- values.insert(values.end(), val);
- return;
- }
- for (unsigned int i = 0; i < values.size(); i++)
- {
- if (std::abs(time - values[i].mTime) < 1e-6f)
- {
- values[i].mKeys.push_back(k);
- return;
- } else if (time > values[i].mTime && time < values[i+1].mTime)
- {
- MorphTimeValues val;
- val.mTime = time;
- val.mKeys.push_back(k);
- values.insert(values.begin() + i, val);
- return;
- }
- }
- // should not get here
-}
-
-float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key, unsigned int value)
-{
- for (unsigned int i = 0; i < values[key].mKeys.size(); i++)
- {
- if (values[key].mKeys[i].mValue == value)
- return values[key].mKeys[i].mWeight;
- }
- // no value at key found, try to interpolate if present at other keys. if not, return zero
- // TODO: interpolation
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the animation for the given source anim
-void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName)
-{
- // collect a list of animatable nodes
- std::vector<const aiNode*> nodes;
- CollectNodes( pScene->mRootNode, nodes);
-
- std::vector<aiNodeAnim*> anims;
- std::vector<aiMeshMorphAnim*> morphAnims;
-
- for( std::vector<const aiNode*>::const_iterator nit = nodes.begin(); nit != nodes.end(); ++nit)
- {
- // find all the collada anim channels which refer to the current node
- std::vector<Collada::ChannelEntry> entries;
- std::string nodeName = (*nit)->mName.data;
-
- // find the collada node corresponding to the aiNode
- const Collada::Node* srcNode = FindNode( pParser.mRootNode, nodeName);
-// ai_assert( srcNode != NULL);
- if( !srcNode)
- continue;
-
- // now check all channels if they affect the current node
- for( std::vector<Collada::AnimationChannel>::const_iterator cit = pSrcAnim->mChannels.begin();
- cit != pSrcAnim->mChannels.end(); ++cit)
- {
- const Collada::AnimationChannel& srcChannel = *cit;
- Collada::ChannelEntry entry;
-
- // we expect the animation target to be of type "nodeName/transformID.subElement". Ignore all others
- // find the slash that separates the node name - there should be only one
- std::string::size_type slashPos = srcChannel.mTarget.find( '/');
- if( slashPos == std::string::npos)
- {
- std::string::size_type targetPos = srcChannel.mTarget.find(srcNode->mID);
- if (targetPos == std::string::npos)
- continue;
-
- // not node transform, but something else. store as unknown animation channel for now
- entry.mChannel = &(*cit);
- entry.mTargetId = srcChannel.mTarget.substr(targetPos + pSrcAnim->mName.length(),
- srcChannel.mTarget.length() - targetPos - pSrcAnim->mName.length());
- if (entry.mTargetId.front() == '-')
- entry.mTargetId = entry.mTargetId.substr(1);
- entries.push_back(entry);
- continue;
- }
- if( srcChannel.mTarget.find( '/', slashPos+1) != std::string::npos)
- continue;
- std::string targetID = srcChannel.mTarget.substr( 0, slashPos);
- if( targetID != srcNode->mID)
- continue;
-
- // find the dot that separates the transformID - there should be only one or zero
- std::string::size_type dotPos = srcChannel.mTarget.find( '.');
- if( dotPos != std::string::npos)
- {
- if( srcChannel.mTarget.find( '.', dotPos+1) != std::string::npos)
- continue;
-
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1, dotPos - slashPos - 1);
-
- std::string subElement = srcChannel.mTarget.substr( dotPos+1);
- if( subElement == "ANGLE")
- entry.mSubElement = 3; // last number in an Axis-Angle-Transform is the angle
- else if( subElement == "X")
- entry.mSubElement = 0;
- else if( subElement == "Y")
- entry.mSubElement = 1;
- else if( subElement == "Z")
- entry.mSubElement = 2;
- else
- DefaultLogger::get()->warn( format() << "Unknown anim subelement <" << subElement << ">. Ignoring" );
- } else
- {
- // no subelement following, transformId is remaining string
- entry.mTransformId = srcChannel.mTarget.substr( slashPos+1);
- }
-
- std::string::size_type bracketPos = srcChannel.mTarget.find('(');
- if (bracketPos != std::string::npos)
- {
- entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1, bracketPos - slashPos - 1);
- std::string subElement = srcChannel.mTarget.substr(bracketPos);
-
- if (subElement == "(0)(0)")
- entry.mSubElement = 0;
- else if (subElement == "(1)(0)")
- entry.mSubElement = 1;
- else if (subElement == "(2)(0)")
- entry.mSubElement = 2;
- else if (subElement == "(3)(0)")
- entry.mSubElement = 3;
- else if (subElement == "(0)(1)")
- entry.mSubElement = 4;
- else if (subElement == "(1)(1)")
- entry.mSubElement = 5;
- else if (subElement == "(2)(1)")
- entry.mSubElement = 6;
- else if (subElement == "(3)(1)")
- entry.mSubElement = 7;
- else if (subElement == "(0)(2)")
- entry.mSubElement = 8;
- else if (subElement == "(1)(2)")
- entry.mSubElement = 9;
- else if (subElement == "(2)(2)")
- entry.mSubElement = 10;
- else if (subElement == "(3)(2)")
- entry.mSubElement = 11;
- else if (subElement == "(0)(3)")
- entry.mSubElement = 12;
- else if (subElement == "(1)(3)")
- entry.mSubElement = 13;
- else if (subElement == "(2)(3)")
- entry.mSubElement = 14;
- else if (subElement == "(3)(3)")
- entry.mSubElement = 15;
-
- }
-
- // determine which transform step is affected by this channel
- entry.mTransformIndex = SIZE_MAX;
- for( size_t a = 0; a < srcNode->mTransforms.size(); ++a)
- if( srcNode->mTransforms[a].mID == entry.mTransformId)
- entry.mTransformIndex = a;
-
- if( entry.mTransformIndex == SIZE_MAX)
- {
- if (entry.mTransformId.find("morph-weights") != std::string::npos)
- {
- entry.mTargetId = entry.mTransformId;
- entry.mTransformId = "";
- } else
- continue;
- }
-
- entry.mChannel = &(*cit);
- entries.push_back( entry);
- }
-
- // if there's no channel affecting the current node, we skip it
- if( entries.empty())
- continue;
-
- // resolve the data pointers for all anim channels. Find the minimum time while we're at it
- ai_real startTime = ai_real( 1e20 ), endTime = ai_real( -1e20 );
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
- e.mTimeAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceTimes);
- e.mTimeData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mTimeAccessor->mSource);
- e.mValueAccessor = &pParser.ResolveLibraryReference( pParser.mAccessorLibrary, e.mChannel->mSourceValues);
- e.mValueData = &pParser.ResolveLibraryReference( pParser.mDataLibrary, e.mValueAccessor->mSource);
-
- // time count and value count must match
- if( e.mTimeAccessor->mCount != e.mValueAccessor->mCount)
- throw DeadlyImportError( format() << "Time count / value count mismatch in animation channel \"" << e.mChannel->mTarget << "\"." );
-
- if( e.mTimeAccessor->mCount > 0 )
- {
- // find bounding times
- startTime = std::min( startTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, 0, 0));
- endTime = std::max( endTime, ReadFloat( *e.mTimeAccessor, *e.mTimeData, e.mTimeAccessor->mCount-1, 0));
- }
- }
-
- std::vector<aiMatrix4x4> resultTrafos;
- if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
- {
- // create a local transformation chain of the node's transforms
- std::vector<Collada::Transform> transforms = srcNode->mTransforms;
-
- // now for every unique point in time, find or interpolate the key values for that time
- // and apply them to the transform chain. Then the node's present transformation can be calculated.
- ai_real time = startTime;
- while( 1)
- {
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
-
- // find the keyframe behind the current point in time
- size_t pos = 0;
- ai_real postTime = 0.0;
- while( 1)
- {
- if( pos >= e.mTimeAccessor->mCount)
- break;
- postTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos, 0);
- if( postTime >= time)
- break;
- ++pos;
- }
-
- pos = std::min( pos, e.mTimeAccessor->mCount-1);
-
- // read values from there
- ai_real temp[16];
- for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- temp[c] = ReadFloat( *e.mValueAccessor, *e.mValueData, pos, c);
-
- // if not exactly at the key time, interpolate with previous value set
- if( postTime > time && pos > 0)
- {
- ai_real preTime = ReadFloat( *e.mTimeAccessor, *e.mTimeData, pos-1, 0);
- ai_real factor = (time - postTime) / (preTime - postTime);
-
- for( size_t c = 0; c < e.mValueAccessor->mSize; ++c)
- {
- ai_real v = ReadFloat( *e.mValueAccessor, *e.mValueData, pos-1, c);
- temp[c] += (v - temp[c]) * factor;
- }
- }
-
- // Apply values to current transformation
- std::copy( temp, temp + e.mValueAccessor->mSize, transforms[e.mTransformIndex].f + e.mSubElement);
- }
-
- // Calculate resulting transformation
- aiMatrix4x4 mat = pParser.CalculateResultTransform( transforms);
-
- // out of laziness: we store the time in matrix.d4
- mat.d4 = time;
- resultTrafos.push_back( mat);
-
- // find next point in time to evaluate. That's the closest frame larger than the current in any channel
- ai_real nextTime = ai_real( 1e20 );
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& channelElement = *it;
-
- // find the next time value larger than the current
- size_t pos = 0;
- while( pos < channelElement.mTimeAccessor->mCount)
- {
- const ai_real t = ReadFloat( *channelElement.mTimeAccessor, *channelElement.mTimeData, pos, 0);
- if( t > time)
- {
- nextTime = std::min( nextTime, t);
- break;
- }
- ++pos;
- }
-
- // https://github.com/assimp/assimp/issues/458
- // Sub-sample axis-angle channels if the delta between two consecutive
- // key-frame angles is >= 180 degrees.
- if (transforms[channelElement.mTransformIndex].mType == Collada::TF_ROTATE && channelElement.mSubElement == 3 && pos > 0 && pos < channelElement.mTimeAccessor->mCount) {
- const ai_real cur_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos, 0);
- const ai_real last_key_angle = ReadFloat(*channelElement.mValueAccessor, *channelElement.mValueData, pos - 1, 0);
- const ai_real cur_key_time = ReadFloat(*channelElement.mTimeAccessor, *channelElement.mTimeData, pos, 0);
- const ai_real last_key_time = ReadFloat(*channelElement.mTimeAccessor, *channelElement.mTimeData, pos - 1, 0);
- const ai_real last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time);
- const ai_real delta = std::abs(cur_key_angle - last_eval_angle);
- if (delta >= 180.0) {
- const int subSampleCount = static_cast<int>(std::floor(delta / 90.0));
- if (cur_key_time != time) {
- const ai_real nextSampleTime = time + (cur_key_time - time) / subSampleCount;
- nextTime = std::min(nextTime, nextSampleTime);
- }
- }
- }
- }
-
- // no more keys on any channel after the current time -> we're done
- if( nextTime > 1e19)
- break;
-
- // else construct next keyframe at this following time point
- time = nextTime;
- }
- }
-
- // there should be some keyframes, but we aren't that fixated on valid input data
-// ai_assert( resultTrafos.size() > 0);
-
- // build an animation channel for the given node out of these trafo keys
- if( !resultTrafos.empty() )
- {
- aiNodeAnim* dstAnim = new aiNodeAnim;
- dstAnim->mNodeName = nodeName;
- dstAnim->mNumPositionKeys = static_cast<unsigned int>(resultTrafos.size());
- dstAnim->mNumRotationKeys = static_cast<unsigned int>(resultTrafos.size());
- dstAnim->mNumScalingKeys = static_cast<unsigned int>(resultTrafos.size());
- dstAnim->mPositionKeys = new aiVectorKey[resultTrafos.size()];
- dstAnim->mRotationKeys = new aiQuatKey[resultTrafos.size()];
- dstAnim->mScalingKeys = new aiVectorKey[resultTrafos.size()];
-
- for( size_t a = 0; a < resultTrafos.size(); ++a)
- {
- aiMatrix4x4 mat = resultTrafos[a];
- double time = double( mat.d4); // remember? time is stored in mat.d4
- mat.d4 = 1.0f;
-
- dstAnim->mPositionKeys[a].mTime = time;
- dstAnim->mRotationKeys[a].mTime = time;
- dstAnim->mScalingKeys[a].mTime = time;
- mat.Decompose( dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
- }
-
- anims.push_back( dstAnim);
- } else
- {
- DefaultLogger::get()->warn( "Collada loader: found empty animation channel, ignored. Please check your exporter.");
- }
-
- if( !entries.empty() && entries.front().mTimeAccessor->mCount > 0 )
- {
- std::vector<Collada::ChannelEntry> morphChannels;
- for( std::vector<Collada::ChannelEntry>::iterator it = entries.begin(); it != entries.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
-
- // skip non-transform types
- if (e.mTargetId.empty())
- continue;
-
- if (e.mTargetId.find("morph-weights") != std::string::npos)
- morphChannels.push_back(e);
- }
- if (morphChannels.size() > 0)
- {
- // either 1) morph weight animation count should contain morph target count channels
- // or 2) one channel with morph target count arrays
- // assume first
-
- aiMeshMorphAnim *morphAnim = new aiMeshMorphAnim;
- morphAnim->mName.Set(nodeName);
-
- std::vector<MorphTimeValues> morphTimeValues;
-
- int morphAnimChannelIndex = 0;
- for( std::vector<Collada::ChannelEntry>::iterator it = morphChannels.begin(); it != morphChannels.end(); ++it)
- {
- Collada::ChannelEntry& e = *it;
- std::string::size_type apos = e.mTargetId.find('(');
- std::string::size_type bpos = e.mTargetId.find(')');
- if (apos == std::string::npos || bpos == std::string::npos)
- // unknown way to specify weight -> ignore this animation
- continue;
-
- // weight target can be in format Weight_M_N, Weight_N, WeightN, or some other way
- // we ignore the name and just assume the channels are in the right order
- for (unsigned int i = 0; i < e.mTimeData->mValues.size(); i++)
- insertMorphTimeValue(morphTimeValues, e.mTimeData->mValues.at(i), e.mValueData->mValues.at(i), morphAnimChannelIndex);
-
- ++morphAnimChannelIndex;
- }
-
- morphAnim->mNumKeys = static_cast<unsigned int>(morphTimeValues.size());
- morphAnim->mKeys = new aiMeshMorphKey[morphAnim->mNumKeys];
- for (unsigned int key = 0; key < morphAnim->mNumKeys; key++)
- {
- morphAnim->mKeys[key].mNumValuesAndWeights = static_cast<unsigned int>(morphChannels.size());
- morphAnim->mKeys[key].mValues = new unsigned int [morphChannels.size()];
- morphAnim->mKeys[key].mWeights = new double [morphChannels.size()];
-
- morphAnim->mKeys[key].mTime = morphTimeValues[key].mTime;
- for (unsigned int valueIndex = 0; valueIndex < morphChannels.size(); valueIndex++)
- {
- morphAnim->mKeys[key].mValues[valueIndex] = valueIndex;
- morphAnim->mKeys[key].mWeights[valueIndex] = getWeightAtKey(morphTimeValues, key, valueIndex);
- }
- }
-
- morphAnims.push_back(morphAnim);
- }
- }
- }
-
- if( !anims.empty() || !morphAnims.empty())
- {
- aiAnimation* anim = new aiAnimation;
- anim->mName.Set( pName);
- anim->mNumChannels = static_cast<unsigned int>(anims.size());
- if (anim->mNumChannels > 0)
- {
- anim->mChannels = new aiNodeAnim*[anims.size()];
- std::copy( anims.begin(), anims.end(), anim->mChannels);
- }
- anim->mNumMorphMeshChannels = static_cast<unsigned int>(morphAnims.size());
- if (anim->mNumMorphMeshChannels > 0)
- {
- anim->mMorphMeshChannels = new aiMeshMorphAnim*[anim->mNumMorphMeshChannels];
- std::copy( morphAnims.begin(), morphAnims.end(), anim->mMorphMeshChannels);
- }
- anim->mDuration = 0.0f;
- for( size_t a = 0; a < anims.size(); ++a)
- {
- anim->mDuration = std::max( anim->mDuration, anims[a]->mPositionKeys[anims[a]->mNumPositionKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mRotationKeys[anims[a]->mNumRotationKeys-1].mTime);
- anim->mDuration = std::max( anim->mDuration, anims[a]->mScalingKeys[anims[a]->mNumScalingKeys-1].mTime);
- }
- for (size_t a = 0; a < morphAnims.size(); ++a)
- {
- anim->mDuration = std::max(anim->mDuration, morphAnims[a]->mKeys[morphAnims[a]->mNumKeys-1].mTime);
- }
- anim->mTicksPerSecond = 1;
- mAnims.push_back( anim);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a texture to a material structure
-void ColladaLoader::AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
- const Collada::Effect& effect,
- const Collada::Sampler& sampler,
- aiTextureType type, unsigned int idx)
-{
- // first of all, basic file name
- const aiString name = FindFilenameForEffectTexture( pParser, effect, sampler.mName );
- mat.AddProperty( &name, _AI_MATKEY_TEXTURE_BASE, type, idx );
-
- // mapping mode
- int map = aiTextureMapMode_Clamp;
- if (sampler.mWrapU)
- map = aiTextureMapMode_Wrap;
- if (sampler.mWrapU && sampler.mMirrorU)
- map = aiTextureMapMode_Mirror;
-
- mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_U_BASE, type, idx);
-
- map = aiTextureMapMode_Clamp;
- if (sampler.mWrapV)
- map = aiTextureMapMode_Wrap;
- if (sampler.mWrapV && sampler.mMirrorV)
- map = aiTextureMapMode_Mirror;
-
- mat.AddProperty( &map, 1, _AI_MATKEY_MAPPINGMODE_V_BASE, type, idx);
-
- // UV transformation
- mat.AddProperty(&sampler.mTransform, 1,
- _AI_MATKEY_UVTRANSFORM_BASE, type, idx);
-
- // Blend mode
- mat.AddProperty((int*)&sampler.mOp , 1,
- _AI_MATKEY_TEXBLEND_BASE, type, idx);
-
- // Blend factor
- mat.AddProperty((ai_real*)&sampler.mWeighting , 1,
- _AI_MATKEY_TEXBLEND_BASE, type, idx);
-
- // UV source index ... if we didn't resolve the mapping, it is actually just
- // a guess but it works in most cases. We search for the frst occurrence of a
- // number in the channel name. We assume it is the zero-based index into the
- // UV channel array of all corresponding meshes. It could also be one-based
- // for some exporters, but we won't care of it unless someone complains about.
- if (sampler.mUVId != UINT_MAX)
- map = sampler.mUVId;
- else {
- map = -1;
- for (std::string::const_iterator it = sampler.mUVChannel.begin();it != sampler.mUVChannel.end(); ++it){
- if (IsNumeric(*it)) {
- map = strtoul10(&(*it));
- break;
- }
- }
- if (-1 == map) {
- DefaultLogger::get()->warn("Collada: unable to determine UV channel for texture");
- map = 0;
- }
- }
- mat.AddProperty(&map,1,_AI_MATKEY_UVWSRC_BASE,type,idx);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Fills materials from the collada material definitions
-void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pScene*/)
-{
- for (auto &elem : newMats)
- {
- aiMaterial& mat = (aiMaterial&)*elem.second;
- Collada::Effect& effect = *elem.first;
-
- // resolve shading mode
- int shadeMode;
- if (effect.mFaceted) /* fixme */
- shadeMode = aiShadingMode_Flat;
- else {
- switch( effect.mShadeType)
- {
- case Collada::Shade_Constant:
- shadeMode = aiShadingMode_NoShading;
- break;
- case Collada::Shade_Lambert:
- shadeMode = aiShadingMode_Gouraud;
- break;
- case Collada::Shade_Blinn:
- shadeMode = aiShadingMode_Blinn;
- break;
- case Collada::Shade_Phong:
- shadeMode = aiShadingMode_Phong;
- break;
-
- default:
- DefaultLogger::get()->warn("Collada: Unrecognized shading mode, using gouraud shading");
- shadeMode = aiShadingMode_Gouraud;
- break;
- }
- }
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // double-sided?
- shadeMode = effect.mDoubleSided;
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_TWOSIDED);
-
- // wireframe?
- shadeMode = effect.mWireframe;
- mat.AddProperty<int>( &shadeMode, 1, AI_MATKEY_ENABLE_WIREFRAME);
-
- // add material colors
- mat.AddProperty( &effect.mAmbient, 1,AI_MATKEY_COLOR_AMBIENT);
- mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR);
- mat.AddProperty( &effect.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
- mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE);
-
- // scalar properties
- mat.AddProperty( &effect.mShininess, 1, AI_MATKEY_SHININESS);
- mat.AddProperty( &effect.mReflectivity, 1, AI_MATKEY_REFLECTIVITY);
- mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
-
- // transparency, a very hard one. seemingly not all files are following the
- // specification here (1.0 transparency => completely opaque)...
- // therefore, we let the opportunity for the user to manually invert
- // the transparency if necessary and we add preliminary support for RGB_ZERO mode
- if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
- // handle RGB transparency completely, cf Collada specs 1.5.0 pages 249 and 304
- if(effect.mRGBTransparency) {
- // use luminance as defined by ISO/CIE color standards (see ITU-R Recommendation BT.709-4)
- effect.mTransparency *= (
- 0.212671f * effect.mTransparent.r +
- 0.715160f * effect.mTransparent.g +
- 0.072169f * effect.mTransparent.b
- );
-
- effect.mTransparent.a = 1.f;
-
- mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
- } else {
- effect.mTransparency *= effect.mTransparent.a;
- }
-
- if(effect.mInvertTransparency) {
- effect.mTransparency = 1.f - effect.mTransparency;
- }
-
- // Is the material finally transparent ?
- if (effect.mHasTransparency || effect.mTransparency < 1.f) {
- mat.AddProperty( &effect.mTransparency, 1, AI_MATKEY_OPACITY );
- }
- }
-
- // add textures, if given
- if( !effect.mTexAmbient.mName.empty())
- /* It is merely a lightmap */
- AddTexture( mat, pParser, effect, effect.mTexAmbient, aiTextureType_LIGHTMAP);
-
- if( !effect.mTexEmissive.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexEmissive, aiTextureType_EMISSIVE);
-
- if( !effect.mTexSpecular.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexSpecular, aiTextureType_SPECULAR);
-
- if( !effect.mTexDiffuse.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexDiffuse, aiTextureType_DIFFUSE);
-
- if( !effect.mTexBump.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexBump, aiTextureType_NORMALS);
-
- if( !effect.mTexTransparent.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexTransparent, aiTextureType_OPACITY);
-
- if( !effect.mTexReflective.mName.empty())
- AddTexture( mat, pParser, effect, effect.mTexReflective, aiTextureType_REFLECTION);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs materials from the collada material definitions
-void ColladaLoader::BuildMaterials( ColladaParser& pParser, aiScene* /*pScene*/)
-{
- newMats.reserve(pParser.mMaterialLibrary.size());
-
- for( ColladaParser::MaterialLibrary::const_iterator matIt = pParser.mMaterialLibrary.begin(); matIt != pParser.mMaterialLibrary.end(); ++matIt)
- {
- const Collada::Material& material = matIt->second;
- // a material is only a reference to an effect
- ColladaParser::EffectLibrary::iterator effIt = pParser.mEffectLibrary.find( material.mEffect);
- if( effIt == pParser.mEffectLibrary.end())
- continue;
- Collada::Effect& effect = effIt->second;
-
- // create material
- aiMaterial* mat = new aiMaterial;
- aiString name( material.mName.empty() ? matIt->first : material.mName );
- mat->AddProperty(&name,AI_MATKEY_NAME);
-
- // store the material
- mMaterialIndexByName[matIt->first] = newMats.size();
- newMats.push_back( std::pair<Collada::Effect*, aiMaterial*>( &effect,mat) );
- }
- // ScenePreprocessor generates a default material automatically if none is there.
- // All further code here in this loader works well without a valid material so
- // we can safely let it to ScenePreprocessor.
-#if 0
- if( newMats.size() == 0)
- {
- aiMaterial* mat = new aiMaterial;
- aiString name( AI_DEFAULT_MATERIAL_NAME );
- mat->AddProperty( &name, AI_MATKEY_NAME);
-
- const int shadeMode = aiShadingMode_Phong;
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- aiColor4D colAmbient( 0.2, 0.2, 0.2, 1.0), colDiffuse( 0.8, 0.8, 0.8, 1.0), colSpecular( 0.5, 0.5, 0.5, 0.5);
- mat->AddProperty( &colAmbient, 1, AI_MATKEY_COLOR_AMBIENT);
- mat->AddProperty( &colDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty( &colSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
- const ai_real specExp = 5.0;
- mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
- }
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// Resolves the texture name for the given effect texture entry
-aiString ColladaLoader::FindFilenameForEffectTexture( const ColladaParser& pParser,
- const Collada::Effect& pEffect, const std::string& pName)
-{
- aiString result;
-
- // recurse through the param references until we end up at an image
- std::string name = pName;
- while( 1)
- {
- // the given string is a param entry. Find it
- Collada::Effect::ParamLibrary::const_iterator it = pEffect.mParams.find( name);
- // if not found, we're at the end of the recursion. The resulting string should be the image ID
- if( it == pEffect.mParams.end())
- break;
-
- // else recurse on
- name = it->second.mReference;
- }
-
- // find the image referred by this name in the image library of the scene
- ColladaParser::ImageLibrary::const_iterator imIt = pParser.mImageLibrary.find( name);
- if( imIt == pParser.mImageLibrary.end())
- {
- //missing texture should not stop the conversion
- //throw DeadlyImportError( format() <<
- // "Collada: Unable to resolve effect texture entry \"" << pName << "\", ended up at ID \"" << name << "\"." );
-
- DefaultLogger::get()->warn("Collada: Unable to resolve effect texture entry \"" + pName + "\", ended up at ID \"" + name + "\".");
-
- //set default texture file name
- result.Set(name + ".jpg");
- ConvertPath(result);
- return result;
- }
-
- // if this is an embedded texture image setup an aiTexture for it
- if (imIt->second.mFileName.empty())
- {
- if (imIt->second.mImageData.empty()) {
- throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
- }
-
- aiTexture* tex = new aiTexture();
-
- // setup format hint
- if (imIt->second.mEmbeddedFormat.length() > 3) {
- DefaultLogger::get()->warn("Collada: texture format hint is too long, truncating to 3 characters");
- }
- strncpy(tex->achFormatHint,imIt->second.mEmbeddedFormat.c_str(),3);
-
- // and copy texture data
- tex->mHeight = 0;
- tex->mWidth = static_cast<unsigned int>(imIt->second.mImageData.size());
- tex->pcData = (aiTexel*)new char[tex->mWidth];
- memcpy(tex->pcData,&imIt->second.mImageData[0],tex->mWidth);
-
- // setup texture reference string
- result.data[0] = '*';
- result.length = 1 + ASSIMP_itoa10(result.data+1,static_cast<unsigned int>(MAXLEN-1),static_cast<int32_t>(mTextures.size()));
-
- // and add this texture to the list
- mTextures.push_back(tex);
- }
- else
- {
- result.Set( imIt->second.mFileName );
- ConvertPath(result);
- }
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a path read from a collada file to the usual representation
-void ColladaLoader::ConvertPath (aiString& ss)
-{
- // TODO: collada spec, p 22. Handle URI correctly.
- // For the moment we're just stripping the file:// away to make it work.
- // Windoes doesn't seem to be able to find stuff like
- // 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
- if (0 == strncmp(ss.data,"file://",7))
- {
- ss.length -= 7;
- memmove(ss.data,ss.data+7,ss.length);
- ss.data[ss.length] = '\0';
- }
-
- // Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
- // I need to filter it without destroying linux paths starting with "/somewhere"
- if( ss.data[0] == '/' && isalpha( ss.data[1]) && ss.data[2] == ':' )
- {
- ss.length--;
- memmove( ss.data, ss.data+1, ss.length);
- ss.data[ss.length] = 0;
- }
-
- // find and convert all %xy special chars
- char* out = ss.data;
- for( const char* it = ss.data; it != ss.data + ss.length; /**/ )
- {
- if( *it == '%' && (it + 3) < ss.data + ss.length )
- {
- // 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
- {
- *out++ = *it++;
- }
- }
-
- // adjust length and terminator of the shortened string
- *out = 0;
- ss.length = (ptrdiff_t) (out - ss.data);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a float value from an accessor and its data array.
-ai_real ColladaLoader::ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
-{
- // FIXME: (thom) Test for data type here in every access? For the moment, I leave this to the caller
- size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset + pOffset;
- ai_assert( pos < pData.mValues.size());
- return pData.mValues[pos];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a string value from an accessor and its data array.
-const std::string& ColladaLoader::ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const
-{
- size_t pos = pAccessor.mStride * pIndex + pAccessor.mOffset;
- ai_assert( pos < pData.mStrings.size());
- return pData.mStrings[pos];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collects all nodes into the given array
-void ColladaLoader::CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const
-{
- poNodes.push_back( pNode);
-
- for( size_t a = 0; a < pNode->mNumChildren; ++a)
- CollectNodes( pNode->mChildren[a], poNodes);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds a node in the collada scene by the given name
-const Collada::Node* ColladaLoader::FindNode( const Collada::Node* pNode, const std::string& pName) const
-{
- if( pNode->mName == pName || pNode->mID == pName)
- return pNode;
-
- for( size_t a = 0; a < pNode->mChildren.size(); ++a)
- {
- const Collada::Node* node = FindNode( pNode->mChildren[a], pName);
- if( node)
- return node;
- }
-
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds a node in the collada scene by the given SID
-const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const
-{
- if( pNode->mSID == pSID)
- return pNode;
-
- for( size_t a = 0; a < pNode->mChildren.size(); ++a)
- {
- const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID);
- if( node)
- return node;
- }
-
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Finds a proper unique name for a node derived from the collada-node's properties.
-// The name must be unique for proper node-bone association.
-std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
-{
- // Now setup the name of the assimp node. The collada name might not be
- // unique, so we use the collada ID.
- if (!pNode->mID.empty())
- return pNode->mID;
- else if (!pNode->mSID.empty())
- return pNode->mSID;
- else
- {
- // No need to worry. Unnamed nodes are no problem at all, except
- // if cameras or lights need to be assigned to them.
- return format() << "$ColladaAutoName$_" << mNodeNameCounter++;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
diff --git a/src/3rdparty/assimp/code/ColladaLoader.h b/src/3rdparty/assimp/code/ColladaLoader.h
deleted file mode 100644
index 8388ab01e..000000000
--- a/src/3rdparty/assimp/code/ColladaLoader.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/** Defines the collada loader class */
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_COLLADALOADER_H_INC
-#define AI_COLLADALOADER_H_INC
-
-#include "BaseImporter.h"
-#include "ColladaParser.h"
-
-struct aiNode;
-struct aiCamera;
-struct aiLight;
-struct aiTexture;
-struct aiAnimation;
-
-namespace Assimp
-{
-
-struct ColladaMeshIndex
-{
- std::string mMeshID;
- size_t mSubMesh;
- std::string mMaterial;
- ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
- : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
- { }
-
- bool operator < (const ColladaMeshIndex& p) const
- {
- if( mMeshID == p.mMeshID)
- {
- if( mSubMesh == p.mSubMesh)
- return mMaterial < p.mMaterial;
- else
- return mSubMesh < p.mSubMesh;
- } else
- {
- return mMeshID < p.mMeshID;
- }
- }
-};
-
-/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
- * more useless stuff, so I limited the data to what I think is useful for games.
-*/
-class ColladaLoader : public BaseImporter
-{
-public:
- ColladaLoader();
- ~ColladaLoader();
-
-
-public:
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-protected:
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- void SetupProperties(const Importer* pImp);
-
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- /** Recursively constructs a scene node for the given parser node and returns it. */
- aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
-
- /** Resolve node instances */
- void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
- std::vector<const Collada::Node*>& resolved);
-
- /** Builds meshes for the given node and references them */
- void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- aiMesh *findMesh(std::string meshid);
-
- /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
- aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
- const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
-
- /** Builds cameras for the given node and references them */
- void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- /** Builds lights for the given node and references them */
- void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
- aiNode* pTarget);
-
- /** Stores all meshes in the given scene */
- void StoreSceneMeshes( aiScene* pScene);
-
- /** Stores all materials in the given scene */
- void StoreSceneMaterials( aiScene* pScene);
-
- /** Stores all lights in the given scene */
- void StoreSceneLights( aiScene* pScene);
-
- /** Stores all cameras in the given scene */
- void StoreSceneCameras( aiScene* pScene);
-
- /** Stores all textures in the given scene */
- void StoreSceneTextures( aiScene* pScene);
-
- /** Stores all animations
- * @param pScene target scene to store the anims
- */
- void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
-
- /** Stores all animations for the given source anim and its nested child animations
- * @param pScene target scene to store the anims
- * @param pSrcAnim the source animation to process
- * @param pPrefix Prefix to the name in case of nested animations
- */
- void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
-
- /** Constructs the animation for the given source anim */
- void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
-
- /** Constructs materials from the collada material definitions */
- void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
-
- /** Fill materials from the collada material definitions */
- void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
-
- /** Resolve UV channel mappings*/
- void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
- const Collada::SemanticMappingTable& table);
-
- /** Add a texture and all of its sampling properties to a material*/
- void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
- const Collada::Effect& effect,
- const Collada::Sampler& sampler,
- aiTextureType type, unsigned int idx = 0);
-
- /** Resolves the texture name for the given effect texture entry */
- aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
- const Collada::Effect& pEffect, const std::string& pName);
-
- /** Converts a path read from a collada file to the usual representation */
- void ConvertPath( aiString& ss);
-
- /** Reads a float value from an accessor and its data array.
- * @param pAccessor The accessor to use for reading
- * @param pData The data array to read from
- * @param pIndex The index of the element to retrieve
- * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
- * @return the specified value
- */
- ai_real ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
-
- /** Reads a string value from an accessor and its data array.
- * @param pAccessor The accessor to use for reading
- * @param pData The data array to read from
- * @param pIndex The index of the element to retrieve
- * @return the specified value
- */
- const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
-
- /** Recursively collects all nodes into the given array */
- void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
-
- /** Finds a node in the collada scene by the given name */
- const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
- /** Finds a node in the collada scene by the given SID */
- const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
-
- /** Finds a proper name for a node derived from the collada-node's properties */
- std::string FindNameForNode( const Collada::Node* pNode);
-
-protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** Which mesh-material compound was stored under which mesh ID */
- std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
-
- /** Which material was stored under which index in the scene */
- std::map<std::string, size_t> mMaterialIndexByName;
-
- /** Accumulated meshes for the target scene */
- std::vector<aiMesh*> mMeshes;
-
- /** Accumulated morph target meshes */
- std::vector<aiMesh*> mTargetMeshes;
-
- /** Temporary material list */
- std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
-
- /** Temporary camera list */
- std::vector<aiCamera*> mCameras;
-
- /** Temporary light list */
- std::vector<aiLight*> mLights;
-
- /** Temporary texture list */
- std::vector<aiTexture*> mTextures;
-
- /** Accumulated animations for the target scene */
- std::vector<aiAnimation*> mAnims;
-
- bool noSkeletonMesh;
- bool ignoreUpDirection;
-
- /** Used by FindNameForNode() to generate unique node names */
- unsigned int mNodeNameCounter;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_COLLADALOADER_H_INC
diff --git a/src/3rdparty/assimp/code/ColladaParser.cpp b/src/3rdparty/assimp/code/ColladaParser.cpp
deleted file mode 100644
index 2fe0f1e0a..000000000
--- a/src/3rdparty/assimp/code/ColladaParser.cpp
+++ /dev/null
@@ -1,3199 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ColladaParser.cpp
- * @brief Implementation of the Collada parser helper
- */
-
-#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-
-#include <sstream>
-#include <stdarg.h>
-#include "ColladaParser.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "StringUtils.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/light.h>
-#include "TinyFormatter.h"
-
-#include <memory>
-
-using namespace Assimp;
-using namespace Assimp::Collada;
-using namespace Assimp::Formatter;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
- : mFileName( pFile )
- , mReader( NULL )
- , mDataLibrary()
- , mAccessorLibrary()
- , mMeshLibrary()
- , mNodeLibrary()
- , mImageLibrary()
- , mEffectLibrary()
- , mMaterialLibrary()
- , mLightLibrary()
- , mCameraLibrary()
- , mControllerLibrary()
- , mRootNode( NULL )
- , mAnims()
- , mUnitSize( 1.0f )
- , mUpDirection( UP_Y )
- , mFormat(FV_1_5_n ) // We assume the newest file format by default
-{
- // validate io-handler instance
- if ( NULL == pIOHandler ) {
- throw DeadlyImportError("IOSystem is NULL." );
- }
-
- // open the file
- std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
- if (file.get() == NULL) {
- throw DeadlyImportError( "Failed to open file " + pFile + "." );
- }
-
- // generate a XML reader for it
- std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
- mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- if (!mReader) {
- ThrowException("Collada: Unable to open file.");
- }
-
- // start reading
- ReadContents();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ColladaParser::~ColladaParser()
-{
- delete mReader;
- for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
- delete it->second;
- for( MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
- delete it->second;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read bool from text contents of current element
-bool ColladaParser::ReadBoolFromTextContent()
-{
- const char* cur = GetTextContent();
- return (!ASSIMP_strincmp(cur,"true",4) || '0' != *cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read float from text contents of current element
-ai_real ColladaParser::ReadFloatFromTextContent()
-{
- const char* cur = GetTextContent();
- return fast_atof(cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the contents of the file
-void ColladaParser::ReadContents()
-{
- while( mReader->read())
- {
- // handle the root element "COLLADA"
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "COLLADA"))
- {
- // check for 'version' attribute
- const int attrib = TestAttribute("version");
- if (attrib != -1) {
- const char* version = mReader->getAttributeValue(attrib);
-
- if (!::strncmp(version,"1.5",3)) {
- mFormat = FV_1_5_n;
- DefaultLogger::get()->debug("Collada schema version is 1.5.n");
- }
- else if (!::strncmp(version,"1.4",3)) {
- mFormat = FV_1_4_n;
- DefaultLogger::get()->debug("Collada schema version is 1.4.n");
- }
- else if (!::strncmp(version,"1.3",3)) {
- mFormat = FV_1_3_n;
- DefaultLogger::get()->debug("Collada schema version is 1.3.n");
- }
- }
-
- ReadStructure();
- } else
- {
- DefaultLogger::get()->debug( format() << "Ignoring global element <" << mReader->getNodeName() << ">." );
- SkipElement();
- }
- } else
- {
- // skip everything else silently
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the structure of the file
-void ColladaParser::ReadStructure()
-{
- while( mReader->read())
- {
- // beginning of elements
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "asset"))
- ReadAssetInfo();
- else if( IsElement( "library_animations"))
- ReadAnimationLibrary();
- else if (IsElement("library_animation_clips"))
- ReadAnimationClipLibrary();
- else if( IsElement( "library_controllers"))
- ReadControllerLibrary();
- else if( IsElement( "library_images"))
- ReadImageLibrary();
- else if( IsElement( "library_materials"))
- ReadMaterialLibrary();
- else if( IsElement( "library_effects"))
- ReadEffectLibrary();
- else if( IsElement( "library_geometries"))
- ReadGeometryLibrary();
- else if( IsElement( "library_visual_scenes"))
- ReadSceneLibrary();
- else if( IsElement( "library_lights"))
- ReadLightLibrary();
- else if( IsElement( "library_cameras"))
- ReadCameraLibrary();
- else if( IsElement( "library_nodes"))
- ReadSceneNode(NULL); /* some hacking to reuse this piece of code */
- else if( IsElement( "scene"))
- ReadScene();
- else
- SkipElement();
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- break;
- }
- }
-
- PostProcessRootAnimations();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads asset information such as coordinate system information and legal blah
-void ColladaParser::ReadAssetInfo()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "unit"))
- {
- // read unit data from the element's attributes
- const int attrIndex = TestAttribute( "meter");
- if (attrIndex == -1) {
- mUnitSize = 1.f;
- }
- else {
- mUnitSize = mReader->getAttributeValueAsFloat( attrIndex);
- }
-
- // consume the trailing stuff
- if( !mReader->isEmptyElement())
- SkipElement();
- }
- else if( IsElement( "up_axis"))
- {
- // read content, strip whitespace, compare
- const char* content = GetTextContent();
- if( strncmp( content, "X_UP", 4) == 0)
- mUpDirection = UP_X;
- else if( strncmp( content, "Z_UP", 4) == 0)
- mUpDirection = UP_Z;
- else
- mUpDirection = UP_Y;
-
- // check element end
- TestClosing( "up_axis");
- } else
- {
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "asset") != 0)
- ThrowException( "Expected end of <asset> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the animation clips
-void ColladaParser::ReadAnimationClipLibrary()
-{
- if (mReader->isEmptyElement())
- return;
-
- while (mReader->read())
- {
- if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if (IsElement("animation_clip"))
- {
- // optional name given as an attribute
- std::string animName;
- int indexName = TestAttribute("name");
- int indexID = TestAttribute("id");
- if (indexName >= 0)
- animName = mReader->getAttributeValue(indexName);
- else if (indexID >= 0)
- animName = mReader->getAttributeValue(indexID);
- else
- animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
-
- std::pair<std::string, std::vector<std::string> > clip;
-
- clip.first = animName;
-
- while (mReader->read())
- {
- if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if (IsElement("instance_animation"))
- {
- int indexUrl = TestAttribute("url");
- if (indexUrl >= 0)
- {
- const char* url = mReader->getAttributeValue(indexUrl);
- if (url[0] != '#')
- ThrowException("Unknown reference format");
-
- url++;
-
- clip.second.push_back(url);
- }
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if (strcmp(mReader->getNodeName(), "animation_clip") != 0)
- ThrowException("Expected end of <animation_clip> element.");
-
- break;
- }
- }
-
- if (clip.second.size() > 0)
- {
- mAnimationClipLibrary.push_back(clip);
- }
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if (strcmp(mReader->getNodeName(), "library_animation_clips") != 0)
- ThrowException("Expected end of <library_animation_clips> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
-void ColladaParser::PostProcessRootAnimations()
-{
- if (mAnimationClipLibrary.size() > 0)
- {
- Animation temp;
-
- for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it)
- {
- std::string clipName = it->first;
-
- Animation *clip = new Animation();
- clip->mName = clipName;
-
- temp.mSubAnims.push_back(clip);
-
- for (std::vector<std::string>::iterator a = it->second.begin(); a != it->second.end(); ++a)
- {
- std::string animationID = *a;
-
- AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
-
- if (animation != mAnimationLibrary.end())
- {
- Animation *pSourceAnimation = animation->second;
-
- pSourceAnimation->CollectChannelsRecursively(clip->mChannels);
- }
- }
- }
-
- mAnims = temp;
-
- // Ensure no double deletes.
- temp.mSubAnims.clear();
- }
- else
- {
- mAnims.CombineSingleChannelAnimations();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the animation library
-void ColladaParser::ReadAnimationLibrary()
-{
- if (mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "animation"))
- {
- // delegate the reading. Depending on the inner elements it will be a container or a anim channel
- ReadAnimation( &mAnims);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "library_animations") != 0)
- ThrowException( "Expected end of <library_animations> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an animation into the given parent structure
-void ColladaParser::ReadAnimation( Collada::Animation* pParent)
-{
- if( mReader->isEmptyElement())
- return;
-
- // an <animation> element may be a container for grouping sub-elements or an animation channel
- // this is the channel collection by ID, in case it has channels
- typedef std::map<std::string, AnimationChannel> ChannelMap;
- ChannelMap channels;
- // this is the anim container in case we're a container
- Animation* anim = NULL;
-
- // optional name given as an attribute
- std::string animName;
- std::string animID;
- int indexName = TestAttribute( "name");
- int indexID = TestAttribute( "id");
-
- if (indexID >= 0)
- animID = mReader->getAttributeValue(indexID);
-
- if( indexName >= 0)
- animName = mReader->getAttributeValue( indexName);
- else if( indexID >= 0)
- animName = animID;
- else
- animName = "animation";
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // we have subanimations
- if( IsElement( "animation"))
- {
- // create container from our element
- if( !anim)
- {
- anim = new Animation;
- anim->mName = animName;
- pParent->mSubAnims.push_back( anim);
- }
-
- // recurse into the subelement
- ReadAnimation( anim);
- }
- else if( IsElement( "source"))
- {
- // possible animation data - we'll never know. Better store it
- ReadSource();
- }
- else if( IsElement( "sampler"))
- {
- // read the ID to assign the corresponding collada channel afterwards.
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
- ChannelMap::iterator newChannel = channels.insert( std::make_pair( id, AnimationChannel())).first;
-
- // have it read into a channel
- ReadAnimationSampler( newChannel->second);
- }
- else if( IsElement( "channel"))
- {
- // the binding element whose whole purpose is to provide the target to animate
- // Thanks, Collada! A directly posted information would have been too simple, I guess.
- // Better add another indirection to that! Can't have enough of those.
- int indexTarget = GetAttribute( "target");
- int indexSource = GetAttribute( "source");
- const char* sourceId = mReader->getAttributeValue( indexSource);
- if( sourceId[0] == '#')
- sourceId++;
- ChannelMap::iterator cit = channels.find( sourceId);
- if( cit != channels.end())
- cit->second.mTarget = mReader->getAttributeValue( indexTarget);
-
- if( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "animation") != 0)
- ThrowException( "Expected end of <animation> element.");
-
- break;
- }
- }
-
- // it turned out to have channels - add them
- if( !channels.empty())
- {
- // FIXME: Is this essentially doing the same as "single-anim-node" codepath in
- // ColladaLoader::StoreAnimations? For now, this has been deferred to after
- // all animations and all clips have been read. Due to handling of
- // <library_animation_clips> this cannot be done here, as the channel owner
- // is lost, and some exporters make up animations by referring to multiple
- // single-channel animations from an <instance_animation>.
-/*
- // special filtering for stupid exporters packing each channel into a separate animation
- if( channels.size() == 1)
- {
- pParent->mChannels.push_back( channels.begin()->second);
- } else
-*/
- {
- // else create the animation, if not done yet, and store the channels
- if( !anim)
- {
- anim = new Animation;
- anim->mName = animName;
- pParent->mSubAnims.push_back( anim);
- }
- for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
- anim->mChannels.push_back( it->second);
-
- if (indexID >= 0)
- {
- mAnimationLibrary[animID] = anim;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an animation sampler into the given anim channel
-void ColladaParser::ReadAnimationSampler( Collada::AnimationChannel& pChannel)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "input"))
- {
- int indexSemantic = GetAttribute( "semantic");
- const char* semantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( indexSource);
- if( source[0] != '#')
- ThrowException( "Unsupported URL format");
- source++;
-
- if( strcmp( semantic, "INPUT") == 0)
- pChannel.mSourceTimes = source;
- else if( strcmp( semantic, "OUTPUT") == 0)
- pChannel.mSourceValues = source;
- else if( strcmp( semantic, "IN_TANGENT") == 0)
- pChannel.mInTanValues = source;
- else if( strcmp( semantic, "OUT_TANGENT") == 0)
- pChannel.mOutTanValues = source;
- else if( strcmp( semantic, "INTERPOLATION") == 0)
- pChannel.mInterpolationValues = source;
-
- if( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "sampler") != 0)
- ThrowException( "Expected end of <sampler> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the skeleton controller library
-void ColladaParser::ReadControllerLibrary()
-{
- if (mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "controller"))
- {
- // read ID. Ask the spec if it's necessary or optional... you might be surprised.
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mControllerLibrary[id] = Controller();
-
- // read on from there
- ReadController( mControllerLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "library_controllers") != 0)
- ThrowException( "Expected end of <library_controllers> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a controller into the given mesh structure
-void ColladaParser::ReadController( Collada::Controller& pController)
-{
- // initial values
- pController.mType = Skin;
- pController.mMethod = Normalized;
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // two types of controllers: "skin" and "morph". Only the first one is relevant, we skip the other
- if( IsElement( "morph"))
- {
- pController.mType = Morph;
- int baseIndex = GetAttribute("source");
- pController.mMeshId = mReader->getAttributeValue(baseIndex) + 1;
- int methodIndex = GetAttribute("method");
- if (methodIndex > 0) {
- const char *method = mReader->getAttributeValue(methodIndex);
- if (strcmp(method, "RELATIVE") == 0)
- pController.mMethod = Relative;
- }
- }
- 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 single idea they've come up with
- int sourceIndex = GetAttribute( "source");
- pController.mMeshId = mReader->getAttributeValue( sourceIndex) + 1;
- }
- else if( IsElement( "bind_shape_matrix"))
- {
- // content is 16 floats to define a matrix... it seems to be important for some models
- const char* content = GetTextContent();
-
- // read the 16 floats
- for( unsigned int a = 0; a < 16; a++)
- {
- // read a number
- content = fast_atoreal_move<ai_real>( content, pController.mBindShapeMatrix[a]);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- TestClosing( "bind_shape_matrix");
- }
- else if( IsElement( "source"))
- {
- // data array - we have specialists to handle this
- ReadSource();
- }
- else if( IsElement( "joints"))
- {
- ReadControllerJoints( pController);
- }
- else if( IsElement( "vertex_weights"))
- {
- ReadControllerWeights( pController);
- }
- else if ( IsElement( "targets" ))
- {
- while (mReader->read()) {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if ( IsElement( "input")) {
- int semanticsIndex = GetAttribute("semantic");
- int sourceIndex = GetAttribute("source");
-
- const char *semantics = mReader->getAttributeValue(semanticsIndex);
- const char *source = mReader->getAttributeValue(sourceIndex);
- if (strcmp(semantics, "MORPH_TARGET") == 0) {
- pController.mMorphTarget = source + 1;
- }
- else if (strcmp(semantics, "MORPH_WEIGHT") == 0)
- {
- pController.mMorphWeight = source + 1;
- }
- }
- } else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "targets") == 0)
- break;
- else
- ThrowException( "Expected end of <targets> element.");
- }
- }
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "controller") == 0)
- break;
- else if( strcmp( mReader->getNodeName(), "skin") != 0 && strcmp( mReader->getNodeName(), "morph") != 0)
- ThrowException( "Expected end of <controller> element.");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the joint definitions for the given controller
-void ColladaParser::ReadControllerJoints( Collada::Controller& pController)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // Input channels for joint data. Two possible semantics: "JOINT" and "INV_BIND_MATRIX"
- if( IsElement( "input"))
- {
- int indexSemantic = GetAttribute( "semantic");
- const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* attrSource = mReader->getAttributeValue( indexSource);
-
- // local URLS always start with a '#'. We don't support global URLs
- if( attrSource[0] != '#')
- ThrowException( format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <joints> data <input> element" );
- attrSource++;
-
- // parse source URL to corresponding source
- if( strcmp( attrSemantic, "JOINT") == 0)
- pController.mJointNameSource = attrSource;
- else if( strcmp( attrSemantic, "INV_BIND_MATRIX") == 0)
- pController.mJointOffsetMatrixSource = attrSource;
- else
- ThrowException( format() << "Unknown semantic \"" << attrSemantic << "\" in <joints> data <input> element" );
-
- // skip inner data, if present
- if( !mReader->isEmptyElement())
- SkipElement();
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "joints") != 0)
- ThrowException( "Expected end of <joints> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the joint weights for the given controller
-void ColladaParser::ReadControllerWeights( Collada::Controller& pController)
-{
- // read vertex count from attributes and resize the array accordingly
- int indexCount = GetAttribute( "count");
- size_t vertexCount = (size_t) mReader->getAttributeValueAsInt( indexCount);
- pController.mWeightCounts.resize( vertexCount);
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT"
- if( IsElement( "input") && vertexCount > 0 )
- {
- InputChannel channel;
-
- int indexSemantic = GetAttribute( "semantic");
- const char* attrSemantic = mReader->getAttributeValue( indexSemantic);
- int indexSource = GetAttribute( "source");
- const char* attrSource = mReader->getAttributeValue( indexSource);
- int indexOffset = TestAttribute( "offset");
- if( indexOffset >= 0)
- channel.mOffset = mReader->getAttributeValueAsInt( indexOffset);
-
- // local URLS always start with a '#'. We don't support global URLs
- if( attrSource[0] != '#')
- ThrowException( format() << "Unsupported URL format in \"" << attrSource << "\" in source attribute of <vertex_weights> data <input> element" );
- channel.mAccessor = attrSource + 1;
-
- // parse source URL to corresponding source
- if( strcmp( attrSemantic, "JOINT") == 0)
- pController.mWeightInputJoints = channel;
- else if( strcmp( attrSemantic, "WEIGHT") == 0)
- pController.mWeightInputWeights = channel;
- else
- ThrowException( format() << "Unknown semantic \"" << attrSemantic << "\" in <vertex_weights> data <input> element" );
-
- // skip inner data, if present
- if( !mReader->isEmptyElement())
- SkipElement();
- }
- else if( IsElement( "vcount") && vertexCount > 0 )
- {
- // read weight count per vertex
- const char* text = GetTextContent();
- size_t numWeights = 0;
- 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>");
-
- *it = strtoul10( text, &text);
- numWeights += *it;
- SkipSpacesAndLineEnd( &text);
- }
-
- TestClosing( "vcount");
-
- // reserve weight count
- pController.mWeights.resize( numWeights);
- }
- else if( IsElement( "v") && vertexCount > 0 )
- {
- // read JointIndex - WeightIndex pairs
- const char* text = GetTextContent();
-
- 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>");
- it->first = strtoul10( text, &text);
- SkipSpacesAndLineEnd( &text);
- if( *text == 0)
- ThrowException( "Out of data while reading <vertex_weights>");
- it->second = strtoul10( text, &text);
- SkipSpacesAndLineEnd( &text);
- }
-
- TestClosing( "v");
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "vertex_weights") != 0)
- ThrowException( "Expected end of <vertex_weights> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the image library contents
-void ColladaParser::ReadImageLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "image"))
- {
- // read ID. Another entry which is "optional" by design but obligatory in reality
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mImageLibrary[id] = Image();
-
- // read on from there
- ReadImage( mImageLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "library_images") != 0)
- ThrowException( "Expected end of <library_images> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an image entry into the given image
-void ColladaParser::ReadImage( Collada::Image& pImage)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT){
- // Need to run different code paths here, depending on the Collada XSD version
- if (IsElement("image")) {
- SkipElement();
- }
- else if( IsElement( "init_from"))
- {
- if (mFormat == FV_1_4_n)
- {
- // FIX: C4D exporter writes empty <init_from/> tags
- if (!mReader->isEmptyElement()) {
- // element content is filename - hopefully
- const char* sz = TestTextContent();
- if (sz)pImage.mFileName = sz;
- TestClosing( "init_from");
- }
- if (!pImage.mFileName.length()) {
- pImage.mFileName = "unknown_texture";
- }
- }
- else if (mFormat == FV_1_5_n)
- {
- // make sure we skip over mip and array initializations, which
- // we don't support, but which could confuse the loader if
- // they're not skipped.
- int attrib = TestAttribute("array_index");
- if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
- DefaultLogger::get()->warn("Collada: Ignoring texture array index");
- continue;
- }
-
- attrib = TestAttribute("mip_index");
- if (attrib != -1 && mReader->getAttributeValueAsInt(attrib) > 0) {
- DefaultLogger::get()->warn("Collada: Ignoring MIP map layer");
- continue;
- }
-
- // TODO: correctly jump over cube and volume maps?
- }
- }
- else if (mFormat == FV_1_5_n)
- {
- if( IsElement( "ref"))
- {
- // element content is filename - hopefully
- const char* sz = TestTextContent();
- if (sz)pImage.mFileName = sz;
- TestClosing( "ref");
- }
- else if( IsElement( "hex") && !pImage.mFileName.length())
- {
- // embedded image. get format
- const int attrib = TestAttribute("format");
- if (-1 == attrib)
- DefaultLogger::get()->warn("Collada: Unknown image file format");
- else pImage.mEmbeddedFormat = mReader->getAttributeValue(attrib);
-
- const char* data = GetTextContent();
-
- // hexadecimal-encoded binary octets. First of all, find the
- // required buffer size to reserve enough storage.
- const char* cur = data;
- while (!IsSpaceOrNewLine(*cur)) cur++;
-
- const unsigned int size = (unsigned int)(cur-data) * 2;
- pImage.mImageData.resize(size);
- for (unsigned int i = 0; i < size;++i)
- pImage.mImageData[i] = HexOctetToDecimal(data+(i<<1));
-
- TestClosing( "hex");
- }
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "image") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the material library
-void ColladaParser::ReadMaterialLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- std::map<std::string, int> names;
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "material"))
- {
- // read ID. By now you probably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- std::string name;
- int attrName = TestAttribute("name");
- if (attrName >= 0)
- name = mReader->getAttributeValue( attrName);
-
- // create an entry and store it in the library under its ID
- mMaterialLibrary[id] = Material();
-
- if( !name.empty())
- {
- std::map<std::string, int>::iterator it = names.find( name);
- if( it != names.end())
- {
- std::ostringstream strStream;
- strStream << ++it->second;
- name.append( " " + strStream.str());
- }
- else
- {
- names[name] = 0;
- }
-
- mMaterialLibrary[id].mName = name;
- }
-
- ReadMaterial( mMaterialLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "library_materials") != 0)
- ThrowException( "Expected end of <library_materials> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the light library
-void ColladaParser::ReadLightLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "light"))
- {
- // read ID. By now you probably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- ReadLight(mLightLibrary[id] = Light());
-
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "library_lights") != 0)
- ThrowException( "Expected end of <library_lights> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the camera library
-void ColladaParser::ReadCameraLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "camera"))
- {
- // read ID. By now you probably know my opinion about this "specification"
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- Camera& cam = mCameraLibrary[id];
- attrID = TestAttribute( "name");
- if (attrID != -1)
- cam.mName = mReader->getAttributeValue( attrID);
-
- ReadCamera(cam);
-
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "library_cameras") != 0)
- ThrowException( "Expected end of <library_cameras> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a material entry into the given material
-void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("material")) {
- SkipElement();
- }
- else if( IsElement( "instance_effect"))
- {
- // referred effect by URL
- int attrUrl = GetAttribute( "url");
- const char* url = mReader->getAttributeValue( attrUrl);
- if( url[0] != '#')
- ThrowException( "Unknown reference format");
-
- pMaterial.mEffect = url+1;
-
- SkipElement();
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "material") != 0)
- ThrowException( "Expected end of <material> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a light entry into the given light
-void ColladaParser::ReadLight( Collada::Light& pLight)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("light")) {
- SkipElement();
- }
- else if (IsElement("spot")) {
- pLight.mType = aiLightSource_SPOT;
- }
- else if (IsElement("ambient")) {
- pLight.mType = aiLightSource_AMBIENT;
- }
- else if (IsElement("directional")) {
- pLight.mType = aiLightSource_DIRECTIONAL;
- }
- else if (IsElement("point")) {
- pLight.mType = aiLightSource_POINT;
- }
- else if (IsElement("color")) {
- // text content contains 3 floats
- const char* content = GetTextContent();
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pLight.mColor.r);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pLight.mColor.g);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pLight.mColor.b);
- SkipSpacesAndLineEnd( &content);
-
- TestClosing( "color");
- }
- else if (IsElement("constant_attenuation")) {
- pLight.mAttConstant = ReadFloatFromTextContent();
- TestClosing("constant_attenuation");
- }
- else if (IsElement("linear_attenuation")) {
- pLight.mAttLinear = ReadFloatFromTextContent();
- TestClosing("linear_attenuation");
- }
- else if (IsElement("quadratic_attenuation")) {
- pLight.mAttQuadratic = ReadFloatFromTextContent();
- TestClosing("quadratic_attenuation");
- }
- else if (IsElement("falloff_angle")) {
- pLight.mFalloffAngle = ReadFloatFromTextContent();
- TestClosing("falloff_angle");
- }
- else if (IsElement("falloff_exponent")) {
- pLight.mFalloffExponent = ReadFloatFromTextContent();
- TestClosing("falloff_exponent");
- }
- // FCOLLADA extensions
- // -------------------------------------------------------
- else if (IsElement("outer_cone")) {
- pLight.mOuterAngle = ReadFloatFromTextContent();
- TestClosing("outer_cone");
- }
- // ... and this one is even deprecated
- else if (IsElement("penumbra_angle")) {
- pLight.mPenumbraAngle = ReadFloatFromTextContent();
- TestClosing("penumbra_angle");
- }
- else if (IsElement("intensity")) {
- pLight.mIntensity = ReadFloatFromTextContent();
- TestClosing("intensity");
- }
- else if (IsElement("falloff")) {
- pLight.mOuterAngle = ReadFloatFromTextContent();
- TestClosing("falloff");
- }
- else if (IsElement("hotspot_beam")) {
- pLight.mFalloffAngle = ReadFloatFromTextContent();
- TestClosing("hotspot_beam");
- }
- // OpenCOLLADA extensions
- // -------------------------------------------------------
- else if (IsElement("decay_falloff")) {
- pLight.mOuterAngle = ReadFloatFromTextContent();
- TestClosing("decay_falloff");
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "light") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a camera entry into the given light
-void ColladaParser::ReadCamera( Collada::Camera& pCamera)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if (IsElement("camera")) {
- SkipElement();
- }
- else if (IsElement("orthographic")) {
- pCamera.mOrtho = true;
- }
- else if (IsElement("xfov") || IsElement("xmag")) {
- pCamera.mHorFov = ReadFloatFromTextContent();
- TestClosing((pCamera.mOrtho ? "xmag" : "xfov"));
- }
- else if (IsElement("yfov") || IsElement("ymag")) {
- pCamera.mVerFov = ReadFloatFromTextContent();
- TestClosing((pCamera.mOrtho ? "ymag" : "yfov"));
- }
- else if (IsElement("aspect_ratio")) {
- pCamera.mAspect = ReadFloatFromTextContent();
- TestClosing("aspect_ratio");
- }
- else if (IsElement("znear")) {
- pCamera.mZNear = ReadFloatFromTextContent();
- TestClosing("znear");
- }
- else if (IsElement("zfar")) {
- pCamera.mZFar = ReadFloatFromTextContent();
- TestClosing("zfar");
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "camera") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the effect library
-void ColladaParser::ReadEffectLibrary()
-{
- if (mReader->isEmptyElement()) {
- return;
- }
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "effect"))
- {
- // read ID. Do I have to repeat my ranting about "optional" attributes?
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mEffectLibrary[id] = Effect();
- // read on from there
- ReadEffect( mEffectLibrary[id]);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "library_effects") != 0)
- ThrowException( "Expected end of <library_effects> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry into the given effect
-void ColladaParser::ReadEffect( Collada::Effect& pEffect)
-{
- // for the moment we don't support any other type of effect.
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "profile_COMMON"))
- ReadEffectProfileCommon( pEffect);
- else
- SkipElement();
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "effect") != 0)
- ThrowException( "Expected end of <effect> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an COMMON effect profile
-void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "newparam")) {
- // save ID
- int attrSID = GetAttribute( "sid");
- std::string sid = mReader->getAttributeValue( attrSID);
- pEffect.mParams[sid] = EffectParam();
- ReadEffectParam( pEffect.mParams[sid]);
- }
- else if( IsElement( "technique") || IsElement( "extra"))
- {
- // just syntactic sugar
- }
-
- else if( mFormat == FV_1_4_n && IsElement( "image"))
- {
- // read ID. Another entry which is "optional" by design but obligatory in reality
- int attrID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( attrID);
-
- // create an entry and store it in the library under its ID
- mImageLibrary[id] = Image();
-
- // read on from there
- ReadImage( mImageLibrary[id]);
- }
-
- /* Shading modes */
- else if( IsElement( "phong"))
- pEffect.mShadeType = Shade_Phong;
- else if( IsElement( "constant"))
- pEffect.mShadeType = Shade_Constant;
- else if( IsElement( "lambert"))
- pEffect.mShadeType = Shade_Lambert;
- else if( IsElement( "blinn"))
- pEffect.mShadeType = Shade_Blinn;
-
- /* Color + texture properties */
- else if( IsElement( "emission"))
- ReadEffectColor( pEffect.mEmissive, pEffect.mTexEmissive);
- else if( IsElement( "ambient"))
- ReadEffectColor( pEffect.mAmbient, pEffect.mTexAmbient);
- else if( IsElement( "diffuse"))
- ReadEffectColor( pEffect.mDiffuse, pEffect.mTexDiffuse);
- else if( IsElement( "specular"))
- ReadEffectColor( pEffect.mSpecular, pEffect.mTexSpecular);
- else if( IsElement( "reflective")) {
- ReadEffectColor( pEffect.mReflective, pEffect.mTexReflective);
- }
- else if( IsElement( "transparent")) {
- pEffect.mHasTransparency = true;
-
- const char* opaque = mReader->getAttributeValueSafe("opaque");
-
- if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) {
- pEffect.mRGBTransparency = true;
- }
-
- // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
- if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "A_ZERO") == 0) {
- pEffect.mInvertTransparency = true;
- }
-
- ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent);
- }
- else if( IsElement( "shininess"))
- ReadEffectFloat( pEffect.mShininess);
- else if( IsElement( "reflectivity"))
- ReadEffectFloat( pEffect.mReflectivity);
-
- /* Single scalar properties */
- else if( IsElement( "transparency"))
- ReadEffectFloat( pEffect.mTransparency);
- else if( IsElement( "index_of_refraction"))
- ReadEffectFloat( pEffect.mRefractIndex);
-
- // GOOGLEEARTH/OKINO extensions
- // -------------------------------------------------------
- else if( IsElement( "double_sided"))
- pEffect.mDoubleSided = ReadBoolFromTextContent();
-
- // FCOLLADA extensions
- // -------------------------------------------------------
- else if( IsElement( "bump")) {
- aiColor4D dummy;
- ReadEffectColor( dummy,pEffect.mTexBump);
- }
-
- // MAX3D extensions
- // -------------------------------------------------------
- else if( IsElement( "wireframe")) {
- pEffect.mWireframe = ReadBoolFromTextContent();
- TestClosing( "wireframe");
- }
- else if( IsElement( "faceted")) {
- pEffect.mFaceted = ReadBoolFromTextContent();
- TestClosing( "faceted");
- }
- else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "profile_COMMON") == 0)
- {
- break;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read texture wrapping + UV transform settings from a profile==Maya chunk
-void ColladaParser::ReadSamplerProperties( Sampler& out )
-{
- if (mReader->isEmptyElement()) {
- return;
- }
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
-
- // MAYA extensions
- // -------------------------------------------------------
- if( IsElement( "wrapU")) {
- out.mWrapU = ReadBoolFromTextContent();
- TestClosing( "wrapU");
- }
- else if( IsElement( "wrapV")) {
- out.mWrapV = ReadBoolFromTextContent();
- TestClosing( "wrapV");
- }
- else if( IsElement( "mirrorU")) {
- out.mMirrorU = ReadBoolFromTextContent();
- TestClosing( "mirrorU");
- }
- else if( IsElement( "mirrorV")) {
- out.mMirrorV = ReadBoolFromTextContent();
- TestClosing( "mirrorV");
- }
- else if( IsElement( "repeatU")) {
- out.mTransform.mScaling.x = ReadFloatFromTextContent();
- TestClosing( "repeatU");
- }
- else if( IsElement( "repeatV")) {
- out.mTransform.mScaling.y = ReadFloatFromTextContent();
- TestClosing( "repeatV");
- }
- else if( IsElement( "offsetU")) {
- out.mTransform.mTranslation.x = ReadFloatFromTextContent();
- TestClosing( "offsetU");
- }
- else if( IsElement( "offsetV")) {
- out.mTransform.mTranslation.y = ReadFloatFromTextContent();
- TestClosing( "offsetV");
- }
- else if( IsElement( "rotateUV")) {
- out.mTransform.mRotation = ReadFloatFromTextContent();
- TestClosing( "rotateUV");
- }
- else if( IsElement( "blend_mode")) {
-
- const char* sz = GetTextContent();
- // http://www.feelingsoftware.com/content/view/55/72/lang,en/
- // NONE, OVER, IN, OUT, ADD, SUBTRACT, MULTIPLY, DIFFERENCE, LIGHTEN, DARKEN, SATURATE, DESATURATE and ILLUMINATE
- if (0 == ASSIMP_strincmp(sz,"ADD",3))
- out.mOp = aiTextureOp_Add;
-
- else if (0 == ASSIMP_strincmp(sz,"SUBTRACT",8))
- out.mOp = aiTextureOp_Subtract;
-
- else if (0 == ASSIMP_strincmp(sz,"MULTIPLY",8))
- out.mOp = aiTextureOp_Multiply;
-
- else {
- DefaultLogger::get()->warn("Collada: Unsupported MAYA texture blend mode");
- }
- TestClosing( "blend_mode");
- }
- // OKINO extensions
- // -------------------------------------------------------
- else if( IsElement( "weighting")) {
- out.mWeighting = ReadFloatFromTextContent();
- TestClosing( "weighting");
- }
- else if( IsElement( "mix_with_previous_layer")) {
- out.mMixWithPrevious = ReadFloatFromTextContent();
- TestClosing( "mix_with_previous_layer");
- }
- // MAX3D extensions
- // -------------------------------------------------------
- else if( IsElement( "amount")) {
- out.mWeighting = ReadFloatFromTextContent();
- TestClosing( "amount");
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "technique") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry containing a color or a texture defining that color
-void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
-{
- if (mReader->isEmptyElement())
- return;
-
- // Save current element name
- const std::string curElem = mReader->getNodeName();
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "color"))
- {
- // text content contains 4 floats
- const char* content = GetTextContent();
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pColor.r);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pColor.g);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pColor.b);
- SkipSpacesAndLineEnd( &content);
-
- content = fast_atoreal_move<ai_real>( content, (ai_real&)pColor.a);
- SkipSpacesAndLineEnd( &content);
- TestClosing( "color");
- }
- else if( IsElement( "texture"))
- {
- // get name of source texture/sampler
- int attrTex = GetAttribute( "texture");
- pSampler.mName = 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();
-
- // as we've read texture, the color needs to be 1,1,1,1
- pColor = aiColor4D(1.f, 1.f, 1.f, 1.f);
- }
- else if( IsElement( "technique"))
- {
- const int _profile = GetAttribute( "profile");
- const char* profile = mReader->getAttributeValue( _profile );
-
- // Some extensions are quite useful ... ReadSamplerProperties processes
- // several extensions in MAYA, OKINO and MAX3D profiles.
- if (!::strcmp(profile,"MAYA") || !::strcmp(profile,"MAX3D") || !::strcmp(profile,"OKINO"))
- {
- // get more information on this sampler
- ReadSamplerProperties(pSampler);
- }
- else SkipElement();
- }
- else if( !IsElement( "extra"))
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- if (mReader->getNodeName() == curElem)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect entry containing a float
-void ColladaParser::ReadEffectFloat( ai_real& pFloat)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT){
- if( IsElement( "float"))
- {
- // text content contains a single floats
- const char* content = GetTextContent();
- content = fast_atoreal_move<ai_real>( content, pFloat);
- SkipSpacesAndLineEnd( &content);
-
- TestClosing( "float");
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an effect parameter specification of any kind
-void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "surface"))
- {
- // image ID given inside <init_from> tags
- TestOpening( "init_from");
- const char* content = GetTextContent();
- pParam.mType = Param_Surface;
- pParam.mReference = content;
- TestClosing( "init_from");
-
- // don't care for remaining stuff
- SkipElement( "surface");
- }
- else if( IsElement( "sampler2D") && (FV_1_4_n == mFormat || FV_1_3_n == mFormat))
- {
- // surface ID is given inside <source> tags
- TestOpening( "source");
- const char* content = GetTextContent();
- pParam.mType = Param_Sampler;
- pParam.mReference = content;
- TestClosing( "source");
-
- // don't care for remaining stuff
- SkipElement( "sampler2D");
- }
- else if( IsElement( "sampler2D"))
- {
- // surface ID is given inside <instance_image> tags
- TestOpening( "instance_image");
- int attrURL = GetAttribute("url");
- const char* url = mReader->getAttributeValue( attrURL);
- if( url[0] != '#')
- ThrowException( "Unsupported URL format in instance_image");
- url++;
- pParam.mType = Param_Sampler;
- pParam.mReference = url;
- SkipElement( "sampler2D");
- } else
- {
- // ignore unknown element
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the geometry library contents
-void ColladaParser::ReadGeometryLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "geometry"))
- {
- // read ID. Another entry which is "optional" by design but obligatory in reality
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
-
- // TODO: (thom) support SIDs
- // ai_assert( TestAttribute( "sid") == -1);
-
- // 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);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "library_geometries") != 0)
- ThrowException( "Expected end of <library_geometries> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a geometry from the geometry library.
-void ColladaParser::ReadGeometry( Collada::Mesh* pMesh)
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "mesh"))
- {
- // read on from there
- ReadMesh( pMesh);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "geometry") != 0)
- ThrowException( "Expected end of <geometry> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a mesh from the geometry library
-void ColladaParser::ReadMesh( Mesh* pMesh)
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "source"))
- {
- // we have professionals dealing with this
- ReadSource();
- }
- else if( IsElement( "vertices"))
- {
- // read per-vertex mesh data
- ReadVertexData( pMesh);
- }
- else if( IsElement( "triangles") || IsElement( "lines") || IsElement( "linestrips")
- || IsElement( "polygons") || IsElement( "polylist") || IsElement( "trifans") || IsElement( "tristrips"))
- {
- // read per-index mesh data and faces setup
- ReadIndexData( pMesh);
- } else
- {
- // ignore the restf
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "technique_common") == 0)
- {
- // end of another meaningless element - read over it
- }
- else if( strcmp( mReader->getNodeName(), "mesh") == 0)
- {
- // end of <mesh> element - we're done here
- break;
- } else
- {
- // everything else should be punished
- ThrowException( "Expected end of <mesh> element.");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a source element
-void ColladaParser::ReadSource()
-{
- int indexID = GetAttribute( "id");
- std::string sourceID = mReader->getAttributeValue( indexID);
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "float_array") || IsElement( "IDREF_array") || IsElement( "Name_array"))
- {
- ReadDataArray();
- }
- else if( IsElement( "technique_common"))
- {
- // I don't care for your profiles
- }
- else if( IsElement( "accessor"))
- {
- ReadAccessor( sourceID);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "source") == 0)
- {
- // end of <source> - we're done
- break;
- }
- else if( strcmp( mReader->getNodeName(), "technique_common") == 0)
- {
- // end of another meaningless element - read over it
- } else
- {
- // everything else should be punished
- ThrowException( "Expected end of <source> element.");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a data array holding a number of floats, and stores it in the global library
-void ColladaParser::ReadDataArray()
-{
- std::string elmName = mReader->getNodeName();
- bool isStringArray = (elmName == "IDREF_array" || elmName == "Name_array");
- bool isEmptyElement = mReader->isEmptyElement();
-
- // read attributes
- int indexID = GetAttribute( "id");
- std::string id = mReader->getAttributeValue( indexID);
- int indexCount = GetAttribute( "count");
- unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount);
- const char* content = TestTextContent();
-
- // read values and store inside an array in the data library
- mDataLibrary[id] = Data();
- Data& data = mDataLibrary[id];
- data.mIsStringArray = isStringArray;
-
- // some exporters write empty data arrays, but we need to conserve them anyways because others might reference them
- if (content)
- {
- if( isStringArray)
- {
- data.mStrings.reserve( count);
- std::string s;
-
- for( unsigned int a = 0; a < count; a++)
- {
- if( *content == 0)
- ThrowException( "Expected more values while reading IDREF_array contents.");
-
- s.clear();
- while( !IsSpaceOrNewLine( *content))
- s += *content++;
- data.mStrings.push_back( s);
-
- SkipSpacesAndLineEnd( &content);
- }
- } else
- {
- data.mValues.reserve( count);
-
- for( unsigned int a = 0; a < count; a++)
- {
- if( *content == 0)
- ThrowException( "Expected more values while reading float_array contents.");
-
- ai_real value;
- // read a number
- content = fast_atoreal_move<ai_real>( content, value);
- data.mValues.push_back( value);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
- }
- }
-
- // test for closing tag
- if( !isEmptyElement )
- TestClosing( elmName.c_str());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads an accessor and stores it in the global library
-void ColladaParser::ReadAccessor( const std::string& pID)
-{
- // read accessor attributes
- int attrSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( attrSource);
- if( source[0] != '#')
- ThrowException( format() << "Unknown reference format in url \"" << source << "\" in source attribute of <accessor> element." );
- int attrCount = GetAttribute( "count");
- unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( attrCount);
- int attrOffset = TestAttribute( "offset");
- unsigned int offset = 0;
- if( attrOffset > -1)
- offset = (unsigned int) mReader->getAttributeValueAsInt( attrOffset);
- int attrStride = TestAttribute( "stride");
- unsigned int stride = 1;
- if( attrStride > -1)
- stride = (unsigned int) mReader->getAttributeValueAsInt( attrStride);
-
- // store in the library under the given ID
- mAccessorLibrary[pID] = Accessor();
- Accessor& acc = mAccessorLibrary[pID];
- acc.mCount = count;
- acc.mOffset = offset;
- acc.mStride = stride;
- acc.mSource = source+1; // ignore the leading '#'
- acc.mSize = 0; // gets incremented with every param
-
- // and read the components
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "param"))
- {
- // read data param
- int attrName = TestAttribute( "name");
- std::string name;
- if( attrName > -1)
- {
- name = mReader->getAttributeValue( attrName);
-
- // analyse for common type components and store it's sub-offset in the corresponding field
-
- /* Cartesian coordinates */
- if( name == "X") acc.mSubOffset[0] = acc.mParams.size();
- else if( name == "Y") acc.mSubOffset[1] = acc.mParams.size();
- else if( name == "Z") acc.mSubOffset[2] = acc.mParams.size();
-
- /* RGBA colors */
- else if( name == "R") acc.mSubOffset[0] = acc.mParams.size();
- else if( name == "G") acc.mSubOffset[1] = acc.mParams.size();
- else if( name == "B") acc.mSubOffset[2] = acc.mParams.size();
- else if( name == "A") acc.mSubOffset[3] = acc.mParams.size();
-
- /* UVWQ (STPQ) texture coordinates */
- else if( name == "S") acc.mSubOffset[0] = acc.mParams.size();
- else if( name == "T") acc.mSubOffset[1] = acc.mParams.size();
- else if( name == "P") acc.mSubOffset[2] = acc.mParams.size();
- // else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size();
- /* 4D uv coordinates are not supported in Assimp */
-
- /* Generic extra data, interpreted as UV data, too*/
- else if( name == "U") acc.mSubOffset[0] = acc.mParams.size();
- else if( name == "V") acc.mSubOffset[1] = acc.mParams.size();
- //else
- // DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." );
- }
-
- // read data type
- int attrType = TestAttribute( "type");
- if( attrType > -1)
- {
- // for the moment we only distinguish between a 4x4 matrix and anything else.
- // TODO: (thom) I don't have a spec here at work. Check if there are other multi-value types
- // which should be tested for here.
- std::string type = mReader->getAttributeValue( attrType);
- if( type == "float4x4")
- acc.mSize += 16;
- else
- acc.mSize += 1;
- }
-
- acc.mParams.push_back( name);
-
- // skip remaining stuff of this element, if any
- SkipElement();
- } else
- {
- ThrowException( format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <accessor>" );
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "accessor") != 0)
- ThrowException( "Expected end of <accessor> element.");
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads input declarations of per-vertex mesh data into the given mesh
-void ColladaParser::ReadVertexData( Mesh* pMesh)
-{
- // extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
- int attrID= GetAttribute( "id");
- pMesh->mVertexID = mReader->getAttributeValue( attrID);
-
- // a number of <input> elements
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "input"))
- {
- ReadInputChannel( pMesh->mPerVertexData);
- } else
- {
- ThrowException( format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <vertices>" );
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "vertices") != 0)
- ThrowException( "Expected end of <vertices> element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads input declarations of per-index mesh data into the given mesh
-void ColladaParser::ReadIndexData( Mesh* pMesh)
-{
- std::vector<size_t> vcount;
- std::vector<InputChannel> perIndexData;
-
- // read primitive count from the attribute
- int attrCount = GetAttribute( "count");
- size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
- // some mesh types (e.g. tristrips) don't specify primitive count upfront,
- // so we need to sum up the actual number of primitives while we read the <p>-tags
- size_t actualPrimitives = 0;
-
- // material subgroup
- int attrMaterial = TestAttribute( "material");
- SubMesh subgroup;
- if( attrMaterial > -1)
- subgroup.mMaterial = mReader->getAttributeValue( attrMaterial);
-
- // distinguish between polys and triangles
- std::string elementName = mReader->getNodeName();
- PrimitiveType primType = Prim_Invalid;
- if( IsElement( "lines"))
- primType = Prim_Lines;
- else if( IsElement( "linestrips"))
- primType = Prim_LineStrip;
- else if( IsElement( "polygons"))
- primType = Prim_Polygon;
- else if( IsElement( "polylist"))
- primType = Prim_Polylist;
- else if( IsElement( "triangles"))
- primType = Prim_Triangles;
- else if( IsElement( "trifans"))
- primType = Prim_TriFans;
- else if( IsElement( "tristrips"))
- primType = Prim_TriStrips;
-
- ai_assert( primType != Prim_Invalid);
-
- // also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "input"))
- {
- ReadInputChannel( perIndexData);
- }
- else if( IsElement( "vcount"))
- {
- if( !mReader->isEmptyElement())
- {
- if (numPrimitives) // It is possible to define a mesh without any primitives
- {
- // case <polylist> - specifies the number of indices for each polygon
- const char* content = GetTextContent();
- vcount.reserve( numPrimitives);
- for( unsigned int a = 0; a < numPrimitives; a++)
- {
- if( *content == 0)
- ThrowException( "Expected more values while reading <vcount> contents.");
- // read a number
- vcount.push_back( (size_t) strtoul10( content, &content));
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
- }
-
- TestClosing( "vcount");
- }
- }
- else if( IsElement( "p"))
- {
- if( !mReader->isEmptyElement())
- {
- // now here the actual fun starts - these are the indices to construct the mesh data from
- actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
- }
- }
- else if (IsElement("extra"))
- {
- SkipElement("extra");
- } else if ( IsElement("ph")) {
- SkipElement("ph");
- } else {
- ThrowException( format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">" );
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( mReader->getNodeName() != elementName)
- ThrowException( format() << "Expected end of <" << elementName << "> element." );
-
- break;
- }
- }
-
-#ifdef ASSIMP_BUILD_DEBUG
- if (primType != Prim_TriFans && primType != Prim_TriStrips && primType != Prim_LineStrip &&
- primType != Prim_Lines) { // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'.
- ai_assert(actualPrimitives == numPrimitives);
- }
-#endif
-
- // only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
- subgroup.mNumFaces = actualPrimitives;
- pMesh->mSubMeshes.push_back(subgroup);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a single input channel element and stores it in the given array, if valid
-void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
-{
- InputChannel channel;
-
- // read semantic
- int attrSemantic = GetAttribute( "semantic");
- std::string semantic = mReader->getAttributeValue( attrSemantic);
- channel.mType = GetTypeForSemantic( semantic);
-
- // read source
- int attrSource = GetAttribute( "source");
- const char* source = mReader->getAttributeValue( attrSource);
- if( source[0] != '#')
- ThrowException( format() << "Unknown reference format in url \"" << source << "\" in source attribute of <input> element." );
- channel.mAccessor = source+1; // skipping the leading #, hopefully the remaining text is the accessor ID only
-
- // read index offset, if per-index <input>
- int attrOffset = TestAttribute( "offset");
- if( attrOffset > -1)
- channel.mOffset = mReader->getAttributeValueAsInt( attrOffset);
-
- // read set if texture coordinates
- if(channel.mType == IT_Texcoord || channel.mType == IT_Color){
- int attrSet = TestAttribute("set");
- if(attrSet > -1){
- attrSet = mReader->getAttributeValueAsInt( attrSet);
- if(attrSet < 0)
- ThrowException( format() << "Invalid index \"" << (attrSet) << "\" in set attribute of <input> element" );
-
- channel.mIndex = attrSet;
- }
- }
-
- // store, if valid type
- if( channel.mType != IT_Invalid)
- poChannels.push_back( channel);
-
- // skip remaining stuff of this element, if any
- SkipElement();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a <p> primitive index list and assembles the mesh data into the given mesh
-size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
- size_t pNumPrimitives, const std::vector<size_t>& pVCount, PrimitiveType pPrimType)
-{
- // determine number of indices coming per vertex
- // find the offset index for all per-vertex channels
- size_t numOffsets = 1;
- size_t perVertexOffset = SIZE_MAX; // invalid value
- for( const InputChannel& channel : pPerIndexChannels)
- {
- numOffsets = std::max( numOffsets, channel.mOffset+1);
- if( channel.mType == IT_Vertex)
- perVertexOffset = channel.mOffset;
- }
-
- // determine the expected number of indices
- size_t expectedPointCount = 0;
- switch( pPrimType)
- {
- case Prim_Polylist:
- {
- for( size_t i : pVCount)
- expectedPointCount += i;
- break;
- }
- case Prim_Lines:
- expectedPointCount = 2 * pNumPrimitives;
- break;
- case Prim_Triangles:
- expectedPointCount = 3 * pNumPrimitives;
- break;
- default:
- // other primitive types don't state the index count upfront... we need to guess
- break;
- }
-
- // and read all indices into a temporary array
- std::vector<size_t> indices;
- if( expectedPointCount > 0)
- indices.reserve( expectedPointCount * numOffsets);
-
- if (pNumPrimitives > 0) // It is possible to not contain any indices
- {
- const char* content = GetTextContent();
- while( *content != 0)
- {
- // read a value.
- // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
- int value = std::max( 0, strtol10( content, &content));
- indices.push_back( size_t( value));
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
- }
-
- // complain if the index count doesn't fit
- if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) {
- if (pPrimType == Prim_Lines) {
- // HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines'
- ReportWarning( "Expected different index count in <p> element, %d instead of %d.", indices.size(), expectedPointCount * numOffsets);
- pNumPrimitives = (indices.size() / numOffsets) / 2;
- } else
- ThrowException( "Expected different index count in <p> element.");
-
- } else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
- ThrowException( "Expected different index count in <p> element.");
-
- // find the data for all sources
- for( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
- {
- InputChannel& input = *it;
- if( input.mResolved)
- continue;
-
- // find accessor
- input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
- // resolve accessor's data pointer as well, if necessary
- const Accessor* acc = input.mResolved;
- if( !acc->mData)
- acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
- }
- // and the same for the per-index channels
- for( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
- {
- InputChannel& input = *it;
- if( input.mResolved)
- continue;
-
- // ignore vertex pointer, it doesn't refer to an accessor
- if( input.mType == IT_Vertex)
- {
- // 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.");
- continue;
- }
-
- // find accessor
- input.mResolved = &ResolveLibraryReference( mAccessorLibrary, input.mAccessor);
- // resolve accessor's data pointer as well, if necessary
- const Accessor* acc = input.mResolved;
- if( !acc->mData)
- acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
- }
-
- // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
- size_t numPrimitives = pNumPrimitives;
- if( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
- numPrimitives = 1;
- // For continued primitives, the given count is actually the number of <p>'s inside the parent tag
- if ( pPrimType == Prim_TriStrips){
- size_t numberOfVertices = indices.size() / numOffsets;
- numPrimitives = numberOfVertices - 2;
- }
- if (pPrimType == Prim_LineStrip) {
- size_t numberOfVertices = indices.size() / numOffsets;
- numPrimitives = numberOfVertices - 1;
- }
-
- pMesh->mFaceSize.reserve( numPrimitives);
- pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
-
- size_t polylistStartVertex = 0;
- for (size_t currentPrimitive = 0; currentPrimitive < numPrimitives; currentPrimitive++)
- {
- // determine number of points for this primitive
- size_t numPoints = 0;
- switch( pPrimType)
- {
- case Prim_Lines:
- numPoints = 2;
- for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
- CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- break;
- case Prim_LineStrip:
- numPoints = 2;
- for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
- CopyVertex(currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- break;
- case Prim_Triangles:
- numPoints = 3;
- for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
- CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- break;
- case Prim_TriStrips:
- numPoints = 3;
- ReadPrimTriStrips(numOffsets, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- break;
- case Prim_Polylist:
- numPoints = pVCount[currentPrimitive];
- for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
- CopyVertex(polylistStartVertex + currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, 0, indices);
- polylistStartVertex += numPoints;
- break;
- case Prim_TriFans:
- case Prim_Polygon:
- numPoints = indices.size() / numOffsets;
- for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
- CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- break;
- default:
- // LineStrip is not supported due to expected index unmangling
- ThrowException( "Unsupported primitive type.");
- break;
- }
-
- // store the face size to later reconstruct the face from
- pMesh->mFaceSize.push_back( numPoints);
- }
-
- // if I ever get my hands on that guy who invented this steaming pile of indirection...
- TestClosing( "p");
- return numPrimitives;
-}
-
-///@note This function willn't work correctly if both PerIndex and PerVertex channels have same channels.
-///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
-///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
-void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices){
- // calculate the base offset of the vertex whose attributes we ant to copy
- size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
-
- // don't overrun the boundaries of the index list
- ai_assert((baseOffset + numOffsets - 1) < indices.size());
-
- // extract per-vertex channels using the global per-vertex offset
- for (std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
- ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
- // and extract per-index channels using there specified offset
- for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
- ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
-
- // store the vertex-data index for later assignment of bone vertex weights
- pMesh->mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
-}
-
-void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices){
- if (currentPrimitive % 2 != 0){
- //odd tristrip triangles need their indices mangled, to preserve winding direction
- CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- }
- else {//for non tristrips or even tristrip triangles
- CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extracts a single object from an input channel and stores it in the appropriate mesh data array
-void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, size_t pLocalIndex, Mesh* pMesh)
-{
- // ignore vertex referrer - we handle them that separate
- if( pInput.mType == IT_Vertex)
- return;
-
- const Accessor& acc = *pInput.mResolved;
- if( pLocalIndex >= acc.mCount)
- ThrowException( format() << "Invalid data index (" << pLocalIndex << "/" << acc.mCount << ") in primitive specification" );
-
- // get a pointer to the start of the data object referred to by the accessor and the local index
- const ai_real* 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
- ai_real obj[4];
- for( size_t c = 0; c < 4; ++c)
- obj[c] = dataObject[acc.mSubOffset[c]];
-
- // now we reinterpret it according to the type we're reading here
- switch( pInput.mType)
- {
- case IT_Position: // ignore all position streams except 0 - there can be only one position
- if( pInput.mIndex == 0)
- pMesh->mPositions.push_back( aiVector3D( obj[0], obj[1], obj[2]));
- else
- 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));
-
- // 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));
-
- // 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));
-
- // 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
- 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));
-
- 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
- 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));
-
- aiColor4D result(0, 0, 0, 1);
- for (size_t i = 0; i < pInput.mResolved->mSize; ++i)
- {
- result[static_cast<unsigned int>(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");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the library of node hierarchies and scene parts
-void ColladaParser::ReadSceneLibrary()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- // a visual scene - generate root node under its ID and let ReadNode() do the recursive work
- if( IsElement( "visual_scene"))
- {
- // read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
- int indexID = GetAttribute( "id");
- const char* attrID = mReader->getAttributeValue( indexID);
-
- // read name if given.
- int indexName = TestAttribute( "name");
- const char* attrName = "unnamed";
- if( indexName > -1)
- attrName = mReader->getAttributeValue( indexName);
-
- // create a node and store it in the library under its ID
- Node* node = new Node;
- node->mID = attrID;
- node->mName = attrName;
- mNodeLibrary[node->mID] = node;
-
- ReadSceneNode( node);
- } else
- {
- // ignore the rest
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "library_visual_scenes") == 0)
- //ThrowException( "Expected end of \"library_visual_scenes\" element.");
-
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a scene node's contents including children and stores it in the given node
-void ColladaParser::ReadSceneNode( Node* pNode)
-{
- // quit immediately on <bla/> elements
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "node"))
- {
- Node* child = new Node;
- int attrID = TestAttribute( "id");
- if( attrID > -1)
- child->mID = mReader->getAttributeValue( attrID);
- int attrSID = TestAttribute( "sid");
- if( attrSID > -1)
- child->mSID = mReader->getAttributeValue( attrSID);
-
- int attrName = TestAttribute( "name");
- if( attrName > -1)
- child->mName = mReader->getAttributeValue( attrName);
-
- // TODO: (thom) support SIDs
- // ai_assert( TestAttribute( "sid") == -1);
-
- if (pNode)
- {
- pNode->mChildren.push_back( child);
- child->mParent = pNode;
- }
- else
- {
- // no parent node given, probably called from <library_nodes> element.
- // create new node in node library
- mNodeLibrary[child->mID] = child;
- }
-
- // read on recursively from there
- ReadSceneNode( child);
- continue;
- }
- // For any further stuff we need a valid node to work on
- else if (!pNode)
- continue;
-
- if( IsElement( "lookat"))
- ReadNodeTransformation( pNode, TF_LOOKAT);
- else if( IsElement( "matrix"))
- ReadNodeTransformation( pNode, TF_MATRIX);
- else if( IsElement( "rotate"))
- ReadNodeTransformation( pNode, TF_ROTATE);
- else if( IsElement( "scale"))
- ReadNodeTransformation( pNode, TF_SCALE);
- else if( IsElement( "skew"))
- ReadNodeTransformation( pNode, TF_SKEW);
- else if( IsElement( "translate"))
- ReadNodeTransformation( pNode, TF_TRANSLATE);
- else if( IsElement( "render") && pNode->mParent == NULL && 0 == pNode->mPrimaryCamera.length())
- {
- // ... scene evaluation or, in other words, postprocessing pipeline,
- // or, again in other words, a turing-complete description how to
- // render a Collada scene. The only thing that is interesting for
- // us is the primary camera.
- int attrId = TestAttribute("camera_node");
- if (-1 != attrId)
- {
- const char* s = mReader->getAttributeValue(attrId);
- if (s[0] != '#')
- DefaultLogger::get()->error("Collada: Unresolved reference format of camera");
- else
- pNode->mPrimaryCamera = s+1;
- }
- }
- else if( IsElement( "instance_node"))
- {
- // find the node in the library
- int attrID = TestAttribute( "url");
- if( attrID != -1)
- {
- const char* s = mReader->getAttributeValue(attrID);
- if (s[0] != '#')
- DefaultLogger::get()->error("Collada: Unresolved reference format of node");
- else
- {
- pNode->mNodeInstances.push_back(NodeInstance());
- pNode->mNodeInstances.back().mNode = s+1;
- }
- }
- }
- else if( IsElement( "instance_geometry") || IsElement( "instance_controller"))
- {
- // Reference to a mesh or controller, with possible material associations
- ReadNodeGeometry( pNode);
- }
- else if( IsElement( "instance_light"))
- {
- // Reference to a light, name given in 'url' attribute
- int attrID = TestAttribute("url");
- if (-1 == attrID)
- DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_light> element");
- else
- {
- const char* url = mReader->getAttributeValue( attrID);
- if( url[0] != '#')
- ThrowException( "Unknown reference format in <instance_light> element");
-
- pNode->mLights.push_back(LightInstance());
- pNode->mLights.back().mLight = url+1;
- }
- }
- else if( IsElement( "instance_camera"))
- {
- // Reference to a camera, name given in 'url' attribute
- int attrID = TestAttribute("url");
- if (-1 == attrID)
- DefaultLogger::get()->warn("Collada: Expected url attribute in <instance_camera> element");
- else
- {
- const char* url = mReader->getAttributeValue( attrID);
- if( url[0] != '#')
- ThrowException( "Unknown reference format in <instance_camera> element");
-
- pNode->mCameras.push_back(CameraInstance());
- pNode->mCameras.back().mCamera = url+1;
- }
- }
- else
- {
- // skip everything else for the moment
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
-void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType)
-{
- if( mReader->isEmptyElement())
- return;
-
- std::string tagName = mReader->getNodeName();
-
- Transform tf;
- tf.mType = pType;
-
- // read SID
- int indexSID = TestAttribute( "sid");
- if( indexSID >= 0)
- tf.mID = mReader->getAttributeValue( indexSID);
-
- // how many parameters to read per transformation type
- static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
- const char* content = GetTextContent();
-
- // read as many parameters and store in the transformation
- for( unsigned int a = 0; a < sNumParameters[pType]; a++)
- {
- // read a number
- content = fast_atoreal_move<ai_real>( content, tf.f[a]);
- // skip whitespace after it
- SkipSpacesAndLineEnd( &content);
- }
-
- // place the transformation at the queue of the node
- pNode->mTransforms.push_back( tf);
-
- // and consume the closing tag
- TestClosing( tagName.c_str());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Processes bind_vertex_input and bind elements
-void ColladaParser::ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl)
-{
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "bind_vertex_input"))
- {
- Collada::InputSemanticMapEntry vn;
-
- // effect semantic
- int n = GetAttribute("semantic");
- std::string s = mReader->getAttributeValue(n);
-
- // input semantic
- n = GetAttribute("input_semantic");
- vn.mType = GetTypeForSemantic( mReader->getAttributeValue(n) );
-
- // index of input set
- n = TestAttribute("input_set");
- if (-1 != n)
- vn.mSet = mReader->getAttributeValueAsInt(n);
-
- tbl.mMap[s] = vn;
- }
- else if( IsElement( "bind")) {
- DefaultLogger::get()->warn("Collada: Found unsupported <bind> element");
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
- if( strcmp( mReader->getNodeName(), "instance_material") == 0)
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads a mesh reference in a node and adds it to the node's mesh list
-void ColladaParser::ReadNodeGeometry( Node* pNode)
-{
- // referred mesh is given as an attribute of the <instance_geometry> element
- int attrUrl = GetAttribute( "url");
- const char* url = mReader->getAttributeValue( attrUrl);
- if( url[0] != '#')
- ThrowException( "Unknown reference format");
-
- Collada::MeshInstance instance;
- instance.mMeshOrController = url+1; // skipping the leading #
-
- if( !mReader->isEmptyElement())
- {
- // read material associations. Ignore additional elements in between
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if( IsElement( "instance_material"))
- {
- // read ID of the geometry subgroup and the target material
- int attrGroup = GetAttribute( "symbol");
- std::string group = mReader->getAttributeValue( attrGroup);
- int attrMaterial = GetAttribute( "target");
- const char* urlMat = mReader->getAttributeValue( attrMaterial);
- Collada::SemanticMappingTable s;
- if( urlMat[0] == '#')
- urlMat++;
-
- s.mMatName = urlMat;
-
- // resolve further material details + THIS UGLY AND NASTY semantic mapping stuff
- if( !mReader->isEmptyElement())
- ReadMaterialVertexInputBinding(s);
-
- // store the association
- instance.mMaterials[group] = s;
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if( strcmp( mReader->getNodeName(), "instance_geometry") == 0
- || strcmp( mReader->getNodeName(), "instance_controller") == 0)
- break;
- }
- }
- }
-
- // store it
- pNode->mMeshes.push_back( instance);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the collada scene
-void ColladaParser::ReadScene()
-{
- if( mReader->isEmptyElement())
- return;
-
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
- if( IsElement( "instance_visual_scene"))
- {
- // should be the first and only occurrence
- if( mRootNode)
- 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 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) + "\" in <instance_visual_scene> element.");
- mRootNode = sit->second;
- } else {
- SkipElement();
- }
- }
- else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END){
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Aborts the file reading with an exception
-AI_WONT_RETURN void ColladaParser::ThrowException( const std::string& pError) const
-{
- throw DeadlyImportError( format() << "Collada: " << mFileName << " - " << pError );
-}
-void ColladaParser::ReportWarning(const char* msg,...)
-{
- ai_assert(NULL != msg);
-
- va_list args;
- va_start(args,msg);
-
- char szBuffer[3000];
- const int iLen = vsprintf(szBuffer,msg,args);
- ai_assert(iLen > 0);
-
- va_end(args);
- DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Skips all data until the end node of the current element
-void ColladaParser::SkipElement()
-{
- // nothing to skip if it's an <element />
- if( mReader->isEmptyElement())
- return;
-
- // reroute
- SkipElement( mReader->getNodeName());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skips all data until the end node of the given element
-void ColladaParser::SkipElement( const char* pElement)
-{
- // copy the current node's name because it'a pointer to the reader's internal buffer,
- // which is going to change with the upcoming parsing
- std::string element = pElement;
- while( mReader->read())
- {
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- if( mReader->getNodeName() == element)
- break;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for an opening element of the given name, throws an exception if not found
-void ColladaParser::TestOpening( const char* pName)
-{
- // read element start
- if( !mReader->read())
- ThrowException( format() << "Unexpected end of file while beginning of <" << pName << "> element." );
- // whitespace in front is ok, just read again if found
- if( mReader->getNodeType() == irr::io::EXN_TEXT)
- if( !mReader->read())
- ThrowException( format() << "Unexpected end of file while reading beginning of <" << pName << "> element." );
-
- if( mReader->getNodeType() != irr::io::EXN_ELEMENT || strcmp( mReader->getNodeName(), pName) != 0)
- ThrowException( format() << "Expected start of <" << pName << "> element." );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for the closing tag of the given element, throws an exception if not found
-void ColladaParser::TestClosing( const char* pName)
-{
- // check if we're already on the closing tag and return right away
- if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END && strcmp( mReader->getNodeName(), pName) == 0)
- return;
-
- // if not, read some more
- if( !mReader->read())
- ThrowException( format() << "Unexpected end of file while reading end of <" << pName << "> element." );
- // whitespace in front is ok, just read again if found
- if( mReader->getNodeType() == irr::io::EXN_TEXT)
- if( !mReader->read())
- ThrowException( format() << "Unexpected end of file while reading end of <" << pName << "> element." );
-
- // 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( format() << "Expected end of <" << pName << "> element." );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
-int ColladaParser::GetAttribute( const char* pAttr) const
-{
- int index = TestAttribute( pAttr);
- if( index != -1)
- return index;
-
- // attribute not found -> throw an exception
- ThrowException( format() << "Expected attribute \"" << pAttr << "\" for element <" << mReader->getNodeName() << ">." );
- return -1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found
-int ColladaParser::TestAttribute( const char* pAttr) const
-{
- for( int a = 0; a < mReader->getAttributeCount(); a++)
- if( strcmp( mReader->getAttributeName( a), pAttr) == 0)
- return a;
-
- return -1;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace.
-const char* ColladaParser::GetTextContent()
-{
- const char* sz = TestTextContent();
- if(!sz) {
- ThrowException( "Invalid contents in element \"n\".");
- }
- return sz;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the text contents of an element, returns NULL if not given. Skips leading whitespace.
-const char* ColladaParser::TestTextContent()
-{
- // present node should be the beginning of an element
- if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
- return NULL;
-
- // read contents of the element
- if( !mReader->read() )
- return NULL;
- if( mReader->getNodeType() != irr::io::EXN_TEXT)
- return NULL;
-
- // skip leading whitespace
- const char* text = mReader->getNodeData();
- SkipSpacesAndLineEnd( &text);
-
- return text;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Calculates the resulting transformation fromm all the given transform steps
-aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform>& pTransforms) const
-{
- aiMatrix4x4 res;
-
- for( std::vector<Transform>::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it)
- {
- const Transform& tf = *it;
- switch( tf.mType)
- {
- case TF_LOOKAT:
- {
- aiVector3D pos( tf.f[0], tf.f[1], tf.f[2]);
- aiVector3D dstPos( tf.f[3], tf.f[4], tf.f[5]);
- aiVector3D up = aiVector3D( tf.f[6], tf.f[7], tf.f[8]).Normalize();
- aiVector3D dir = aiVector3D( dstPos - pos).Normalize();
- aiVector3D right = (dir ^ up).Normalize();
-
- res *= aiMatrix4x4(
- right.x, up.x, -dir.x, pos.x,
- right.y, up.y, -dir.y, pos.y,
- right.z, up.z, -dir.z, pos.z,
- 0, 0, 0, 1);
- break;
- }
- case TF_ROTATE:
- {
- aiMatrix4x4 rot;
- ai_real angle = tf.f[3] * ai_real( AI_MATH_PI) / ai_real( 180.0 );
- aiVector3D axis( tf.f[0], tf.f[1], tf.f[2]);
- aiMatrix4x4::Rotation( angle, axis, rot);
- res *= rot;
- break;
- }
- case TF_TRANSLATE:
- {
- aiMatrix4x4 trans;
- aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans);
- res *= trans;
- break;
- }
- case TF_SCALE:
- {
- aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- res *= scale;
- break;
- }
- case TF_SKEW:
- // TODO: (thom)
- ai_assert( false);
- break;
- case TF_MATRIX:
- {
- aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7],
- tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]);
- res *= mat;
- break;
- }
- default:
- ai_assert( false);
- break;
- }
- }
-
- return res;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Determines the input data type for the given semantic string
-Collada::InputType ColladaParser::GetTypeForSemantic( const std::string& semantic)
-{
- if ( semantic.empty() ) {
- DefaultLogger::get()->warn( format() << "Vertex input type is empty." );
- return IT_Invalid;
- }
-
- if( semantic == "POSITION")
- return IT_Position;
- else if( semantic == "TEXCOORD")
- return IT_Texcoord;
- else if( semantic == "NORMAL")
- return IT_Normal;
- else if( semantic == "COLOR")
- return IT_Color;
- else if( semantic == "VERTEX")
- return IT_Vertex;
- else if( semantic == "BINORMAL" || semantic == "TEXBINORMAL")
- return IT_Bitangent;
- else if( semantic == "TANGENT" || semantic == "TEXTANGENT")
- return IT_Tangent;
-
- DefaultLogger::get()->warn( format() << "Unknown vertex input type \"" << semantic << "\". Ignoring." );
- return IT_Invalid;
-}
-
-#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
diff --git a/src/3rdparty/assimp/code/ColladaParser.h b/src/3rdparty/assimp/code/ColladaParser.h
deleted file mode 100644
index 941ab8414..000000000
--- a/src/3rdparty/assimp/code/ColladaParser.h
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- Open Asset Import Library (assimp)
- ----------------------------------------------------------------------
-
- Copyright (c) 2006-2017, 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 ColladaParser.h
- * @brief Defines the parser helper class for the collada loader
- */
-
-#ifndef AI_COLLADAPARSER_H_INC
-#define AI_COLLADAPARSER_H_INC
-
-#include "irrXMLWrapper.h"
-#include "ColladaHelper.h"
-#include <assimp/ai_assert.h>
-#include "TinyFormatter.h"
-
-namespace Assimp
-{
-
- // ------------------------------------------------------------------------------------------
- /** Parser helper class for the Collada loader.
- *
- * Does all the XML reading and builds internal data structures from it,
- * but leaves the resolving of all the references to the loader.
- */
- class ColladaParser
- {
- friend class ColladaLoader;
-
- protected:
- /** Constructor from XML file */
- ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
-
- /** Destructor */
- ~ColladaParser();
-
- /** Reads the contents of the file */
- void ReadContents();
-
- /** Reads the structure of the file */
- void ReadStructure();
-
- /** Reads asset information such as coordinate system information and legal blah */
- void ReadAssetInfo();
-
- /** Reads the animation library */
- void ReadAnimationLibrary();
-
- /** Reads the animation clip library */
- void ReadAnimationClipLibrary();
-
- /** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
- void PostProcessRootAnimations();
-
- /** Reads an animation into the given parent structure */
- void ReadAnimation( Collada::Animation* pParent);
-
- /** Reads an animation sampler into the given anim channel */
- void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
-
- /** Reads the skeleton controller library */
- void ReadControllerLibrary();
-
- /** Reads a controller into the given mesh structure */
- void ReadController( Collada::Controller& pController);
-
- /** Reads the joint definitions for the given controller */
- void ReadControllerJoints( Collada::Controller& pController);
-
- /** Reads the joint weights for the given controller */
- void ReadControllerWeights( Collada::Controller& pController);
-
- /** Reads the image library contents */
- void ReadImageLibrary();
-
- /** Reads an image entry into the given image */
- void ReadImage( Collada::Image& pImage);
-
- /** Reads the material library */
- void ReadMaterialLibrary();
-
- /** Reads a material entry into the given material */
- void ReadMaterial( Collada::Material& pMaterial);
-
- /** Reads the camera library */
- void ReadCameraLibrary();
-
- /** Reads a camera entry into the given camera */
- void ReadCamera( Collada::Camera& pCamera);
-
- /** Reads the light library */
- void ReadLightLibrary();
-
- /** Reads a light entry into the given light */
- void ReadLight( Collada::Light& pLight);
-
- /** Reads the effect library */
- void ReadEffectLibrary();
-
- /** Reads an effect entry into the given effect*/
- void ReadEffect( Collada::Effect& pEffect);
-
- /** Reads an COMMON effect profile */
- void ReadEffectProfileCommon( Collada::Effect& pEffect);
-
- /** Read sampler properties */
- void ReadSamplerProperties( Collada::Sampler& pSampler);
-
- /** Reads an effect entry containing a color or a texture defining that color */
- void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
-
- /** Reads an effect entry containing a float */
- void ReadEffectFloat( ai_real& pFloat);
-
- /** Reads an effect parameter specification of any kind */
- void ReadEffectParam( Collada::EffectParam& pParam);
-
- /** Reads the geometry library contents */
- void ReadGeometryLibrary();
-
- /** Reads a geometry from the geometry library. */
- void ReadGeometry( Collada::Mesh* pMesh);
-
- /** Reads a mesh from the geometry library */
- void ReadMesh( Collada::Mesh* pMesh);
-
- /** Reads a source element - a combination of raw data and an accessor defining
- * things that should not be redefinable. Yes, that's another rant.
- */
- void ReadSource();
-
- /** Reads a data array holding a number of elements, and stores it in the global library.
- * Currently supported are array of floats and arrays of strings.
- */
- void ReadDataArray();
-
- /** Reads an accessor and stores it in the global library under the given ID -
- * accessors use the ID of the parent <source> element
- */
- void ReadAccessor( const std::string& pID);
-
- /** Reads input declarations of per-vertex mesh data into the given mesh */
- void ReadVertexData( Collada::Mesh* pMesh);
-
- /** Reads input declarations of per-index mesh data into the given mesh */
- void ReadIndexData( Collada::Mesh* pMesh);
-
- /** Reads a single input channel element and stores it in the given array, if valid */
- void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
-
- /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
- size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
- size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
-
- /** Copies the data for a single primitive into the mesh, based on the InputChannels */
- void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
- Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
- size_t currentPrimitive, const std::vector<size_t>& indices);
-
- /** Reads one triangle of a tristrip into the mesh */
- void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
- std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
-
- /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
- void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
-
- /** Reads the library of node hierarchies and scene parts */
- void ReadSceneLibrary();
-
- /** Reads a scene node's contents including children and stores it in the given node */
- void ReadSceneNode( Collada::Node* pNode);
-
- /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
- void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
-
- /** Reads a mesh reference in a node and adds it to the node's mesh list */
- void ReadNodeGeometry( Collada::Node* pNode);
-
- /** Reads the collada scene */
- void ReadScene();
-
- // Processes bind_vertex_input and bind elements
- void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
-
- protected:
- /** Aborts the file reading with an exception */
- AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
- void ReportWarning(const char* msg,...);
-
- /** Skips all data until the end node of the current element */
- void SkipElement();
-
- /** Skips all data until the end node of the given element */
- void SkipElement( const char* pElement);
-
- /** Compares the current xml element name to the given string and returns true if equal */
- bool IsElement( const char* pName) const;
-
- /** Tests for the opening tag of the given element, throws an exception if not found */
- void TestOpening( const char* pName);
-
- /** Tests for the closing tag of the given element, throws an exception if not found */
- void TestClosing( const char* pName);
-
- /** Checks the present element for the presence of the attribute, returns its index
- or throws an exception if not found */
- int GetAttribute( const char* pAttr) const;
-
- /** Returns the index of the named attribute or -1 if not found. Does not throw,
- therefore useful for optional attributes */
- int TestAttribute( const char* pAttr) const;
-
- /** Reads the text contents of an element, throws an exception if not given.
- Skips leading whitespace. */
- const char* GetTextContent();
-
- /** Reads the text contents of an element, returns NULL if not given.
- Skips leading whitespace. */
- const char* TestTextContent();
-
- /** Reads a single bool from current text content */
- bool ReadBoolFromTextContent();
-
- /** Reads a single float from current text content */
- ai_real ReadFloatFromTextContent();
-
- /** Calculates the resulting transformation from all the given transform steps */
- aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
-
- /** Determines the input data type for the given semantic string */
- Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
-
- /** Finds the item in the given library by its reference, throws if not found */
- template <typename Type> const Type& ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
-
- protected:
- /** Filename, for a verbose error message */
- std::string mFileName;
-
- /** XML reader, member for everyday use */
- irr::io::IrrXMLReader* mReader;
-
- /** All data arrays found in the file by ID. Might be referred to by actually
- everyone. Collada, you are a steaming pile of indirection. */
- typedef std::map<std::string, Collada::Data> DataLibrary;
- DataLibrary mDataLibrary;
-
- /** Same for accessors which define how the data in a data array is accessed. */
- typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
- AccessorLibrary mAccessorLibrary;
-
- /** Mesh library: mesh by ID */
- typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
- MeshLibrary mMeshLibrary;
-
- /** node library: root node of the hierarchy part by ID */
- typedef std::map<std::string, Collada::Node*> NodeLibrary;
- NodeLibrary mNodeLibrary;
-
- /** Image library: stores texture properties by ID */
- typedef std::map<std::string, Collada::Image> ImageLibrary;
- ImageLibrary mImageLibrary;
-
- /** Effect library: surface attributes by ID */
- typedef std::map<std::string, Collada::Effect> EffectLibrary;
- EffectLibrary mEffectLibrary;
-
- /** Material library: surface material by ID */
- typedef std::map<std::string, Collada::Material> MaterialLibrary;
- MaterialLibrary mMaterialLibrary;
-
- /** Light library: surface light by ID */
- typedef std::map<std::string, Collada::Light> LightLibrary;
- LightLibrary mLightLibrary;
-
- /** Camera library: surface material by ID */
- typedef std::map<std::string, Collada::Camera> CameraLibrary;
- CameraLibrary mCameraLibrary;
-
- /** Controller library: joint controllers by ID */
- typedef std::map<std::string, Collada::Controller> ControllerLibrary;
- ControllerLibrary mControllerLibrary;
-
- /** Animation library: animation references by ID */
- typedef std::map<std::string, Collada::Animation*> AnimationLibrary;
- AnimationLibrary mAnimationLibrary;
-
- /** Animation clip library: clip animation references by ID */
- typedef std::vector<std::pair<std::string, std::vector<std::string> > > AnimationClipLibrary;
- AnimationClipLibrary mAnimationClipLibrary;
-
- /** Pointer to the root node. Don't delete, it just points to one of
- the nodes in the node library. */
- Collada::Node* mRootNode;
-
- /** Root animation container */
- Collada::Animation mAnims;
-
- /** Size unit: how large compared to a meter */
- ai_real mUnitSize;
-
- /** Which is the up vector */
- enum { UP_X, UP_Y, UP_Z } mUpDirection;
-
- /** Collada file format version */
- Collada::FormatVersion mFormat;
- };
-
- // ------------------------------------------------------------------------------------------------
- // Check for element match
- inline bool ColladaParser::IsElement( const char* pName) const
- {
- ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
- return ::strcmp( mReader->getNodeName(), pName) == 0;
- }
-
- // ------------------------------------------------------------------------------------------------
- // Finds the item in the given library by its reference, throws if not found
- template <typename Type>
- const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
- {
- typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
- if( it == pLibrary.end())
- ThrowException( Formatter::format() << "Unable to resolve library reference \"" << pURL << "\"." );
- return it->second;
- }
-
-} // end of namespace Assimp
-
-#endif // AI_COLLADAPARSER_H_INC
diff --git a/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp b/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp
deleted file mode 100644
index c49666de8..000000000
--- a/src/3rdparty/assimp/code/ComputeUVMappingProcess.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 GenUVCoords step */
-
-
-#include "ComputeUVMappingProcess.h"
-#include "ProcessHelper.h"
-#include "Exceptional.h"
-
-using namespace Assimp;
-
-namespace {
-
- const static aiVector3D base_axis_y(0.0,1.0,0.0);
- const static aiVector3D base_axis_x(1.0,0.0,0.0);
- const static aiVector3D base_axis_z(0.0,0.0,1.0);
- const static ai_real angle_epsilon = ai_real( 0.95 );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ComputeUVMappingProcess::ComputeUVMappingProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ComputeUVMappingProcess::~ComputeUVMappingProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenUVCoords) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a ray intersects a plane and find the intersection point
-inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
- const aiVector3D& planeNormal, aiVector3D& pos)
-{
- const ai_real b = planeNormal * (planePos - ray.pos);
- ai_real h = ray.dir * planeNormal;
- if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0)
- return false;
-
- pos = ray.pos + (ray.dir * h);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find the first empty UV channel in a mesh
-inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
-{
- for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m)
- if (!mesh->mTextureCoords[m])return m;
-
- DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found");
- return UINT_MAX;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to remove UV seams
-void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
-{
- // TODO: just a very rough algorithm. I think it could be done
- // much easier, but I don't know how and am currently too tired to
- // to think about a better solution.
-
- const static ai_real LOWER_LIMIT = ai_real( 0.1 );
- const static ai_real UPPER_LIMIT = ai_real( 0.9 );
-
- const static ai_real LOWER_EPSILON = ai_real( 10e-3 );
- const static ai_real UPPER_EPSILON = ai_real( 1.0-10e-3 );
-
- for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
- {
- const aiFace& face = mesh->mFaces[fidx];
- if (face.mNumIndices < 3) continue; // triangles and polygons only, please
-
- unsigned int small = face.mNumIndices, large = small;
- bool zero = false, one = false, round_to_zero = false;
-
- // Check whether this face lies on a UV seam. We can just guess,
- // but the assumption that a face with at least one very small
- // on the one side and one very large U coord on the other side
- // lies on a UV seam should work for most cases.
- for (unsigned int n = 0; n < face.mNumIndices;++n)
- {
- if (out[face.mIndices[n]].x < LOWER_LIMIT)
- {
- small = n;
-
- // If we have a U value very close to 0 we can't
- // round the others to 0, too.
- if (out[face.mIndices[n]].x <= LOWER_EPSILON)
- zero = true;
- else round_to_zero = true;
- }
- if (out[face.mIndices[n]].x > UPPER_LIMIT)
- {
- large = n;
-
- // If we have a U value very close to 1 we can't
- // round the others to 1, too.
- if (out[face.mIndices[n]].x >= UPPER_EPSILON)
- one = true;
- }
- }
- if (small != face.mNumIndices && large != face.mNumIndices)
- {
- for (unsigned int n = 0; n < face.mNumIndices;++n)
- {
- // If the u value is over the upper limit and no other u
- // value of that face is 0, round it to 0
- if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
- out[face.mIndices[n]].x = 0.0;
-
- // If the u value is below the lower limit and no other u
- // value of that face is 1, round it to 1
- else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one)
- out[face.mIndices[n]].x = 1.0;
-
- // The face contains both 0 and 1 as UV coords. This can occur
- // for faces which have an edge that lies directly on the seam.
- // Due to numerical inaccuracies one U coord becomes 0, the
- // other 1. But we do still have a third UV coord to determine
- // to which side we must round to.
- else if (one && zero)
- {
- if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
- out[face.mIndices[n]].x = 0.0;
- else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
- out[face.mIndices[n]].x = 1.0;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- aiVector3D center, min, max;
- FindMeshCenter(mesh, center, min, max);
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
-
- // For each point get a normalized projection vector in the sphere,
- // get its longitude and latitude and map them to their respective
- // UV axes. Problems occur around the poles ... unsolvable.
- //
- // The spherical coordinate system looks like this:
- // x = cos(lon)*cos(lat)
- // y = sin(lon)*cos(lat)
- // z = sin(lat)
- //
- // Thus we can derive:
- // lat = arcsin (z)
- // lon = arctan (y/x)
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (std::asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- // ... just the same again
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (std::asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- // ... just the same again
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize();
- out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (std::asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize();
- out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F,
- (std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
- }
- }
-
-
- // Now find and remove UV seams. A seam occurs if a face has a tcoord
- // close to zero on the one side, and a tcoord close to one on the
- // other side.
- RemoveUVSeams(mesh,out);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- aiVector3D center, min, max;
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const ai_real diff = max.x - min.x;
-
- // If the main axis is 'z', the z coordinate of a point 'p' is mapped
- // directly to the texture V axis. The other axis is derived from
- // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where
- // 'c' is the center point of the mesh.
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.x - min.x) / diff;
- uv.x = (std::atan2( pos.z - center.z, pos.y - center.y) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const ai_real diff = max.y - min.y;
-
- // just the same ...
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.y - min.y) / diff;
- uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- const ai_real diff = max.z - min.z;
-
- // just the same ...
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.z - min.z) / diff;
- uv.x = (std::atan2( pos.y - center.y, pos.x - center.x) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
- FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
- const ai_real diff = max.y - min.y;
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){
- const aiVector3D pos = mTrafo* mesh->mVertices[pnt];
- aiVector3D& uv = out[pnt];
-
- uv.y = (pos.y - min.y) / diff;
- uv.x = (std::atan2( pos.x - center.x, pos.z - center.z) +(ai_real)AI_MATH_PI ) / (ai_real)AI_MATH_TWO_PI;
- }
- }
-
- // Now find and remove UV seams. A seam occurs if a face has a tcoord
- // close to zero on the one side, and a tcoord close to one on the
- // other side.
- RemoveUVSeams(mesh,out);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
-{
- ai_real diffu,diffv;
- aiVector3D center, min, max;
-
- // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
- // currently the mapping axis will always be one of x,y,z, except if the
- // PretransformVertices step is used (it transforms the meshes into worldspace,
- // thus changing the mapping axis)
- if (axis * base_axis_x >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.z - min.z;
- diffv = max.y - min.y;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.0);
- }
- }
- else if (axis * base_axis_y >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.x - min.x;
- diffv = max.z - min.z;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0);
- }
- }
- else if (axis * base_axis_z >= angle_epsilon) {
- FindMeshCenter(mesh, center, min, max);
- diffu = max.y - min.y;
- diffv = max.z - min.z;
-
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D& pos = mesh->mVertices[pnt];
- out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
- }
- }
- // slower code path in case the mapping axis is not one of the coordinate system axes
- else
- {
- aiMatrix4x4 mTrafo;
- aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo);
- FindMeshCenterTransformed(mesh, center, min, max,mTrafo);
- diffu = max.x - min.x;
- diffv = max.z - min.z;
-
- // again the same, except we're applying a transformation now
- for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) {
- const aiVector3D pos = mTrafo * mesh->mVertices[pnt];
- out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.0);
- }
- }
-
- // shouldn't be necessary to remove UV seams ...
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
-{
- DefaultLogger::get()->error("Mapping type currently not implemented");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ComputeUVMappingProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenUVCoordsProcess begin");
- char buffer[1024];
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
-
- std::list<MappingInfo> mappingStack;
-
- /* Iterate through all materials and search for non-UV mapped textures
- */
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- mappingStack.clear();
- aiMaterial* mat = pScene->mMaterials[i];
- for (unsigned int a = 0; a < mat->mNumProperties;++a)
- {
- aiMaterialProperty* prop = mat->mProperties[a];
- if (!::strcmp( prop->mKey.data, "$tex.mapping"))
- {
- aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData);
- if (aiTextureMapping_UV != mapping)
- {
- if (!DefaultLogger::isNullLogger())
- {
- ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
- TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
- MappingTypeToString(mapping));
-
- DefaultLogger::get()->info(buffer);
- }
-
- if (aiTextureMapping_OTHER == mapping)
- continue;
-
- MappingInfo info (mapping);
-
- // Get further properties - currently only the major axis
- for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
- {
- aiMaterialProperty* prop2 = mat->mProperties[a2];
- if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
- continue;
-
- if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) {
- info.axis = *((aiVector3D*)prop2->mData);
- break;
- }
- }
-
- unsigned int idx( 99999999 );
-
- // Check whether we have this mapping mode already
- std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info);
- if (mappingStack.end() != it)
- {
- idx = (*it).uv;
- }
- else
- {
- /* We have found a non-UV mapped texture. Now
- * we need to find all meshes using this material
- * that we can compute UV channels for them.
- */
- for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
- {
- aiMesh* mesh = pScene->mMeshes[m];
- unsigned int outIdx = 0;
- if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX ||
- !mesh->mNumVertices)
- {
- continue;
- }
-
- // Allocate output storage
- aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
-
- switch (mapping)
- {
- case aiTextureMapping_SPHERE:
- ComputeSphereMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_CYLINDER:
- ComputeCylinderMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_PLANE:
- ComputePlaneMapping(mesh,info.axis,p);
- break;
- case aiTextureMapping_BOX:
- ComputeBoxMapping(mesh,p);
- break;
- default:
- ai_assert(false);
- }
- if (m && idx != outIdx)
- {
- DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to "
- "this material have equal numbers of UV channels. The UV index stored in "
- "the material structure does therefore not apply for all meshes. ");
- }
- idx = outIdx;
- }
- info.uv = idx;
- mappingStack.push_back(info);
- }
-
- // Update the material property list
- mapping = aiTextureMapping_UV;
- ((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex));
- }
- }
- }
- }
- DefaultLogger::get()->debug("GenUVCoordsProcess finished");
-}
diff --git a/src/3rdparty/assimp/code/ComputeUVMappingProcess.h b/src/3rdparty/assimp/code/ComputeUVMappingProcess.h
deleted file mode 100644
index 1de97961d..000000000
--- a/src/3rdparty/assimp/code/ComputeUVMappingProcess.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to compute UV coordinates
- from abstract mappings, such as box or spherical*/
-#ifndef AI_COMPUTEUVMAPPING_H_INC
-#define AI_COMPUTEUVMAPPING_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-#include <assimp/types.h>
-
-class ComputeUVMappingTest;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** ComputeUVMappingProcess - converts special mappings, such as spherical,
- * cylindrical or boxed to proper UV coordinates for rendering.
-*/
-class ComputeUVMappingProcess : public BaseProcess
-{
-public:
- ComputeUVMappingProcess();
- ~ComputeUVMappingProcess();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Computes spherical UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes cylindrical UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes planar UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param axis Main axis
- * @param out Receives output UV coordinates
- */
- void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
- aiVector3D* out);
-
- // -------------------------------------------------------------------
- /** Computes cubic UV coordinates for a mesh
- *
- * @param mesh Mesh to be processed
- * @param out Receives output UV coordinates
- */
- void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
-
-private:
-
- // temporary structure to describe a mapping
- struct MappingInfo
- {
- explicit MappingInfo(aiTextureMapping _type)
- : type (_type)
- , axis (0.f,1.f,0.f)
- , uv (0u)
- {}
-
- aiTextureMapping type;
- aiVector3D axis;
- unsigned int uv;
-
- bool operator== (const MappingInfo& other)
- {
- return type == other.type && axis == other.axis;
- }
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_COMPUTEUVMAPPING_H_INC
diff --git a/src/3rdparty/assimp/code/ConvertToLHProcess.cpp b/src/3rdparty/assimp/code/ConvertToLHProcess.cpp
deleted file mode 100644
index 6a43d5c2d..000000000
--- a/src/3rdparty/assimp/code/ConvertToLHProcess.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MakeLeftHandedProcess.cpp
- * @brief Implementation of the post processing step to convert all
- * imported data to a left-handed coordinate system.
- *
- * Face order & UV flip are also implemented here, for the sake of a
- * better location.
- */
-
-
-#include "ConvertToLHProcess.h"
-#include <assimp/scene.h>
-#include <assimp/postprocess.h>
-#include <assimp/DefaultLogger.hpp>
-
-using namespace Assimp;
-
-#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MakeLeftHandedProcess::MakeLeftHandedProcess()
-: BaseProcess() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MakeLeftHandedProcess::~MakeLeftHandedProcess() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_MakeLeftHanded);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void MakeLeftHandedProcess::Execute( aiScene* pScene)
-{
- // Check for an existent root node to proceed
- ai_assert(pScene->mRootNode != NULL);
- DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
-
- // recursively convert all the nodes
- ProcessNode( pScene->mRootNode, aiMatrix4x4());
-
- // process the meshes accordingly
- for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
- ProcessMesh( pScene->mMeshes[a]);
-
- // process the materials accordingly
- for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
- ProcessMaterial( pScene->mMaterials[a]);
-
- // transform all animation channels as well
- for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
- {
- aiAnimation* anim = pScene->mAnimations[a];
- for( unsigned int b = 0; b < anim->mNumChannels; b++)
- {
- aiNodeAnim* nodeAnim = anim->mChannels[b];
- ProcessAnimation( nodeAnim);
- }
- }
- DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively converts a node, all of its children and all of its meshes
-void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
-{
- // mirror all base vectors at the local Z axis
- pNode->mTransformation.c1 = -pNode->mTransformation.c1;
- pNode->mTransformation.c2 = -pNode->mTransformation.c2;
- pNode->mTransformation.c3 = -pNode->mTransformation.c3;
- pNode->mTransformation.c4 = -pNode->mTransformation.c4;
-
- // now invert the Z axis again to keep the matrix determinant positive.
- // The local meshes will be inverted accordingly so that the result should look just fine again.
- pNode->mTransformation.a3 = -pNode->mTransformation.a3;
- pNode->mTransformation.b3 = -pNode->mTransformation.b3;
- pNode->mTransformation.c3 = -pNode->mTransformation.c3;
- pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
-
- // continue for all children
- for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
- ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
-{
- // mirror positions, normals and stuff along the Z axis
- for( size_t a = 0; a < pMesh->mNumVertices; ++a)
- {
- pMesh->mVertices[a].z *= -1.0f;
- if( pMesh->HasNormals())
- pMesh->mNormals[a].z *= -1.0f;
- if( pMesh->HasTangentsAndBitangents())
- {
- pMesh->mTangents[a].z *= -1.0f;
- pMesh->mBitangents[a].z *= -1.0f;
- }
- }
-
- // mirror offset matrices of all bones
- for( size_t a = 0; a < pMesh->mNumBones; ++a)
- {
- aiBone* bone = pMesh->mBones[a];
- bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
- bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
- bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
- bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
- bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
- bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
- }
-
- // mirror bitangents as well as they're derived from the texture coords
- if( pMesh->HasTangentsAndBitangents())
- {
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- pMesh->mBitangents[a] *= -1.0f;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single material to left handed coordinates.
-void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
-{
- aiMaterial* mat = (aiMaterial*)_mat;
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
- aiMaterialProperty* prop = mat->mProperties[a];
-
- // Mapping axis for UV mappings?
- if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
- ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
- aiVector3D* pff = (aiVector3D*)prop->mData;
-
- pff->z *= -1.f;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the given animation to LH coordinates.
-void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
-{
- // position keys
- for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
- pAnim->mPositionKeys[a].mValue.z *= -1.0f;
-
- // rotation keys
- for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
- {
- /* That's the safe version, but the float errors add up. So we try the short version instead
- aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
- rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
- rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
- aiQuaternion rotquat( rotmat);
- pAnim->mRotationKeys[a].mValue = rotquat;
- */
- pAnim->mRotationKeys[a].mValue.x *= -1.0f;
- pAnim->mRotationKeys[a].mValue.y *= -1.0f;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
-#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
-// # FlipUVsProcess
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FlipUVsProcess::FlipUVsProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FlipUVsProcess::~FlipUVsProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FlipUVsProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FlipUVs);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FlipUVsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FlipUVsProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- ProcessMesh(pScene->mMeshes[i]);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- ProcessMaterial(pScene->mMaterials[i]);
- DefaultLogger::get()->debug("FlipUVsProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single material
-void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
-{
- aiMaterial* mat = (aiMaterial*)_mat;
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
- aiMaterialProperty* prop = mat->mProperties[a];
- if( !prop ) {
- DefaultLogger::get()->debug( "Property is null" );
- continue;
- }
-
- // UV transformation key?
- if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
- ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
- aiUVTransform* uv = (aiUVTransform*)prop->mData;
-
- // just flip it, that's everything
- uv->mTranslation.y *= -1.f;
- uv->mRotation *= -1.f;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh
-void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
-{
- // mirror texture y coordinate
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
- if( !pMesh->HasTextureCoords( a ) ) {
- break;
- }
-
- for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
- pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
- }
- }
-}
-
-#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
-#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
-// # FlipWindingOrderProcess
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FlipWindingOrderProcess::FlipWindingOrderProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FlipWindingOrderProcess::~FlipWindingOrderProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FlipWindingOrder);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FlipWindingOrderProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- ProcessMesh(pScene->mMeshes[i]);
- DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts a single mesh
-void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
-{
- // invert the order of all faces in this mesh
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- aiFace& face = pMesh->mFaces[a];
- for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
- std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
diff --git a/src/3rdparty/assimp/code/ConvertToLHProcess.h b/src/3rdparty/assimp/code/ConvertToLHProcess.h
deleted file mode 100644
index 130fdcafd..000000000
--- a/src/3rdparty/assimp/code/ConvertToLHProcess.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MakeLeftHandedProcess.h
- * @brief Defines a bunch of post-processing steps to handle
- * coordinate system conversions.
- *
- * - LH to RH
- * - UV origin upper-left to lower-left
- * - face order cw to ccw
- */
-#ifndef AI_CONVERTTOLHPROCESS_H_INC
-#define AI_CONVERTTOLHPROCESS_H_INC
-
-#include <assimp/types.h>
-#include "BaseProcess.h"
-
-struct aiMesh;
-struct aiNodeAnim;
-struct aiNode;
-struct aiMaterial;
-
-namespace Assimp {
-
-// -----------------------------------------------------------------------------------
-/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
- * coordinate system.
- *
- * This implies a mirroring of the Z axis of the coordinate system. But to keep
- * transformation matrices free from reflections we shift the reflection to other
- * places. We mirror the meshes and adapt the rotations.
- *
- * @note RH-LH and LH-RH is the same, so this class can be used for both
- */
-class MakeLeftHandedProcess : public BaseProcess
-{
-
-
-public:
- MakeLeftHandedProcess();
- ~MakeLeftHandedProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Recursively converts a node and all of its children
- */
- void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
-
- // -------------------------------------------------------------------
- /** Converts a single mesh to left handed coordinates.
- * This means that positions, normals and tangents are mirrored at
- * the local Z axis and the order of all faces are inverted.
- * @param pMesh The mesh to convert.
- */
- void ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Converts a single material to left-handed coordinates
- * @param pMat Material to convert
- */
- void ProcessMaterial( aiMaterial* pMat);
-
- // -------------------------------------------------------------------
- /** Converts the given animation to LH coordinates.
- * The rotation and translation keys are transformed, the scale keys
- * work in local space and can therefore be left untouched.
- * @param pAnim The bone animation to transform
- */
- void ProcessAnimation( aiNodeAnim* pAnim);
-};
-
-
-// ---------------------------------------------------------------------------
-/** Postprocessing step to flip the face order of the imported data
- */
-class FlipWindingOrderProcess : public BaseProcess
-{
- friend class Importer;
-
-public:
- /** Constructor to be privately used by Importer */
- FlipWindingOrderProcess();
-
- /** Destructor, private as well */
- ~FlipWindingOrderProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
- void ProcessMesh( aiMesh* pMesh);
-};
-
-// ---------------------------------------------------------------------------
-/** Postprocessing step to flip the UV coordinate system of the import data
- */
-class FlipUVsProcess : public BaseProcess
-{
- friend class Importer;
-
-public:
- /** Constructor to be privately used by Importer */
- FlipUVsProcess();
-
- /** Destructor, private as well */
- ~FlipUVsProcess();
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-protected:
- void ProcessMesh( aiMesh* pMesh);
- void ProcessMaterial( aiMaterial* mat);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CONVERTTOLHPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/CreateAnimMesh.cpp b/src/3rdparty/assimp/code/CreateAnimMesh.cpp
deleted file mode 100644
index 094a414bf..000000000
--- a/src/3rdparty/assimp/code/CreateAnimMesh.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (C) 2016 The Qt Company Ltd.
-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.
----------------------------------------------------------------------------
-*/
-
-#include "CreateAnimMesh.h"
-
-namespace Assimp {
-
-aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh)
-{
- aiAnimMesh *animesh = new aiAnimMesh;
- animesh->mVertices = NULL;
- animesh->mNormals = NULL;
- animesh->mTangents = NULL;
- animesh->mBitangents = NULL;
- animesh->mNumVertices = mesh->mNumVertices;
- if (mesh->mVertices) {
- animesh->mVertices = new aiVector3D[animesh->mNumVertices];
- std::memcpy(animesh->mVertices, mesh->mVertices, mesh->mNumVertices * sizeof(aiVector3D));
- }
- if (mesh->mNormals) {
- animesh->mNormals = new aiVector3D[animesh->mNumVertices];
- std::memcpy(animesh->mNormals, mesh->mNormals, mesh->mNumVertices * sizeof(aiVector3D));
- }
- if (mesh->mTangents) {
- animesh->mTangents = new aiVector3D[animesh->mNumVertices];
- std::memcpy(animesh->mTangents, mesh->mTangents, mesh->mNumVertices * sizeof(aiVector3D));
- }
- if (mesh->mBitangents) {
- animesh->mBitangents = new aiVector3D[animesh->mNumVertices];
- std::memcpy(animesh->mBitangents, mesh->mBitangents, mesh->mNumVertices * sizeof(aiVector3D));
- }
-
- for (int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- if (mesh->mColors[i]) {
- animesh->mColors[i] = new aiColor4D[animesh->mNumVertices];
- std::memcpy(animesh->mColors[i], mesh->mColors[i], mesh->mNumVertices * sizeof(aiColor4D));
- } else {
- animesh->mColors[i] = NULL;
- }
- }
-
- for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- if (mesh->mTextureCoords[i]) {
- animesh->mTextureCoords[i] = new aiVector3D[animesh->mNumVertices];
- std::memcpy(animesh->mTextureCoords[i], mesh->mTextureCoords[i], mesh->mNumVertices * sizeof(aiVector3D));
- } else {
- animesh->mTextureCoords[i] = NULL;
- }
- }
- return animesh;
-}
-
-} // end of namespace Assimp
diff --git a/src/3rdparty/assimp/code/CreateAnimMesh.h b/src/3rdparty/assimp/code/CreateAnimMesh.h
deleted file mode 100644
index 84cab8932..000000000
--- a/src/3rdparty/assimp/code/CreateAnimMesh.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 CreateAnimMesh.h
- * Create AnimMesh from Mesh
- */
-#ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
-#define INCLUDED_AI_CREATE_ANIM_MESH_H
-
-#include <assimp/mesh.h>
-
-namespace Assimp {
-
-/** Create aiAnimMesh from aiMesh. */
-aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
-
-} // end of namespace Assimp
-#endif // INCLUDED_AI_CREATE_ANIM_MESH_H
-
diff --git a/src/3rdparty/assimp/code/D3MFExporter.cpp b/src/3rdparty/assimp/code/D3MFExporter.cpp
deleted file mode 100644
index 162d20764..000000000
--- a/src/3rdparty/assimp/code/D3MFExporter.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
-
-#include "D3MFExporter.h"
-
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/IOStream.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/DefaultLogger.hpp>
-
-#include "Exceptional.h"
-#include "3MFXmlTags.h"
-#include "D3MFOpcPackage.h"
-
-#include <contrib/zip/src/zip.h>
-
-namespace Assimp {
-
-void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/ ) {
- if ( nullptr == pIOSystem ) {
- throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
- }
- D3MF::D3MFExporter myExporter( pFile, pScene );
- if ( myExporter.validate() ) {
- if ( pIOSystem->Exists( pFile ) ) {
- if ( !pIOSystem->DeleteFile( pFile ) ) {
- throw DeadlyExportError( "File exists, cannot override : " + std::string( pFile ) );
- }
- }
- bool ok = myExporter.exportArchive(pFile);
- if ( !ok ) {
- throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
- }
- }
-}
-
-namespace D3MF {
-
-D3MFExporter::D3MFExporter( const char* pFile, const aiScene* pScene )
-: mArchiveName( pFile )
-, m_zipArchive( nullptr )
-, mScene( pScene )
-, mModelOutput()
-, mRelOutput()
-, mContentOutput()
-, mBuildItems()
-, mRelations() {
- // empty
-}
-
-D3MFExporter::~D3MFExporter() {
- for ( size_t i = 0; i < mRelations.size(); ++i ) {
- delete mRelations[ i ];
- }
- mRelations.clear();
-}
-
-bool D3MFExporter::validate() {
- if ( mArchiveName.empty() ) {
- return false;
- }
-
- if ( nullptr == mScene ) {
- return false;
- }
-
- return true;
-}
-
-bool D3MFExporter::exportArchive( const char *file ) {
- bool ok( true );
-
- m_zipArchive = zip_open( file, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w' );
- if ( nullptr == m_zipArchive ) {
- return false;
- }
- ok |= exportContentTypes();
- ok |= export3DModel();
- ok |= exportRelations();
-
- zip_close( m_zipArchive );
- m_zipArchive = nullptr;
-
- return ok;
-}
-
-
-bool D3MFExporter::exportContentTypes() {
- mContentOutput.clear();
-
- mContentOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- mContentOutput << std::endl;
- mContentOutput << "<Types xmlns = \"http://schemas.openxmlformats.org/package/2006/content-types\">";
- mContentOutput << std::endl;
- mContentOutput << "<Default Extension = \"rels\" ContentType = \"application/vnd.openxmlformats-package.relationships+xml\" />";
- mContentOutput << std::endl;
- mContentOutput << "<Default Extension = \"model\" ContentType = \"application/vnd.ms-package.3dmanufacturing-3dmodel+xml\" />";
- mContentOutput << std::endl;
- mContentOutput << "</Types>";
- mContentOutput << std::endl;
- exportContentTyp( XmlTag::CONTENT_TYPES_ARCHIVE );
-
- return true;
-}
-
-bool D3MFExporter::exportRelations() {
- mRelOutput.clear();
-
- mRelOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- mRelOutput << std::endl;
- mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
-
- for ( size_t i = 0; i < mRelations.size(); ++i ) {
- mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
- mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
- mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
- mRelOutput << std::endl;
- }
- mRelOutput << "</Relationships>";
- mRelOutput << std::endl;
-
- writeRelInfoToFile( "_rels", ".rels" );
- mRelOutput.flush();
-
- return true;
-}
-
-bool D3MFExporter::export3DModel() {
- mModelOutput.clear();
-
- writeHeader();
- mModelOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\""
- << "xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">"
- << std::endl;
- mModelOutput << "<" << XmlTag::resources << ">";
- mModelOutput << std::endl;
-
- writeObjects();
-
-
- mModelOutput << "</" << XmlTag::resources << ">";
- mModelOutput << std::endl;
- writeBuild();
-
- mModelOutput << "</" << XmlTag::model << ">\n";
-
- OpcPackageRelationship *info = new OpcPackageRelationship;
- info->id = "rel0";
- info->target = "/3D/3DModel.model";
- info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
- mRelations.push_back( info );
-
- writeModelToArchive( "3D", "3DModel.model" );
- mModelOutput.flush();
-
- return true;
-}
-
-void D3MFExporter::writeHeader() {
- mModelOutput << "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
- mModelOutput << std::endl;
-}
-
-void D3MFExporter::writeObjects() {
- if ( nullptr == mScene->mRootNode ) {
- return;
- }
-
- aiNode *root = mScene->mRootNode;
- for ( unsigned int i = 0; i < root->mNumChildren; ++i ) {
- aiNode *currentNode( root->mChildren[ i ] );
- if ( nullptr == currentNode ) {
- continue;
- }
- mModelOutput << "<" << XmlTag::object << " id=\"" << currentNode->mName.C_Str() << "\" type=\"model\">";
- mModelOutput << std::endl;
- for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) {
- aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ];
- if ( nullptr == currentMesh ) {
- continue;
- }
- writeMesh( currentMesh );
- }
- mBuildItems.push_back( i );
-
- mModelOutput << "</" << XmlTag::object << ">";
- mModelOutput << std::endl;
- }
-}
-
-void D3MFExporter::writeMesh( aiMesh *mesh ) {
- if ( nullptr == mesh ) {
- return;
- }
-
- mModelOutput << "<" << XmlTag::mesh << ">" << std::endl;
- mModelOutput << "<" << XmlTag::vertices << ">" << std::endl;
- for ( unsigned int i = 0; i < mesh->mNumVertices; ++i ) {
- writeVertex( mesh->mVertices[ i ] );
- }
- mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
-
- writeFaces( mesh );
-
- mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
-}
-
-void D3MFExporter::writeVertex( const aiVector3D &pos ) {
- mModelOutput << "<" << XmlTag::vertex << " x=\"" << pos.x << "\" y=\"" << pos.y << "\" z=\"" << pos.z << "\" />";
- mModelOutput << std::endl;
-}
-
-void D3MFExporter::writeFaces( aiMesh *mesh ) {
- if ( nullptr == mesh ) {
- return;
- }
-
- if ( !mesh->HasFaces() ) {
- return;
- }
- mModelOutput << "<" << XmlTag::triangles << ">" << std::endl;
- for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) {
- aiFace &currentFace = mesh->mFaces[ i ];
- mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\""
- << currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] << "\"/>";
- mModelOutput << std::endl;
- }
- mModelOutput << "</" << XmlTag::triangles << ">";
- mModelOutput << std::endl;
-}
-
-void D3MFExporter::writeBuild() {
- mModelOutput << "<" << XmlTag::build << ">" << std::endl;
-
- for ( size_t i = 0; i < mBuildItems.size(); ++i ) {
- mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 1 << "\"/>";
- mModelOutput << std::endl;
- }
- mModelOutput << "</" << XmlTag::build << ">";
- mModelOutput << std::endl;
-}
-
-void D3MFExporter::exportContentTyp( const std::string &filename ) {
- if ( nullptr == m_zipArchive ) {
- throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
- }
- const std::string entry = filename;
- zip_entry_open( m_zipArchive, entry.c_str() );
-
- const std::string &exportTxt( mContentOutput.str() );
- zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
-
- zip_entry_close( m_zipArchive );
-}
-
-void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) {
- if ( nullptr == m_zipArchive ) {
- throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
- }
- const std::string entry = folder + "/" + modelName;
- zip_entry_open( m_zipArchive, entry.c_str() );
-
- const std::string &exportTxt( mModelOutput.str() );
- zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
-
- zip_entry_close( m_zipArchive );
-}
-
-void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::string &relName ) {
- if ( nullptr == m_zipArchive ) {
- throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
- }
- const std::string entry = folder + "/" + relName;
- zip_entry_open( m_zipArchive, entry.c_str() );
-
- const std::string &exportTxt( mRelOutput.str() );
- zip_entry_write( m_zipArchive, exportTxt.c_str(), exportTxt.size() );
-
- zip_entry_close( m_zipArchive );
-}
-
-
-} // Namespace D3MF
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO3MF_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/D3MFExporter.h b/src/3rdparty/assimp/code/D3MFExporter.h
deleted file mode 100644
index 16efabf29..000000000
--- a/src/3rdparty/assimp/code/D3MFExporter.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <memory>
-#include <sstream>
-#include <vector>
-#include <assimp/vector3.h>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-struct aiMesh;
-
-struct zip_t;
-
-namespace Assimp {
-
-class IOStream;
-
-namespace D3MF {
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO3MF_EXPORTER
-
-struct OpcPackageRelationship;
-
-class D3MFExporter {
-public:
- D3MFExporter( const char* pFile, const aiScene* pScene );
- ~D3MFExporter();
- bool validate();
- bool exportArchive( const char *file );
- bool exportContentTypes();
- bool exportRelations();
- bool export3DModel();
-
-protected:
- void writeHeader();
- void writeObjects();
- void writeMesh( aiMesh *mesh );
- void writeVertex( const aiVector3D &pos );
- void writeFaces( aiMesh *mesh );
- void writeBuild();
- void exportContentTyp( const std::string &filename );
- void writeModelToArchive( const std::string &folder, const std::string &modelName );
- void writeRelInfoToFile( const std::string &folder, const std::string &relName );
-
-private:
- std::string mArchiveName;
- zip_t *m_zipArchive;
- const aiScene *mScene;
- std::ostringstream mModelOutput;
- std::ostringstream mRelOutput;
- std::ostringstream mContentOutput;
- std::vector<unsigned int> mBuildItems;
- std::vector<OpcPackageRelationship*> mRelations;
-};
-
-#endif // ASSIMP_BUILD_NO3MF_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
-
-} // Namespace D3MF
-} // Namespace Assimp
-
diff --git a/src/3rdparty/assimp/code/D3MFImporter.cpp b/src/3rdparty/assimp/code/D3MFImporter.cpp
deleted file mode 100644
index 372416dbd..000000000
--- a/src/3rdparty/assimp/code/D3MFImporter.cpp
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_3MF_IMPORTER
-
-#include "D3MFImporter.h"
-
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include "StringComparison.h"
-#include "StringUtils.h"
-
-#include <string>
-#include <vector>
-#include <map>
-#include <cassert>
-#include <memory>
-
-#include "D3MFOpcPackage.h"
-#include <contrib/unzip/unzip.h>
-#include "irrXMLWrapper.h"
-#include "3MFXmlTags.h"
-
-namespace Assimp {
-namespace D3MF {
-
-class XmlSerializer {
-public:
- XmlSerializer(XmlReader* xmlReader)
- : xmlReader(xmlReader) {
- // empty
- }
-
- ~XmlSerializer() {
- // empty
- }
-
- void ImportXml(aiScene* scene) {
- scene->mRootNode = new aiNode();
- std::vector<aiNode*> children;
-
- while(ReadToEndElement(D3MF::XmlTag::model)) {
- if(xmlReader->getNodeName() == D3MF::XmlTag::object) {
- children.push_back(ReadObject(scene));
- } else if(xmlReader->getNodeName() == D3MF::XmlTag::build) {
-
- }
- }
-
- if ( scene->mRootNode->mName.length == 0 ) {
- scene->mRootNode->mName.Set( "3MF" );
- }
-
- scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
-
- std::copy(meshes.begin(), meshes.end(), scene->mMeshes);
-
- scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
- scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
-
- std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
- }
-
-private:
- aiNode* ReadObject(aiScene* scene)
- {
- std::unique_ptr<aiNode> node(new aiNode());
-
- std::vector<unsigned long> meshIds;
-
- const char *attrib( nullptr );
- std::string name, type;
- attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
- if ( nullptr != attrib ) {
- name = attrib;
- }
- attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
- if ( nullptr != attrib ) {
- type = attrib;
- }
-
- node->mParent = scene->mRootNode;
- node->mName.Set(name);
-
- size_t meshIdx = meshes.size();
-
- while(ReadToEndElement(D3MF::XmlTag::object))
- {
- if(xmlReader->getNodeName() == D3MF::XmlTag::mesh)
- {
- auto mesh = ReadMesh();
-
- mesh->mName.Set(name);
- meshes.push_back(mesh);
- meshIds.push_back(static_cast<unsigned long>(meshIdx));
- meshIdx++;
-
- }
- }
-
- node->mNumMeshes = static_cast<unsigned int>(meshIds.size());
-
- node->mMeshes = new unsigned int[node->mNumMeshes];
-
- std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
-
- return node.release();
-
- }
-
- aiMesh* ReadMesh() {
- aiMesh* mesh = new aiMesh();
- while(ReadToEndElement(D3MF::XmlTag::mesh))
- {
- if(xmlReader->getNodeName() == D3MF::XmlTag::vertices)
- {
- ImportVertices(mesh);
- }
- else if(xmlReader->getNodeName() == D3MF::XmlTag::triangles)
- {
- ImportTriangles(mesh);
- }
- }
-
- return mesh;
- }
-
- void ImportVertices(aiMesh* mesh)
- {
- std::vector<aiVector3D> vertices;
-
- while(ReadToEndElement(D3MF::XmlTag::vertices))
- {
- if(xmlReader->getNodeName() == D3MF::XmlTag::vertex)
- {
- vertices.push_back(ReadVertex());
- }
- }
- mesh->mNumVertices = static_cast<unsigned int>(vertices.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
-
- std::copy(vertices.begin(), vertices.end(), mesh->mVertices);
-
- }
-
- aiVector3D ReadVertex()
- {
- aiVector3D vertex;
-
- vertex.x = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::x.c_str()), nullptr);
- vertex.y = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::y.c_str()), nullptr);
- vertex.z = ai_strtof(xmlReader->getAttributeValue(D3MF::XmlTag::z.c_str()), nullptr);
-
- return vertex;
- }
-
- void ImportTriangles(aiMesh* mesh)
- {
- std::vector<aiFace> faces;
-
-
- while(ReadToEndElement(D3MF::XmlTag::triangles))
- {
- if(xmlReader->getNodeName() == D3MF::XmlTag::triangle)
- {
- faces.push_back(ReadTriangle());
- }
- }
-
- mesh->mNumFaces = static_cast<unsigned int>(faces.size());
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- std::copy(faces.begin(), faces.end(), mesh->mFaces);
- }
-
- aiFace ReadTriangle()
- {
- aiFace face;
-
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[face.mNumIndices];
- face.mIndices[0] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v1.c_str())));
- face.mIndices[1] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v2.c_str())));
- face.mIndices[2] = static_cast<unsigned int>(std::atoi(xmlReader->getAttributeValue(D3MF::XmlTag::v3.c_str())));
-
- return face;
- }
-
-private:
- bool ReadToStartElement(const std::string& startTag)
- {
- while(xmlReader->read())
- {
- if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && xmlReader->getNodeName() == startTag)
- {
- return true;
- }
- else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END &&
- xmlReader->getNodeName() == startTag)
- {
- return false;
- }
- }
- //DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
- return false;
- }
-
- bool ReadToEndElement(const std::string& closeTag)
- {
- while(xmlReader->read())
- {
- if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) {
- return true;
- }
- else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END
- && xmlReader->getNodeName() == closeTag)
- {
- return false;
- }
- }
- DefaultLogger::get()->error("unexpected EOF, expected closing <" + closeTag + "> tag");
- return false;
- }
-
-
-private:
- std::vector<aiMesh*> meshes;
- XmlReader* xmlReader;
-};
-
-} //namespace D3MF
-
-static const std::string Extension = "3mf";
-
-static const aiImporterDesc desc = {
- "3mf Importer",
- "",
- "",
- "http://3mf.io/",
- aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
- 0,
- 0,
- 0,
- 0,
- Extension.c_str()
-};
-
-
-D3MFImporter::D3MFImporter()
-: BaseImporter() {
- // empty
-}
-
-D3MFImporter::~D3MFImporter() {
- // empty
-}
-
-bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
- const std::string extension = GetExtension(pFile);
- if(extension == Extension ) {
- return true;
- } else if ( !extension.length() || checkSig ) {
- if (nullptr == pIOHandler ) {
- return true;
- }
- }
-
- return false;
-}
-
-void D3MFImporter::SetupProperties(const Importer * /*pImp*/) {
- // empty
-}
-
-const aiImporterDesc *D3MFImporter::GetInfo() const {
- return &desc;
-}
-
-void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
- D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
-
- std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
- std::unique_ptr<D3MF::XmlReader> xmlReader(irr::io::createIrrXMLReader(xmlStream.get()));
-
- D3MF::XmlSerializer xmlSerializer(xmlReader.get());
-
- xmlSerializer.ImportXml(pScene);
-}
-
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_3MF_IMPORTER
diff --git a/src/3rdparty/assimp/code/D3MFImporter.h b/src/3rdparty/assimp/code/D3MFImporter.h
deleted file mode 100644
index 604d73bd5..000000000
--- a/src/3rdparty/assimp/code/D3MFImporter.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_D3MFLOADER_H_INCLUDED
-#define AI_D3MFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-
-namespace Assimp {
-
-class D3MFImporter : public BaseImporter {
-public:
- // BaseImporter interface
- D3MFImporter();
- ~D3MFImporter();
- bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
- void SetupProperties(const Importer *pImp);
- const aiImporterDesc *GetInfo() const;
-
-protected:
- void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
-};
-
-} // Namespace Assimp
-
-#endif // AI_D3MFLOADER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/D3MFOpcPackage.cpp b/src/3rdparty/assimp/code/D3MFOpcPackage.cpp
deleted file mode 100644
index 49143fee7..000000000
--- a/src/3rdparty/assimp/code/D3MFOpcPackage.cpp
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_3MF_IMPORTER
-
-#include "D3MFOpcPackage.h"
-#include "Exceptional.h"
-
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/ai_assert.h>
-
-#include <cstdlib>
-#include <memory>
-#include <vector>
-#include <map>
-#include <algorithm>
-#include <cassert>
-#include <contrib/unzip/unzip.h>
-#include "3MFXmlTags.h"
-
-namespace Assimp {
-
-namespace D3MF {
-
-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);
-};
-
-voidpf IOSystem2Unzip::open(voidpf opaque, const char* filename, int mode) {
- IOSystem* io_system = reinterpret_cast<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 static_cast<uLong>(io_stream->Read(buf, 1, size));
-}
-
-uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
- IOStream* io_stream = (IOStream*) stream;
-
- return static_cast<uLong>(io_stream->Write(buf, 1, size));
-}
-
-long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
- IOStream* io_stream = (IOStream*) stream;
-
- return static_cast<long>(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 = reinterpret_cast<voidpf>(pIOHandler);
-
- return mapping;
-}
-
-class ZipFile : public IOStream {
- friend class D3MFZipArchive;
-
-public:
- explicit ZipFile(size_t size);
- virtual ~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;
-};
-
-ZipFile::ZipFile(size_t size)
-: m_Buffer( nullptr )
-, m_Size(size) {
- ai_assert(m_Size != 0);
- m_Buffer = ::malloc(m_Size);
-}
-
-ZipFile::~ZipFile() {
- ::free(m_Buffer);
- m_Buffer = NULL;
-}
-
-size_t ZipFile::Read(void* pvBuffer, size_t pSize, size_t pCount) {
- const size_t size = pSize * pCount;
- ai_assert(size <= m_Size);
-
- std::memcpy(pvBuffer, m_Buffer, size);
-
- return size;
-}
-
-size_t ZipFile::Write(const void* pvBuffer, size_t size, size_t pCount ) {
- const size_t size_to_write( size * pCount );
- if ( 0 == size_to_write ) {
- return 0U;
- }
- return 0U;
-}
-
-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
-}
-
-class D3MFZipArchive : public IOSystem {
-public:
- static const unsigned int FileNameSize = 256;
-
- D3MFZipArchive(IOSystem* pIOHandler, const std::string & rFile);
- ~D3MFZipArchive();
- 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;
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-D3MFZipArchive::D3MFZipArchive(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();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-D3MFZipArchive::~D3MFZipArchive() {
- for(auto &file : m_ArchiveMap) {
- delete file.second;
- }
- m_ArchiveMap.clear();
-
- if(m_ZipFileHandle != NULL) {
- unzClose(m_ZipFileHandle);
- m_ZipFileHandle = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the archive is already open.
-bool D3MFZipArchive::isOpen() const {
- return (m_ZipFileHandle != NULL);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the filename is part of the archive.
-bool D3MFZipArchive::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);
-
- if(it != m_ArchiveMap.end()) {
- exist = true;
- }
- }
-
- return exist;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the separator delimiter.
-char D3MFZipArchive::getOsSeparator() const {
-#ifndef _WIN32
- return '/';
-#else
- return '\\';
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// Opens a file, which is part of the archive.
-IOStream *D3MFZipArchive::Open(const char* pFile, const char* /*pMode*/) {
- ai_assert(pFile != NULL);
-
- IOStream* result = NULL;
-
- std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
-
- if(it != m_ArchiveMap.end()) {
- result = static_cast<IOStream*>(it->second);
- }
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Close a filestream.
-void D3MFZipArchive::Close(IOStream *pFile) {
- (void)(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 D3MFZipArchive::getFileList(std::vector<std::string> &rFileList) {
- rFileList.clear();
-
- for(const auto &file : m_ArchiveMap) {
- rFileList.push_back(file.first);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Maps the archive content.
-bool D3MFZipArchive::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(fileInfo.uncompressed_size != 0 && 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;
- }
-
- return success;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-typedef std::shared_ptr<OpcPackageRelationship> OpcPackageRelationshipPtr;
-
-class OpcPackageRelationshipReader {
-public:
- OpcPackageRelationshipReader(XmlReader* xmlReader) {
- while(xmlReader->read()) {
- if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
- xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_CONTAINER)
- {
- ParseRootNode(xmlReader);
- }
- }
- }
-
- void ParseRootNode(XmlReader* xmlReader)
- {
- ParseAttributes(xmlReader);
-
- while(xmlReader->read())
- {
- if(xmlReader->getNodeType() == irr::io::EXN_ELEMENT &&
- xmlReader->getNodeName() == XmlTag::RELS_RELATIONSHIP_NODE)
- {
- ParseChildNode(xmlReader);
- }
- }
- }
-
- void ParseAttributes(XmlReader*) {
- // empty
- }
-
- bool validateRels( OpcPackageRelationshipPtr &relPtr ) {
- if ( relPtr->id.empty() || relPtr->type.empty() || relPtr->target.empty() ) {
- return false;
- }
- return true;
- }
-
- void ParseChildNode(XmlReader* xmlReader) {
- OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
-
- relPtr->id = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_ID.c_str());
- relPtr->type = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TYPE.c_str());
- relPtr->target = xmlReader->getAttributeValueSafe(XmlTag::RELS_ATTRIB_TARGET.c_str());
- if ( validateRels( relPtr ) ) {
- m_relationShips.push_back( relPtr );
- }
- }
-
- std::vector<OpcPackageRelationshipPtr> m_relationShips;
-};
-// ------------------------------------------------------------------------------------------------
-
-D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
-: mRootStream(nullptr)
-, mZipArchive() {
- mZipArchive.reset( new D3MF::D3MFZipArchive( pIOHandler, rFile ) );
- if(!mZipArchive->isOpen()) {
- throw DeadlyImportError("Failed to open file " + rFile+ ".");
- }
-
- std::vector<std::string> fileList;
- mZipArchive->getFileList(fileList);
-
- for (auto& file: fileList) {
- if(file == D3MF::XmlTag::ROOT_RELATIONSHIPS_ARCHIVE) {
- //PkgRelationshipReader pkgRelReader(file, archive);
- ai_assert(mZipArchive->Exists(file.c_str()));
-
- IOStream *fileStream = mZipArchive->Open(file.c_str());
-
- ai_assert(fileStream != nullptr);
-
- std::string rootFile = ReadPackageRootRelationship(fileStream);
- if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
- rootFile = rootFile.substr( 1 );
- if ( rootFile[ 0 ] == '/' ) {
- // deal with zipbug
- rootFile = rootFile.substr( 1 );
- }
- }
-
- DefaultLogger::get()->debug(rootFile);
-
- mRootStream = mZipArchive->Open(rootFile.c_str());
- ai_assert( mRootStream != nullptr );
- if ( nullptr == mRootStream ) {
- throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile );
- }
-
- // const size_t size = zipArchive->FileSize();
- // m_Data.resize( size );
-
- // const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
- // if ( readSize != size )
- // {
- // m_Data.clear();
- // return false;
- // }
- mZipArchive->Close( fileStream );
-
- } else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
-
- }
- }
-}
-
-D3MFOpcPackage::~D3MFOpcPackage() {
- // empty
-}
-
-IOStream* D3MFOpcPackage::RootStream() const {
- return mRootStream;
-}
-
-std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
- std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
- std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
-
- OpcPackageRelationshipReader reader(xml.get());
-
- auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr& rel){
- return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
- });
-
- if(itr == reader.m_relationShips.end())
- throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
-
- return (*itr)->target;
-}
-
-} // Namespace D3MF
-
-} // Namespace Assimp
-
-#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
diff --git a/src/3rdparty/assimp/code/D3MFOpcPackage.h b/src/3rdparty/assimp/code/D3MFOpcPackage.h
deleted file mode 100644
index 818415e9f..000000000
--- a/src/3rdparty/assimp/code/D3MFOpcPackage.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 D3MFOPCPACKAGE_H
-#define D3MFOPCPACKAGE_H
-
-#include <memory>
-
-#include <assimp/IOSystem.hpp>
-#include "irrXMLWrapper.h"
-
-namespace Assimp {
-namespace D3MF {
-
-typedef irr::io::IrrXMLReader XmlReader;
-typedef std::shared_ptr<XmlReader> XmlReaderPtr;
-
-struct OpcPackageRelationship {
- std::string id;
- std::string type;
- std::string target;
-};
-
-class D3MFZipArchive;
-
-class D3MFOpcPackage {
-public:
- D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
- ~D3MFOpcPackage();
- IOStream* RootStream() const;
-
-protected:
- std::string ReadPackageRootRelationship(IOStream* stream);
-
-private:
- IOStream* mRootStream;
- std::unique_ptr<D3MFZipArchive> mZipArchive;
-};
-
-}
-}
-
-#endif // D3MFOPCPACKAGE_H
diff --git a/src/3rdparty/assimp/code/DXFHelper.h b/src/3rdparty/assimp/code/DXFHelper.h
deleted file mode 100644
index e16b7f1aa..000000000
--- a/src/3rdparty/assimp/code/DXFHelper.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DXFHelper.h
- * @brief Internal utilities for the DXF loader.
- */
-
-#ifndef INCLUDED_DXFHELPER_H
-#define INCLUDED_DXFHELPER_H
-
-#include "LineSplitter.h"
-#include "TinyFormatter.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-#include <vector>
-#include <assimp/DefaultLogger.hpp>
-
-namespace Assimp {
- namespace DXF {
-
-
-// read pairs of lines, parse group code and value and provide utilities
-// to convert the data to the target data type.
-class LineReader
-{
-
-public:
-
- LineReader(StreamReaderLE& reader)
- // do NOT skip empty lines. In DXF files, they count as valid data.
- : splitter(reader,false,true)
- , groupcode( 0 )
- , value()
- , end()
- {
- }
-
-public:
-
-
- // -----------------------------------------
- bool Is(int gc, const char* what) const {
- return groupcode == gc && !strcmp(what,value.c_str());
- }
-
- // -----------------------------------------
- bool Is(int gc) const {
- return groupcode == gc;
- }
-
- // -----------------------------------------
- int GroupCode() const {
- return groupcode;
- }
-
- // -----------------------------------------
- const std::string& Value() const {
- return value;
- }
-
- // -----------------------------------------
- bool End() const {
- return !((bool)*this);
- }
-
-public:
-
- // -----------------------------------------
- unsigned int ValueAsUnsignedInt() const {
- return strtoul10(value.c_str());
- }
-
- // -----------------------------------------
- int ValueAsSignedInt() const {
- return strtol10(value.c_str());
- }
-
- // -----------------------------------------
- float ValueAsFloat() const {
- return fast_atof(value.c_str());
- }
-
-public:
-
- // -----------------------------------------
- /** pseudo-iterator increment to advance to the next (groupcode/value) pair */
- LineReader& operator++() {
- if (end) {
- if (end == 1) {
- ++end;
- }
- return *this;
- }
-
- try {
- groupcode = strtol10(splitter->c_str());
- splitter++;
-
- value = *splitter;
- splitter++;
-
- // automatically skip over {} meta blocks (these are for application use
- // and currently not relevant for Assimp).
- if (value.length() && value[0] == '{') {
-
- size_t cnt = 0;
- for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
-
- splitter++;
- DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
- }
- } catch(std::logic_error&) {
- ai_assert(!splitter);
- }
- if (!splitter) {
- end = 1;
- }
- return *this;
- }
-
- // -----------------------------------------
- LineReader& operator++(int) {
- return ++(*this);
- }
-
-
- // -----------------------------------------
- operator bool() const {
- return end <= 1;
- }
-
-private:
-
- LineSplitter splitter;
- int groupcode;
- std::string value;
- int end;
-};
-
-
-
-// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
-struct PolyLine
-{
- PolyLine()
- : flags()
- {}
-
- std::vector<aiVector3D> positions;
- std::vector<aiColor4D> colors;
- std::vector<unsigned int> indices;
- std::vector<unsigned int> counts;
- unsigned int flags;
-
- std::string layer;
- std::string desc;
-};
-
-
-// reference to a BLOCK. Specifies its own coordinate system.
-struct InsertBlock
-{
- InsertBlock()
- : scale(1.f,1.f,1.f)
- , angle()
- {}
-
- aiVector3D pos;
- aiVector3D scale;
- float angle;
-
- std::string name;
-};
-
-
-// keeps track of all geometry in a single BLOCK.
-struct Block
-{
- std::vector< std::shared_ptr<PolyLine> > lines;
- std::vector<InsertBlock> insertions;
-
- std::string name;
- aiVector3D base;
-};
-
-
-struct FileData
-{
- // note: the LAST block always contains the stuff from ENTITIES.
- std::vector<Block> blocks;
-};
-
-
-
-
-
-}}
-#endif
diff --git a/src/3rdparty/assimp/code/DXFLoader.cpp b/src/3rdparty/assimp/code/DXFLoader.cpp
deleted file mode 100644
index 1e932e509..000000000
--- a/src/3rdparty/assimp/code/DXFLoader.cpp
+++ /dev/null
@@ -1,919 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DXFLoader.cpp
- * @brief Implementation of the DXF importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-
-#include "DXFLoader.h"
-#include "ParsingUtils.h"
-#include "ConvertToLHProcess.h"
-#include "fast_atof.h"
-
-#include "DXFHelper.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include <numeric>
-
-using namespace Assimp;
-
-// AutoCAD Binary DXF<CR><LF><SUB><NULL>
-#define AI_DXF_BINARY_IDENT ("AutoCAD Binary DXF\r\n\x1a\0")
-#define AI_DXF_BINARY_IDENT_LEN (24)
-
-// default vertex color that all uncolored vertices will receive
-#define AI_DXF_DEFAULT_COLOR aiColor4D(0.6f,0.6f,0.6f,0.6f)
-
-// color indices for DXF - 16 are supported, the table is
-// taken directly from the DXF spec.
-static aiColor4D g_aclrDxfIndexColors[] =
-{
- aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
- aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
- aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
- aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
- aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
- aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
- aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
- aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
- aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
- aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
- aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
- aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
- aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
- aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
- aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
- aiColor4D (0.6f, 0.0f, 1.0f, 1.0f) // violet
-};
-#define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
-#define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
-
-
-static const aiImporterDesc desc = {
- "Drawing Interchange Format (DXF) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport,
- 0,
- 0,
- 0,
- 0,
- "dxf"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-DXFImporter::DXFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DXFImporter::~DXFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool DXFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"dxf");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported file extensions
-const aiImporterDesc* DXFImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void DXFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler)
-{
- std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( pFile) );
-
- // Check whether we can read the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open DXF file " + pFile + "");
- }
-
- // check whether this is a binaray DXF file - we can't read binary DXF files :-(
- char buff[AI_DXF_BINARY_IDENT_LEN+1] = {0};
- file->Read(buff,AI_DXF_BINARY_IDENT_LEN,1);
-
- if (!strncmp(AI_DXF_BINARY_IDENT,buff,AI_DXF_BINARY_IDENT_LEN)) {
- throw DeadlyImportError("DXF: Binary files are not supported at the moment");
- }
-
- // DXF files can grow very large, so read them via the StreamReader,
- // which will choose a suitable strategy.
- file->Seek(0,aiOrigin_SET);
- StreamReaderLE stream( file );
-
- DXF::LineReader reader (stream);
- DXF::FileData output;
-
- // now get all lines of the file and process top-level sections
- bool eof = false;
- while(!reader.End()) {
-
- // blocks table - these 'build blocks' are later (in ENTITIES)
- // referenced an included via INSERT statements.
- if (reader.Is(2,"BLOCKS")) {
- ParseBlocks(reader,output);
- continue;
- }
-
- // primary entity table
- if (reader.Is(2,"ENTITIES")) {
- ParseEntities(reader,output);
- continue;
- }
-
- // skip unneeded sections entirely to avoid any problems with them
- // altogether.
- else if (reader.Is(2,"CLASSES") || reader.Is(2,"TABLES")) {
- SkipSection(reader);
- continue;
- }
-
- else if (reader.Is(2,"HEADER")) {
- ParseHeader(reader,output);
- continue;
- }
-
- // comments
- else if (reader.Is(999)) {
- DefaultLogger::get()->info("DXF Comment: " + reader.Value());
- }
-
- // don't read past the official EOF sign
- else if (reader.Is(0,"EOF")) {
- eof = true;
- break;
- }
-
- ++reader;
- }
- if (!eof) {
- DefaultLogger::get()->warn("DXF: EOF reached, but did not encounter DXF EOF marker");
- }
-
- ConvertMeshes(pScene,output);
-
- // Now rotate the whole scene by 90 degrees around the x axis to convert from AutoCAD's to Assimp's coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(
- 1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,
- 0.f,-1.f,0.f,0.f,
- 0.f,0.f,0.f,1.f) * pScene->mRootNode->mTransformation;
-}
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output)
-{
- // the process of resolving all the INSERT statements can grow the
- // polycount excessively, so log the original number.
- // XXX Option to import blocks as separate nodes?
- if (!DefaultLogger::isNullLogger()) {
-
- unsigned int vcount = 0, icount = 0;
- for (const DXF::Block& bl : output.blocks) {
- for (std::shared_ptr<const DXF::PolyLine> pl : bl.lines) {
- vcount += static_cast<unsigned int>(pl->positions.size());
- icount += static_cast<unsigned int>(pl->counts.size());
- }
- }
-
- DefaultLogger::get()->debug((Formatter::format("DXF: Unexpanded polycount is "),
- icount,", vertex count is ",vcount
- ));
- }
-
- if (! output.blocks.size() ) {
- throw DeadlyImportError("DXF: no data blocks loaded");
- }
-
- DXF::Block* entities = 0;
-
- // index blocks by name
- DXF::BlockMap blocks_by_name;
- for (DXF::Block& bl : output.blocks) {
- blocks_by_name[bl.name] = &bl;
- if ( !entities && bl.name == AI_DXF_ENTITIES_MAGIC_BLOCK ) {
- entities = &bl;
- }
- }
-
- if (!entities) {
- throw DeadlyImportError("DXF: no ENTITIES data block loaded");
- }
-
- typedef std::map<std::string, unsigned int> LayerMap;
-
- LayerMap layers;
- std::vector< std::vector< const DXF::PolyLine*> > corr;
-
- // now expand all block references in the primary ENTITIES block
- // XXX this involves heavy memory copying, consider a faster solution for future versions.
- ExpandBlockReferences(*entities,blocks_by_name);
-
- unsigned int cur = 0;
- for (std::shared_ptr<const DXF::PolyLine> pl : entities->lines) {
- if (pl->positions.size()) {
-
- std::map<std::string, unsigned int>::iterator it = layers.find(pl->layer);
- if (it == layers.end()) {
- ++pScene->mNumMeshes;
-
- layers[pl->layer] = cur++;
-
- std::vector< const DXF::PolyLine* > pv;
- pv.push_back(&*pl);
-
- corr.push_back(pv);
- }
- else {
- corr[(*it).second].push_back(&*pl);
- }
- }
- }
-
- if (!pScene->mNumMeshes) {
- throw DeadlyImportError("DXF: this file contains no 3d data");
- }
-
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ] ();
-
- for(const LayerMap::value_type& elem : layers){
- aiMesh* const mesh = pScene->mMeshes[elem.second] = new aiMesh();
- mesh->mName.Set(elem.first);
-
- unsigned int cvert = 0,cface = 0;
- for(const DXF::PolyLine* pl : corr[elem.second]){
- // sum over all faces since we need to 'verbosify' them.
- cvert += std::accumulate(pl->counts.begin(),pl->counts.end(),0);
- cface += static_cast<unsigned int>(pl->counts.size());
- }
-
- aiVector3D* verts = mesh->mVertices = new aiVector3D[cvert];
- aiColor4D* colors = mesh->mColors[0] = new aiColor4D[cvert];
- aiFace* faces = mesh->mFaces = new aiFace[cface];
-
- mesh->mNumVertices = cvert;
- mesh->mNumFaces = cface;
-
- unsigned int prims = 0;
- unsigned int overall_indices = 0;
- for(const DXF::PolyLine* pl : corr[elem.second]){
-
- std::vector<unsigned int>::const_iterator it = pl->indices.begin();
- for(unsigned int facenumv : pl->counts) {
- aiFace& face = *faces++;
- face.mIndices = new unsigned int[face.mNumIndices = facenumv];
-
- for (unsigned int i = 0; i < facenumv; ++i) {
- face.mIndices[i] = overall_indices++;
-
- ai_assert(pl->positions.size() == pl->colors.size());
- if (*it >= pl->positions.size()) {
- throw DeadlyImportError("DXF: vertex index out of bounds");
- }
-
- *verts++ = pl->positions[*it];
- *colors++ = pl->colors[*it++];
- }
-
- // set primitive flags now, this saves the extra pass in ScenePreprocessor.
- switch(face.mNumIndices) {
- case 1:
- prims |= aiPrimitiveType_POINT;
- break;
- case 2:
- prims |= aiPrimitiveType_LINE;
- break;
- case 3:
- prims |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- prims |= aiPrimitiveType_POLYGON;
- break;
- }
- }
- }
-
- mesh->mPrimitiveTypes = prims;
- mesh->mMaterialIndex = 0;
- }
-
- GenerateHierarchy(pScene,output);
- GenerateMaterials(pScene,output);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& blocks_by_name)
-{
- for (const DXF::InsertBlock& insert : bl.insertions) {
-
- // first check if the referenced blocks exists ...
- const DXF::BlockMap::const_iterator it = blocks_by_name.find(insert.name);
- if (it == blocks_by_name.end()) {
- DefaultLogger::get()->error((Formatter::format("DXF: Failed to resolve block reference: "),
- insert.name,"; skipping"
- ));
- continue;
- }
-
- // XXX this would be the place to implement recursive expansion if needed.
- const DXF::Block& bl_src = *(*it).second;
-
- for (std::shared_ptr<const DXF::PolyLine> pl_in : bl_src.lines) {
- std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
-
- if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
- // manual coordinate system transformation
- // XXX order
- aiMatrix4x4 trafo, tmp;
- aiMatrix4x4::Translation(-bl_src.base,trafo);
- trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
- trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
-
- // XXX rotation currently ignored - I didn't find an appropriate sample model.
- if (insert.angle != 0.f) {
- DefaultLogger::get()->warn("DXF: BLOCK rotation not currently implemented");
- }
-
- for (aiVector3D& v : pl_out->positions) {
- v *= trafo;
- }
- }
-
- bl.lines.push_back(pl_out);
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::GenerateMaterials(aiScene* pScene, DXF::FileData& /*output*/)
-{
- // generate an almost-white default material. Reason:
- // the default vertex color is GREY, so we are
- // already at Assimp's usual default color.
- // generate a default material
- aiMaterial* pcMat = new aiMaterial();
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- pcMat->AddProperty(&s, AI_MATKEY_NAME);
-
- aiColor4D clrDiffuse(0.9f,0.9f,0.9f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
-
- clrDiffuse = aiColor4D(1.0f,1.0f,1.0f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
-
- clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
-
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::GenerateHierarchy(aiScene* pScene, DXF::FileData& /*output*/)
-{
- // generate the output scene graph, which is just the root node with a single child for each layer.
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<DXF_ROOT>");
-
- if (1 == pScene->mNumMeshes) {
- pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
- for (unsigned int m = 0; m < pScene->mRootNode->mNumChildren;++m) {
- aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
- p->mName = pScene->mMeshes[m]->mName;
-
- p->mMeshes = new unsigned int[p->mNumMeshes = 1];
- p->mMeshes[0] = m;
- p->mParent = pScene->mRootNode;
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::SkipSection(DXF::LineReader& reader)
-{
- for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseHeader(DXF::LineReader& reader, DXF::FileData& /*output*/)
-{
- for( ;!reader.End() && !reader.Is(0,"ENDSEC"); reader++);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseBlocks(DXF::LineReader& reader, DXF::FileData& output)
-{
- while( !reader.End() && !reader.Is(0,"ENDSEC")) {
- if (reader.Is(0,"BLOCK")) {
- ParseBlock(++reader,output);
- continue;
- }
- ++reader;
- }
-
- DefaultLogger::get()->debug((Formatter::format("DXF: got "),
- output.blocks.size()," entries in BLOCKS"
- ));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseBlock(DXF::LineReader& reader, DXF::FileData& output)
-{
- // push a new block onto the stack.
- output.blocks.push_back( DXF::Block() );
- DXF::Block& block = output.blocks.back();
-
- while( !reader.End() && !reader.Is(0,"ENDBLK")) {
-
- switch(reader.GroupCode()) {
- case 2:
- block.name = reader.Value();
- break;
-
- case 10:
- block.base.x = reader.ValueAsFloat();
- break;
- case 20:
- block.base.y = reader.ValueAsFloat();
- break;
- case 30:
- block.base.z = reader.ValueAsFloat();
- break;
- }
-
- if (reader.Is(0,"POLYLINE")) {
- ParsePolyLine(++reader,output);
- continue;
- }
-
- // XXX is this a valid case?
- if (reader.Is(0,"INSERT")) {
- DefaultLogger::get()->warn("DXF: INSERT within a BLOCK not currently supported; skipping");
- for( ;!reader.End() && !reader.Is(0,"ENDBLK"); ++reader);
- break;
- }
-
- else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
- //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
- Parse3DFace(++reader, output);
- continue;
- }
- ++reader;
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParseEntities(DXF::LineReader& reader, DXF::FileData& output)
-{
- // push a new block onto the stack.
- output.blocks.push_back( DXF::Block() );
- DXF::Block& block = output.blocks.back();
-
- block.name = AI_DXF_ENTITIES_MAGIC_BLOCK;
-
- while( !reader.End() && !reader.Is(0,"ENDSEC")) {
- if (reader.Is(0,"POLYLINE")) {
- ParsePolyLine(++reader,output);
- continue;
- }
-
- else if (reader.Is(0,"INSERT")) {
- ParseInsertion(++reader,output);
- continue;
- }
-
- else if (reader.Is(0,"3DFACE") || reader.Is(0,"LINE") || reader.Is(0,"3DLINE")) {
- //http://sourceforge.net/tracker/index.php?func=detail&aid=2970566&group_id=226462&atid=1067632
- Parse3DFace(++reader, output);
- continue;
- }
-
- ++reader;
- }
-
- DefaultLogger::get()->debug((Formatter::format("DXF: got "),
- block.lines.size()," polylines and ", block.insertions.size() ," inserted blocks in ENTITIES"
- ));
-}
-
-
-void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
-{
- output.blocks.back().insertions.push_back( DXF::InsertBlock() );
- DXF::InsertBlock& bl = output.blocks.back().insertions.back();
-
- while( !reader.End() && !reader.Is(0)) {
-
- switch(reader.GroupCode())
- {
- // name of referenced block
- case 2:
- bl.name = reader.Value();
- break;
-
- // translation
- case 10:
- bl.pos.x = reader.ValueAsFloat();
- break;
- case 20:
- bl.pos.y = reader.ValueAsFloat();
- break;
- case 30:
- bl.pos.z = reader.ValueAsFloat();
- break;
-
- // scaling
- case 41:
- bl.scale.x = reader.ValueAsFloat();
- break;
- case 42:
- bl.scale.y = reader.ValueAsFloat();
- break;
- case 43:
- bl.scale.z = reader.ValueAsFloat();
- break;
-
- // rotation angle
- case 50:
- bl.angle = reader.ValueAsFloat();
- break;
- }
- reader++;
- }
-}
-
-#define DXF_POLYLINE_FLAG_CLOSED 0x1
-#define DXF_POLYLINE_FLAG_3D_POLYLINE 0x8
-#define DXF_POLYLINE_FLAG_3D_POLYMESH 0x10
-#define DXF_POLYLINE_FLAG_POLYFACEMESH 0x40
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
-{
- output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
- DXF::PolyLine& line = *output.blocks.back().lines.back();
-
- unsigned int iguess = 0, vguess = 0;
- while( !reader.End() && !reader.Is(0,"ENDSEC")) {
-
- if (reader.Is(0,"VERTEX")) {
- ParsePolyLineVertex(++reader,line);
- if (reader.Is(0,"SEQEND")) {
- break;
- }
- continue;
- }
-
- switch(reader.GroupCode())
- {
- // flags --- important that we know whether it is a
- // polyface mesh or 'just' a line.
- case 70:
- if (!line.flags) {
- line.flags = reader.ValueAsSignedInt();
- }
- break;
-
- // optional number of vertices
- case 71:
- vguess = reader.ValueAsSignedInt();
- line.positions.reserve(vguess);
- break;
-
- // optional number of faces
- case 72:
- iguess = reader.ValueAsSignedInt();
- line.indices.reserve(iguess);
- break;
-
- // 8 specifies the layer on which this line is placed on
- case 8:
- line.layer = reader.Value();
- break;
- }
-
- reader++;
- }
-
- //if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH)) {
- // DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags));
- // output.blocks.back().lines.pop_back();
- // return;
- //}
-
- if (vguess && line.positions.size() != vguess) {
- DefaultLogger::get()->warn((Formatter::format("DXF: unexpected vertex count in polymesh: "),
- line.positions.size(),", expected ", vguess
- ));
- }
-
- if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH ) {
- if (line.positions.size() < 3 || line.indices.size() < 3) {
- DefaultLogger::get()->warn("DXF: not enough vertices for polymesh; ignoring");
- output.blocks.back().lines.pop_back();
- return;
- }
-
- // if these numbers are wrong, parsing might have gone wild.
- // however, the docs state that applications are not required
- // to set the 71 and 72 fields, respectively, to valid values.
- // So just fire a warning.
- if (iguess && line.counts.size() != iguess) {
- DefaultLogger::get()->warn((Formatter::format("DXF: unexpected face count in polymesh: "),
- line.counts.size(),", expected ", iguess
- ));
- }
- }
- else if (!line.indices.size() && !line.counts.size()) {
- // a polyline - so there are no indices yet.
- size_t guess = line.positions.size() + (line.flags & DXF_POLYLINE_FLAG_CLOSED ? 1 : 0);
- line.indices.reserve(guess);
-
- line.counts.reserve(guess/2);
- for (unsigned int i = 0; i < line.positions.size()/2; ++i) {
- line.indices.push_back(i*2);
- line.indices.push_back(i*2+1);
- line.counts.push_back(2);
- }
-
- // closed polyline?
- if (line.flags & DXF_POLYLINE_FLAG_CLOSED) {
- line.indices.push_back(static_cast<unsigned int>(line.positions.size()-1));
- line.indices.push_back(0);
- line.counts.push_back(2);
- }
- }
-}
-
-#define DXF_VERTEX_FLAG_PART_OF_POLYFACE 0x80
-#define DXF_VERTEX_FLAG_HAS_POSITIONS 0x40
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& line)
-{
- unsigned int cnti = 0, flags = 0;
- unsigned int indices[4];
-
- aiVector3D out;
- aiColor4D clr = AI_DXF_DEFAULT_COLOR;
-
- while( !reader.End() ) {
-
- if (reader.Is(0)) { // SEQEND or another VERTEX
- break;
- }
-
- switch (reader.GroupCode())
- {
- case 8:
- // layer to which the vertex belongs to - assume that
- // this is always the layer the top-level polyline
- // entity resides on as well.
- if(reader.Value() != line.layer) {
- DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
- }
- break;
-
- case 70:
- flags = reader.ValueAsUnsignedInt();
- break;
-
- // VERTEX COORDINATES
- case 10: out.x = reader.ValueAsFloat();break;
- case 20: out.y = reader.ValueAsFloat();break;
- case 30: out.z = reader.ValueAsFloat();break;
-
- // POLYFACE vertex indices
- case 71:
- case 72:
- case 73:
- case 74:
- if (cnti == 4) {
- DefaultLogger::get()->warn("DXF: more than 4 indices per face not supported; ignoring");
- break;
- }
- indices[cnti++] = reader.ValueAsUnsignedInt();
- break;
-
- // color
- case 62:
- clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS];
- break;
- };
-
- reader++;
- }
-
- if (line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH && !(flags & DXF_VERTEX_FLAG_PART_OF_POLYFACE)) {
- DefaultLogger::get()->warn("DXF: expected vertex to be part of a polyface but the 0x128 flag isn't set");
- }
-
- if (cnti) {
- line.counts.push_back(cnti);
- for (unsigned int i = 0; i < cnti; ++i) {
- // IMPORTANT NOTE: POLYMESH indices are ONE-BASED
- if (indices[i] == 0) {
- DefaultLogger::get()->warn("DXF: invalid vertex index, indices are one-based.");
- --line.counts.back();
- continue;
- }
- line.indices.push_back(indices[i]-1);
- }
- }
- else {
- line.positions.push_back(out);
- line.colors.push_back(clr);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
-{
- // (note) this is also used for for parsing line entities, so we
- // must handle the vertex_count == 2 case as well.
-
- output.blocks.back().lines.push_back( std::shared_ptr<DXF::PolyLine>( new DXF::PolyLine() ) );
- DXF::PolyLine& line = *output.blocks.back().lines.back();
-
- aiVector3D vip[4];
- aiColor4D clr = AI_DXF_DEFAULT_COLOR;
-
- bool b[4] = {false,false,false,false};
- while( !reader.End() ) {
-
- // next entity with a groupcode == 0 is probably already the next vertex or polymesh entity
- if (reader.GroupCode() == 0) {
- break;
- }
- switch (reader.GroupCode())
- {
-
- // 8 specifies the layer
- case 8:
- line.layer = reader.Value();
- break;
-
- // x position of the first corner
- case 10: vip[0].x = reader.ValueAsFloat();
- b[2] = true;
- break;
-
- // y position of the first corner
- case 20: vip[0].y = reader.ValueAsFloat();
- b[2] = true;
- break;
-
- // z position of the first corner
- case 30: vip[0].z = reader.ValueAsFloat();
- b[2] = true;
- break;
-
- // x position of the second corner
- case 11: vip[1].x = reader.ValueAsFloat();
- b[3] = true;
- break;
-
- // y position of the second corner
- case 21: vip[1].y = reader.ValueAsFloat();
- b[3] = true;
- break;
-
- // z position of the second corner
- case 31: vip[1].z = reader.ValueAsFloat();
- b[3] = true;
- break;
-
- // x position of the third corner
- case 12: vip[2].x = reader.ValueAsFloat();
- b[0] = true;
- break;
-
- // y position of the third corner
- case 22: vip[2].y = reader.ValueAsFloat();
- b[0] = true;
- break;
-
- // z position of the third corner
- case 32: vip[2].z = reader.ValueAsFloat();
- b[0] = true;
- break;
-
- // x position of the fourth corner
- case 13: vip[3].x = reader.ValueAsFloat();
- b[1] = true;
- break;
-
- // y position of the fourth corner
- case 23: vip[3].y = reader.ValueAsFloat();
- b[1] = true;
- break;
-
- // z position of the fourth corner
- case 33: vip[3].z = reader.ValueAsFloat();
- b[1] = true;
- break;
-
- // color
- case 62:
- clr = g_aclrDxfIndexColors[reader.ValueAsUnsignedInt() % AI_DXF_NUM_INDEX_COLORS];
- break;
- };
-
- ++reader;
- }
-
- // the fourth corner may even be identical to the third,
- // in this case we treat it as if it didn't exist.
- if (vip[3] == vip[2]) {
- b[1] = false;
- }
-
- // sanity checks to see if we got something meaningful
- if ((b[1] && !b[0]) || !b[2] || !b[3]) {
- DefaultLogger::get()->warn("DXF: unexpected vertex setup in 3DFACE/LINE/FACE entity; ignoring");
- output.blocks.back().lines.pop_back();
- return;
- }
-
- const unsigned int cnt = (2+(b[0]?1:0)+(b[1]?1:0));
- line.counts.push_back(cnt);
-
- for (unsigned int i = 0; i < cnt; ++i) {
- line.indices.push_back(static_cast<unsigned int>(line.positions.size()));
- line.positions.push_back(vip[i]);
- line.colors.push_back(clr);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_DXF_IMPORTER
-
diff --git a/src/3rdparty/assimp/code/DXFLoader.h b/src/3rdparty/assimp/code/DXFLoader.h
deleted file mode 100644
index 64822e9e2..000000000
--- a/src/3rdparty/assimp/code/DXFLoader.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DXFLoader.h
- * @brief Declaration of the .dxf importer class.
- */
-#ifndef AI_DXFLOADER_H_INCLUDED
-#define AI_DXFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <map>
-
-namespace Assimp {
- namespace DXF {
-
- class LineReader;
- struct FileData;
- struct PolyLine;
- struct Block;
- struct InsertBlock;
-
- typedef std::map<std::string, const DXF::Block*> BlockMap;
- }
-
-
-// ---------------------------------------------------------------------------
-/** DXF importer implementation.
- *
-*/
-class DXFImporter : public BaseImporter
-{
-public:
- DXFImporter();
- ~DXFImporter();
-
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details*/
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details */
- void InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- // -----------------------------------------------------
- void SkipSection(DXF::LineReader& reader);
-
- // -----------------------------------------------------
- void ParseHeader(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParseEntities(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParseBlocks(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParseBlock(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParseInsertion(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParsePolyLine(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ParsePolyLineVertex(DXF::LineReader& reader,
- DXF::PolyLine& line);
-
- // -----------------------------------------------------
- void Parse3DFace(DXF::LineReader& reader,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ConvertMeshes(aiScene* pScene,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void GenerateHierarchy(aiScene* pScene,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void GenerateMaterials(aiScene* pScene,
- DXF::FileData& output);
-
- // -----------------------------------------------------
- void ExpandBlockReferences(DXF::Block& bl,
- const DXF::BlockMap& blocks_by_name);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/DeboneProcess.cpp b/src/3rdparty/assimp/code/DeboneProcess.cpp
deleted file mode 100644
index b43dcad84..000000000
--- a/src/3rdparty/assimp/code/DeboneProcess.cpp
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DeboneProcess.cpp
-/** Implementation of the DeboneProcess post processing step */
-
-
-
-// internal headers of the post-processing framework
-#include "ProcessHelper.h"
-#include "DeboneProcess.h"
-#include <stdio.h>
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-DeboneProcess::DeboneProcess()
-{
- mNumBones = 0;
- mNumBonesCanDoWithout = 0;
-
- mThreshold = AI_DEBONE_THRESHOLD;
- mAllOrNone = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DeboneProcess::~DeboneProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool DeboneProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_Debone) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void DeboneProcess::SetupProperties(const Importer* pImp)
-{
- // get the current value of the property
- mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
- mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void DeboneProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("DeboneProcess begin");
-
- if(!pScene->mNumMeshes) {
- return;
- }
-
- std::vector<bool> splitList(pScene->mNumMeshes);
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
- }
-
- int numSplits = 0;
-
- if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
- for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- if(splitList[a]) {
- numSplits++;
- }
- }
- }
-
- if(numSplits) {
- // we need to do something. Let's go.
- //mSubMeshIndices.clear(); // really needed?
- mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
-
- // build a new array of meshes for the scene
- std::vector<aiMesh*> meshes;
-
- for(unsigned int a=0;a<pScene->mNumMeshes;a++)
- {
- aiMesh* srcMesh = pScene->mMeshes[a];
-
- std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
-
- if(splitList[a]) {
- SplitMesh(srcMesh,newMeshes);
- }
-
- // mesh was split
- if(!newMeshes.empty()) {
- unsigned int out = 0, in = srcMesh->mNumBones;
-
- // store new meshes and indices of the new meshes
- for(unsigned int b=0;b<newMeshes.size();b++) {
- const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
-
- aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
- std::pair<unsigned int,aiNode*> push_pair(static_cast<unsigned int>(meshes.size()),theNode);
-
- mSubMeshIndices[a].push_back(push_pair);
- meshes.push_back(newMeshes[b].first);
-
- out+=newMeshes[b].first->mNumBones;
- }
-
- if(!DefaultLogger::isNullLogger()) {
- char buffer[1024];
- ::ai_snprintf(buffer,1024,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
- DefaultLogger::get()->info(buffer);
- }
-
- // and destroy the source mesh. It should be completely contained inside the new submeshes
- delete srcMesh;
- }
- else {
- // Mesh is kept unchanged - store it's new place in the mesh array
- mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(static_cast<unsigned int>(meshes.size()),(aiNode*)0));
- meshes.push_back(srcMesh);
- }
- }
-
- // rebuild the scene's mesh array
- pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- delete [] pScene->mMeshes;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
-
- // recurse through all nodes and translate the node's mesh indices to fit the new mesh array
- UpdateNode( pScene->mRootNode);
- }
-
- DefaultLogger::get()->debug("DeboneProcess end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts bones total/removable in a given mesh.
-bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
-{
- if(!pMesh->HasBones()) {
- return false;
- }
-
- bool split = false;
-
- //interstitial faces not permitted
- bool isInterstitialRequired = false;
-
- std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
- std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
-
- const unsigned int cUnowned = UINT_MAX;
- const unsigned int cCoowned = UINT_MAX-1;
-
- for(unsigned int i=0;i<pMesh->mNumBones;i++) {
- for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
- float w = pMesh->mBones[i]->mWeights[j].mWeight;
-
- if(w==0.0f) {
- continue;
- }
-
- unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
- if(w>=mThreshold) {
-
- if(vertexBones[vid]!=cUnowned) {
- if(vertexBones[vid]==i) //double entry
- {
- DefaultLogger::get()->warn("Encountered double entry in bone weights");
- }
- else //TODO: track attraction in order to break tie
- {
- vertexBones[vid] = cCoowned;
- }
- }
- else vertexBones[vid] = i;
- }
-
- if(!isBoneNecessary[i]) {
- isBoneNecessary[i] = w<mThreshold;
- }
- }
-
- if(!isBoneNecessary[i]) {
- isInterstitialRequired = true;
- }
- }
-
- if(isInterstitialRequired) {
- for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
- unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
-
- for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
- unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
-
- if(v!=w) {
- if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
- if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
- }
- }
- }
- }
-
- for(unsigned int i=0;i<pMesh->mNumBones;i++) {
- if(!isBoneNecessary[i]) {
- mNumBonesCanDoWithout++;
- split = true;
- }
-
- mNumBones++;
- }
- return split;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Splits the given mesh by bone count.
-void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
-{
- // same deal here as ConsiderMesh basically
-
- std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
- std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
-
- const unsigned int cUnowned = UINT_MAX;
- const unsigned int cCoowned = UINT_MAX-1;
-
- for(unsigned int i=0;i<pMesh->mNumBones;i++) {
- for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
- float w = pMesh->mBones[i]->mWeights[j].mWeight;
-
- if(w==0.0f) {
- continue;
- }
-
- unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
-
- if(w>=mThreshold) {
- if(vertexBones[vid]!=cUnowned) {
- if(vertexBones[vid]==i) //double entry
- {
- //DefaultLogger::get()->warn("Encountered double entry in bone weights");
- }
- else //TODO: track attraction in order to break tie
- {
- vertexBones[vid] = cCoowned;
- }
- }
- else vertexBones[vid] = i;
- }
-
- if(!isBoneNecessary[i]) {
- isBoneNecessary[i] = w<mThreshold;
- }
- }
- }
-
- unsigned int nFacesUnowned = 0;
-
- std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
- std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
-
- for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
- unsigned int nInterstitial = 1;
-
- unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
-
- for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
- unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
-
- if(v!=w) {
- if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
- if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
- }
- else nInterstitial++;
- }
-
- if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) {
- faceBones[i] = v; //primitive belongs to bone #v
- facesPerBone[v]++;
- }
- else nFacesUnowned++;
- }
-
- // invalidate any "cojoined" faces
- for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
- if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]])
- {
- ai_assert(facesPerBone[faceBones[i]]>0);
- facesPerBone[faceBones[i]]--;
-
- nFacesUnowned++;
- faceBones[i] = cUnowned;
- }
- }
-
- if(nFacesUnowned) {
- std::vector<unsigned int> subFaces;
-
- for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
- if(faceBones[i]==cUnowned) {
- subFaces.push_back(i);
- }
- }
-
- aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
- std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
-
- poNewMeshes.push_back(push_pair);
- }
-
- for(unsigned int i=0;i<pMesh->mNumBones;i++) {
-
- if(!isBoneNecessary[i]&&facesPerBone[i]>0) {
- std::vector<unsigned int> subFaces;
-
- for(unsigned int j=0;j<pMesh->mNumFaces;j++) {
- if(faceBones[j]==i) {
- subFaces.push_back(j);
- }
- }
-
- unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
- aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
-
- //Lifted from PretransformVertices.cpp
- ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
- std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
-
- poNewMeshes.push_back(push_pair);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively updates the node's mesh list to account for the changed mesh list
-void DeboneProcess::UpdateNode(aiNode* pNode) const
-{
- // rebuild the node's mesh index list
-
- std::vector<unsigned int> newMeshList;
-
- // this will require two passes
-
- unsigned int m = static_cast<unsigned int>(pNode->mNumMeshes), n = static_cast<unsigned int>(mSubMeshIndices.size());
-
- // first pass, look for meshes which have not moved
-
- for(unsigned int a=0;a<m;a++) {
-
- unsigned int srcIndex = pNode->mMeshes[a];
- const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
- unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
-
- for(unsigned int b=0;b<nSubmeshes;b++) {
- if(!subMeshes[b].second) {
- newMeshList.push_back(subMeshes[b].first);
- }
- }
- }
-
- // second pass, collect deboned meshes
-
- for(unsigned int a=0;a<n;a++)
- {
- const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
- unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
-
- for(unsigned int b=0;b<nSubmeshes;b++) {
- if(subMeshes[b].second == pNode) {
- newMeshList.push_back(subMeshes[b].first);
- }
- }
- }
-
- if( pNode->mNumMeshes > 0 ) {
- delete [] pNode->mMeshes; pNode->mMeshes = NULL;
- }
-
- pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
-
- if(pNode->mNumMeshes) {
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
- std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
- }
-
- // do that also recursively for all children
- for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
- UpdateNode( pNode->mChildren[a]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apply the node transformation to a mesh
-void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
-{
- // Check whether we need to transform the coordinates at all
- if (!mat.IsIdentity()) {
-
- if (mesh->HasPositions()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mVertices[i] = mat * mesh->mVertices[i];
- }
- }
- if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
- aiMatrix4x4 mWorldIT = mat;
- mWorldIT.Inverse().Transpose();
-
- // TODO: implement Inverse() for aiMatrix3x3
- aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
-
- if (mesh->HasNormals()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
- }
- }
- if (mesh->HasTangentsAndBitangents()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
- mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
- }
- }
- }
- }
-}
diff --git a/src/3rdparty/assimp/code/DeboneProcess.h b/src/3rdparty/assimp/code/DeboneProcess.h
deleted file mode 100644
index 8d4607bb9..000000000
--- a/src/3rdparty/assimp/code/DeboneProcess.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-/** Defines a post processing step to limit the number of bones affecting a single vertex. */
-#ifndef AI_DEBONEPROCESS_H_INC
-#define AI_DEBONEPROCESS_H_INC
-
-#include <vector>
-#include <utility>
-#include "BaseProcess.h"
-
-#include <assimp/mesh.h>
-#include <assimp/scene.h>
-
-class DeboneTest;
-
-namespace Assimp
-{
-
-#if (!defined AI_DEBONE_THRESHOLD)
-# define AI_DEBONE_THRESHOLD 1.0f
-#endif // !! AI_DEBONE_THRESHOLD
-
-// ---------------------------------------------------------------------------
-/** This post processing step removes bones nearly losslessly or according to
-* a configured threshold. In order to remove the bone, the primitives affected by
-* the bone are split from the mesh. The split off (new) mesh is boneless. At any
-* point in time, bones without affect upon a given mesh are to be removed.
-*/
-class DeboneProcess : public BaseProcess
-{
-public:
-
- DeboneProcess();
- ~DeboneProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Counts bones total/removable in a given mesh.
- * @param pMesh The mesh to process.
- */
- bool ConsiderMesh( const aiMesh* pMesh);
-
- /// Splits the given mesh by bone count.
- /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
- /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
- void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
-
- /// Recursively updates the node's mesh list to account for the changed mesh list
- void UpdateNode(aiNode* pNode) const;
-
- // -------------------------------------------------------------------
- // Apply transformation to a mesh
- void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
-
-public:
- /** Number of bones present in the scene. */
- unsigned int mNumBones;
- unsigned int mNumBonesCanDoWithout;
-
- float mThreshold;
- bool mAllOrNone;
-
- /// Per mesh index: Array of indices of the new submeshes.
- std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_DEBONEPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/DefaultIOStream.cpp b/src/3rdparty/assimp/code/DefaultIOStream.cpp
deleted file mode 100644
index cce9af19d..000000000
--- a/src/3rdparty/assimp/code/DefaultIOStream.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DefaultIOStream.cpp
- * @brief Default File I/O implementation for #Importer
- */
-
-
-#include <assimp/ai_assert.h>
-#include <assimp/DefaultIOStream.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-using namespace Assimp;
-
-// ----------------------------------------------------------------------------------
-DefaultIOStream::~DefaultIOStream()
-{
- if (mFile) {
- ::fclose(mFile);
- mFile = nullptr;
- }
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Read(void* pvBuffer,
- size_t pSize,
- size_t pCount)
-{
- ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
- return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount)
-{
- ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
- return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
-}
-
-// ----------------------------------------------------------------------------------
-aiReturn DefaultIOStream::Seek(size_t pOffset,
- aiOrigin pOrigin)
-{
- if (!mFile) {
- return AI_FAILURE;
- }
-
- // Just to check whether our enum maps one to one with the CRT constants
- static_assert(aiOrigin_CUR == SEEK_CUR &&
- aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET, "aiOrigin_CUR == SEEK_CUR && \
- aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET");
-
- // do the seek
- return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::Tell() const
-{
- if (!mFile) {
- return 0;
- }
- return ::ftell(mFile);
-}
-
-// ----------------------------------------------------------------------------------
-size_t DefaultIOStream::FileSize() const
-{
- if (! mFile || mFilename.empty()) {
- return 0;
- }
-
- if (SIZE_MAX == mCachedSize ) {
-
- // Although fseek/ftell would allow us to reuse the existing 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__ || __MSVCRT_VERSION__ >= 0x0601)
- struct __stat64 fileStat;
- int err = _stat64( mFilename.c_str(), &fileStat );
- if (0 != err)
- return 0;
- mCachedSize = (size_t) (fileStat.st_size);
-#elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__
- struct stat fileStat;
- int err = stat(mFilename.c_str(), &fileStat );
- if (0 != err)
- return 0;
- const unsigned long long cachedSize = fileStat.st_size;
- mCachedSize = static_cast< size_t >( cachedSize );
-#else
-# error "Unknown platform"
-#endif
- }
- return mCachedSize;
-}
-
-// ----------------------------------------------------------------------------------
-void DefaultIOStream::Flush()
-{
- if (mFile) {
- ::fflush(mFile);
- }
-}
-
-// ----------------------------------------------------------------------------------
diff --git a/src/3rdparty/assimp/code/DefaultIOSystem.cpp b/src/3rdparty/assimp/code/DefaultIOSystem.cpp
deleted file mode 100644
index 8687b0059..000000000
--- a/src/3rdparty/assimp/code/DefaultIOSystem.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Default implementation of IOSystem using the standard C file functions */
-
-#include "StringComparison.h"
-
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/DefaultIOStream.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/ai_assert.h>
-#include <stdlib.h>
-
-#ifdef __unix__
-#include <sys/param.h>
-#include <stdlib.h>
-#endif
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-DefaultIOSystem::DefaultIOSystem()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-DefaultIOSystem::~DefaultIOSystem()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tests for the existence of a file at the given path.
-bool DefaultIOSystem::Exists( const char* pFile) const
-{
- FILE* file = ::fopen( pFile, "rb");
- if( !file)
- return false;
-
- ::fclose( file);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Open a new file with a given path.
-IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
-{
- ai_assert(NULL != strFile);
- ai_assert(NULL != strMode);
-
- FILE* file = ::fopen( strFile, strMode);
- if( NULL == file)
- return NULL;
-
- return new DefaultIOStream(file, (std::string) strFile);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Closes the given file and releases all resources associated with it.
-void DefaultIOSystem::Close( IOStream* pFile)
-{
- delete pFile;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the operation specific directory separator
-char DefaultIOSystem::getOsSeparator() const
-{
-#ifndef _WIN32
- return '/';
-#else
- return '\\';
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// IOSystem default implementation (ComparePaths isn't a pure virtual function)
-bool IOSystem::ComparePaths (const char* one, const char* second) const
-{
- return !ASSIMP_stricmp(one,second);
-}
-
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-# define PATHLIMIT PATH_MAX
-#else
-# define PATHLIMIT 4096
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Convert a relative path into an absolute path
-inline void MakeAbsolutePath (const char* in, char* _out)
-{
- ai_assert(in && _out);
- char* ret;
-#if defined( _MSC_VER ) || defined( __MINGW32__ )
- ret = ::_fullpath( _out, in, PATHLIMIT );
-#else
- // use realpath
- ret = realpath(in, _out);
-#endif
- if(!ret) {
- // preserve the input path, maybe someone else is able to fix
- // the path before it is accessed (e.g. our file system filter)
- DefaultLogger::get()->warn("Invalid path: "+std::string(in));
- strcpy(_out,in);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// DefaultIOSystem's more specialized implementation
-bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
-{
- // chances are quite good both paths are formatted identically,
- // so we can hopefully return here already
- if( !ASSIMP_stricmp(one,second) )
- return true;
-
- char temp1[PATHLIMIT];
- char temp2[PATHLIMIT];
-
- MakeAbsolutePath (one, temp1);
- MakeAbsolutePath (second, temp2);
-
- return !ASSIMP_stricmp(temp1,temp2);
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::fileName( const std::string &path )
-{
- std::string ret = path;
- std::size_t last = ret.find_last_of("\\/");
- if (last != std::string::npos) ret = ret.substr(last + 1);
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::completeBaseName( const std::string &path )
-{
- std::string ret = fileName(path);
- std::size_t pos = ret.find_last_of('.');
- if(pos != ret.npos) ret = ret.substr(0, pos);
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::absolutePath( const std::string &path )
-{
- std::string ret = path;
- std::size_t last = ret.find_last_of("\\/");
- if (last != std::string::npos) ret = ret.substr(0, last);
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-#undef PATHLIMIT
diff --git a/src/3rdparty/assimp/code/DefaultLogger.cpp b/src/3rdparty/assimp/code/DefaultLogger.cpp
deleted file mode 100644
index b69e18ea9..000000000
--- a/src/3rdparty/assimp/code/DefaultLogger.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DefaultLogger.cpp
- * @brief Implementation of DefaultLogger (and Logger)
- */
-
-
-// Default log streams
-#include "Win32DebugLogStream.h"
-#include "StdOStreamLogStream.h"
-#include "FileLogStream.h"
-#include "StringUtils.h"
-
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/NullLogger.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/ai_assert.h>
-#include <iostream>
-#include <stdio.h>
-
-#ifndef ASSIMP_BUILD_SINGLETHREADED
-# include <thread>
-# include <mutex>
-
-std::mutex loggerMutex;
-#endif
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-NullLogger DefaultLogger::s_pNullLogger;
-Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
-
-static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
-
-// ----------------------------------------------------------------------------------
-// Represents a log-stream + its error severity
-struct LogStreamInfo
-{
- unsigned int m_uiErrorSeverity;
- LogStream *m_pStream;
-
- // Constructor
- LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
- m_uiErrorSeverity( uiErrorSev ),
- m_pStream( pStream )
- {
- // empty
- }
-
- // Destructor
- ~LogStreamInfo()
- {
- delete m_pStream;
- }
-};
-
-// ----------------------------------------------------------------------------------
-// Construct a default log stream
-LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
- const char* name /*= "AssimpLog.txt"*/,
- IOSystem* io /*= NULL*/)
-{
- switch (streams)
- {
- // This is a platform-specific feature
- case aiDefaultLogStream_DEBUGGER:
-#ifdef WIN32
- return new Win32DebugLogStream();
-#else
- return NULL;
-#endif
-
- // Platform-independent default streams
- case aiDefaultLogStream_STDERR:
- return new StdOStreamLogStream(std::cerr);
- case aiDefaultLogStream_STDOUT:
- return new StdOStreamLogStream(std::cout);
- case aiDefaultLogStream_FILE:
- return (name && *name ? new FileLogStream(name,io) : NULL);
- default:
- // We don't know this default log stream, so raise an assertion
- ai_assert(false);
-
- };
-
- // For compilers without dead code path detection
- return NULL;
-}
-
-// ----------------------------------------------------------------------------------
-// Creates the only singleton instance
-Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
- LogSeverity severity /*= NORMAL*/,
- unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
- IOSystem* io /*= NULL*/)
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(loggerMutex);
-#endif
-
- if (m_pLogger && !isNullLogger() )
- delete m_pLogger;
-
- m_pLogger = new DefaultLogger( severity );
-
- // Attach default log streams
- // Stream the log to the MSVC debugger?
- if (defStreams & aiDefaultLogStream_DEBUGGER)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
-
- // Stream the log to COUT?
- if (defStreams & aiDefaultLogStream_STDOUT)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
-
- // Stream the log to CERR?
- if (defStreams & aiDefaultLogStream_STDERR)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
-
- // Stream the log to a file
- if (defStreams & aiDefaultLogStream_FILE && name && *name)
- m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
-
- return m_pLogger;
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::debug(const char* message) {
-
- // SECURITY FIX: otherwise it's easy to produce overruns since
- // sometimes importers will include data from the input file
- // (i.e. node names) in their messages.
- if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
- return;
- }
- return OnDebug(message);
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::info(const char* message) {
-
- // SECURITY FIX: see above
- if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
- return;
- }
- return OnInfo(message);
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::warn(const char* message) {
-
- // SECURITY FIX: see above
- if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
- return;
- }
- return OnWarn(message);
-}
-
-// ----------------------------------------------------------------------------------
-void Logger::error(const char* message) {
-
- // SECURITY FIX: see above
- if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
- return;
- }
- return OnError(message);
-}
-
-// ----------------------------------------------------------------------------------
-void DefaultLogger::set( Logger *logger )
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(loggerMutex);
-#endif
-
- if (!logger)logger = &s_pNullLogger;
- if (m_pLogger && !isNullLogger() )
- delete m_pLogger;
-
- DefaultLogger::m_pLogger = logger;
-}
-
-// ----------------------------------------------------------------------------------
-bool DefaultLogger::isNullLogger()
-{
- return m_pLogger == &s_pNullLogger;
-}
-
-// ----------------------------------------------------------------------------------
-Logger *DefaultLogger::get() {
- return m_pLogger;
-}
-
-// ----------------------------------------------------------------------------------
-// Kills the only instance
-void DefaultLogger::kill()
-{
- // enter the mutex here to avoid concurrency problems
-#ifndef ASSIMP_BUILD_SINGLETHREADED
- std::lock_guard<std::mutex> lock(loggerMutex);
-#endif
-
- if ( m_pLogger == &s_pNullLogger ) {
- return;
- }
- delete m_pLogger;
- m_pLogger = &s_pNullLogger;
-}
-
-// ----------------------------------------------------------------------------------
-// Debug message
-void DefaultLogger::OnDebug( const char* message )
-{
- if ( m_Severity == Logger::NORMAL )
- return;
-
- static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
- char msg[Size];
- ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);
-
- WriteToStreams( msg, Logger::Debugging );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs an info
-void DefaultLogger::OnInfo( const char* message )
-{
- static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
- char msg[Size];
- ai_snprintf(msg, Size, "Info, T%u: %s", GetThreadID(), message );
-
- WriteToStreams( msg , Logger::Info );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs a warning
-void DefaultLogger::OnWarn( const char* message )
-{
- static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
- char msg[Size];
- ai_snprintf(msg, Size, "Warn, T%u: %s", GetThreadID(), message );
-
- WriteToStreams( msg, Logger::Warn );
-}
-
-// ----------------------------------------------------------------------------------
-// Logs an error
-void DefaultLogger::OnError( const char* message )
-{
- static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
- char msg[ Size ];
- ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message );
-
- WriteToStreams( msg, Logger::Err );
-}
-
-// ----------------------------------------------------------------------------------
-// Will attach a new stream
-bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
-{
- if (!pStream)
- return false;
-
- if (0 == severity) {
- severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
- }
-
- for ( StreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it )
- {
- if ( (*it)->m_pStream == pStream )
- {
- (*it)->m_uiErrorSeverity |= severity;
- return true;
- }
- }
-
- LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
- m_StreamArray.push_back( pInfo );
- return true;
-}
-
-// ----------------------------------------------------------------------------------
-// Detach a stream
-bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
-{
- if (!pStream)
- return false;
-
- if (0 == severity) {
- severity = SeverityAll;
- }
-
- for ( StreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it )
- {
- if ( (*it)->m_pStream == pStream )
- {
- (*it)->m_uiErrorSeverity &= ~severity;
- if ( (*it)->m_uiErrorSeverity == 0 )
- {
- // don't delete the underlying stream 'cause the caller gains ownership again
- (**it).m_pStream = NULL;
- delete *it;
- m_StreamArray.erase( it );
- break;
- }
- return true;
- }
- }
- return false;
-}
-
-// ----------------------------------------------------------------------------------
-// Constructor
-DefaultLogger::DefaultLogger(LogSeverity severity)
- : Logger ( severity )
- , noRepeatMsg (false)
- , lastLen( 0 )
-{
- lastMsg[0] = '\0';
-}
-
-// ----------------------------------------------------------------------------------
-// Destructor
-DefaultLogger::~DefaultLogger()
-{
- for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
- // also frees the underlying stream, we are its owner.
- delete *it;
- }
-}
-
-// ----------------------------------------------------------------------------------
-// Writes message to stream
-void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev )
-{
- ai_assert(NULL != message);
-
- // Check whether this is a repeated message
- if (! ::strncmp( message,lastMsg, lastLen-1))
- {
- if (!noRepeatMsg)
- {
- noRepeatMsg = true;
- message = "Skipping one or more lines with the same contents\n";
- }
- else return;
- }
- else
- {
- // append a new-line character to the message to be printed
- lastLen = ::strlen(message);
- ::memcpy(lastMsg,message,lastLen+1);
- ::strcat(lastMsg+lastLen,"\n");
-
- message = lastMsg;
- noRepeatMsg = false;
- ++lastLen;
- }
- for ( ConstStreamIt it = m_StreamArray.begin();
- it != m_StreamArray.end();
- ++it)
- {
- if ( ErrorSev & (*it)->m_uiErrorSeverity )
- (*it)->m_pStream->write( message);
- }
-}
-
-// ----------------------------------------------------------------------------------
-// Returns thread id, if not supported only a zero will be returned.
-unsigned int DefaultLogger::GetThreadID()
-{
- // fixme: we can get this value via std::threads
- // std::this_thread::get_id().hash() returns a (big) size_t, not sure if this is useful in this case.
-#ifdef WIN32
- return (unsigned int)::GetCurrentThreadId();
-#else
- return 0; // not supported
-#endif
-}
-
-// ----------------------------------------------------------------------------------
-
-} // !namespace Assimp
diff --git a/src/3rdparty/assimp/code/DefaultProgressHandler.h b/src/3rdparty/assimp/code/DefaultProgressHandler.h
deleted file mode 100644
index 6cd872eaa..000000000
--- a/src/3rdparty/assimp/code/DefaultProgressHandler.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ProgressHandler.hpp
- * @brief Abstract base class 'ProgressHandler'.
- */
-#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
-#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
-
-#include <assimp/ProgressHandler.hpp>
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------
-/** @brief Internal default implementation of the #ProgressHandler interface. */
-class DefaultProgressHandler
- : public ProgressHandler {
-
-
- virtual bool Update(float /*percentage*/) {
- return false;
- }
-
-
-}; // !class DefaultProgressHandler
-} // Namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/Exceptional.h b/src/3rdparty/assimp/code/Exceptional.h
deleted file mode 100644
index 5109b8f07..000000000
--- a/src/3rdparty/assimp/code/Exceptional.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, 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_EXCEPTIONAL_H
-#define INCLUDED_EXCEPTIONAL_H
-
-#include <stdexcept>
-#include <assimp/DefaultIOStream.h>
-using std::runtime_error;
-
-#ifdef _MSC_VER
-# pragma warning(disable : 4275)
-#endif
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
- * unrecoverable error occurs while importing. Loading APIs return
- * NULL instead of a valid aiScene then. */
-class DeadlyImportError
- : public runtime_error
-{
-public:
- /** Constructor with arguments */
- explicit DeadlyImportError( const std::string& errorText)
- : runtime_error(errorText)
- {
- }
-
-private:
-};
-
-typedef DeadlyImportError DeadlyExportError;
-
-#ifdef _MSC_VER
-# pragma warning(default : 4275)
-#endif
-
-// ---------------------------------------------------------------------------
-template <typename T>
-struct ExceptionSwallower {
- T operator ()() const {
- return T();
- }
-};
-
-// ---------------------------------------------------------------------------
-template <typename T>
-struct ExceptionSwallower<T*> {
- T* operator ()() const {
- return NULL;
- }
-};
-
-// ---------------------------------------------------------------------------
-template <>
-struct ExceptionSwallower<aiReturn> {
- aiReturn operator ()() const {
- try {
- throw;
- }
- catch (std::bad_alloc&) {
- return aiReturn_OUTOFMEMORY;
- }
- catch (...) {
- return aiReturn_FAILURE;
- }
- }
-};
-
-// ---------------------------------------------------------------------------
-template <>
-struct ExceptionSwallower<void> {
- void operator ()() const {
- return;
- }
-};
-
-#define ASSIMP_BEGIN_EXCEPTION_REGION()\
-{\
- try {
-
-#define ASSIMP_END_EXCEPTION_REGION(type)\
- } catch(...) {\
- return ExceptionSwallower<type>()();\
- }\
-}
-
-#endif // INCLUDED_EXCEPTIONAL_H
diff --git a/src/3rdparty/assimp/code/Exporter.cpp b/src/3rdparty/assimp/code/Exporter.cpp
deleted file mode 100644
index 3fc31a722..000000000
--- a/src/3rdparty/assimp/code/Exporter.cpp
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Exporter.cpp
-
-Assimp export interface. While it's public interface bears many similarities
-to the import interface (in fact, it is largely symmetric), the internal
-implementations differs a lot. Exporters are considered stateless and are
-simple callbacks which we maintain in a global list along with their
-description strings.
-
-Here we implement only the C++ interface (Assimp::Exporter).
-*/
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-
-#include "BlobIOSystem.h"
-#include <assimp/SceneCombiner.h>
-#include "BaseProcess.h"
-#include "Importer.h" // need this for GetPostProcessingStepInstanceList()
-
-#include "JoinVerticesProcess.h"
-#include "MakeVerboseFormat.h"
-#include "ConvertToLHProcess.h"
-#include "Exceptional.h"
-#include "ScenePrivate.h"
-#include <memory>
-
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Exporter.hpp>
-#include <assimp/mesh.h>
-#include <assimp/postprocess.h>
-#include <assimp/scene.h>
-
-namespace Assimp {
-
-// PostStepRegistry.cpp
-void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
-
-// ------------------------------------------------------------------------------------------------
-// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
-// do not use const, because some exporter need to convert the scene temporary
-void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
-void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
-
-// ------------------------------------------------------------------------------------------------
-// global array of all export formats which Assimp supports in its current build
-Exporter::ExportFormatEntry gExporters[] =
-{
-#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
- Exporter::ExportFormatEntry( "collada", "COLLADA - Digital Asset Exchange Schema", "dae", &ExportSceneCollada ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_X_EXPORTER
- Exporter::ExportFormatEntry( "x", "X Files", "x", &ExportSceneXFile,
- aiProcess_MakeLeftHanded | aiProcess_FlipWindingOrder | aiProcess_FlipUVs ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
- Exporter::ExportFormatEntry( "stp", "Step Files", "stp", &ExportSceneStep, 0 ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
- Exporter::ExportFormatEntry( "obj", "Wavefront OBJ format", "obj", &ExportSceneObj,
- aiProcess_GenSmoothNormals /*| aiProcess_PreTransformVertices */ ),
- Exporter::ExportFormatEntry( "objnomtl", "Wavefront OBJ format without material file", "obj", &ExportSceneObjNoMtl,
- 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
- Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
- aiProcess_PreTransformVertices
- ),
- Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
- aiProcess_PreTransformVertices
- ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
- Exporter::ExportFormatEntry( "3ds", "Autodesk 3DS (legacy)", "3ds" , &ExportScene3DS,
- aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
- Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
- aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
- Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
- aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
- Exporter::ExportFormatEntry( "gltf2", "GL Transmission Format v. 2", "gltf2", &ExportSceneGLTF2,
- aiProcess_JoinIdenticalVertices | aiProcess_Triangulate | aiProcess_SortByPType ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
- Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0 ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
- Exporter::ExportFormatEntry( "assxml", "Assxml Document", "assxml" , &ExportSceneAssxml, 0 ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
- Exporter::ExportFormatEntry( "x3d", "Extensible 3D", "x3d" , &ExportSceneX3D, 0 ),
-#endif
-
-#ifndef ASSIMP_BUILD_NO3MF_EXPORTER
- Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 )
-#endif
-};
-
-#define ASSIMP_NUM_EXPORTERS (sizeof(gExporters)/sizeof(gExporters[0]))
-
-
-class ExporterPimpl {
-public:
- ExporterPimpl()
- : blob()
- , mIOSystem(new Assimp::DefaultIOSystem())
- , mIsDefaultIOHandler(true)
- {
- GetPostProcessingStepInstanceList(mPostProcessingSteps);
-
- // grab all built-in exporters
- if ( 0 != ( ASSIMP_NUM_EXPORTERS ) ) {
- mExporters.resize( ASSIMP_NUM_EXPORTERS );
- std::copy( gExporters, gExporters + ASSIMP_NUM_EXPORTERS, mExporters.begin() );
- }
- }
-
- ~ExporterPimpl()
- {
- delete blob;
-
- // Delete all post-processing plug-ins
- for( unsigned int a = 0; a < mPostProcessingSteps.size(); a++) {
- delete mPostProcessingSteps[a];
- }
- }
-
-public:
- aiExportDataBlob* blob;
- std::shared_ptr< Assimp::IOSystem > mIOSystem;
- bool mIsDefaultIOHandler;
-
- /** Post processing steps we can apply at the imported data. */
- std::vector< BaseProcess* > mPostProcessingSteps;
-
- /** Last fatal export error */
- std::string mError;
-
- /** Exporters, this includes those registered using #Assimp::Exporter::RegisterExporter */
- std::vector<Exporter::ExportFormatEntry> mExporters;
-};
-
-} // end of namespace Assimp
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-Exporter :: Exporter()
-: pimpl(new ExporterPimpl()) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Exporter::~Exporter() {
- FreeBlob();
-
- delete pimpl;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Exporter::SetIOHandler( IOSystem* pIOHandler) {
- pimpl->mIsDefaultIOHandler = !pIOHandler;
- pimpl->mIOSystem.reset(pIOHandler);
-}
-
-// ------------------------------------------------------------------------------------------------
-IOSystem* Exporter::GetIOHandler() const {
- return pimpl->mIOSystem.get();
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Exporter::IsDefaultIOHandler() const {
- return pimpl->mIsDefaultIOHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const char* pFormatId,
- unsigned int, const ExportProperties* /*pProperties*/ ) {
- if (pimpl->blob) {
- delete pimpl->blob;
- pimpl->blob = NULL;
- }
-
- std::shared_ptr<IOSystem> old = pimpl->mIOSystem;
- BlobIOSystem* blobio = new BlobIOSystem();
- pimpl->mIOSystem = std::shared_ptr<IOSystem>( blobio );
-
- if (AI_SUCCESS != Export(pScene,pFormatId,blobio->GetMagicFileName())) {
- pimpl->mIOSystem = old;
- return NULL;
- }
-
- pimpl->blob = blobio->GetBlobChain();
- pimpl->mIOSystem = old;
-
- return pimpl->blob;
-}
-
-// ------------------------------------------------------------------------------------------------
-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, const ExportProperties* pProperties) {
- 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];
- if (!strcmp(exp.mDescription.id,pFormatId)) {
- try {
- // Always create a full copy of the scene. We might optimize this one day,
- // but for now it is the most pragmatic way.
- aiScene* scenecopy_tmp = NULL;
- SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
-
- std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
- const ScenePrivateData* const priv = ScenePriv(pScene);
-
- // steps that are not idempotent, i.e. we might need to run them again, usually to get back to the
- // original state before the step was applied first. When checking which steps we don't need
- // to run, those are excluded.
- const unsigned int nonIdempotentSteps = aiProcess_FlipWindingOrder | aiProcess_FlipUVs | aiProcess_MakeLeftHanded;
-
- // Erase all pp steps that were already applied to this scene
- const unsigned int pp = (exp.mEnforcePP | pPreprocessing) & ~(priv && !priv->mIsCopy
- ? (priv->mPPStepsApplied & ~nonIdempotentSteps)
- : 0u);
-
- // If no extra post-processing was specified, and we obtained this scene from an
- // Assimp importer, apply the reverse steps automatically.
- // 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 post-processing step that relies on it,
- // we need to run the MakeVerboseFormat step first.
- bool must_join_again = false;
- if (!is_verbose_format) {
- bool verbosify = false;
- for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
- BaseProcess* const p = pimpl->mPostProcessingSteps[a];
-
- if (p->IsActive(pp) && p->RequireVerboseFormat()) {
- verbosify = true;
- break;
- }
- }
-
- if (verbosify || (exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
- DefaultLogger::get()->debug("export: Scene data not in verbose format, applying MakeVerboseFormat step first");
-
- MakeVerboseFormatProcess proc;
- proc.Execute(scenecopy.get());
-
- if(!(exp.mEnforcePP & aiProcess_JoinIdenticalVertices)) {
- must_join_again = true;
- }
- }
- }
-
- if (pp) {
- // the three 'conversion' steps need to be executed first because all other steps rely on the standard data layout
- {
- FlipWindingOrderProcess step;
- if (step.IsActive(pp)) {
- step.Execute(scenecopy.get());
- }
- }
-
- {
- FlipUVsProcess step;
- if (step.IsActive(pp)) {
- step.Execute(scenecopy.get());
- }
- }
-
- {
- MakeLeftHandedProcess step;
- if (step.IsActive(pp)) {
- step.Execute(scenecopy.get());
- }
- }
-
- // dispatch other processes
- for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
- BaseProcess* const p = pimpl->mPostProcessingSteps[a];
-
- if (p->IsActive(pp)
- && !dynamic_cast<FlipUVsProcess*>(p)
- && !dynamic_cast<FlipWindingOrderProcess*>(p)
- && !dynamic_cast<MakeLeftHandedProcess*>(p)) {
-
- p->Execute(scenecopy.get());
- }
- }
- ScenePrivateData* const privOut = ScenePriv(scenecopy.get());
- ai_assert(privOut);
-
- privOut->mPPStepsApplied |= pp;
- }
-
- if(must_join_again) {
- JoinVerticesProcess proc;
- proc.Execute(scenecopy.get());
- }
-
- ExportProperties emptyProperties; // Never pass NULL ExportProperties so Exporters don't have to worry.
- exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
- } catch (DeadlyExportError& err) {
- pimpl->mError = err.what();
- return AI_FAILURE;
- }
- return AI_SUCCESS;
- }
- }
-
- pimpl->mError = std::string("Found no exporter to handle this file format: ") + pFormatId;
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
-
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-const char* Exporter::GetErrorString() const {
- return pimpl->mError.c_str();
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void Exporter::FreeBlob() {
- delete pimpl->blob;
- pimpl->blob = NULL;
-
- pimpl->mError = "";
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiExportDataBlob* Exporter::GetBlob() const {
- return pimpl->blob;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiExportDataBlob* Exporter::GetOrphanedBlob() const {
- const aiExportDataBlob* tmp = pimpl->blob;
- pimpl->blob = NULL;
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-size_t Exporter::GetExportFormatCount() const {
- return pimpl->mExporters.size();
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
- if (index >= GetExportFormatCount()) {
- return NULL;
- }
-
- // Return from static storage if the requested index is built-in.
- if (index < sizeof(gExporters) / sizeof(gExporters[0])) {
- return &gExporters[index].mDescription;
- }
-
- return &pimpl->mExporters[index].mDescription;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
- for(const ExportFormatEntry& e : pimpl->mExporters) {
- if (!strcmp(e.mDescription.id,desc.mDescription.id)) {
- return aiReturn_FAILURE;
- }
- }
-
- pimpl->mExporters.push_back(desc);
- return aiReturn_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Exporter::UnregisterExporter(const char* id) {
- for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
- if (!strcmp((*it).mDescription.id,id)) {
- pimpl->mExporters.erase(it);
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-ExportProperties::ExportProperties() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-ExportProperties::ExportProperties(const ExportProperties &other)
-: mIntProperties(other.mIntProperties)
-, mFloatProperties(other.mFloatProperties)
-, mStringProperties(other.mStringProperties)
-, mMatrixProperties(other.mMatrixProperties) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool ExportProperties::SetPropertyInteger(const char* szName, int iValue) {
- return SetGenericProperty<int>(mIntProperties, szName,iValue);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) {
- return SetGenericProperty<ai_real>(mFloatProperties, szName,iValue);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
-{
- return SetGenericProperty<std::string>(mStringProperties, szName,value);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool ExportProperties :: SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
-{
- return SetGenericProperty<aiMatrix4x4>(mMatrixProperties, szName,value);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-int ExportProperties :: GetPropertyInteger(const char* szName,
- int iErrorReturn /*= 0xffffffff*/) const
-{
- return GetGenericProperty<int>(mIntProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-ai_real ExportProperties :: GetPropertyFloat(const char* szName,
- ai_real iErrorReturn /*= 10e10*/) const
-{
- return GetGenericProperty<ai_real>(mFloatProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-const std::string ExportProperties :: GetPropertyString(const char* szName,
- const std::string& iErrorReturn /*= ""*/) const
-{
- return GetGenericProperty<std::string>(mStringProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-const aiMatrix4x4 ExportProperties :: GetPropertyMatrix(const char* szName,
- const aiMatrix4x4& iErrorReturn /*= aiMatrix4x4()*/) const
-{
- return GetGenericProperty<aiMatrix4x4>(mMatrixProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-bool ExportProperties :: HasPropertyInteger(const char* szName) const
-{
- return HasGenericProperty<int>(mIntProperties, szName);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-bool ExportProperties :: HasPropertyBool(const char* szName) const
-{
- return HasGenericProperty<int>(mIntProperties, szName);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-bool ExportProperties :: HasPropertyFloat(const char* szName) const
-{
- return HasGenericProperty<ai_real>(mFloatProperties, szName);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-bool ExportProperties :: HasPropertyString(const char* szName) const
-{
- return HasGenericProperty<std::string>(mStringProperties, szName);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Has a configuration property
-bool ExportProperties :: HasPropertyMatrix(const char* szName) const
-{
- return HasGenericProperty<aiMatrix4x4>(mMatrixProperties, szName);
-}
-
-
-#endif // !ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/FBXAnimation.cpp b/src/3rdparty/assimp/code/FBXAnimation.cpp
deleted file mode 100644
index 6f9613f0d..000000000
--- a/src/3rdparty/assimp/code/FBXAnimation.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXParser.h"
-#include "FBXDocument.h"
-#include "FBXImporter.h"
-#include "FBXDocumentUtil.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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-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);
-
- for(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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-const AnimationCurveMap& AnimationCurveNode::Curves() const
-{
- if ( curves.empty() ) {
- // resolve attached animation curves
- const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
-
- for(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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-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());
-
- for(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());
-
- for(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()
-{
- // empty
-}
-
-} //!FBX
-} //!Assimp
-
-#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
diff --git a/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp b/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp
deleted file mode 100644
index 519f2e176..000000000
--- a/src/3rdparty/assimp/code/FBXBinaryTokenizer.cpp
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXTokenizer.h"
-#include "FBXUtil.h"
-#include <assimp/defs.h>
-#include <stdint.h>
-#include "Exceptional.h"
-#include "ByteSwapper.h"
-
-namespace Assimp {
-namespace FBX {
-
-//enum Flag
-//{
-// e_unknown_0 = 1 << 0,
-// e_unknown_1 = 1 << 1,
-// e_unknown_2 = 1 << 2,
-// e_unknown_3 = 1 << 3,
-// e_unknown_4 = 1 << 4,
-// e_unknown_5 = 1 << 5,
-// e_unknown_6 = 1 << 6,
-// e_unknown_7 = 1 << 7,
-// e_unknown_8 = 1 << 8,
-// e_unknown_9 = 1 << 9,
-// e_unknown_10 = 1 << 10,
-// e_unknown_11 = 1 << 11,
-// e_unknown_12 = 1 << 12,
-// e_unknown_13 = 1 << 13,
-// e_unknown_14 = 1 << 14,
-// e_unknown_15 = 1 << 15,
-// e_unknown_16 = 1 << 16,
-// e_unknown_17 = 1 << 17,
-// e_unknown_18 = 1 << 18,
-// e_unknown_19 = 1 << 19,
-// e_unknown_20 = 1 << 20,
-// e_unknown_21 = 1 << 21,
-// e_unknown_22 = 1 << 22,
-// e_unknown_23 = 1 << 23,
-// e_flag_field_size_64_bit = 1 << 24, // Not sure what is
-// e_unknown_25 = 1 << 25,
-// e_unknown_26 = 1 << 26,
-// e_unknown_27 = 1 << 27,
-// e_unknown_28 = 1 << 28,
-// e_unknown_29 = 1 << 29,
-// e_unknown_30 = 1 << 30,
-// e_unknown_31 = 1 << 31
-//};
-//
-//bool check_flag(uint32_t flags, Flag to_check)
-//{
-// return (flags & to_check) != 0;
-//}
-// ------------------------------------------------------------------------------------------------
-Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
- :
- #ifdef DEBUG
- contents(sbegin, static_cast<size_t>(send-sbegin)),
- #endif
- sbegin(sbegin)
- , send(send)
- , type(type)
- , line(offset)
- , column(BINARY_MARKER)
-{
- 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.
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN 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)
-{
- const size_t k_to_read = sizeof( uint32_t );
- if(Offset(cursor, end) < k_to_read ) {
- TokenizeError("cannot ReadWord, out of bounds",input, cursor);
- }
-
- uint32_t word;
- memcpy(&word, cursor, 4);
- AI_SWAP4(word);
-
- cursor += k_to_read;
-
- return word;
-}
-
-// ------------------------------------------------------------------------------------------------
-uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) {
- const size_t k_to_read = sizeof(uint64_t);
- if(Offset(cursor, end) < k_to_read) {
- TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor);
- }
-
- uint64_t dword = *reinterpret_cast<const uint64_t*>(cursor);
- AI_SWAP8(dword);
-
- cursor += k_to_read;
-
- return dword;
-}
-
-// ------------------------------------------------------------------------------------------------
-uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
-{
- if(Offset(cursor, end) < sizeof( uint8_t ) ) {
- 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 through
-
- // 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, bool const is64bits)
-{
- // the first word contains the offset at which this block ends
- const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : 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 uint64_t prop_count = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
-
- // the third data word contains the length of the property list
- const uint64_t prop_length = is64bits ? ReadDoubleWord(input, cursor, end) : 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 on 32 bit version and 25 bytes long on 64 bit.
- const size_t sentinel_block_length = is64bits ? (sizeof(uint64_t)* 3 + 1) : (sizeof(uint32_t)* 3 + 1);
-
- if (Offset(input, cursor) < end_offset) {
- if (end_offset - Offset(input, cursor) < sentinel_block_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 - sentinel_block_length) {
- ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
- }
- output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
-
- for (unsigned int i = 0; i < sentinel_block_length; ++i) {
- if(cursor[i] != '\0') {
- TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
- }
- }
- cursor += sentinel_block_length;
- }
-
- if (Offset(input, cursor) != end_offset) {
- TokenizeError("scope length not reached, something is wrong",input, cursor);
- }
-
- return true;
-}
-
-}
-
-// ------------------------------------------------------------------------------------------------
-// TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
-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);
- }
-
- const char* cursor = input + 18;
- /*Result ignored*/ ReadByte(input, cursor, input + length);
- /*Result ignored*/ ReadByte(input, cursor, input + length);
- /*Result ignored*/ ReadByte(input, cursor, input + length);
- /*Result ignored*/ ReadByte(input, cursor, input + length);
- /*Result ignored*/ ReadByte(input, cursor, input + length);
- const uint32_t version = ReadWord(input, cursor, input + length);
- const bool is64bits = version >= 7500;
- while (cursor < input + length)
- {
- if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
- break;
- }
- }
-}
-
-} // !FBX
-} // !Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/FBXCompileConfig.h b/src/3rdparty/assimp/code/FBXCompileConfig.h
deleted file mode 100644
index 56aa1c787..000000000
--- a/src/3rdparty/assimp/code/FBXCompileConfig.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
-
-#include <map>
-
-//
-#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 // INCLUDED_AI_FBX_COMPILECONFIG_H
diff --git a/src/3rdparty/assimp/code/FBXConverter.cpp b/src/3rdparty/assimp/code/FBXConverter.cpp
deleted file mode 100644
index 24bdfdd11..000000000
--- a/src/3rdparty/assimp/code/FBXConverter.cpp
+++ /dev/null
@@ -1,3356 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXConverter.h"
-#include "FBXParser.h"
-#include "FBXMeshGeometry.h"
-#include "FBXDocument.h"
-#include "FBXUtil.h"
-#include "FBXProperties.h"
-#include "FBXImporter.h"
-#include "StringComparison.h"
-
-#include <assimp/scene.h>
-
-#include <tuple>
-#include <memory>
-#include <iterator>
-#include <vector>
-
-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 );
- ~Converter();
-
-private:
- // ------------------------------------------------------------------------------------------------
- // find scene root and trigger recursive scene conversion
- void ConvertRootNode();
-
- // ------------------------------------------------------------------------------------------------
- // collect and assign child nodes
- void ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4() );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertLights( const Model& model );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertCameras( const Model& model );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertLight( const Model& model, const Light& light );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertCamera( const Model& model, const Camera& cam );
-
- // ------------------------------------------------------------------------------------------------
- // 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 );
-
- // ------------------------------------------------------------------------------------------------
- // note: this returns the REAL fbx property names
- const char* NameTransformationCompProperty( TransformationComp comp );
-
- // ------------------------------------------------------------------------------------------------
- aiVector3D TransformationCompDefaultValue( TransformationComp comp );
-
- // ------------------------------------------------------------------------------------------------
- void GetRotationMatrix( Model::RotOrder mode, const aiVector3D& rotation, aiMatrix4x4& out );
- // ------------------------------------------------------------------------------------------------
- /**
- * checks if a node has more than just scaling, rotation and translation components
- */
- bool NeedsComplexTransformationChain( const Model& model );
-
- // ------------------------------------------------------------------------------------------------
- // note: name must be a FixNodeName() result
- std::string NameTransformationChainNode( const std::string& name, TransformationComp comp );
-
- // ------------------------------------------------------------------------------------------------
- /**
- * note: memory for output_nodes will be managed by the caller
- */
- void GenerateTransformationNodeChain( const Model& model, std::vector<aiNode*>& output_nodes );
-
- // ------------------------------------------------------------------------------------------------
- void SetupNodeMetadata( const Model& model, aiNode& nd );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertModel( const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform );
-
- // ------------------------------------------------------------------------------------------------
- // 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 );
-
- // ------------------------------------------------------------------------------------------------
- aiMesh* SetupEmptyMesh( const MeshGeometry& mesh );
-
- // ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshSingleMaterial( const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform );
-
- // ------------------------------------------------------------------------------------------------
- std::vector<unsigned int> ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
- const aiMatrix4x4& node_global_transform );
-
- // ------------------------------------------------------------------------------------------------
- unsigned int ConvertMeshMultiMaterial( const MeshGeometry& mesh, const Model& model,
- MatIndexArray::value_type index,
- const aiMatrix4x4& node_global_transform );
-
- // ------------------------------------------------------------------------------------------------
- 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 );
-
- // ------------------------------------------------------------------------------------------------
- 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 );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertMaterialForMesh( aiMesh* out, const Model& model, const MeshGeometry& geo,
- MatIndexArray::value_type materialIndex );
-
- // ------------------------------------------------------------------------------------------------
- unsigned int GetDefaultMaterial();
-
-
- // ------------------------------------------------------------------------------------------------
- // Material -> aiMaterial
- unsigned int ConvertMaterial( const Material& material, const MeshGeometry* const mesh );
-
- // ------------------------------------------------------------------------------------------------
- // Video -> aiTexture
- unsigned int ConvertVideo( const Video& video );
-
- // ------------------------------------------------------------------------------------------------
- void TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh );
-
- // ------------------------------------------------------------------------------------------------
- void TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh );
-
- // ------------------------------------------------------------------------------------------------
- void SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh );
-
- // ------------------------------------------------------------------------------------------------
- void SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh );
-
- // ------------------------------------------------------------------------------------------------
- aiColor3D GetColorPropertyFromMaterial( const PropertyTable& props, const std::string& baseName,
- bool& result );
-
- // ------------------------------------------------------------------------------------------------
- void SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyTable& props );
-
- // ------------------------------------------------------------------------------------------------
- // get the number of fps for a FrameRate enumerated value
- static double FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal = -1.0 );
-
- // ------------------------------------------------------------------------------------------------
- // convert animation data to aiAnimation et al
- void ConvertAnimations();
-
- // ------------------------------------------------------------------------------------------------
- // 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 );
-
- // ------------------------------------------------------------------------------------------------
- // 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 );
-
- 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 );
-
- // ------------------------------------------------------------------------------------------------
- void GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
- const std::string& fixed_name,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time );
-
- // ------------------------------------------------------------------------------------------------
- bool IsRedundantAnimationData( const Model& target,
- TransformationComp comp,
- const std::vector<const AnimationCurveNode*>& curves );
-
- // ------------------------------------------------------------------------------------------------
- aiNodeAnim* GenerateRotationNodeAnim( const std::string& name,
- const Model& target,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time );
-
- // ------------------------------------------------------------------------------------------------
- aiNodeAnim* GenerateScalingNodeAnim( const std::string& name,
- const Model& /*target*/,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time );
-
- // ------------------------------------------------------------------------------------------------
- aiNodeAnim* GenerateTranslationNodeAnim( const std::string& name,
- const Model& /*target*/,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time,
- bool inverse = false );
-
- // ------------------------------------------------------------------------------------------------
- // 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,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time,
- bool reverse_order = false );
-
- // key (time), value, mapto (component index)
- typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
- typedef std::vector<KeyFrameList> KeyFrameListList;
-
- // ------------------------------------------------------------------------------------------------
- KeyFrameListList GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop );
-
- // ------------------------------------------------------------------------------------------------
- KeyTimeList GetKeyTimeList( const KeyFrameListList& inputs );
-
- // ------------------------------------------------------------------------------------------------
- void InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
- const aiVector3D& def_value,
- double& max_time,
- double& min_time );
-
- // ------------------------------------------------------------------------------------------------
- void InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
- const aiVector3D& def_value,
- double& maxTime,
- double& minTime,
- Model::RotOrder order );
-
- // ------------------------------------------------------------------------------------------------
- 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 aiVector3D& def_rotation );
-
- // ------------------------------------------------------------------------------------------------
- // euler xyz -> quat
- aiQuaternion EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- double& maxTime,
- double& minTime );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
- const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- double& maxTime,
- double& minTime );
-
- // ------------------------------------------------------------------------------------------------
- void ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
- const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- double& maxTime,
- double& minTime,
- Model::RotOrder order );
-
- // ------------------------------------------------------------------------------------------------
- // copy generated meshes, animations, lights, cameras and textures to the output scene
- void TransferDataToScene();
-
-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;
- std::vector<aiTexture*> textures;
-
- typedef std::map<const Material*, unsigned int> MaterialMap;
- MaterialMap materials_converted;
-
- typedef std::map<const Video*, unsigned int> VideoMap;
- VideoMap textures_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;
-
- bool FindTextureIndexByFilename(const Video& video, unsigned int& index) {
- index = 0;
- const char* videoFileName = video.FileName().c_str();
- for (auto texture = textures_converted.begin(); texture != textures_converted.end(); ++texture) {
- if (!strcmp(texture->first->FileName().c_str(), videoFileName)) {
- index = texture->second;
- return true;
- }
- }
- return false;
- }
-};
-
-Converter::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
- for( 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, 0 );
- }
- }
- }
- }
-
- 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::~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>() );
- std::for_each( textures.begin(), textures.end(), Util::delete_fun<aiTexture>() );
-}
-
-void Converter::ConvertRootNode()
-{
- out->mRootNode = new aiNode();
- out->mRootNode->mName.Set( "RootNode" );
-
- // root has ID 0
- ConvertNodes( 0L, *out->mRootNode );
-}
-
-
-void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform )
-{
- const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced( id, "Model" );
-
- std::vector<aiNode*> nodes;
- nodes.reserve( conns.size() );
-
- std::vector<aiNode*> nodes_chain;
-
- try {
- for( 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;
- for( 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 ) );
- }
-
- //setup metadata on newest node
- SetupNodeMetadata( *model, *nodes_chain.back() );
-
- // link all nodes in a row
- aiNode* last_parent = &parent;
- for( 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 Converter::ConvertLights( const Model& model )
-{
- const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
- for( const NodeAttribute* attr : node_attrs ) {
- const Light* const light = dynamic_cast<const Light*>( attr );
- if ( light ) {
- ConvertLight( model, *light );
- }
- }
-}
-
-void Converter::ConvertCameras( const Model& model )
-{
- const std::vector<const NodeAttribute*>& node_attrs = model.GetAttributes();
- for( const NodeAttribute* attr : node_attrs ) {
- const Camera* const cam = dynamic_cast<const Camera*>( attr );
- if ( cam ) {
- ConvertCamera( model, *cam );
- }
- }
-}
-
-void Converter::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() / 100.0f;
- 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;
-
- //lights are defined along negative y direction
- out_light->mPosition = aiVector3D(0.0f);
- out_light->mDirection = aiVector3D(0.0f, -1.0f, 0.0f);
- out_light->mUp = aiVector3D(0.0f, 0.0f, -1.0f);
-
- 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 );
- }
-
- float decay = light.DecayStart();
- switch ( light.DecayType() )
- {
- case Light::Decay_None:
- out_light->mAttenuationConstant = decay;
- out_light->mAttenuationLinear = 0.0f;
- out_light->mAttenuationQuadratic = 0.0f;
- break;
- case Light::Decay_Linear:
- out_light->mAttenuationConstant = 0.0f;
- out_light->mAttenuationLinear = 2.0f / decay;
- out_light->mAttenuationQuadratic = 0.0f;
- break;
- case Light::Decay_Quadratic:
- out_light->mAttenuationConstant = 0.0f;
- out_light->mAttenuationLinear = 0.0f;
- out_light->mAttenuationQuadratic = 2.0f / (decay * decay);
- 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 Converter::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();
- //cameras are defined along positive x direction
- out_camera->mPosition = aiVector3D(0.0f);
- out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
- out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
- out_camera->mHorizontalFOV = AI_DEG_TO_RAD( cam.FieldOfView() );
- out_camera->mClipPlaneNear = cam.NearPlane();
- out_camera->mClipPlaneFar = cam.FarPlane();
-}
-
-
-const char* Converter::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
- default:
- break;
- }
-
- ai_assert( false );
- return NULL;
-}
-
-const char* Converter::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 Converter::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 Converter::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 ( std::fabs( rotation.z ) > angle_epsilon ) {
- aiMatrix4x4::RotationZ( AI_DEG_TO_RAD( rotation.z ), temp[ 2 ] );
- is_id[ 2 ] = false;
- }
- if ( std::fabs( rotation.y ) > angle_epsilon ) {
- aiMatrix4x4::RotationY( AI_DEG_TO_RAD( rotation.y ), temp[ 1 ] );
- is_id[ 1 ] = false;
- }
- if ( std::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 ] ];
- }
-}
-
-bool Converter::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;
-}
-
-std::string Converter::NameTransformationChainNode( const std::string& name, TransformationComp comp )
-{
- return name + std::string( MAGIC_NODE_TAG ) + "_" + NameTransformationComp( comp );
-}
-
-void Converter::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 && std::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 && std::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;
- }
-
- if ( comp == TransformationComp_PostRotation ) {
- chain[ i ] = chain[ i ].Inverse();
- }
-
- 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 (const auto &transform : chain) {
- nd->mTransformation = nd->mTransformation * transform;
- }
-}
-
-void Converter::SetupNodeMetadata( const Model& model, aiNode& nd )
-{
- const PropertyTable& props = model.Props();
- DirectPropertyMap unparsedProperties = props.GetUnparsedProperties();
-
- // create metadata on node
- const std::size_t numStaticMetaData = 2;
- aiMetadata* data = aiMetadata::Alloc( static_cast<unsigned int>(unparsedProperties.size() + numStaticMetaData) );
- nd.mMetaData = data;
- int index = 0;
-
- // find user defined properties (3ds Max)
- data->Set( index++, "UserProperties", aiString( PropertyGet<std::string>( props, "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
- for( 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<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >() ) {
- data->Set( index++, prop.first, aiString( interpreted->Value() ) );
- } else if ( const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >() ) {
- data->Set( index++, prop.first, interpreted->Value() );
- } else {
- ai_assert( false );
- }
- }
-}
-
-void Converter::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() );
-
- for( 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 );
- }
-}
-
-std::vector<unsigned int> Converter::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 ];
- for( MatIndexArray::value_type index : mindices ) {
- if ( index != base ) {
- return ConvertMeshMultiMaterial( mesh, model, node_global_transform );
- }
- }
- }
-
- // faster code-path, just copy the data
- temp.push_back( ConvertMeshSingleMaterial( mesh, model, node_global_transform ) );
- return temp;
-}
-
-aiMesh* Converter::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 Converter::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;
- for( 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() );
- ai_assert( 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() ];
- for( 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> Converter::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;
-
- for( 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 Converter::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();
- std::vector<aiVector3D> tempBinormals;
-
- if ( tangents.size() ) {
- 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 );
-}
-
-void Converter::ConvertWeights( aiMesh* out, const Model& model, const MeshGeometry& geo,
- const aiMatrix4x4& node_global_transform ,
- unsigned int materialIndex,
- std::vector<unsigned int>* outputVertStartIndices )
-{
- 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 {
-
- for( 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.
- for( WeightIndexArray::value_type index : indices ) {
-
- unsigned int count = 0;
- const unsigned int* const out_idx = geo.ToOutputVertexIndex( index, count );
- // ToOutputVertexIndex only returns NULL if index is out of bounds
- // which should never happen
- ai_assert( out_idx != NULL );
-
- 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 Converter::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 Converter::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, &geo );
- materials_converted[ mat ] = out->mMaterialIndex;
-}
-
-unsigned int Converter::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;
-}
-
-
-unsigned int Converter::ConvertMaterial( const Material& material, const MeshGeometry* const mesh )
-{
- 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(), mesh );
- SetTextureProperties( out_mat, material.LayeredTextures(), mesh );
-
- return static_cast<unsigned int>( materials.size() - 1 );
-}
-
-unsigned int Converter::ConvertVideo( const Video& video )
-{
- // generate empty output texture
- aiTexture* out_tex = new aiTexture();
- textures.push_back( out_tex );
-
- // assuming the texture is compressed
- out_tex->mWidth = static_cast<unsigned int>( video.ContentLength() ); // total data size
- out_tex->mHeight = 0; // fixed to 0
-
- // steal the data from the Video to avoid an additional copy
- out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>( video ).RelinquishContent() );
-
- // try to extract a hint from the file extension
- const std::string& filename = video.FileName().empty() ? video.RelativeFilename() : video.FileName();
- std::string ext = BaseImporter::GetExtension( filename );
-
- if ( ext == "jpeg" ) {
- ext = "jpg";
- }
-
- if ( ext.size() <= 3 ) {
- memcpy( out_tex->achFormatHint, ext.c_str(), ext.size() );
- }
-
- return static_cast<unsigned int>( textures.size() - 1 );
-}
-
-void Converter::TrySetTextureProperties( aiMaterial* out_mat, const TextureMap& textures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh )
-{
- 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() );
-
- const Video* media = tex->Media();
- if (media != 0) {
- bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
- unsigned int index;
-
- VideoMap::const_iterator it = textures_converted.find(media);
- if (it != textures_converted.end()) {
- index = (*it).second;
- textureReady = true;
- }
- else {
- if (media->ContentLength() > 0) {
- index = ConvertVideo(*media);
- textures_converted[media] = index;
- textureReady = true;
- }
- else if (doc.Settings().searchEmbeddedTextures) { //try to find the texture on the already-loaded textures by the filename, if the flag is on
- textureReady = FindTextureIndexByFilename(*media, index);
- }
- }
-
- // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture), if the texture is ready
- if (textureReady) {
- path.data[0] = '*';
- path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
- }
- }
-
- 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;
- if ( !mesh )
- {
- for( 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" );
- }
- }
- }
- else
- {
- 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" );
- }
-
- if ( uvIndex == -1 ) {
- uvIndex = index;
- }
- }
-
- 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 Converter::TrySetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures,
- const std::string& propName,
- aiTextureType target, const MeshGeometry* const mesh )
-{
- LayeredTextureMap::const_iterator it = layeredTextures.find( propName );
- if ( it == layeredTextures.end() ) {
- return;
- }
-
- int texCount = (*it).second->textureCount();
-
- // Set the blend mode for layered textures
- int blendmode= (*it).second->GetBlendMode();
- out_mat->AddProperty(&blendmode,1,_AI_MATKEY_TEXOP_BASE,target,0);
-
- for(int texIndex = 0; texIndex < texCount; texIndex++){
-
- const Texture* const tex = ( *it ).second->getTexture(texIndex);
-
- aiString path;
- path.Set( tex->RelativeFilename() );
-
- out_mat->AddProperty( &path, _AI_MATKEY_TEXTURE_BASE, target, texIndex );
-
- 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, texIndex );
-
- 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;
- if ( !mesh )
- {
- for( 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" );
- }
- }
- }
- else
- {
- 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" );
- }
-
- if ( uvIndex == -1 ) {
- uvIndex = index;
- }
- }
-
- 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, texIndex );
- }
-}
-
-void Converter::SetTextureProperties( aiMaterial* out_mat, const TextureMap& textures, const MeshGeometry* const mesh )
-{
- TrySetTextureProperties( out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
- TrySetTextureProperties( out_mat, textures, "AmbientColor", aiTextureType_AMBIENT, mesh );
- TrySetTextureProperties( out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE, mesh );
- TrySetTextureProperties( out_mat, textures, "SpecularColor", aiTextureType_SPECULAR, mesh );
- TrySetTextureProperties( out_mat, textures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
- TrySetTextureProperties( out_mat, textures, "TransparentColor", aiTextureType_OPACITY, mesh );
- TrySetTextureProperties( out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
- TrySetTextureProperties( out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
- TrySetTextureProperties( out_mat, textures, "NormalMap", aiTextureType_NORMALS, mesh );
- TrySetTextureProperties( out_mat, textures, "Bump", aiTextureType_HEIGHT, mesh );
- TrySetTextureProperties( out_mat, textures, "ShininessExponent", aiTextureType_SHININESS, mesh );
-}
-
-void Converter::SetTextureProperties( aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh )
-{
- TrySetTextureProperties( out_mat, layeredTextures, "DiffuseColor", aiTextureType_DIFFUSE, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "AmbientColor", aiTextureType_AMBIENT, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "EmissiveColor", aiTextureType_EMISSIVE, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "SpecularColor", aiTextureType_SPECULAR, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "SpecularFactor", aiTextureType_SPECULAR, mesh);
- TrySetTextureProperties( out_mat, layeredTextures, "TransparentColor", aiTextureType_OPACITY, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "ReflectionColor", aiTextureType_REFLECTION, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "DisplacementColor", aiTextureType_DISPLACEMENT, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "NormalMap", aiTextureType_NORMALS, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "Bump", aiTextureType_HEIGHT, mesh );
- TrySetTextureProperties( out_mat, layeredTextures, "ShininessExponent", aiTextureType_SHININESS, mesh );
-}
-
-aiColor3D Converter::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 Converter::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 );
- }
-
- const float BumpFactor = PropertyGet<float>(props, "BumpFactor", ok);
- if (ok) {
- out_mat->AddProperty(&BumpFactor, 1, AI_MATKEY_BUMPSCALING);
- }
-
- const float DispFactor = PropertyGet<float>(props, "DisplacementFactor", ok);
- if (ok) {
- out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0);
- }
-}
-
-
-double Converter::FrameRateToDouble( FileGlobalSettings::FrameRate fp, double customFPSVal )
-{
- 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;
-}
-
-
-void Converter::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();
- for( const AnimationStack* stack : animations ) {
- ConvertAnimationStack( *stack );
- }
-}
-
-void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) {
- if ( node_names.find( fixed_name ) == node_names.end() ) {
- FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
- return;
- }
-
- if ( node_names.find( new_name ) != node_names.end() ) {
- FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
- return;
- }
-
- 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 );
-
- for( aiCamera* cam : cameras ) {
- if ( cam->mName == fn ) {
- cam->mName.Set( new_name );
- break;
- }
- }
-
- for( aiLight* light : lights ) {
- if ( light->mName == fn ) {
- light->mName.Set( new_name );
- break;
- }
- }
-
- for( 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;
- }
- }
- }
-}
-
-
-std::string Converter::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;
-}
-
-void Converter::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 );
- }
- else if ( name.substr( 0, 11 ) == "AnimStack::" ) {
- name = name.substr( 11 );
- }
-
- 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"
- };
-
- for( const AnimationLayer* layer : layers ) {
- ai_assert( layer );
-
- const AnimationCurveNodeList& nodes = layer->Nodes( prop_whitelist, 3 );
- for( 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;
-
- int64_t start_time = st.LocalStart();
- int64_t stop_time = st.LocalStop();
- bool has_local_startstop = start_time != 0 || stop_time != 0;
- if ( !has_local_startstop ) {
- // no time range given, so accept every keyframe and use the actual min/max time
- // the numbers are INT64_MIN/MAX, the 20000 is for safety because GenerateNodeAnimations uses an epsilon of 10000
- start_time = -9223372036854775807ll + 20000;
- stop_time = 9223372036854775807ll - 20000;
- }
-
- try {
- for( const NodeMap::value_type& kv : node_map ) {
- GenerateNodeAnimations( node_anims,
- kv.first,
- kv.second,
- layer_map,
- start_time, stop_time,
- 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;
- }
-
- double start_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(start_time) * anim_fps) : min_time;
- double stop_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(stop_time) * anim_fps) : max_time;
-
- // adjust relative timing for animation
- for ( unsigned int c = 0; c < anim->mNumChannels; c++ ) {
- aiNodeAnim* channel = anim->mChannels[ c ];
- for ( uint32_t i = 0; i < channel->mNumPositionKeys; i++ )
- channel->mPositionKeys[ i ].mTime -= start_time_fps;
- for ( uint32_t i = 0; i < channel->mNumRotationKeys; i++ )
- channel->mRotationKeys[ i ].mTime -= start_time_fps;
- for ( uint32_t i = 0; i < channel->mNumScalingKeys; i++ )
- channel->mScalingKeys[ i ].mTime -= start_time_fps;
- }
-
- // for some mysterious reason, mDuration is simply the maximum key -- the
- // validator always assumes animations to start at zero.
- anim->mDuration = stop_time_fps - start_time_fps;
- anim->mTicksPerSecond = anim_fps;
-}
-
-#ifdef ASSIMP_BUILD_DEBUG
-// ------------------------------------------------------------------------------------------------
-// sanity check whether the input is ok
-static void validateAnimCurveNodes( const std::vector<const AnimationCurveNode*>& curves,
- bool strictMode ) {
- const Object* target( NULL );
- for( const AnimationCurveNode* node : curves ) {
- if ( !target ) {
- target = node->Target();
- }
- if ( node->Target() != target ) {
- FBXImporter::LogWarn( "Node target is nullptr type." );
- }
- if ( strictMode ) {
- ai_assert( node->Target() == target );
- }
- }
-}
-#endif // ASSIMP_BUILD_DEBUG
-
-// ------------------------------------------------------------------------------------------------
-void Converter::GenerateNodeAnimations( std::vector<aiNodeAnim*>& node_anims,
- const std::string& fixed_name,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time )
-{
-
- NodeMap node_property_map;
- ai_assert( curves.size() );
-
-#ifdef ASSIMP_BUILD_DEBUG
- validateAnimCurveNodes( curves, doc.Settings().strictMode );
-#endif
- const AnimationCurveNode* curve_node = NULL;
- for( 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,
- start, stop,
- max_time,
- min_time,
- true // input is TRS order, assimp is SRT
- );
-
- ai_assert( nd );
- if ( nd->mNumPositionKeys == 0 && nd->mNumRotationKeys == 0 && nd->mNumScalingKeys == 0 ) {
- delete nd;
- }
- else {
- 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 = nullptr;
- switch ( comp )
- {
- case TransformationComp_Rotation:
- case TransformationComp_PreRotation:
- case TransformationComp_PostRotation:
- case TransformationComp_GeometricRotation:
- na = GenerateRotationNodeAnim( chain_name,
- target,
- ( *chain[ i ] ).second,
- layer_map,
- start, stop,
- 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,
- start, stop,
- 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,
- start, stop,
- max_time,
- min_time,
- true );
-
- ai_assert( inv );
- if ( inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0 ) {
- delete inv;
- }
- else {
- 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,
- start, stop,
- max_time,
- min_time,
- true );
-
- ai_assert( inv );
- if ( inv->mNumPositionKeys == 0 && inv->mNumRotationKeys == 0 && inv->mNumScalingKeys == 0 ) {
- delete inv;
- }
- else {
- 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,
- start, stop,
- max_time,
- min_time );
-
- break;
-
- default:
- ai_assert( false );
- }
-
- ai_assert( na );
- if ( na->mNumPositionKeys == 0 && na->mNumRotationKeys == 0 && na->mNumScalingKeys == 0 ) {
- delete na;
- }
- else {
- node_anims.push_back( na );
- }
- continue;
- }
- }
-
- node_anim_chain_bits[ fixed_name ] = flags;
-}
-
-bool Converter::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* Converter::GenerateRotationNodeAnim( const std::string& name,
- const Model& target,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time )
-{
- std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
- na->mNodeName.Set( name );
-
- ConvertRotationKeys( na.get(), curves, layer_map, start, stop, 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.release();
-}
-
-aiNodeAnim* Converter::GenerateScalingNodeAnim( const std::string& name,
- const Model& /*target*/,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time )
-{
- std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
- na->mNodeName.Set( name );
-
- ConvertScaleKeys( na.get(), curves, layer_map, start, stop, 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.release();
-}
-
-
-aiNodeAnim* Converter::GenerateTranslationNodeAnim( const std::string& name,
- const Model& /*target*/,
- const std::vector<const AnimationCurveNode*>& curves,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time,
- bool inverse )
-{
- std::unique_ptr<aiNodeAnim> na( new aiNodeAnim() );
- na->mNodeName.Set( name );
-
- ConvertTranslationKeys( na.get(), curves, layer_map, start, stop, 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.release();
-}
-
-aiNodeAnim* Converter::GenerateSimpleNodeAnim( const std::string& name,
- const Model& target,
- NodeMap::const_iterator chain[ TransformationComp_MAXIMUM ],
- NodeMap::const_iterator iter_end,
- const LayerMap& layer_map,
- int64_t start, int64_t stop,
- double& max_time,
- double& min_time,
- bool reverse_order )
-
-{
- std::unique_ptr<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 = PropertyGet( props, "Lcl Scaling", aiVector3D( 1.f, 1.f, 1.f ) );
- aiVector3D def_translate = PropertyGet( props, "Lcl Translation", aiVector3D( 0.f, 0.f, 0.f ) );
- aiVector3D def_rot = PropertyGet( props, "Lcl Rotation", aiVector3D( 0.f, 0.f, 0.f ) );
-
- KeyFrameListList scaling;
- KeyFrameListList translation;
- KeyFrameListList rotation;
-
- if ( chain[ TransformationComp_Scaling ] != iter_end ) {
- scaling = GetKeyframeList( ( *chain[ TransformationComp_Scaling ] ).second, start, stop );
- }
-
- if ( chain[ TransformationComp_Translation ] != iter_end ) {
- translation = GetKeyframeList( ( *chain[ TransformationComp_Translation ] ).second, start, stop );
- }
-
- if ( chain[ TransformationComp_Rotation ] != iter_end ) {
- rotation = GetKeyframeList( ( *chain[ TransformationComp_Rotation ] ).second, start, stop );
- }
-
- 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() ];
-
- if ( 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.get(), ( *chain[ TransformationComp_Scaling ] ).second,
- layer_map,
- start, stop,
- 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.get(), ( *chain[ TransformationComp_Rotation ] ).second,
- layer_map,
- start, stop,
- 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.get(), ( *chain[ TransformationComp_Translation ] ).second,
- layer_map,
- start, stop,
- 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.release();
-}
-
-Converter::KeyFrameListList Converter::GetKeyframeList( const std::vector<const AnimationCurveNode*>& nodes, int64_t start, int64_t stop )
-{
- KeyFrameListList inputs;
- inputs.reserve( nodes.size() * 3 );
-
- //give some breathing room for rounding errors
- int64_t adj_start = start - 10000;
- int64_t adj_stop = stop + 10000;
-
- for( const AnimationCurveNode* node : nodes ) {
- ai_assert( node );
-
- const AnimationCurveMap& curves = node->Curves();
- for( 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() );
-
- //get values within the start/stop time window
- std::shared_ptr<KeyTimeList> Keys( new KeyTimeList() );
- std::shared_ptr<KeyValueList> Values( new KeyValueList() );
- const size_t count = curve->GetKeys().size();
- Keys->reserve( count );
- Values->reserve( count );
- for (size_t n = 0; n < count; n++ )
- {
- int64_t k = curve->GetKeys().at( n );
- if ( k >= adj_start && k <= adj_stop )
- {
- Keys->push_back( k );
- Values->push_back( curve->GetValues().at( n ) );
- }
- }
-
- inputs.push_back( std::make_tuple( Keys, Values, mapto ) );
- }
- }
- return inputs; // pray for NRVO :-)
-}
-
-
-KeyTimeList Converter::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;
- for( const KeyFrameList& kfl : inputs ) {
- estimate = std::max( estimate, std::get<0>(kfl)->size() );
- }
-
- keys.reserve( estimate );
-
- std::vector<unsigned int> next_pos;
- next_pos.resize( inputs.size(), 0 );
-
- const size_t count = inputs.size();
- while ( true ) {
-
- int64_t min_tick = std::numeric_limits<int64_t>::max();
- for ( size_t i = 0; i < count; ++i ) {
- const KeyFrameList& kfl = inputs[ i ];
-
- if ( std::get<0>(kfl)->size() > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) < min_tick ) {
- min_tick = std::get<0>(kfl)->at( next_pos[ i ] );
- }
- }
-
- if ( min_tick == std::numeric_limits<int64_t>::max() ) {
- break;
- }
- keys.push_back( min_tick );
-
- for ( size_t i = 0; i < count; ++i ) {
- const KeyFrameList& kfl = inputs[ i ];
-
-
- while ( std::get<0>(kfl)->size() > next_pos[ i ] && std::get<0>(kfl)->at( next_pos[ i ] ) == min_tick ) {
- ++next_pos[ i ];
- }
- }
- }
-
- return keys;
-}
-
-void Converter::InterpolateKeys( aiVectorKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
- const aiVector3D& def_value,
- 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 );
-
- for( KeyTimeList::value_type time : keys ) {
- ai_real result[ 3 ] = { def_value.x, def_value.y, def_value.z };
-
- for ( size_t i = 0; i < count; ++i ) {
- const KeyFrameList& kfl = inputs[ i ];
-
- const size_t ksize = std::get<0>(kfl)->size();
- if ( ksize > next_pos[ i ] && std::get<0>(kfl)->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 = std::get<1>(kfl)->at( id0 );
- const KeyValueList::value_type valueB = std::get<1>(kfl)->at( id1 );
-
- const KeyTimeList::value_type timeA = std::get<0>(kfl)->at( id0 );
- const KeyTimeList::value_type timeB = std::get<0>(kfl)->at( id1 );
-
- const ai_real factor = timeB == timeA ? ai_real(0.) : static_cast<ai_real>( ( time - timeA ) ) / ( timeB - timeA );
- const ai_real interpValue = static_cast<ai_real>( valueA + ( valueB - valueA ) * factor );
-
- result[ std::get<2>(kfl) ] = 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 Converter::InterpolateKeys( aiQuatKey* valOut, const KeyTimeList& keys, const KeyFrameListList& inputs,
- const aiVector3D& def_value,
- double& maxTime,
- double& minTime,
- Model::RotOrder order )
-{
- ai_assert( keys.size() );
- ai_assert( valOut );
-
- std::unique_ptr<aiVectorKey[]> temp( new aiVectorKey[ keys.size() ] );
- InterpolateKeys( temp.get(), keys, inputs, def_value, 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 Converter::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 aiVector3D& def_rotation )
-{
- if ( rotation.size() ) {
- InterpolateKeys( out_quat, times, rotation, def_rotation, 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 = EulerToQuaternion( def_rotation, order );
- }
- }
-
- if ( scaling.size() ) {
- InterpolateKeys( out_scale, times, scaling, def_scale, 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, def_translate, 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 );
- }
-}
-
-aiQuaternion Converter::EulerToQuaternion( const aiVector3D& rot, Model::RotOrder order )
-{
- aiMatrix4x4 m;
- GetRotationMatrix( order, rot, m );
-
- return aiQuaternion( aiMatrix3x3( m ) );
-}
-
-void Converter::ConvertScaleKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes, const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- 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, start, stop );
- const KeyTimeList& keys = GetKeyTimeList( inputs );
-
- na->mNumScalingKeys = static_cast<unsigned int>( keys.size() );
- na->mScalingKeys = new aiVectorKey[ keys.size() ];
- if ( keys.size() > 0 )
- InterpolateKeys( na->mScalingKeys, keys, inputs, aiVector3D( 1.0f, 1.0f, 1.0f ), maxTime, minTime );
-}
-
-void Converter::ConvertTranslationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
- const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- double& maxTime,
- double& minTime )
-{
- ai_assert( nodes.size() );
-
- // XXX see notes in ConvertScaleKeys()
- const KeyFrameListList& inputs = GetKeyframeList( nodes, start, stop );
- const KeyTimeList& keys = GetKeyTimeList( inputs );
-
- na->mNumPositionKeys = static_cast<unsigned int>( keys.size() );
- na->mPositionKeys = new aiVectorKey[ keys.size() ];
- if ( keys.size() > 0 )
- InterpolateKeys( na->mPositionKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime );
-}
-
-void Converter::ConvertRotationKeys( aiNodeAnim* na, const std::vector<const AnimationCurveNode*>& nodes,
- const LayerMap& /*layers*/,
- int64_t start, int64_t stop,
- double& maxTime,
- double& minTime,
- Model::RotOrder order )
-{
- ai_assert( nodes.size() );
-
- // XXX see notes in ConvertScaleKeys()
- const std::vector< KeyFrameList >& inputs = GetKeyframeList( nodes, start, stop );
- const KeyTimeList& keys = GetKeyTimeList( inputs );
-
- na->mNumRotationKeys = static_cast<unsigned int>( keys.size() );
- na->mRotationKeys = new aiQuatKey[ keys.size() ];
- if ( keys.size() > 0 )
- InterpolateKeys( na->mRotationKeys, keys, inputs, aiVector3D( 0.0f, 0.0f, 0.0f ), maxTime, minTime, order );
-}
-
-void Converter::TransferDataToScene()
-{
- ai_assert( !out->mMeshes );
- ai_assert( !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 );
- }
-
- if ( textures.size() ) {
- out->mTextures = new aiTexture*[ textures.size() ]();
- out->mNumTextures = static_cast<unsigned int>( textures.size() );
-
- std::swap_ranges( textures.begin(), textures.end(), out->mTextures );
- }
-}
-
-//} // !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
deleted file mode 100644
index 8a62d8811..000000000
--- a/src/3rdparty/assimp/code/FBXConverter.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
-
-struct aiScene;
-
-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 // INCLUDED_AI_FBX_CONVERTER_H
diff --git a/src/3rdparty/assimp/code/FBXDeformer.cpp b/src/3rdparty/assimp/code/FBXDeformer.cpp
deleted file mode 100644
index 637144ab1..000000000
--- a/src/3rdparty/assimp/code/FBXDeformer.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXParser.h"
-#include "FBXDocument.h"
-#include "FBXImporter.h"
-#include "FBXDocumentUtil.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");
- for(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)
-, accuracy( 0.0f ) {
- 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());
- for(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
deleted file mode 100644
index 9592bf31f..000000000
--- a/src/3rdparty/assimp/code/FBXDocument.cpp
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXDocument.h"
-#include "FBXMeshGeometry.h"
-#include "FBXParser.h"
-#include "FBXUtil.h"
-#include "FBXImporter.h"
-#include "FBXImportSettings.h"
-#include "FBXDocumentUtil.h"
-#include "FBXProperties.h"
-
-#include <memory>
-#include <functional>
-#include <map>
-
-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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-LazyObject::~LazyObject()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-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());
-
- // For debugging
- //dumpObjectClassInfo( objtype, classtag );
-
- 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,"Video",length)) {
- object.reset(new Video(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)
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Object::~Object()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
-: props(props)
-, doc(doc)
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-FileGlobalSettings::~FileGlobalSettings()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Document::Document(const Parser& parser, const ImportSettings& settings)
-: settings(settings)
-, parser(parser)
-{
- // Cannot use array default initialization syntax because vc8 fails on it
- for (auto &timeStamp : creationTimeStamp) {
- timeStamp = 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()
-{
- for(ObjectMap::value_type& v : objects) {
- delete v.second;
- }
-
- for(ConnectionMap::value_type& v : src_connections) {
- delete v.second;
- }
- // |dest_connections| contain the same Connection objects as the |src_connections|
-}
-
-// ------------------------------------------------------------------------------------------------
-static const unsigned int LowerSupportedVersion = 7100;
-static const unsigned int UpperSupportedVersion = 7400;
-
-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 may have some success with newer files, we don't support
- // the older 6.n fbx format
- if(fbxVersion < LowerSupportedVersion ) {
- DOMError("unsupported, old format version, supported are only FBX 2011, FBX 2012 and FBX 2013");
- }
- if(fbxVersion > UpperSupportedVersion ) {
- 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, std::make_shared<const PropertyTable>()));
- return;
- }
-
- std::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();
- for(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) {
- std::shared_ptr<const PropertyTable> props = std::make_shared<const PropertyTable>(
- *Properties70,std::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));
-
- // PP = property-property connection, ignored for now
- // (tokens: "PP", ID1, "Property1", ID2, "Property2")
- if ( type == "PP" ) {
- continue;
- }
-
- 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.empty()) {
- return animationStacksResolved;
- }
-
- animationStacksResolved.reserve(animationStacks.size());
- for(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_fn(&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 );
- ai_assert( 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_fn(&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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-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
deleted file mode 100644
index a4e28b2aa..000000000
--- a/src/3rdparty/assimp/code/FBXDocument.h
+++ /dev/null
@@ -1,1167 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 <numeric>
-#include <stdint.h>
-#include <assimp/mesh.h>
-#include "FBXProperties.h"
-#include "FBXParser.h"
-
-#define _AI_CONCAT(a,b) a ## b
-#define AI_CONCAT(a,b) _AI_CONCAT(a,b)
-
-namespace Assimp {
-namespace FBX {
-
-class Parser;
-class Object;
-struct ImportSettings;
-
-class PropertyTable;
-class Document;
-class Material;
-class Geometry;
-
-class Video;
-
-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;
- std::unique_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();
-
- 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);
- virtual ~NodeAttribute();
-
- const PropertyTable& Props() const {
- ai_assert(props.get());
- return *props.get();
- }
-
-private:
- std::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);
- virtual ~CameraSwitcher();
-
- 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);
- virtual ~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(NearPlane, float, 0.1f)
- fbx_simple_property(FarPlane, float, 100.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)
-};
-
-
-/** 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);
- virtual ~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);
- virtual ~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);
- virtual ~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, 100.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, 2)
- fbx_simple_property(DecayStart, float, 1.0f)
- 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)
-};
-
-
-/** DOM base class for FBX models (even though its semantics are more "node" than "model" */
-class Model : public Object
-{
-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
- };
-
- Model(uint64_t id, const Element& element, const Document& doc, const std::string& name);
-
- virtual ~Model();
-
- 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)
-
- 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;
- }
-
- /** 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;
- std::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);
- virtual ~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;
- }
-
- const Video* Media() const {
- return media;
- }
-
-private:
- aiVector2D uvTrans;
- aiVector2D uvScaling;
-
- std::string type;
- std::string relativeFileName;
- std::string fileName;
- std::string alphaSource;
- std::shared_ptr<const PropertyTable> props;
-
- unsigned int crop[4];
-
- const Video* media;
-};
-
-/** 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);
- virtual ~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(int index=0) const
- {
- return textures[index];
-
- }
- int textureCount() const {
- return static_cast<int>(textures.size());
- }
- BlendMode GetBlendMode() const
- {
- return blendMode;
- }
- float Alpha()
- {
- return alpha;
- }
-private:
- std::vector<const Texture*> textures;
- 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 videos */
-class Video : public Object
-{
-public:
- Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
- virtual ~Video();
-
-public:
- const std::string& Type() const {
- return type;
- }
-
- const std::string& FileName() const {
- return fileName;
- }
-
- const std::string& RelativeFilename() const {
- return relativeFileName;
- }
-
- const PropertyTable& Props() const {
- ai_assert(props.get());
- return *props.get();
- }
-
- const uint8_t* Content() const {
- ai_assert(content);
- return content;
- }
-
- uint32_t ContentLength() const {
- return contentLength;
- }
-
- uint8_t* RelinquishContent() {
- uint8_t* ptr = content;
- content = 0;
- return ptr;
- }
-
-private:
- std::string type;
- std::string relativeFileName;
- std::string fileName;
- std::shared_ptr<const PropertyTable> props;
-
- uint32_t contentLength;
- uint8_t* content;
-};
-
-/** 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);
- virtual ~Material();
-
- 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;
- std::shared_ptr<const PropertyTable> props;
-
- TextureMap textures;
- LayeredTextureMap layeredTextures;
-};
-
-typedef std::vector<int64_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);
- virtual ~AnimationCurve();
-
- /** 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 white list 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);
-
- virtual ~AnimationCurveNode();
-
- 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;
- std::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);
- virtual ~AnimationLayer();
-
- const PropertyTable& Props() const {
- ai_assert(props.get());
- return *props.get();
- }
-
- /* the optional white list 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:
- std::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);
- virtual ~AnimationStack();
-
- fbx_simple_property(LocalStart, int64_t, 0L)
- fbx_simple_property(LocalStop, int64_t, 0L)
- fbx_simple_property(ReferenceStart, int64_t, 0L)
- fbx_simple_property(ReferenceStop, int64_t, 0L)
-
- const PropertyTable& Props() const {
- ai_assert(props.get());
- return *props.get();
- }
-
- const AnimationLayerList& Layers() const {
- return layers;
- }
-
-private:
- std::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);
- virtual ~Deformer();
-
- const PropertyTable& Props() const {
- ai_assert(props.get());
- return *props.get();
- }
-
-private:
- std::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);
- virtual ~Cluster();
-
- /** 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* 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);
- virtual ~Skin();
-
- 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 {
- ai_assert( NULL != c );
-
- // 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 {
- ai_assert( NULL != c );
-
- 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, std::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, std::shared_ptr<const PropertyTable> props);
- ~FileGlobalSettings();
-
- 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:
- std::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();
-
- 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): Year, 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;
- 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;
-
- std::unique_ptr<FileGlobalSettings> globals;
-};
-
-} // Namespace FBX
-} // Namespace Assimp
-
-#endif // INCLUDED_AI_FBX_DOCUMENT_H
diff --git a/src/3rdparty/assimp/code/FBXDocumentUtil.cpp b/src/3rdparty/assimp/code/FBXDocumentUtil.cpp
deleted file mode 100644
index 27921b920..000000000
--- a/src/3rdparty/assimp/code/FBXDocumentUtil.cpp
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#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
-std::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"];
- std::shared_ptr<const PropertyTable> templateProps = std::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 std::make_shared<const PropertyTable>();
- }
- }
- return std::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
deleted file mode 100644
index 98fae75ca..000000000
--- a/src/3rdparty/assimp/code/FBXDocumentUtil.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-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
-
-#include "../include/assimp/defs.h"
-#include <string>
-#include <memory>
-#include "FBXDocument.h"
-
-struct Token;
-struct Element;
-
-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
-std::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
deleted file mode 100644
index 53fa64ec6..000000000
--- a/src/3rdparty/assimp/code/FBXImportSettings.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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(false)
- , readMaterials(true)
- , readTextures(true)
- , readCameras(true)
- , readLights(true)
- , readAnimations(true)
- , readWeights(true)
- , preservePivots(true)
- , optimizeEmptyAnimationCurves(true)
- , searchEmbeddedTextures(false)
- {}
-
-
- /** 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 embedded textures? Default value is true.*/
- bool readTextures;
-
- /** 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;
-
- /** search for embedded loaded textures, where no embedded texture data is provided.
- * The default value is false. */
- bool searchEmbeddedTextures;
-};
-
-
-} // !FBX
-} // !Assimp
-
-#endif
-
diff --git a/src/3rdparty/assimp/code/FBXImporter.cpp b/src/3rdparty/assimp/code/FBXImporter.cpp
deleted file mode 100644
index 51e41b8f4..000000000
--- a/src/3rdparty/assimp/code/FBXImporter.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-r
-* 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.
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXImporter.h"
-
-#include "FBXTokenizer.h"
-#include "FBXParser.h"
-#include "FBXUtil.h"
-#include "FBXDocument.h"
-#include "FBXConverter.h"
-
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-
-namespace Assimp {
- template<> const char* LogFunctions<FBXImporter>::Prefix()
- {
- static auto prefix = "FBX: ";
- return prefix;
- }
-}
-
-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 == std::string( desc.mFileExtensions ) ) {
- 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.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, 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);
- settings.searchEmbeddedTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES, false);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void FBXImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_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()+1);
- stream->Read( &*contents.begin(), 1, contents.size()-1 );
- contents[ contents.size() - 1 ] = 0;
- 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,static_cast<unsigned int>(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);
-
- std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
- }
- 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
deleted file mode 100644
index 43be97ffa..000000000
--- a/src/3rdparty/assimp/code/FBXImporter.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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();
- virtual ~FBXImporter();
-
- // --------------------
- 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:
- 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
deleted file mode 100644
index a80f243ba..000000000
--- a/src/3rdparty/assimp/code/FBXMaterial.cpp
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXParser.h"
-#include "FBXDocument.h"
-#include "FBXImporter.h"
-#include "FBXImportSettings.h"
-#include "FBXDocumentUtil.h"
-#include "FBXProperties.h"
-#include "ByteSwapper.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());
- for(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)
-, media(0)
-{
- 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);
-
- // resolve video links
- if(doc.Settings().readTextures) {
- const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
- for(const Connection* con : conns) {
- const Object* const ob = con->SourceObject();
- if(!ob) {
- DOMWarning("failed to read source object for texture link, ignoring",&element);
- continue;
- }
-
- const Video* const video = dynamic_cast<const Video*>(ob);
- if(video) {
- media = video;
- }
- }
- }
-}
-
-
-Texture::~Texture()
-{
-
-}
-
-LayeredTexture::LayeredTexture(uint64_t id, const Element& element, const Document& /*doc*/, const std::string& name)
-: Object(id,element,name)
-,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);
-
- textures.push_back(tex);
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: Object(id,element,name)
-, contentLength(0)
-, content(0)
-{
- const Scope& sc = GetRequiredScope(element);
-
- const Element* const Type = sc["Type"];
- const Element* const FileName = sc.FindElementCaseInsensitive("FileName"); //some files retain the information as "Filename", others "FileName", who knows
- const Element* const RelativeFilename = sc["RelativeFilename"];
- const Element* const Content = sc["Content"];
-
- if(Type) {
- type = ParseTokenAsString(GetRequiredToken(*Type,0));
- }
-
- if(FileName) {
- fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
- }
-
- if(RelativeFilename) {
- relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
- }
-
- if(Content) {
- //this field is ommited when the embedded texture is already loaded, let's ignore if it´s not found
- try {
- const Token& token = GetRequiredToken(*Content, 0);
- const char* data = token.begin();
- if (!token.IsBinary()) {
- DOMWarning("video content is not binary data, ignoring", &element);
- }
- else if (static_cast<size_t>(token.end() - data) < 5) {
- DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
- }
- else if (*data != 'R') {
- DOMWarning("video content is not raw binary data, ignoring", &element);
- }
- else {
- // read number of elements
- uint32_t len = 0;
- ::memcpy(&len, data + 1, sizeof(len));
- AI_SWAP4(len);
-
- contentLength = len;
-
- content = new uint8_t[len];
- ::memcpy(content, data + 5, len);
- }
- } catch (runtime_error runtimeError) {
- //we don´t need the content data for contents that has already been loaded
- }
- }
-
- props = GetPropertyTable(doc,"Video.FbxVideo",element,sc);
-}
-
-
-Video::~Video()
-{
- if(content) {
- delete[] content;
- }
-}
-
-} //!FBX
-} //!Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/FBXMeshGeometry.cpp b/src/3rdparty/assimp/code/FBXMeshGeometry.cpp
deleted file mode 100644
index 8d43a2436..000000000
--- a/src/3rdparty/assimp/code/FBXMeshGeometry.cpp
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include <functional>
-
-#include "FBXMeshGeometry.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");
- for(const Connection* con : conns) {
- const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
- if(sk) {
- skin = sk;
- break;
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-Geometry::~Geometry()
-{
-
-}
-
-const Skin* Geometry::DeformerSkin() const {
- return skin;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-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;
- }
-
- m_vertices.reserve(tempFaces.size());
- m_faces.reserve(tempFaces.size() / 3);
-
- m_mapping_offsets.resize(tempVerts.size());
- m_mapping_counts.resize(tempVerts.size(),0);
- m_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;
- for(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);
- }
-
- m_vertices.push_back(tempVerts[absi]);
- ++count;
-
- ++m_mapping_counts[absi];
-
- if (index < 0) {
- m_faces.push_back(count);
- count = 0;
- }
- }
-
- unsigned int cursor = 0;
- for (size_t i = 0, e = tempVerts.size(); i < e; ++i) {
- m_mapping_offsets[i] = cursor;
- cursor += m_mapping_counts[i];
-
- m_mapping_counts[i] = 0;
- }
-
- cursor = 0;
- for(int index : tempFaces) {
- const int absi = index < 0 ? (-index - 1) : index;
- m_mappings[m_mapping_offsets[absi] + m_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()
-{
-
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
- return m_vertices;
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<aiVector3D>& MeshGeometry::GetNormals() const {
- return m_normals;
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<aiVector3D>& MeshGeometry::GetTangents() const {
- return m_tangents;
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<aiVector3D>& MeshGeometry::GetBinormals() const {
- return m_binormals;
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<unsigned int>& MeshGeometry::GetFaceIndexCounts() const {
- return m_faces;
-}
-
-// ------------------------------------------------------------------------------------------------
-const std::vector<aiVector2D>& MeshGeometry::GetTextureCoords( unsigned int index ) const {
- static const std::vector<aiVector2D> empty;
- return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : m_uvs[ index ];
-}
-
-std::string MeshGeometry::GetTextureCoordChannelName( unsigned int index ) const {
- return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : m_uvNames[ index ];
-}
-
-const std::vector<aiColor4D>& MeshGeometry::GetVertexColors( unsigned int index ) const {
- static const std::vector<aiColor4D> empty;
- return index >= AI_MAX_NUMBER_OF_COLOR_SETS ? empty : m_colors[ index ];
-}
-
-const MatIndexArray& MeshGeometry::GetMaterialIndices() const {
- return m_materials;
-}
-
-// ------------------------------------------------------------------------------------------------
-const unsigned int* MeshGeometry::ToOutputVertexIndex( unsigned int in_index, unsigned int& count ) const {
- if ( in_index >= m_mapping_counts.size() ) {
- return NULL;
- }
-
- ai_assert( m_mapping_counts.size() == m_mapping_offsets.size() );
- count = m_mapping_counts[ in_index ];
-
- ai_assert( m_mapping_offsets[ in_index ] + count <= m_mappings.size() );
-
- return &m_mappings[ m_mapping_offsets[ in_index ] ];
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int MeshGeometry::FaceForVertexIndex( unsigned int in_index ) const {
- ai_assert( in_index < m_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 ( m_facesVertexStartIndices.empty() ) {
- m_facesVertexStartIndices.resize( m_faces.size() + 1, 0 );
-
- std::partial_sum( m_faces.begin(), m_faces.end(), m_facesVertexStartIndices.begin() + 1 );
- m_facesVertexStartIndices.pop_back();
- }
-
- ai_assert( m_facesVertexStartIndices.size() == m_faces.size() );
- const std::vector<unsigned int>::iterator it = std::upper_bound(
- m_facesVertexStartIndices.begin(),
- m_facesVertexStartIndices.end(),
- in_index
- );
-
- return static_cast< unsigned int >( std::distance( m_facesVertexStartIndices.begin(), it - 1 ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-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"];
- m_uvNames[index] = "";
- if(Name) {
- m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
- }
-
- ReadVertexDataUV(m_uvs[index],source,
- MappingInformationType,
- ReferenceInformationType
- );
- }
- else if (type == "LayerElementMaterial") {
- if (m_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 losing 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(),[](int n) { return n < 0; });
- if(count_neg == temp_materials.size()) {
- FBXImporter::LogWarn("ignoring dummy material layer (all entries -1)");
- return;
- }
-
- std::swap(temp_materials, m_materials);
- }
- else if (type == "LayerElementNormal") {
- if (m_normals.size() > 0) {
- FBXImporter::LogError("ignoring additional normal layer");
- return;
- }
-
- ReadVertexDataNormals(m_normals,source,
- MappingInformationType,
- ReferenceInformationType
- );
- }
- else if (type == "LayerElementTangent") {
- if (m_tangents.size() > 0) {
- FBXImporter::LogError("ignoring additional tangent layer");
- return;
- }
-
- ReadVertexDataTangents(m_tangents,source,
- MappingInformationType,
- ReferenceInformationType
- );
- }
- else if (type == "LayerElementBinormal") {
- if (m_binormals.size() > 0) {
- FBXImporter::LogError("ignoring additional binormal layer");
- return;
- }
-
- ReadVertexDataBinormals(m_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(m_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)
-{
-
-
- // 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") {
- std::vector<T> tempData;
- ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
-
- data_out.resize(vertex_count);
- for (size_t i = 0, e = tempData.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]] = tempData[i];
- }
- }
- }
- else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") {
- std::vector<T> tempData;
- ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
-
- 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]) >= tempData.size()) {
- DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
- }
- data_out[mappings[j]] = tempData[uvIndices[i]];
- }
- }
- }
- else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {
- std::vector<T> tempData;
- ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
-
- if (tempData.size() != vertex_count) {
- FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
- << tempData.size() << ", expected " << vertex_count
- );
- return;
- }
-
- data_out.swap(tempData);
- }
- else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") {
- std::vector<T> tempData;
- ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
-
- 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;
- for(int i : uvIndices) {
- if (static_cast<size_t>(i) >= tempData.size()) {
- DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
- }
-
- data_out[next++] = tempData[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",
- m_vertices.size(),
- m_mapping_counts,
- m_mapping_offsets,
- m_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",
- m_vertices.size(),
- m_mapping_counts,
- m_mapping_offsets,
- m_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",
- m_vertices.size(),
- m_mapping_counts,
- m_mapping_offsets,
- m_mappings);
-}
-
-// ------------------------------------------------------------------------------------------------
-static const std::string TangentIndexToken = "TangentIndex";
-static const std::string TangentsIndexToken = "TangentsIndex";
-
-void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
- const std::string& MappingInformationType,
- const std::string& ReferenceInformationType)
-{
- const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
- const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
- ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
- str,
- strIdx,
- m_vertices.size(),
- m_mapping_counts,
- m_mapping_offsets,
- m_mappings);
-}
-
-// ------------------------------------------------------------------------------------------------
-static const std::string BinormalIndexToken = "BinormalIndex";
-static const std::string BinormalsIndexToken = "BinormalsIndex";
-
-void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
- const std::string& MappingInformationType,
- const std::string& ReferenceInformationType)
-{
- const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
- const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
- ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
- str,
- strIdx,
- m_vertices.size(),
- m_mapping_counts,
- m_mapping_offsets,
- m_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 = m_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();
- }
-
- m_materials.assign(m_vertices.size(),materials_out[0]);
- }
- else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
- m_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/FBXMeshGeometry.h b/src/3rdparty/assimp/code/FBXMeshGeometry.h
deleted file mode 100644
index 19f7b0a9c..000000000
--- a/src/3rdparty/assimp/code/FBXMeshGeometry.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_MESHGEOMETRY_H
-#define INCLUDED_AI_FBX_MESHGEOMETRY_H
-
-#include "FBXParser.h"
-#include "FBXDocument.h"
-
-namespace Assimp {
-namespace FBX {
-
-/**
- * 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 );
- virtual ~Geometry();
-
- /** Get the Skin attached to this geometry or NULL */
- const Skin* DeformerSkin() const;
-
-private:
- const Skin* skin;
-};
-
-
-typedef std::vector<int> MatIndexArray;
-
-
-/**
- * DOM class for FBX geometry of type "Mesh"
- */
-class MeshGeometry : public Geometry
-{
-public:
- /** The class constructor */
- MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
-
- /** The class destructor */
- virtual ~MeshGeometry();
-
- /** Get a list of all vertex points, non-unique*/
- const std::vector<aiVector3D>& GetVertices() const;
-
- /** Get a list of all vertex normals or an empty array if
- * no normals are specified. */
- const std::vector<aiVector3D>& GetNormals() const;
-
- /** Get a list of all vertex tangents or an empty array
- * if no tangents are specified */
- const std::vector<aiVector3D>& GetTangents() const;
-
- /** Get a list of all vertex binormals or an empty array
- * if no binormals are specified */
- const std::vector<aiVector3D>& GetBinormals() const;
-
- /** 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;
-
- /** 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;
-
- /** Get a UV coordinate slot, returns an empty array if
- * the requested slot does not exist. */
- std::string GetTextureCoordChannelName( unsigned int index ) const;
-
- /** 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;
-
- /** Get per-face-vertex material assignments */
- const MatIndexArray& GetMaterialIndices() const;
-
- /** 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;
-
- /** Determine the face to which a particular output vertex index belongs.
- * This mapping is always unique. */
- unsigned int FaceForVertexIndex( unsigned int in_index ) const;
-
-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 m_materials;
- std::vector<aiVector3D> m_vertices;
- std::vector<unsigned int> m_faces;
- mutable std::vector<unsigned int> m_facesVertexStartIndices;
- std::vector<aiVector3D> m_tangents;
- std::vector<aiVector3D> m_binormals;
- std::vector<aiVector3D> m_normals;
-
- std::string m_uvNames[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
- std::vector<aiVector2D> m_uvs[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
- std::vector<aiColor4D> m_colors[ AI_MAX_NUMBER_OF_COLOR_SETS ];
-
- std::vector<unsigned int> m_mapping_counts;
- std::vector<unsigned int> m_mapping_offsets;
- std::vector<unsigned int> m_mappings;
-};
-
-}
-}
-
-#endif // INCLUDED_AI_FBX_MESHGEOMETRY_H
-
diff --git a/src/3rdparty/assimp/code/FBXModel.cpp b/src/3rdparty/assimp/code/FBXModel.cpp
deleted file mode 100644
index 3d694d7d8..000000000
--- a/src/3rdparty/assimp/code/FBXModel.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXParser.h"
-#include "FBXMeshGeometry.h"
-#include "FBXDocument.h"
-#include "FBXImporter.h"
-#include "FBXDocumentUtil.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());
- for(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();
- for(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
deleted file mode 100644
index 545343c09..000000000
--- a/src/3rdparty/assimp/code/FBXNodeAttribute.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-
-#include "FBXParser.h"
-#include "FBXDocument.h"
-#include "FBXImporter.h"
-#include "FBXDocumentUtil.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)
-, props()
-{
- 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()
-{
- // empty
-}
-
-
-// ------------------------------------------------------------------------------------------------
-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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Camera::~Camera()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
-: NodeAttribute(id,element,doc,name)
-{
- // empty
-}
-
-
-// ------------------------------------------------------------------------------------------------
-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
deleted file mode 100644
index d4d06567b..000000000
--- a/src/3rdparty/assimp/code/FBXParser.cpp
+++ /dev/null
@@ -1,1307 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#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"
-#include "ByteSwapper.h"
-
-#include <iostream>
-
-using namespace Assimp;
-using namespace Assimp::FBX;
-
-namespace {
-
-
- // ------------------------------------------------------------------------------------------------
- // signal parse error, this is always unrecoverable. Throws DeadlyImportError.
- AI_WONT_RETURN void ParseError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
- AI_WONT_RETURN void ParseError(const std::string& message, const Token& token)
- {
- throw DeadlyImportError(Util::AddTokenText("FBX-Parser",message,&token));
- }
-
- // ------------------------------------------------------------------------------------------------
- AI_WONT_RETURN void ParseError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
- AI_WONT_RETURN void ParseError(const std::string& message, const Element* element)
- {
- if(element) {
- ParseError(message,element->KeyToken());
- }
- throw DeadlyImportError("FBX-Parser " + message);
- }
-
-
- // ------------------------------------------------------------------------------------------------
- void ParseError(const std::string& message, TokenPtr token)
- {
- if(token) {
- ParseError(message, *token);
- }
- ParseError(message);
- }
-
- // Initially, we did reinterpret_cast, breaking strict aliasing rules.
- // This actually caused trouble on Android, so let's be safe this time.
- // https://github.com/assimp/assimp/issues/24
- template <typename T>
- T SafeParse(const char* data, const char* end) {
- // Actual size validation happens during Tokenization so
- // this is valid as an assertion.
- (void)(end);
- ai_assert(static_cast<size_t>(end - data) >= sizeof(T));
- T result = static_cast<T>(0);
- ::memcpy(&result, data, sizeof(T));
- return result;
- }
-}
-
-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);
- TokenPtr prev = n;
- n = parser.AdvanceToNextToken();
- if(!n) {
- ParseError("unexpected end of file, expected bracket, comma or key",parser.LastToken());
- }
-
- const TokenType ty = n->Type();
-
- // some exporters are missing a comma on the next line
- if (ty == TokenType_DATA && prev->Type() == TokenType_DATA && (n->Line() == prev->Line() + 1)) {
- tokens.push_back(n);
- continue;
- }
-
- 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()
-{
- for(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()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-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;
- }
-
- BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
- 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 = nullptr;
- 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;
- }
-
- BE_NCONST uint64_t id = SafeParse<uint64_t>(data+1, t.end());
- 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 = nullptr;
- 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') {
- return SafeParse<float>(data+1, t.end());
- }
- else {
- return static_cast<float>( SafeParse<double>(data+1, t.end()) );
- }
- }
-
- // 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;
- }
-
- BE_NCONST int32_t ival = SafeParse<int32_t>(data+1, t.end());
- 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;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-int64_t ParseTokenAsInt64(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 Int64, unexpected data type";
- return 0L;
- }
-
- BE_NCONST int64_t id = SafeParse<int64_t>(data + 1, t.end());
- 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 = nullptr;
- const int64_t id = strtol10_64(t.begin(), &out, &length);
- if (out > t.end()) {
- err_out = "failed to parse Int64 (text)";
- return 0L;
- }
-
- return id;
-}
-
-// ------------------------------------------------------------------------------------------------
-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 "";
- }
-
- // read string length
- BE_NCONST int32_t len = SafeParse<int32_t>(data+1, t.end());
- 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 = SafeParse<uint32_t>(data+1, end);
- 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*/)
-{
- BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end);
- AI_SWAP4(encmode);
- data += 4;
-
- // next comes the compressed length
- BE_NCONST uint32_t comp_len = SafeParse<uint32_t>(data, end);
- 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
- if(Z_OK != inflateInit(&zstream)) {
- ParseError("failure initializing zlib");
- }
-
- zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
- zstream.avail_in = comp_len;
-
- zstream.avail_out = static_cast<uInt>(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.resize( 0 );
-
- 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])));
- }
- // for debugging
- /*for ( size_t i = 0; i < out.size(); i++ ) {
- aiVector3D vec3( out[ i ] );
- std::stringstream stream;
- stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl;
- DefaultLogger::get()->info( stream.str() );
- }*/
- }
- 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.resize( 0 );
- 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.resize( 0 );
- 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.resize( 0 );
- 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.resize( 0 );
- 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.resize( 0 );
- 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.resize( 0 );
- 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);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read an array of int64_ts
-void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
-{
- out.resize( 0 );
- 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 int64_t* ip = reinterpret_cast<const int64_t*>(&buff[0]);
- for (unsigned int i = 0; i < count; ++i, ++ip) {
- BE_NCONST int64_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 int64_t ival = ParseTokenAsInt64(**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;
-}
-
-
-
-// ------------------------------------------------------------------------------------------------
-// wrapper around ParseTokenAsInt64() with ParseError handling
-int64_t ParseTokenAsInt64(const Token& t)
-{
- const char* err;
- const int64_t i = ParseTokenAsInt64(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
deleted file mode 100644
index 4d3766d70..000000000
--- a/src/3rdparty/assimp/code/FBXParser.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 <stdint.h>
-#include <map>
-#include <memory>
-#include "LogAux.h"
-#include "fast_atof.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();
-
- 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;
- std::unique_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();
-
- const Element* operator[] (const std::string& index) const {
- ElementMap::const_iterator it = elements.find(index);
- return it == elements.end() ? NULL : (*it).second;
- }
-
- const Element* FindElementCaseInsensitive(const std::string& elementName) const {
- const char* elementNameCStr = elementName.c_str();
- for (auto element = elements.begin(); element != elements.end(); ++element)
- {
- if (!ASSIMP_strincmp(element->first.c_str(), elementNameCStr, MAXLEN)) {
- return element->second;
- }
- }
- return NULL;
- }
-
- 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();
-
- 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;
- std::unique_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);
-int64_t ParseTokenAsInt64(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);
-int64_t ParseTokenAsInt64(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);
-void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el);
-
-// 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
deleted file mode 100644
index 774beac3c..000000000
--- a/src/3rdparty/assimp/code/FBXProperties.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#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, "Int") || !strcmp(cs, "enum") || !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, "KTime")) {
- return new TypedProperty<int64_t>(ParseTokenAsInt64(*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,"Float") || !strcmp(cs,"FieldOfView")) {
- 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, std::shared_ptr<const PropertyTable> templateProps)
-: templateProps(templateProps)
-, element(&element)
-{
- const Scope& scope = GetRequiredScope(element);
- for(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()
-{
- for(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)
- for(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.
- std::shared_ptr<Property> prop = std::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
deleted file mode 100644
index 09b8aa94c..000000000
--- a/src/3rdparty/assimp/code/FBXProperties.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 "FBXCompileConfig.h"
-#include <memory>
-#include <string>
-
-namespace Assimp {
-namespace FBX {
-
-// Forward declarations
-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:
- explicit TypedProperty(const T& value)
- : value(value) {
- // empty
- }
-
- const T& Value() const {
- return value;
- }
-
-private:
- T value;
-};
-
-
-typedef std::fbx_unordered_map<std::string,std::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, std::shared_ptr<const PropertyTable> templateProps);
- ~PropertyTable();
-
- 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 std::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) {
- const Property* const prop = in.Get(name);
- if( nullptr == prop) {
- return defaultValue;
- }
-
- // strong typing, no need to be lenient
- const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
- if( nullptr == tprop) {
- return defaultValue;
- }
-
- return tprop->Value();
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline
-T PropertyGet(const PropertyTable& in, const std::string& name, bool& result) {
- const Property* const prop = in.Get(name);
- if( nullptr == prop) {
- result = false;
- return T();
- }
-
- // strong typing, no need to be lenient
- const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
- if( nullptr == tprop) {
- result = false;
- return T();
- }
-
- result = true;
- return tprop->Value();
-}
-
-} //! FBX
-} //! Assimp
-
-#endif // INCLUDED_AI_FBX_PROPERTIES_H
diff --git a/src/3rdparty/assimp/code/FBXTokenizer.cpp b/src/3rdparty/assimp/code/FBXTokenizer.cpp
deleted file mode 100644
index 881dcf53d..000000000
--- a/src/3rdparty/assimp/code/FBXTokenizer.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
- */
-
-#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"
-#include "Exceptional.h"
-
-namespace Assimp {
-namespace FBX {
-
-// ------------------------------------------------------------------------------------------------
-Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int line, unsigned int column)
- :
-#ifdef DEBUG
- contents(sbegin, static_cast<size_t>(send-sbegin)),
-#endif
- sbegin(sbegin)
- , send(send)
- , type(type)
- , line(line)
- , column(column)
-{
- 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.
-AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int line, unsigned int column) AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN 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
deleted file mode 100644
index e00ff5b79..000000000
--- a/src/3rdparty/assimp/code/FBXTokenizer.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 "FBXCompileConfig.h"
-#include <assimp/ai_assert.h>
-#include <vector>
-#include <string>
-
-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());
- }
-
- 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
deleted file mode 100644
index 4fd91e18f..000000000
--- a/src/3rdparty/assimp/code/FBXUtil.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 "FBXUtil.h"
-#include "FBXTokenizer.h"
-
-#include "TinyFormatter.h"
-#include <string>
-
-#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
deleted file mode 100644
index c1d9459b3..000000000
--- a/src/3rdparty/assimp/code/FBXUtil.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 "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 Column 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 Column 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/FIReader.cpp b/src/3rdparty/assimp/code/FIReader.cpp
deleted file mode 100644
index 0633ea050..000000000
--- a/src/3rdparty/assimp/code/FIReader.cpp
+++ /dev/null
@@ -1,1833 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FIReader.cpp
-/// \brief Reader for Fast Infoset encoded binary XML files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "FIReader.hpp"
-#include "StringUtils.h"
-
-// Workaround for issue #1361
-// https://github.com/assimp/assimp/issues/1361
-#ifdef __ANDROID__
-# define _GLIBCXX_USE_C99 1
-#endif
-
-#include "Exceptional.h"
-#include <assimp/IOStream.hpp>
-#include <assimp/types.h>
-#include "MemoryIOWrapper.h"
-#include "irrXMLWrapper.h"
-#include "../contrib/utf8cpp/source/utf8.h"
-#include "fast_atof.h"
-#include <stack>
-#include <map>
-#include <iostream>
-#include <sstream>
-#include <iomanip>
-
-namespace Assimp {
-
-static const std::string parseErrorMessage = "Fast Infoset parse error";
-
-static const char *xmlDeclarations[] = {
- "<?xml encoding='finf'?>",
- "<?xml encoding='finf' standalone='yes'?>",
- "<?xml encoding='finf' standalone='no'?>",
- "<?xml version='1.0' encoding='finf'?>",
- "<?xml version='1.0' encoding='finf' standalone='yes'?>",
- "<?xml version='1.0' encoding='finf' standalone='no'?>",
- "<?xml version='1.1' encoding='finf'?>",
- "<?xml version='1.1' encoding='finf' standalone='yes'?>",
- "<?xml version='1.1' encoding='finf' standalone='no'?>"
-};
-
-static size_t parseMagic(const uint8_t *data, const uint8_t *dataEnd) {
- if (dataEnd - data < 4) {
- return 0;
- }
- uint32_t magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- switch (magic) {
- case 0xe0000001:
- return 4;
- case 0x3c3f786d: // "<?xm"
- {
- size_t xmlDeclarationsLength = sizeof(xmlDeclarations) / sizeof(xmlDeclarations[0]);
- for (size_t i = 0; i < xmlDeclarationsLength; ++i) {
- auto xmlDeclaration = xmlDeclarations[i];
- ptrdiff_t xmlDeclarationLength = strlen(xmlDeclaration);
- if ((dataEnd - data >= xmlDeclarationLength) && (memcmp(xmlDeclaration, data, xmlDeclarationLength) == 0)) {
- data += xmlDeclarationLength;
- if (dataEnd - data < 4) {
- return 0;
- }
- magic = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- return magic == 0xe0000001 ? xmlDeclarationLength + 4 : 0;
- }
- }
- return 0;
- }
- default:
- return 0;
- }
-}
-
-static std::string parseUTF8String(const uint8_t *data, size_t len) {
- return std::string((char*)data, len);
-}
-
-static std::string parseUTF16String(const uint8_t *data, size_t len) {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t numShorts = len / 2;
- std::vector<short> utf16;
- utf16.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- short v = (data[0] << 8) | data[1];
- utf16.push_back(v);
- data += 2;
- }
- std::string result;
- utf8::utf16to8(utf16.begin(), utf16.end(), back_inserter(result));
- return result;
-}
-
-struct FIStringValueImpl: public FIStringValue {
- inline FIStringValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FIStringValue> FIStringValue::create(std::string &&value) {
- return std::make_shared<FIStringValueImpl>(std::move(value));
-}
-
-struct FIHexValueImpl: public FIHexValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIHexValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::for_each(value.begin(), value.end(), [&](uint8_t c) { os << std::setw(2) << static_cast<int>(c); });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIHexValue> FIHexValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIHexValueImpl>(std::move(value));
-}
-
-struct FIBase64ValueImpl: public FIBase64Value {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBase64ValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- uint8_t c1 = 0, c2;
- int imod3 = 0;
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- c2 = value[i];
- switch (imod3) {
- case 0:
- os << basis_64[c2 >> 2];
- imod3 = 1;
- break;
- case 1:
- os << basis_64[((c1 & 0x03) << 4) | ((c2 & 0xf0) >> 4)];
- imod3 = 2;
- break;
- case 2:
- os << basis_64[((c1 & 0x0f) << 2) | ((c2 & 0xc0) >> 6)] << basis_64[c2 & 0x3f];
- imod3 = 0;
- break;
- }
- c1 = c2;
- }
- switch (imod3) {
- case 1:
- os << basis_64[(c1 & 0x03) << 4] << "==";
- break;
- case 2:
- os << basis_64[(c1 & 0x0f) << 2] << '=';
- break;
- }
- strValue = os.str();
- }
- return strValue;
- };
- static const char basis_64[];
-};
-
-const char FIBase64ValueImpl::basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-std::shared_ptr<FIBase64Value> FIBase64Value::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIBase64ValueImpl>(std::move(value));
-}
-
-struct FIShortValueImpl: public FIShortValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIShortValueImpl(std::vector<int16_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int16_t s) { if (++n > 1) os << ' '; os << s; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIShortValue> FIShortValue::create(std::vector<int16_t> &&value) {
- return std::make_shared<FIShortValueImpl>(std::move(value));
-}
-
-struct FIIntValueImpl: public FIIntValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIIntValueImpl(std::vector<int32_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int32_t i) { if (++n > 1) os << ' '; os << i; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIIntValue> FIIntValue::create(std::vector<int32_t> &&value) {
- return std::make_shared<FIIntValueImpl>(std::move(value));
-}
-
-struct FILongValueImpl: public FILongValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FILongValueImpl(std::vector<int64_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](int64_t l) { if (++n > 1) os << ' '; os << l; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FILongValue> FILongValue::create(std::vector<int64_t> &&value) {
- return std::make_shared<FILongValueImpl>(std::move(value));
-}
-
-struct FIBoolValueImpl: public FIBoolValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIBoolValueImpl(std::vector<bool> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::boolalpha;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](bool b) { if (++n > 1) os << ' '; os << b; });
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIBoolValue> FIBoolValue::create(std::vector<bool> &&value) {
- return std::make_shared<FIBoolValueImpl>(std::move(value));
-}
-
-struct FIFloatValueImpl: public FIFloatValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIFloatValueImpl(std::vector<float> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](float f) { if (++n > 1) os << ' '; os << f; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIFloatValue> FIFloatValue::create(std::vector<float> &&value) {
- return std::make_shared<FIFloatValueImpl>(std::move(value));
-}
-
-struct FIDoubleValueImpl: public FIDoubleValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIDoubleValueImpl(std::vector<double> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- int n = 0;
- std::for_each(value.begin(), value.end(), [&](double d) { if (++n > 1) os << ' '; os << d; });
- strValue = os.str();
- }
- return strValue;
- }
-};
-
-std::shared_ptr<FIDoubleValue> FIDoubleValue::create(std::vector<double> &&value) {
- return std::make_shared<FIDoubleValueImpl>(std::move(value));
-}
-
-struct FIUUIDValueImpl: public FIUUIDValue {
- mutable std::string strValue;
- mutable bool strValueValid;
- inline FIUUIDValueImpl(std::vector<uint8_t> &&value_): strValueValid(false) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ {
- if (!strValueValid) {
- strValueValid = true;
- std::ostringstream os;
- os << std::hex << std::uppercase << std::setfill('0');
- std::vector<uint8_t>::size_type valueSize = value.size();
- for (std::vector<uint8_t>::size_type i = 0; i < valueSize; ++i) {
- switch (i & 15) {
- case 0:
- if (i > 0) {
- os << ' ';
- }
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- case 4:
- case 6:
- case 8:
- case 10:
- os << '-';
- // intentionally fall through!
- case 1:
- case 2:
- case 3:
- case 5:
- case 7:
- case 9:
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- os << std::setw(2) << static_cast<int>(value[i]);
- break;
- }
- }
- strValue = os.str();
- }
- return strValue;
- };
-};
-
-std::shared_ptr<FIUUIDValue> FIUUIDValue::create(std::vector<uint8_t> &&value) {
- return std::make_shared<FIUUIDValueImpl>(std::move(value));
-}
-
-struct FICDATAValueImpl: public FICDATAValue {
- inline FICDATAValueImpl(std::string &&value_) { value = std::move(value_); }
- virtual const std::string &toString() const /*override*/ { return value; }
-};
-
-std::shared_ptr<FICDATAValue> FICDATAValue::create(std::string &&value) {
- return std::make_shared<FICDATAValueImpl>(std::move(value));
-}
-
-struct FIHexDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIHexValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIBase64Decoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FIBase64Value::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FIShortDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int16_t> value;
- size_t numShorts = len / 2;
- value.reserve(numShorts);
- for (size_t i = 0; i < numShorts; ++i) {
- int16_t v = (data[0] << 8) | data[1];
- value.push_back(v);
- data += 2;
- }
- return FIShortValue::create(std::move(value));
- }
-};
-
-struct FIIntDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int32_t> value;
- size_t numInts = len / 4;
- value.reserve(numInts);
- for (size_t i = 0; i < numInts; ++i) {
- int32_t v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- value.push_back(v);
- data += 4;
- }
- return FIIntValue::create(std::move(value));
- }
-};
-
-struct FILongDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<int64_t> value;
- size_t numLongs = len / 8;
- value.reserve(numLongs);
- for (size_t i = 0; i < numLongs; ++i) {
- int64_t b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- int64_t v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- value.push_back(v);
- data += 8;
- }
- return FILongValue::create(std::move(value));
- }
-};
-
-struct FIBoolDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<bool> value;
- uint8_t b = *data++;
- size_t unusedBits = b >> 4;
- size_t numBools = (len * 8) - 4 - unusedBits;
- value.reserve(numBools);
- uint8_t mask = 1 << 3;
- for (size_t i = 0; i < numBools; ++i) {
- if (!mask) {
- mask = 1 << 7;
- b = *data++;
- }
- value.push_back((b & mask) != 0);
- }
- return FIBoolValue::create(std::move(value));
- }
-};
-
-struct FIFloatDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 3) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<float> value;
- size_t numFloats = len / 4;
- value.reserve(numFloats);
- for (size_t i = 0; i < numFloats; ++i) {
- int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
- float f;
- memcpy(&f, &v, 4);
- value.push_back(f);
- data += 4;
- }
- return FIFloatValue::create(std::move(value));
- }
-};
-
-struct FIDoubleDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 7) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::vector<double> value;
- size_t numDoubles = len / 8;
- value.reserve(numDoubles);
- for (size_t i = 0; i < numDoubles; ++i) {
- long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
- long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
- double f;
- memcpy(&f, &v, 8);
- value.push_back(f);
- data += 8;
- }
- return FIDoubleValue::create(std::move(value));
- }
-};
-
-struct FIUUIDDecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- if (len & 15) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return FIUUIDValue::create(std::vector<uint8_t>(data, data + len));
- }
-};
-
-struct FICDATADecoder: public FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) /*override*/ {
- return FICDATAValue::create(parseUTF8String(data, len));
- }
-};
-
-class CFIReaderImpl: public FIReader {
-public:
-
- CFIReaderImpl(std::unique_ptr<uint8_t[]> data_, size_t size):
- data(std::move(data_)), dataP(data.get()), dataEnd(data.get() + size), currentNodeType(irr::io::EXN_NONE),
- emptyElement(false), headerPending(true), terminatorPending(false)
- {}
-
- virtual ~CFIReaderImpl() {}
-
- virtual bool read() /*override*/ {
- if (headerPending) {
- headerPending = false;
- parseHeader();
- }
- if (terminatorPending) {
- terminatorPending = false;
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- if (dataP >= dataEnd) {
- return false;
- }
- uint8_t b = *dataP;
- if (b < 0x80) { // Element (C.2.11.2, C.3.7.2)
- // C.3
- parseElement();
- return true;
- }
- else if (b < 0xc0) { // Characters (C.3.7.5)
- // C.7
- auto chars = parseNonIdentifyingStringOrIndex3(vocabulary.charactersTable);
- nodeName = chars->toString();
- currentNodeType = irr::io::EXN_TEXT;
- return true;
- }
- else if (b < 0xe0) {
- if ((b & 0xfc) == 0xc4) { // DTD (C.2.11.5)
- // C.9
- ++dataP;
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- elementStack.push(EmptyString);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if ((b & 0xfc) == 0xc8) { // Unexpanded entity reference (C.3.7.4)
- // C.6
- ++dataP;
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b & 0x02) {
- /*const std::string &systemID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b & 0x01) {
- /*const std::string &publicID =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- }
- else if (b < 0xf0) {
- if (b == 0xe1) { // Processing instruction (C.2.11.3, C.3.7.3)
- // C.5
- ++dataP;
- /*const std::string &target =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> data =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- currentNodeType = irr::io::EXN_UNKNOWN;
- return true;
- }
- else if (b == 0xe2) { // Comment (C.2.11.4, C.3.7.6)
- // C.8
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::shared_ptr<const FIValue> comment = parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- nodeName = comment->toString();
- currentNodeType = irr::io::EXN_COMMENT;
- return true;
- }
- }
- else { // Terminator (C.2.12, C.3.8)
- ++dataP;
- if (b == 0xff) {
- terminatorPending = true;
- }
- if (elementStack.empty()) {
- return false;
- }
- else {
- nodeName = elementStack.top();
- elementStack.pop();
- currentNodeType = nodeName.empty() ? irr::io::EXN_UNKNOWN : irr::io::EXN_ELEMENT_END;
- return true;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return currentNodeType;
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return static_cast<int>(attributes.size());
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].name.c_str();
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value->toString().c_str();
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value->toString().c_str();
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return EmptyString.c_str();
- }
- return attr->value->toString().c_str();
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attr->value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attr->value->toString().c_str());
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIIntValue> intValue = std::dynamic_pointer_cast<const FIIntValue>(attributes[idx].value);
- if (intValue) {
- return intValue->value.size() == 1 ? intValue->value.front() : 0;
- }
- return atoi(attributes[idx].value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attr->value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
-
- return fast_atof(attr->value->toString().c_str());
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return 0;
- }
- std::shared_ptr<const FIFloatValue> floatValue = std::dynamic_pointer_cast<const FIFloatValue>(attributes[idx].value);
- if (floatValue) {
- return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
- }
- return fast_atof(attributes[idx].value->toString().c_str());
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return nodeName.c_str();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return emptyElement;
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return irr::io::ETF_UTF8;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const /*override*/ {
- if (idx < 0 || idx >= (int)attributes.size()) {
- return nullptr;
- }
- return attributes[idx].value;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* name) const /*override*/ {
- const Attribute* attr = getAttributeByName(name);
- if (!attr) {
- return nullptr;
- }
- return attr->value;
- }
-
- virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) /*override*/ {
- decoderMap[algorithmUri] = std::move(decoder);
- }
-
- virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) /*override*/ {
- vocabularyMap[vocabularyUri] = vocabulary;
- }
-
-private:
-
- struct QName {
- std::string prefix;
- std::string uri;
- std::string name;
- inline QName() {}
- inline QName(const FIQName &qname): prefix(qname.prefix ? qname.prefix : ""), uri(qname.uri ? qname.uri : ""), name(qname.name) {}
- };
-
- struct Attribute {
- QName qname;
- std::string name;
- std::shared_ptr<const FIValue> value;
- };
-
- struct Vocabulary {
- std::vector<std::string> restrictedAlphabetTable;
- std::vector<std::string> encodingAlgorithmTable;
- std::vector<std::string> prefixTable;
- std::vector<std::string> namespaceNameTable;
- std::vector<std::string> localNameTable;
- std::vector<std::string> otherNCNameTable;
- std::vector<std::string> otherURITable;
- std::vector<std::shared_ptr<const FIValue>> attributeValueTable;
- std::vector<std::shared_ptr<const FIValue>> charactersTable;
- std::vector<std::shared_ptr<const FIValue>> otherStringTable;
- std::vector<QName> elementNameTable;
- std::vector<QName> attributeNameTable;
- Vocabulary() {
- prefixTable.push_back("xml");
- namespaceNameTable.push_back("http://www.w3.org/XML/1998/namespace");
- }
- };
-
- const Attribute* getAttributeByName(const char* name) const {
- if (!name) {
- return 0;
- }
- std::string n = name;
- for (int i=0; i<(int)attributes.size(); ++i) {
- if (attributes[i].name == n) {
- return &attributes[i];
- }
- }
- return 0;
- }
-
- size_t parseInt2() { // C.25
- uint8_t b = *dataP++;
- if (!(b & 0x40)) { // x0...... (C.25.2)
- return b & 0x3f;
- }
- else if ((b & 0x60) == 0x40) { // x10..... ........ (C.25.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x1f) << 8) | *dataP++) + 0x40;
- }
- }
- else if ((b & 0x70) == 0x60) { // x110.... ........ ........ (C.25.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x2040;
- dataP += 2;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt3() { // C.27
- uint8_t b = *dataP++;
- if (!(b & 0x20)) { // xx0..... (C.27.2)
- return b & 0x1f;
- }
- else if ((b & 0x38) == 0x20) { // xx100... ........ (C.27.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x07) << 8) | *dataP++) + 0x20;
- }
- }
- else if ((b & 0x38) == 0x28) { // xx101... ........ ........ (C.27.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x07) << 16) | (dataP[0] << 8) | dataP[1]) + 0x820;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x3f) == 0x30) { // xx110000 0000.... ........ ........ (C.27.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x80820;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseInt4() { // C.28
- uint8_t b = *dataP++;
- if (!(b & 0x10)) { // xxx0.... (C.28.2)
- return b & 0x0f;
- }
- else if ((b & 0x1c) == 0x10) { // xxx100.. ........ (C.28.3)
- if (dataEnd - dataP > 0) {
- return (((b & 0x03) << 8) | *dataP++) + 0x10;
- }
- }
- else if ((b & 0x1c) == 0x14) { // xxx101.. ........ ........ (C.28.4)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x03) << 16) | (dataP[0] << 8) | dataP[1]) + 0x410;
- dataP += 2;
- return result;
- }
- }
- else if ((b & 0x1f) == 0x18) { // xxx11000 0000.... ........ ........ (C.28.5)
- if ((dataEnd - dataP > 2) && !(dataP[0] & 0xf0)) {
- size_t result = (((dataP[0] & 0x0f) << 16) | (dataP[1] << 8) | dataP[2]) + 0x40410;
- dataP += 3;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseSequenceLen() { // C.21
- if (dataEnd - dataP > 0) {
- uint8_t b = *dataP++;
- if (b < 0x80) { // 0....... (C.21.2)
- return b;
- }
- else if ((b & 0xf0) == 0x80) { // 1000.... ........ ........ (C.21.3)
- if (dataEnd - dataP > 1) {
- size_t result = (((b & 0x0f) << 16) | (dataP[0] << 8) | dataP[1]) + 0x80;
- dataP += 2;
- return result;
- }
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::string parseNonEmptyOctetString2() { // C.22
- // Parse the length of the string
- uint8_t b = *dataP++ & 0x7f;
- size_t len;
- if (!(b & 0x40)) { // x0...... (C.22.3.1)
- len = b + 1;
- }
- else if (b == 0x40) { // x1000000 ........ (C.22.3.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = *dataP++ + 0x41;
- }
- else if (b == 0x60) { // x1100000 ........ ........ ........ ........ (C.22.3.3)
- if (dataEnd - dataP < 4) {
- throw DeadlyImportError(parseErrorMessage);
- }
- len = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x141;
- dataP += 4;
- }
- else {
- throw DeadlyImportError(parseErrorMessage);
- }
-
- // Parse the string (C.22.4)
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string s = parseUTF8String(dataP, len);
- dataP += len;
-
- return s;
- }
-
- size_t parseNonEmptyOctetString5Length() { // C.23
- // Parse the length of the string
- size_t b = *dataP++ & 0x0f;
- if (!(b & 0x08)) { // xxxx0... (C.23.3.1)
- return b + 1;
- }
- else if (b == 0x08) { // xxxx1000 ........ (C.23.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x09;
- }
- }
- else if (b == 0x0c) { // xxxx1100 ........ ........ ........ ........ (C.23.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x109;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- size_t parseNonEmptyOctetString7Length() { // C.24
- // Parse the length of the string
- size_t b = *dataP++ & 0x03;
- if (!(b & 0x02)) { // xxxxxx0. (C.24.3.1)
- return b + 1;
- }
- else if (b == 0x02) { // xxxxxx10 ........ (C.24.3.2)
- if (dataEnd - dataP > 0) {
- return *dataP++ + 0x3;
- }
- }
- else if (b == 0x03) { // xxxxxx11 ........ ........ ........ ........ (C.24.3.3)
- if (dataEnd - dataP > 3) {
- size_t result = ((dataP[0] << 24) | (dataP[1] << 16) | (dataP[2] << 8) | dataP[3]) + 0x103;
- dataP += 4;
- return result;
- }
- }
- throw DeadlyImportError(parseErrorMessage);
- }
-
- std::shared_ptr<const FIValue> parseEncodedData(size_t index, size_t len) {
- if (index < 32) {
- FIDecoder *decoder = defaultDecoder[index];
- if (!decoder) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- return decoder->decode(dataP, len);
- }
- else {
- if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
- throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
- }
- std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
- auto it = decoderMap.find(uri);
- if (it == decoderMap.end()) {
- throw DeadlyImportError("Unsupported encoding algorithm " + uri);
- }
- else {
- return it->second->decode(dataP, len);
- }
- }
- }
-
- std::shared_ptr<const FIValue> parseRestrictedAlphabet(size_t index, size_t len) {
- std::string alphabet;
- if (index < 16) {
- switch (index) {
- case 0: // numeric
- alphabet = "0123456789-+.e ";
- break;
- case 1: // date and time
- alphabet = "0123456789-:TZ ";
- break;
- default:
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- }
- else {
- if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
- throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
- }
- alphabet = vocabulary.restrictedAlphabetTable[index - 16];
- }
- std::vector<uint32_t> alphabetUTF32;
- utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
- std::string::size_type alphabetLength = alphabetUTF32.size();
- if (alphabetLength < 2) {
- throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
- }
- std::string::size_type bitsPerCharacter = 1;
- while ((1ull << bitsPerCharacter) <= alphabetLength) {
- ++bitsPerCharacter;
- }
- size_t bitsAvail = 0;
- uint8_t mask = (1 << bitsPerCharacter) - 1;
- uint32_t bits = 0;
- std::string s;
- for (size_t i = 0; i < len; ++i) {
- bits = (bits << 8) | dataP[i];
- bitsAvail += 8;
- while (bitsAvail >= bitsPerCharacter) {
- bitsAvail -= bitsPerCharacter;
- size_t charIndex = (bits >> bitsAvail) & mask;
- if (charIndex < alphabetLength) {
- s.push_back(alphabetUTF32[charIndex]);
- }
- else if (charIndex != mask) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
- }
- return FIStringValue::create(std::move(s));
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString3() { // C.19
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x20) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x0f) << 4) | ((*dataP & 0xf0) >> 4); // C.29
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // encoding algorithm (C.19.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.19.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString5Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x10) {
- // UTF-16 (C.19.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.19.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- std::shared_ptr<const FIValue> parseEncodedCharacterString5() { // C.20
- std::shared_ptr<const FIValue> result;
- size_t len;
- uint8_t b = *dataP;
- if (b & 0x08) {
- ++dataP;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- size_t index = ((b & 0x03) << 6) | ((*dataP & 0xfc) >> 2); /* C.29 */
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // encoding algorithm (C.20.3.4)
- result = parseEncodedData(index, len);
- }
- else {
- // Restricted alphabet (C.20.3.3)
- result = parseRestrictedAlphabet(index, len);
- }
- }
- else {
- len = parseNonEmptyOctetString7Length();
- if (dataEnd - dataP < static_cast<ptrdiff_t>(len)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- if (b & 0x04) {
- // UTF-16 (C.20.3.2)
- if (len & 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result = FIStringValue::create(parseUTF16String(dataP, len));
- }
- else {
- // UTF-8 (C.20.3.1)
- result = FIStringValue::create(parseUTF8String(dataP, len));
- }
- }
- dataP += len;
- return result;
- }
-
- const std::string &parseIdentifyingStringOrIndex(std::vector<std::string> &stringTable) { // C.13
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP;
- if (b & 0x80) {
- // We have an index (C.13.4)
- size_t index = parseInt2();
- if (index >= stringTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return stringTable[index];
- }
- else {
- // We have a string (C.13.3)
- stringTable.push_back(parseNonEmptyOctetString2());
- return stringTable.back();
- }
- }
-
- QName parseNameSurrogate() { // C.16
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0xfc) { // Padding '000000' C.2.5.5
- throw DeadlyImportError(parseErrorMessage);
- }
- QName result;
- size_t index;
- if (b & 0x02) { // prefix (C.16.3)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.prefixTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.prefix = vocabulary.prefixTable[index];
- }
- if (b & 0x01) { // namespace-name (C.16.4)
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.namespaceNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.uri = vocabulary.namespaceNameTable[index];
- }
- // local-name
- if ((dataEnd - dataP < 1) || (*dataP & 0x80)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- index = parseInt2();
- if (index >= vocabulary.localNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- result.name = vocabulary.localNameTable[index];
- return result;
- }
-
- const QName &parseQualifiedNameOrIndex2(std::vector<QName> &qNameTable) { // C.17
- uint8_t b = *dataP;
- if ((b & 0x7c) == 0x78) { // x11110..
- // We have a literal (C.17.3)
- ++dataP;
- QName result;
- // prefix (C.17.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.17.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.17.4)
- size_t index = parseInt2();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- const QName &parseQualifiedNameOrIndex3(std::vector<QName> &qNameTable) { // C.18
- uint8_t b = *dataP;
- if ((b & 0x3c) == 0x3c) { // xx1111..
- // We have a literal (C.18.3)
- ++dataP;
- QName result;
- // prefix (C.18.3.1)
- result.prefix = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- // namespace-name (C.18.3.1)
- result.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- // local-name
- result.name = parseIdentifyingStringOrIndex(vocabulary.localNameTable);
- qNameTable.push_back(result);
- return qNameTable.back();
- }
- else {
- // We have an index (C.18.4)
- size_t index = parseInt3();
- if (index >= qNameTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return qNameTable[index];
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex1(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.14
- uint8_t b = *dataP;
- if (b == 0xff) { // C.26.2
- // empty string
- ++dataP;
- return EmptyFIString;
- }
- else if (b & 0x80) { // C.14.4
- // We have an index
- size_t index = parseInt2();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.14.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString3();
- if (b & 0x40) { // C.14.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- std::shared_ptr<const FIValue> parseNonIdentifyingStringOrIndex3(std::vector<std::shared_ptr<const FIValue>> &valueTable) { // C.15
- uint8_t b = *dataP;
- if (b & 0x20) { // C.15.4
- // We have an index
- size_t index = parseInt4();
- if (index >= valueTable.size()) {
- throw DeadlyImportError(parseErrorMessage);
- }
- return valueTable[index];
- }
- else { // C.15.3
- // We have a literal
- std::shared_ptr<const FIValue> result = parseEncodedCharacterString5();
- if (b & 0x10) { // C.15.3.1
- valueTable.push_back(result);
- }
- return result;
- }
- }
-
- void parseElement() {
- // C.3
-
- attributes.clear();
-
- uint8_t b = *dataP;
- bool hasAttributes = (b & 0x40) != 0; // C.3.3
- if ((b & 0x3f) == 0x38) { // C.3.4.1
- // Parse namespaces
- ++dataP;
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP++;
- if (b == 0xf0) { // C.3.4.3
- break;
- }
- if ((b & 0xfc) != 0xcc) { // C.3.4.2
- throw DeadlyImportError(parseErrorMessage);
- }
- // C.12
- Attribute attr;
- attr.qname.prefix = "xmlns";
- attr.qname.name = b & 0x02 ? parseIdentifyingStringOrIndex(vocabulary.prefixTable) : std::string();
- attr.qname.uri = b & 0x01 ? parseIdentifyingStringOrIndex(vocabulary.namespaceNameTable) : std::string();
- attr.name = attr.qname.name.empty() ? "xmlns" : "xmlns:" + attr.qname.name;
- attr.value = FIStringValue::create(std::string(attr.qname.uri));
- attributes.push_back(attr);
- }
- if ((dataEnd - dataP < 1) || (*dataP & 0xc0)) {
- throw DeadlyImportError(parseErrorMessage);
- }
- }
-
- // Parse Element name (C.3.5)
- const QName &elemName = parseQualifiedNameOrIndex3(vocabulary.elementNameTable);
- nodeName = elemName.prefix.empty() ? elemName.name : elemName.prefix + ':' + elemName.name;
-
- if (hasAttributes) {
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- if (b < 0x80) { // C.3.6.1
- // C.4
- Attribute attr;
- attr.qname = parseQualifiedNameOrIndex2(vocabulary.attributeNameTable);
- attr.name = attr.qname.prefix.empty() ? attr.qname.name : attr.qname.prefix + ':' + attr.qname.name;
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- attr.value = parseNonIdentifyingStringOrIndex1(vocabulary.attributeValueTable);
- attributes.push_back(attr);
- }
- else {
- if ((b & 0xf0) != 0xf0) { // C.3.6.2
- throw DeadlyImportError(parseErrorMessage);
- }
- emptyElement = b == 0xff; // C.3.6.2, C.3.8
- ++dataP;
- break;
- }
- }
- }
- else {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- b = *dataP;
- switch (b) {
- case 0xff:
- terminatorPending = true;
- // Intentionally fall through
- case 0xf0:
- emptyElement = true;
- ++dataP;
- break;
- default:
- emptyElement = false;
- }
- }
- if (!emptyElement) {
- elementStack.push(nodeName);
- }
-
- currentNodeType = irr::io::EXN_ELEMENT;
- }
-
- void parseHeader() {
- // Parse header (C.1.3)
- size_t magicSize = parseMagic(dataP, dataEnd);
- if (!magicSize) {
- throw DeadlyImportError(parseErrorMessage);
- }
- dataP += magicSize;
- // C.2.3
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b = *dataP++;
- if (b & 0x40) {
- // Parse additional data (C.2.4)
- size_t len = parseSequenceLen();
- for (size_t i = 0; i < len; ++i) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string id =*/ parseNonEmptyOctetString2();
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string data =*/ parseNonEmptyOctetString2();
- }
- }
- if (b & 0x20) {
- // Parse initial vocabulary (C.2.5)
- if (dataEnd - dataP < 2) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint16_t b1 = (dataP[0] << 8) | dataP[1];
- dataP += 2;
- if (b1 & 0x1000) {
- // External vocabulary (C.2.5.2)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- std::string uri = parseNonEmptyOctetString2();
- auto it = vocabularyMap.find(uri);
- if (it == vocabularyMap.end()) {
- throw DeadlyImportError("Unknown vocabulary " + uri);
- }
- const FIVocabulary *externalVocabulary = it->second;
- if (externalVocabulary->restrictedAlphabetTable) {
- std::copy(externalVocabulary->restrictedAlphabetTable, externalVocabulary->restrictedAlphabetTable + externalVocabulary->restrictedAlphabetTableSize, std::back_inserter(vocabulary.restrictedAlphabetTable));
- }
- if (externalVocabulary->encodingAlgorithmTable) {
- std::copy(externalVocabulary->encodingAlgorithmTable, externalVocabulary->encodingAlgorithmTable + externalVocabulary->encodingAlgorithmTableSize, std::back_inserter(vocabulary.encodingAlgorithmTable));
- }
- if (externalVocabulary->prefixTable) {
- std::copy(externalVocabulary->prefixTable, externalVocabulary->prefixTable + externalVocabulary->prefixTableSize, std::back_inserter(vocabulary.prefixTable));
- }
- if (externalVocabulary->namespaceNameTable) {
- std::copy(externalVocabulary->namespaceNameTable, externalVocabulary->namespaceNameTable + externalVocabulary->namespaceNameTableSize, std::back_inserter(vocabulary.namespaceNameTable));
- }
- if (externalVocabulary->localNameTable) {
- std::copy(externalVocabulary->localNameTable, externalVocabulary->localNameTable + externalVocabulary->localNameTableSize, std::back_inserter(vocabulary.localNameTable));
- }
- if (externalVocabulary->otherNCNameTable) {
- std::copy(externalVocabulary->otherNCNameTable, externalVocabulary->otherNCNameTable + externalVocabulary->otherNCNameTableSize, std::back_inserter(vocabulary.otherNCNameTable));
- }
- if (externalVocabulary->otherURITable) {
- std::copy(externalVocabulary->otherURITable, externalVocabulary->otherURITable + externalVocabulary->otherURITableSize, std::back_inserter(vocabulary.otherURITable));
- }
- if (externalVocabulary->attributeValueTable) {
- std::copy(externalVocabulary->attributeValueTable, externalVocabulary->attributeValueTable + externalVocabulary->attributeValueTableSize, std::back_inserter(vocabulary.attributeValueTable));
- }
- if (externalVocabulary->charactersTable) {
- std::copy(externalVocabulary->charactersTable, externalVocabulary->charactersTable + externalVocabulary->charactersTableSize, std::back_inserter(vocabulary.charactersTable));
- }
- if (externalVocabulary->otherStringTable) {
- std::copy(externalVocabulary->otherStringTable, externalVocabulary->otherStringTable + externalVocabulary->otherStringTableSize, std::back_inserter(vocabulary.otherStringTable));
- }
- if (externalVocabulary->elementNameTable) {
- std::copy(externalVocabulary->elementNameTable, externalVocabulary->elementNameTable + externalVocabulary->elementNameTableSize, std::back_inserter(vocabulary.elementNameTable));
- }
- if (externalVocabulary->attributeNameTable) {
- std::copy(externalVocabulary->attributeNameTable, externalVocabulary->attributeNameTable + externalVocabulary->attributeNameTableSize, std::back_inserter(vocabulary.attributeNameTable));
- }
- }
- if (b1 & 0x0800) {
- // Parse restricted alphabets (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.restrictedAlphabetTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0400) {
- // Parse encoding algorithms (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.encodingAlgorithmTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0200) {
- // Parse prefixes (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.prefixTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0100) {
- // Parse namespace names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.namespaceNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0080) {
- // Parse local names (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.localNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0040) {
- // Parse other ncnames (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherNCNameTable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0020) {
- // Parse other uris (C.2.5.3)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherURITable.push_back(parseNonEmptyOctetString2());
- }
- }
- if (b1 & 0x0010) {
- // Parse attribute values (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.attributeValueTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0008) {
- // Parse content character chunks (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.charactersTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0004) {
- // Parse other strings (C.2.5.4)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- vocabulary.otherStringTable.push_back(parseEncodedCharacterString3());
- }
- }
- if (b1 & 0x0002) {
- // Parse element name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.elementNameTable.push_back(parseNameSurrogate());
- }
- }
- if (b1 & 0x0001) {
- // Parse attribute name surrogates (C.2.5.5)
- for (size_t len = parseSequenceLen(); len > 0; --len) {
- vocabulary.attributeNameTable.push_back(parseNameSurrogate());
- }
- }
- }
- if (b & 0x10) {
- // Parse notations (C.2.6)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfc) != 0xc0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.11 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- if (b1 & 0x02) {
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- }
- }
- if (b & 0x08) {
- // Parse unparsed entities (C.2.7)
- for (;;) {
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 == 0xf0) {
- break;
- }
- if ((b1 & 0xfe) != 0xd0) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /* C.10 */
- /*const std::string &name =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- /*const std::string &systemId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- if (b1 & 0x01) {
- /*const std::string &publicId =*/ parseIdentifyingStringOrIndex(vocabulary.otherURITable);
- }
- /*const std::string &notationName =*/ parseIdentifyingStringOrIndex(vocabulary.otherNCNameTable);
- }
- }
- if (b & 0x04) {
- // Parse character encoding scheme (C.2.8)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::string characterEncodingScheme =*/ parseNonEmptyOctetString2();
- }
- if (b & 0x02) {
- // Parse standalone flag (C.2.9)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- uint8_t b1 = *dataP++;
- if (b1 & 0xfe) {
- throw DeadlyImportError(parseErrorMessage);
- }
- //bool standalone = b1 & 0x01;
- }
- if (b & 0x01) {
- // Parse version (C.2.10)
- if (dataEnd - dataP < 1) {
- throw DeadlyImportError(parseErrorMessage);
- }
- /*std::shared_ptr<const FIValue> version =*/ parseNonIdentifyingStringOrIndex1(vocabulary.otherStringTable);
- }
- }
-
- std::unique_ptr<uint8_t[]> data;
- uint8_t *dataP, *dataEnd;
- irr::io::EXML_NODE currentNodeType;
- bool emptyElement;
- bool headerPending;
- bool terminatorPending;
- Vocabulary vocabulary;
- std::vector<Attribute> attributes;
- std::stack<std::string> elementStack;
- std::string nodeName;
- std::map<std::string, std::unique_ptr<FIDecoder>> decoderMap;
- std::map<std::string, const FIVocabulary*> vocabularyMap;
-
- static const std::string EmptyString;
- static std::shared_ptr<const FIValue> EmptyFIString;
-
- static FIHexDecoder hexDecoder;
- static FIBase64Decoder base64Decoder;
- static FIShortDecoder shortDecoder;
- static FIIntDecoder intDecoder;
- static FILongDecoder longDecoder;
- static FIBoolDecoder boolDecoder;
- static FIFloatDecoder floatDecoder;
- static FIDoubleDecoder doubleDecoder;
- static FIUUIDDecoder uuidDecoder;
- static FICDATADecoder cdataDecoder;
- static FIDecoder *defaultDecoder[32];
-};
-
-const std::string CFIReaderImpl::EmptyString;
-std::shared_ptr<const FIValue> CFIReaderImpl::EmptyFIString = FIStringValue::create(std::string());
-
-FIHexDecoder CFIReaderImpl::hexDecoder;
-FIBase64Decoder CFIReaderImpl::base64Decoder;
-FIShortDecoder CFIReaderImpl::shortDecoder;
-FIIntDecoder CFIReaderImpl::intDecoder;
-FILongDecoder CFIReaderImpl::longDecoder;
-FIBoolDecoder CFIReaderImpl::boolDecoder;
-FIFloatDecoder CFIReaderImpl::floatDecoder;
-FIDoubleDecoder CFIReaderImpl::doubleDecoder;
-FIUUIDDecoder CFIReaderImpl::uuidDecoder;
-FICDATADecoder CFIReaderImpl::cdataDecoder;
-
-FIDecoder *CFIReaderImpl::defaultDecoder[32] = {
- &hexDecoder,
- &base64Decoder,
- &shortDecoder,
- &intDecoder,
- &longDecoder,
- &boolDecoder,
- &floatDecoder,
- &doubleDecoder,
- &uuidDecoder,
- &cdataDecoder
-};
-
-class CXMLReaderImpl : public FIReader
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader_)
- : reader(std::move(reader_))
- {}
-
- virtual ~CXMLReaderImpl() {}
-
- virtual bool read() /*override*/ {
- return reader->read();
- }
-
- virtual irr::io::EXML_NODE getNodeType() const /*override*/ {
- return reader->getNodeType();
- }
-
- virtual int getAttributeCount() const /*override*/ {
- return reader->getAttributeCount();
- }
-
- virtual const char* getAttributeName(int idx) const /*override*/ {
- return reader->getAttributeName(idx);
- }
-
- virtual const char* getAttributeValue(int idx) const /*override*/ {
- return reader->getAttributeValue(idx);
- }
-
- virtual const char* getAttributeValue(const char* name) const /*override*/ {
- return reader->getAttributeValue(name);
- }
-
- virtual const char* getAttributeValueSafe(const char* name) const /*override*/ {
- return reader->getAttributeValueSafe(name);
- }
-
- virtual int getAttributeValueAsInt(const char* name) const /*override*/ {
- return reader->getAttributeValueAsInt(name);
- }
-
- virtual int getAttributeValueAsInt(int idx) const /*override*/ {
- return reader->getAttributeValueAsInt(idx);
- }
-
- virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
- return reader->getAttributeValueAsFloat(name);
- }
-
- virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
- return reader->getAttributeValueAsFloat(idx);
- }
-
- virtual const char* getNodeName() const /*override*/ {
- return reader->getNodeName();
- }
-
- virtual const char* getNodeData() const /*override*/ {
- return reader->getNodeData();
- }
-
- virtual bool isEmptyElement() const /*override*/ {
- return reader->isEmptyElement();
- }
-
- virtual irr::io::ETEXT_FORMAT getSourceFormat() const /*override*/ {
- return reader->getSourceFormat();
- }
-
- virtual irr::io::ETEXT_FORMAT getParserFormat() const /*override*/ {
- return reader->getParserFormat();
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int /*idx*/) const /*override*/ {
- return nullptr;
- }
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char* /*name*/) const /*override*/ {
- return nullptr;
- }
-
- virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
-
-
- virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}
-
-private:
-
- std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>> reader;
-};
-
-static std::unique_ptr<uint8_t[]> readFile(IOStream *stream, size_t &size, bool &isFI) {
- size = stream->FileSize();
- std::unique_ptr<uint8_t[]> data = std::unique_ptr<uint8_t[]>(new uint8_t[size]);
- if (stream->Read(data.get(), size, 1) != 1) {
- size = 0;
- data.reset();
- }
- isFI = parseMagic(data.get(), data.get() + size) > 0;
- return data;
-}
-
-std::unique_ptr<FIReader> FIReader::create(IOStream *stream)
-{
- size_t size;
- bool isFI;
- auto data = readFile(stream, size, isFI);
- if (isFI) {
- return std::unique_ptr<FIReader>(new CFIReaderImpl(std::move(data), size));
- }
- else {
- auto memios = std::unique_ptr<MemoryIOStream>(new MemoryIOStream(data.release(), size, true));
- auto callback = std::unique_ptr<CIrrXML_IOStreamReader>(new CIrrXML_IOStreamReader(memios.get()));
- return std::unique_ptr<FIReader>(new CXMLReaderImpl(std::unique_ptr<irr::io::IIrrXMLReader<char, irr::io::IXMLBase>>(createIrrXMLReader(callback.get()))));
- }
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/FIReader.hpp b/src/3rdparty/assimp/code/FIReader.hpp
deleted file mode 100644
index 5f4e5bb48..000000000
--- a/src/3rdparty/assimp/code/FIReader.hpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FIReader.hpp
-/// \brief Reader for Fast Infoset encoded binary XML files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef INCLUDED_AI_FI_READER_H
-#define INCLUDED_AI_FI_READER_H
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-//#include <wchar.h>
-#include <string>
-#include <memory>
-#include <cerrno>
-#include <cwchar>
-#include <vector>
-//#include <stdio.h>
-//#include <cstdint>
-#include <irrXML.h>
-
-namespace Assimp {
-
-struct FIValue {
- virtual const std::string &toString() const = 0;
-};
-
-struct FIStringValue: public FIValue {
- std::string value;
- static std::shared_ptr<FIStringValue> create(std::string &&value);
-};
-
-struct FIByteValue: public FIValue {
- std::vector<uint8_t> value;
-};
-
-struct FIHexValue: public FIByteValue {
- static std::shared_ptr<FIHexValue> create(std::vector<uint8_t> &&value);
-};
-
-struct FIBase64Value: public FIByteValue {
- static std::shared_ptr<FIBase64Value> create(std::vector<uint8_t> &&value);
-};
-
-struct FIShortValue: public FIValue {
- std::vector<int16_t> value;
- static std::shared_ptr<FIShortValue> create(std::vector<int16_t> &&value);
-};
-
-struct FIIntValue: public FIValue {
- std::vector<int32_t> value;
- static std::shared_ptr<FIIntValue> create(std::vector<int32_t> &&value);
-};
-
-struct FILongValue: public FIValue {
- std::vector<int64_t> value;
- static std::shared_ptr<FILongValue> create(std::vector<int64_t> &&value);
-};
-
-struct FIBoolValue: public FIValue {
- std::vector<bool> value;
- static std::shared_ptr<FIBoolValue> create(std::vector<bool> &&value);
-};
-
-struct FIFloatValue: public FIValue {
- std::vector<float> value;
- static std::shared_ptr<FIFloatValue> create(std::vector<float> &&value);
-};
-
-struct FIDoubleValue: public FIValue {
- std::vector<double> value;
- static std::shared_ptr<FIDoubleValue> create(std::vector<double> &&value);
-};
-
-struct FIUUIDValue: public FIByteValue {
- static std::shared_ptr<FIUUIDValue> create(std::vector<uint8_t> &&value);
-};
-
-struct FICDATAValue: public FIStringValue {
- static std::shared_ptr<FICDATAValue> create(std::string &&value);
-};
-
-struct FIDecoder {
- virtual std::shared_ptr<const FIValue> decode(const uint8_t *data, size_t len) = 0;
-};
-
-struct FIQName {
- const char *name;
- const char *prefix;
- const char *uri;
-};
-
-struct FIVocabulary {
- const char **restrictedAlphabetTable;
- size_t restrictedAlphabetTableSize;
- const char **encodingAlgorithmTable;
- size_t encodingAlgorithmTableSize;
- const char **prefixTable;
- size_t prefixTableSize;
- const char **namespaceNameTable;
- size_t namespaceNameTableSize;
- const char **localNameTable;
- size_t localNameTableSize;
- const char **otherNCNameTable;
- size_t otherNCNameTableSize;
- const char **otherURITable;
- size_t otherURITableSize;
- const std::shared_ptr<const FIValue> *attributeValueTable;
- size_t attributeValueTableSize;
- const std::shared_ptr<const FIValue> *charactersTable;
- size_t charactersTableSize;
- const std::shared_ptr<const FIValue> *otherStringTable;
- size_t otherStringTableSize;
- const FIQName *elementNameTable;
- size_t elementNameTableSize;
- const FIQName *attributeNameTable;
- size_t attributeNameTableSize;
-};
-
-class IOStream;
-
-class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
-public:
- virtual ~FIReader();
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
-
- virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
-
- virtual void registerDecoder(const std::string &algorithmUri, std::unique_ptr<FIDecoder> decoder) = 0;
-
- virtual void registerVocabulary(const std::string &vocabularyUri, const FIVocabulary *vocabulary) = 0;
-
- static std::unique_ptr<FIReader> create(IOStream *stream);
-
-};// class IFIReader
-
-inline
-FIReader::~FIReader() {
- // empty
-}
-
-}// namespace Assimp
-
-#endif // #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#endif // INCLUDED_AI_FI_READER_H
diff --git a/src/3rdparty/assimp/code/FileLogStream.h b/src/3rdparty/assimp/code/FileLogStream.h
deleted file mode 100644
index e935624a1..000000000
--- a/src/3rdparty/assimp/code/FileLogStream.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FileLofStream.h
-*/
-#ifndef ASSIMP_FILELOGSTREAM_H_INC
-#define ASSIMP_FILELOGSTREAM_H_INC
-
-#include <assimp/LogStream.hpp>
-#include <assimp/IOStream.hpp>
-#include <assimp/DefaultIOSystem.h>
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** @class FileLogStream
- * @brief Logstream to write into a file.
- */
-class FileLogStream :
- public LogStream
-{
-public:
- FileLogStream( const char* file, IOSystem* io = NULL );
- ~FileLogStream();
- void write( const char* message );
-
-private:
- IOStream *m_pStream;
-};
-
-// ----------------------------------------------------------------------------------
-// Constructor
-inline FileLogStream::FileLogStream( const char* file, IOSystem* io ) :
- m_pStream(NULL)
-{
- if ( !file || 0 == *file )
- return;
-
- // If no IOSystem is specified: take a default one
- if (!io)
- {
- DefaultIOSystem FileSystem;
- m_pStream = FileSystem.Open( file, "wt");
- }
- else m_pStream = io->Open( file, "wt" );
-}
-
-// ----------------------------------------------------------------------------------
-// Destructor
-inline FileLogStream::~FileLogStream()
-{
- // The virtual d'tor should destroy the underlying file
- delete m_pStream;
-}
-
-// ----------------------------------------------------------------------------------
-// Write method
-inline void FileLogStream::write( const char* message )
-{
- if (m_pStream != NULL)
- {
- m_pStream->Write(message, sizeof(char), ::strlen(message));
- m_pStream->Flush();
- }
-}
-
-// ----------------------------------------------------------------------------------
-} // !Namespace Assimp
-
-#endif // !! ASSIMP_FILELOGSTREAM_H_INC
diff --git a/src/3rdparty/assimp/code/FileSystemFilter.h b/src/3rdparty/assimp/code/FileSystemFilter.h
deleted file mode 100644
index 3370589d6..000000000
--- a/src/3rdparty/assimp/code/FileSystemFilter.h
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, 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 FileSystemFilter.h
- * Implements a filter system to filter calls to Exists() and Open()
- * in order to improve the success rate of file opening ...
- */
-#ifndef AI_FILESYSTEMFILTER_H_INC
-#define AI_FILESYSTEMFILTER_H_INC
-
-#include "../include/assimp/IOSystem.hpp"
-#include "../include/assimp/DefaultLogger.hpp"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-
-namespace Assimp {
-
-inline bool IsHex(char s) {
- return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F');
-}
-
-// ---------------------------------------------------------------------------
-/** File system filter
- */
-class FileSystemFilter : public IOSystem
-{
-public:
- /** Constructor. */
- FileSystemFilter(const std::string& file, IOSystem* old)
- : wrapped (old)
- , src_file (file)
- , sep(wrapped->getOsSeparator())
- {
- ai_assert(NULL != wrapped);
-
- // Determine base directory
- base = src_file;
- std::string::size_type ss2;
- if (std::string::npos != (ss2 = base.find_last_of("\\/"))) {
- base.erase(ss2,base.length()-ss2);
- }
- else {
- base = "";
- // return;
- }
-
- // make sure the directory is terminated properly
- char s;
-
- if (base.length() == 0) {
- base = ".";
- base += getOsSeparator();
- }
- else if ((s = *(base.end()-1)) != '\\' && s != '/') {
- base += getOsSeparator();
- }
-
- DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
- }
-
- /** Destructor. */
- ~FileSystemFilter()
- {
- // haha
- }
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const
- {
- std::string tmp = pFile;
-
- // Currently this IOSystem is also used to open THE ONE FILE.
- if (tmp != src_file) {
- BuildPath(tmp);
- Cleanup(tmp);
- }
-
- return wrapped->Exists(tmp);
- }
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const
- {
- return sep;
- }
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* pMode = "rb")
- {
- ai_assert(pFile);
- ai_assert(pMode);
-
- // First try the unchanged path
- IOStream* s = wrapped->Open(pFile,pMode);
-
- if (!s) {
- std::string tmp = pFile;
-
- // Try to convert between absolute and relative paths
- BuildPath(tmp);
- s = wrapped->Open(tmp,pMode);
-
- if (!s) {
- // Finally, look for typical issues with paths
- // and try to correct them. This is our last
- // resort.
- tmp = pFile;
- Cleanup(tmp);
- BuildPath(tmp);
- s = wrapped->Open(tmp,pMode);
- }
- }
-
- return s;
- }
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* pFile)
- {
- return wrapped->Close(pFile);
- }
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* one, const char* second) const
- {
- return wrapped->ComparePaths (one,second);
- }
-
-private:
-
- // -------------------------------------------------------------------
- /** Build a valid path from a given relative or absolute path.
- */
- void BuildPath (std::string& in) const
- {
- // if we can already access the file, great.
- if (in.length() < 3 || wrapped->Exists(in)) {
- return;
- }
-
- // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows).
- if (in[1] != ':') {
-
- // append base path and try
- const std::string tmp = base + in;
- if (wrapped->Exists(tmp)) {
- in = tmp;
- return;
- }
- }
-
- // Chop of the file name and look in the model directory, if
- // this fails try all sub paths of the given path, i.e.
- // if the given path is foo/bar/something.lwo, try
- // <base>/something.lwo
- // <base>/bar/something.lwo
- // <base>/foo/bar/something.lwo
- std::string::size_type pos = in.rfind('/');
- if (std::string::npos == pos) {
- pos = in.rfind('\\');
- }
-
- if (std::string::npos != pos) {
- std::string tmp;
- std::string::size_type last_dirsep = std::string::npos;
-
- while(true) {
- tmp = base;
- tmp += sep;
-
- std::string::size_type dirsep = in.rfind('/', last_dirsep);
- if (std::string::npos == dirsep) {
- dirsep = in.rfind('\\', last_dirsep);
- }
-
- if (std::string::npos == dirsep || dirsep == 0) {
- // we did try this already.
- break;
- }
-
- last_dirsep = dirsep-1;
-
- tmp += in.substr(dirsep+1, in.length()-pos);
- if (wrapped->Exists(tmp)) {
- in = tmp;
- return;
- }
- }
- }
-
- // hopefully the underlying file system has another few tricks to access this file ...
- }
-
- // -------------------------------------------------------------------
- /** Cleanup the given path
- */
- void Cleanup (std::string& in) const
- {
- char last = 0;
- if(in.empty()) {
- return;
- }
-
- // Remove a very common issue when we're parsing file names: spaces at the
- // beginning of the path.
- std::string::iterator it = in.begin();
- while (IsSpaceOrNewLine( *it ))++it;
- if (it != in.begin()) {
- in.erase(in.begin(),it+1);
- }
-
- const char sep = getOsSeparator();
- for (it = in.begin(); it != in.end(); ++it) {
- // Exclude :// and \\, which remain untouched.
- // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
- if ( !strncmp(&*it, "://", 3 )) {
- it += 3;
- continue;
- }
- if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) {
- it += 2;
- continue;
- }
-
- // Cleanup path delimiters
- if (*it == '/' || (*it) == '\\') {
- *it = sep;
-
- // And we're removing double delimiters, frequent issue with
- // incorrectly composited paths ...
- if (last == *it) {
- it = in.erase(it);
- --it;
- }
- }
- else if (*it == '%' && in.end() - it > 2) {
-
- // Hex sequence in URIs
- if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
- *it = HexOctetToDecimal(&*it);
- it = in.erase(it+1,it+2);
- --it;
- }
- }
-
- last = *it;
- }
- }
-
-private:
- IOSystem* wrapped;
- std::string src_file, base;
- char sep;
-};
-
-} //!ns Assimp
-
-#endif //AI_DEFAULTIOSYSTEM_H_INC
diff --git a/src/3rdparty/assimp/code/FindDegenerates.cpp b/src/3rdparty/assimp/code/FindDegenerates.cpp
deleted file mode 100644
index f9c04133a..000000000
--- a/src/3rdparty/assimp/code/FindDegenerates.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FindDegenerates.cpp
- * @brief Implementation of the FindDegenerates post-process step.
-*/
-
-
-
-// internal headers
-#include "ProcessHelper.h"
-#include "FindDegenerates.h"
-#include "Exceptional.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindDegeneratesProcess::FindDegeneratesProcess()
-: mConfigRemoveDegenerates( false )
-, mConfigCheckAreaOfTriangle( false ){
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindDegeneratesProcess::~FindDegeneratesProcess() {
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
- return 0 != (pFlags & aiProcess_FindDegenerates);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
- // Get the current value of AI_CONFIG_PP_FD_REMOVE
- mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
- mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindDegeneratesProcess::Execute( aiScene* pScene) {
- DefaultLogger::get()->debug("FindDegeneratesProcess begin");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
- ExecuteOnMesh( pScene->mMeshes[ i ] );
- }
- DefaultLogger::get()->debug("FindDegeneratesProcess finished");
-}
-
-static ai_real heron( ai_real a, ai_real b, ai_real c ) {
- ai_real s = (a + b + c) / 2;
- ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
- return area;
-}
-
-static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
- const ai_real lx = ( vB.x - vA.x );
- const ai_real ly = ( vB.y - vA.y );
- const ai_real lz = ( vB.z - vA.z );
- ai_real a = lx*lx + ly*ly + lz*lz;
- ai_real d = pow( a, (ai_real)0.5 );
-
- return d;
-}
-
-static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
- ai_real area = 0;
-
- aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
- aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
- aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
-
- ai_real a( distance3D( vA, vB ) );
- ai_real b( distance3D( vB, vC ) );
- ai_real c( distance3D( vC, vA ) );
- area = heron( a, b, c );
-
- return area;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported mesh
-void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
- mesh->mPrimitiveTypes = 0;
-
- std::vector<bool> remove_me;
- if (mConfigRemoveDegenerates) {
- remove_me.resize( mesh->mNumFaces, false );
- }
-
- unsigned int deg = 0, limit;
- for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) {
- aiFace& face = mesh->mFaces[a];
- bool first = true;
-
- // check whether the face contains degenerated entries
- for (unsigned int i = 0; i < face.mNumIndices; ++i) {
- // Polygons with more than 4 points are allowed to have double points, that is
- // simulating polygons with holes just with concave polygons. However,
- // double points may not come directly after another.
- limit = face.mNumIndices;
- if (face.mNumIndices > 4) {
- limit = std::min( limit, i+2 );
- }
-
- for (unsigned int t = i+1; t < limit; ++t) {
- if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) {
- // we have found a matching vertex position
- // remove the corresponding index from the array
- --face.mNumIndices;
- --limit;
- for (unsigned int m = t; m < face.mNumIndices; ++m) {
- face.mIndices[ m ] = face.mIndices[ m+1 ];
- }
- --t;
-
- // NOTE: we set the removed vertex index to an unique value
- // to make sure the developer gets notified when his
- // application attemps to access this data.
- face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
-
- if(first) {
- ++deg;
- first = false;
- }
-
- if ( mConfigRemoveDegenerates ) {
- remove_me[ a ] = true;
- goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
- }
- }
- }
-
- if ( mConfigCheckAreaOfTriangle ) {
- if ( face.mNumIndices == 3 ) {
- ai_real area = calculateAreaOfTriangle( face, mesh );
- if ( area < 1e-6 ) {
- if ( mConfigRemoveDegenerates ) {
- remove_me[ a ] = true;
- goto evil_jump_outside;
- }
-
- // todo: check for index which is corrupt.
- }
- }
- }
- }
-
- // We need to update the primitive flags array of the mesh.
- switch (face.mNumIndices)
- {
- case 1u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- };
-evil_jump_outside:
- continue;
- }
-
- // If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
- if (mConfigRemoveDegenerates && deg) {
- unsigned int n = 0;
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
- {
- aiFace& face_src = mesh->mFaces[a];
- if (!remove_me[a]) {
- aiFace& face_dest = mesh->mFaces[n++];
-
- // Do a manual copy, keep the index array
- face_dest.mNumIndices = face_src.mNumIndices;
- face_dest.mIndices = face_src.mIndices;
-
- if (&face_src != &face_dest) {
- // clear source
- face_src.mNumIndices = 0;
- face_src.mIndices = NULL;
- }
- }
- else {
- // Otherwise delete it if we don't need this face
- delete[] face_src.mIndices;
- face_src.mIndices = NULL;
- face_src.mNumIndices = 0;
- }
- }
- // Just leave the rest of the array unreferenced, we don't care for now
- mesh->mNumFaces = n;
- if (!mesh->mNumFaces) {
- // WTF!?
- // OK ... for completeness and because I'm not yet tired,
- // let's write code that willl hopefully never be called
- // (famous last words)
-
- // OK ... bad idea.
- throw DeadlyImportError("Mesh is empty after removal of degenerated primitives ... WTF!?");
- }
- }
-
- if (deg && !DefaultLogger::isNullLogger())
- {
- char s[64];
- ASSIMP_itoa10(s,deg);
- DefaultLogger::get()->warn(std::string("Found ") + s + " degenerated primitives");
- }
-}
diff --git a/src/3rdparty/assimp/code/FindDegenerates.h b/src/3rdparty/assimp/code/FindDegenerates.h
deleted file mode 100644
index cf03a24bc..000000000
--- a/src/3rdparty/assimp/code/FindDegenerates.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to search all meshes for
- degenerated faces */
-#ifndef AI_FINDDEGENERATESPROCESS_H_INC
-#define AI_FINDDEGENERATESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-class FindDegeneratesProcessTest;
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
-*/
-class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
-public:
- FindDegeneratesProcess();
- ~FindDegeneratesProcess();
-
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- // Execute step on a given mesh
- void ExecuteOnMesh( aiMesh* mesh);
-
- // -------------------------------------------------------------------
- /// @brief Enable the instant removal of degenerated primitives
- /// @param enabled true for enabled.
- void EnableInstantRemoval(bool enabled);
-
- // -------------------------------------------------------------------
- /// @brief Check whether instant removal is currently enabled
- /// @return The instant removal state.
- bool IsInstantRemoval() const;
-
- // -------------------------------------------------------------------
- /// @brief Enable the area check for triangles.
- /// @param enabled true for enabled.
- void EnableAreaCheck( bool enabled );
-
- // -------------------------------------------------------------------
- /// @brief Check whether the area check is enabled.
- /// @return The area check state.
- bool isAreaCheckEnabled() const;
-
-private:
- //! Configuration option: remove degenerates faces immediately
- bool mConfigRemoveDegenerates;
- //! Configuration option: check for area
- bool mConfigCheckAreaOfTriangle;
-};
-
-inline
-void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
- mConfigRemoveDegenerates = enabled;
-}
-
-inline
-bool FindDegeneratesProcess::IsInstantRemoval() const {
- return mConfigRemoveDegenerates;
-}
-
-inline
-void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
- mConfigCheckAreaOfTriangle = enabled;
-}
-
-inline
-bool FindDegeneratesProcess::isAreaCheckEnabled() const {
- return mConfigCheckAreaOfTriangle;
-}
-
-} // Namespace Assimp
-
-#endif // !! AI_FINDDEGENERATESPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/FindInstancesProcess.cpp b/src/3rdparty/assimp/code/FindInstancesProcess.cpp
deleted file mode 100644
index ab2d2257b..000000000
--- a/src/3rdparty/assimp/code/FindInstancesProcess.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FindInstancesProcess.cpp
- * @brief Implementation of the aiProcess_FindInstances postprocessing step
-*/
-
-
-#include "FindInstancesProcess.h"
-#include <memory>
-#include <stdio.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindInstancesProcess::FindInstancesProcess()
-: configSpeedFlag (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInstancesProcess::~FindInstancesProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindInstancesProcess::IsActive( unsigned int pFlags) const
-{
- // FindInstances makes absolutely no sense together with PreTransformVertices
- // fixme: spawn error message somewhere else?
- return 0 != (pFlags & aiProcess_FindInstances) && 0 == (pFlags & aiProcess_PreTransformVertices);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the step
-void FindInstancesProcess::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compare the bones of two meshes
-bool CompareBones(const aiMesh* orig, const aiMesh* inst)
-{
- for (unsigned int i = 0; i < orig->mNumBones;++i) {
- aiBone* aha = orig->mBones[i];
- aiBone* oha = inst->mBones[i];
-
- if (aha->mNumWeights != oha->mNumWeights ||
- aha->mOffsetMatrix != oha->mOffsetMatrix) {
- return false;
- }
-
- // compare weight per weight ---
- for (unsigned int n = 0; n < aha->mNumWeights;++n) {
- if (aha->mWeights[n].mVertexId != oha->mWeights[n].mVertexId ||
- (aha->mWeights[n].mWeight - oha->mWeights[n].mWeight) < 10e-3f) {
- return false;
- }
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update mesh indices in the node graph
-void UpdateMeshIndices(aiNode* node, unsigned int* lookup)
-{
- for (unsigned int n = 0; n < node->mNumMeshes;++n)
- node->mMeshes[n] = lookup[node->mMeshes[n]];
-
- for (unsigned int n = 0; n < node->mNumChildren;++n)
- UpdateMeshIndices(node->mChildren[n],lookup);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindInstancesProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FindInstancesProcess begin");
- if (pScene->mNumMeshes) {
-
- // use a pseudo hash for all meshes in the scene to quickly find
- // the ones which are possibly equal. This step is executed early
- // in the pipeline, so we could, depending on the file format,
- // have several thousand small meshes. That's too much for a brute
- // everyone-against-everyone check involving up to 10 comparisons
- // each.
- std::unique_ptr<uint64_t[]> hashes (new uint64_t[pScene->mNumMeshes]);
- std::unique_ptr<unsigned int[]> remapping (new unsigned int[pScene->mNumMeshes]);
-
- unsigned int numMeshesOut = 0;
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
-
- aiMesh* inst = pScene->mMeshes[i];
- hashes[i] = GetMeshHash(inst);
-
- for (int a = i-1; a >= 0; --a) {
- if (hashes[i] == hashes[a])
- {
- aiMesh* orig = pScene->mMeshes[a];
- if (!orig)
- continue;
-
- // check for hash collision .. we needn't check
- // the vertex format, it *must* match due to the
- // (brilliant) construction of the hash
- if (orig->mNumBones != inst->mNumBones ||
- orig->mNumFaces != inst->mNumFaces ||
- orig->mNumVertices != inst->mNumVertices ||
- orig->mMaterialIndex != inst->mMaterialIndex ||
- orig->mPrimitiveTypes != inst->mPrimitiveTypes)
- continue;
-
- // up to now the meshes are equal. find an appropriate
- // epsilon to compare position differences against
- float epsilon = ComputePositionEpsilon(inst);
- epsilon *= epsilon;
-
- // now compare vertex positions, normals,
- // tangents and bitangents using this epsilon.
- if (orig->HasPositions()) {
- if(!CompareArrays(orig->mVertices,inst->mVertices,orig->mNumVertices,epsilon))
- continue;
- }
- if (orig->HasNormals()) {
- if(!CompareArrays(orig->mNormals,inst->mNormals,orig->mNumVertices,epsilon))
- continue;
- }
- if (orig->HasTangentsAndBitangents()) {
- if (!CompareArrays(orig->mTangents,inst->mTangents,orig->mNumVertices,epsilon) ||
- !CompareArrays(orig->mBitangents,inst->mBitangents,orig->mNumVertices,epsilon))
- continue;
- }
-
- // use a constant epsilon for colors and UV coordinates
- static const float uvEpsilon = 10e-4f;
- {
- unsigned int i, end = orig->GetNumUVChannels();
- for(i = 0; i < end; ++i) {
- if (!orig->mTextureCoords[i]) {
- continue;
- }
- if(!CompareArrays(orig->mTextureCoords[i],inst->mTextureCoords[i],orig->mNumVertices,uvEpsilon)) {
- break;
- }
- }
- if (i != end) {
- continue;
- }
- }
- {
- unsigned int i, end = orig->GetNumColorChannels();
- for(i = 0; i < end; ++i) {
- if (!orig->mColors[i]) {
- continue;
- }
- if(!CompareArrays(orig->mColors[i],inst->mColors[i],orig->mNumVertices,uvEpsilon)) {
- break;
- }
- }
- if (i != end) {
- continue;
- }
- }
-
- // These two checks are actually quite expensive and almost *never* required.
- // Almost. That's why they're still here. But there's no reason to do them
- // in speed-targeted imports.
- if (!configSpeedFlag) {
-
- // It seems to be strange, but we really need to check whether the
- // bones are identical too. Although it's extremely unprobable
- // that they're not if control reaches here, we need to deal
- // with unprobable cases, too. It could still be that there are
- // equal shapes which are deformed differently.
- if (!CompareBones(orig,inst))
- continue;
-
- // For completeness ... compare even the index buffers for equality
- // face order & winding order doesn't care. Input data is in verbose format.
- std::unique_ptr<unsigned int[]> ftbl_orig(new unsigned int[orig->mNumVertices]);
- std::unique_ptr<unsigned int[]> ftbl_inst(new unsigned int[orig->mNumVertices]);
-
- for (unsigned int tt = 0; tt < orig->mNumFaces;++tt) {
- aiFace& f = orig->mFaces[tt];
- for (unsigned int nn = 0; nn < f.mNumIndices;++nn)
- ftbl_orig[f.mIndices[nn]] = tt;
-
- aiFace& f2 = inst->mFaces[tt];
- for (unsigned int nn = 0; nn < f2.mNumIndices;++nn)
- ftbl_inst[f2.mIndices[nn]] = tt;
- }
- if (0 != ::memcmp(ftbl_inst.get(),ftbl_orig.get(),orig->mNumVertices*sizeof(unsigned int)))
- continue;
- }
-
- // We're still here. Or in other words: 'inst' is an instance of 'orig'.
- // Place a marker in our list that we can easily update mesh indices.
- remapping[i] = remapping[a];
-
- // Delete the instanced mesh, we don't need it anymore
- delete inst;
- pScene->mMeshes[i] = NULL;
- break;
- }
- }
-
- // If we didn't find a match for the current mesh: keep it
- if (pScene->mMeshes[i]) {
- remapping[i] = numMeshesOut++;
- }
- }
- ai_assert(0 != numMeshesOut);
- if (numMeshesOut != pScene->mNumMeshes) {
-
- // Collapse the meshes array by removing all NULL entries
- for (unsigned int real = 0, i = 0; real < numMeshesOut; ++i) {
- if (pScene->mMeshes[i])
- pScene->mMeshes[real++] = pScene->mMeshes[i];
- }
-
- // And update the node graph with our nice lookup table
- UpdateMeshIndices(pScene->mRootNode,remapping.get());
-
- // write to log
- if (!DefaultLogger::isNullLogger()) {
-
- char buffer[512];
- ::ai_snprintf(buffer,512,"FindInstancesProcess finished. Found %i instances",pScene->mNumMeshes-numMeshesOut);
- DefaultLogger::get()->info(buffer);
- }
- pScene->mNumMeshes = numMeshesOut;
- }
- else DefaultLogger::get()->debug("FindInstancesProcess finished. No instanced meshes found");
- }
-}
diff --git a/src/3rdparty/assimp/code/FindInstancesProcess.h b/src/3rdparty/assimp/code/FindInstancesProcess.h
deleted file mode 100644
index dc4396566..000000000
--- a/src/3rdparty/assimp/code/FindInstancesProcess.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 FindInstancesProcess.h
- * @brief Declares the aiProcess_FindInstances post-process step
- */
-#ifndef AI_FINDINSTANCES_H_INC
-#define AI_FINDINSTANCES_H_INC
-
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
-
-class FindInstancesProcessTest;
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-/** @brief Get a pseudo(!)-hash representing a mesh.
- *
- * The hash is built from number of vertices, faces, primitive types,
- * .... but *not* from the real mesh data. The funcction is not a perfect hash.
- * @param in Input mesh
- * @return Hash.
- */
-inline uint64_t GetMeshHash(aiMesh* in)
-{
- ai_assert(NULL != in);
-
- // ... get an unique value representing the vertex format of the mesh
- const unsigned int fhash = GetMeshVFormatUnique(in);
-
- // and bake it with number of vertices/faces/bones/matidx/ptypes
- return ((uint64_t)fhash << 32u) | ((
- (in->mNumBones << 16u) ^ (in->mNumVertices) ^
- (in->mNumFaces<<4u) ^ (in->mMaterialIndex<<15) ^
- (in->mPrimitiveTypes<<28)) & 0xffffffff );
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Perform a component-wise comparison of two arrays
- *
- * @param first First array
- * @param second Second aray
- * @param size Size of both arrays
- * @param e Epsilon
- * @return true if the arrays are identical
- */
-inline bool CompareArrays(const aiVector3D* first, const aiVector3D* second,
- unsigned int size, float e)
-{
- for (const aiVector3D* end = first+size; first != end; ++first,++second) {
- if ( (*first - *second).SquareLength() >= e)
- return false;
- }
- return true;
-}
-
-// and the same for colors ...
-inline bool CompareArrays(const aiColor4D* first, const aiColor4D* second,
- unsigned int size, float e)
-{
- for (const aiColor4D* end = first+size; first != end; ++first,++second) {
- if ( GetColorDifference(*first,*second) >= e)
- return false;
- }
- return true;
-}
-
-// ---------------------------------------------------------------------------
-/** @brief A post-processing steps to search for instanced meshes
-*/
-class FindInstancesProcess : public BaseProcess
-{
-public:
-
- FindInstancesProcess();
- ~FindInstancesProcess();
-
-public:
- // -------------------------------------------------------------------
- // Check whether step is active in given flags combination
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup properties prior to executing the process
- void SetupProperties(const Importer* pImp);
-
-private:
-
- bool configSpeedFlag;
-
-}; // ! end class FindInstancesProcess
-} // ! end namespace Assimp
-
-#endif // !! AI_FINDINSTANCES_H_INC
diff --git a/src/3rdparty/assimp/code/FindInvalidDataProcess.cpp b/src/3rdparty/assimp/code/FindInvalidDataProcess.cpp
deleted file mode 100644
index c37d8956c..000000000
--- a/src/3rdparty/assimp/code/FindInvalidDataProcess.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to search an importer's output
- for data that is obviously invalid */
-
-
-
-#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-
-// internal headers
-#include "FindInvalidDataProcess.h"
-#include "ProcessHelper.h"
-#include "Macros.h"
-#include "Exceptional.h"
-#include "qnan.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FindInvalidDataProcess::FindInvalidDataProcess()
- : configEpsilon(0.0)
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FindInvalidDataProcess::~FindInvalidDataProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FindInvalidDataProcess::IsActive( unsigned int pFlags) const
-{
- return 0 != (pFlags & aiProcess_FindInvalidData);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void FindInvalidDataProcess::SetupProperties(const Importer* pImp)
-{
- // Get the current value of AI_CONFIG_PP_FID_ANIM_ACCURACY
- configEpsilon = (0 != pImp->GetPropertyFloat(AI_CONFIG_PP_FID_ANIM_ACCURACY,0.f));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update mesh references in the node graph
-void UpdateMeshReferences(aiNode* node, const std::vector<unsigned int>& meshMapping)
-{
- if (node->mNumMeshes) {
- unsigned int out = 0;
- for (unsigned int a = 0; a < node->mNumMeshes;++a) {
-
- unsigned int ref = node->mMeshes[a];
- if (UINT_MAX != (ref = meshMapping[ref])) {
- node->mMeshes[out++] = ref;
- }
- }
- // just let the members that are unused, that's much cheaper
- // than a full array realloc'n'copy party ...
- if(!(node->mNumMeshes = out)) {
-
- delete[] node->mMeshes;
- node->mMeshes = NULL;
- }
- }
- // recursively update all children
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- UpdateMeshReferences(node->mChildren[i],meshMapping);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FindInvalidDataProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FindInvalidDataProcess begin");
-
- bool out = false;
- std::vector<unsigned int> meshMapping(pScene->mNumMeshes);
- unsigned int real = 0;
-
- // Process meshes
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
-
- int result;
- if ((result = ProcessMesh( pScene->mMeshes[a]))) {
- out = true;
-
- if (2 == result) {
- // remove this mesh
- delete pScene->mMeshes[a];
- AI_DEBUG_INVALIDATE_PTR(pScene->mMeshes[a]);
-
- meshMapping[a] = UINT_MAX;
- continue;
- }
- }
- pScene->mMeshes[real] = pScene->mMeshes[a];
- meshMapping[a] = real++;
- }
-
- // Process animations
- for (unsigned int a = 0; a < pScene->mNumAnimations;++a) {
- ProcessAnimation( pScene->mAnimations[a]);
- }
-
-
- if (out) {
- if ( real != pScene->mNumMeshes) {
- if (!real) {
- throw DeadlyImportError("No meshes remaining");
- }
-
- // we need to remove some meshes.
- // therefore we'll also need to remove all references
- // to them from the scenegraph
- UpdateMeshReferences(pScene->mRootNode,meshMapping);
- pScene->mNumMeshes = real;
- }
-
- DefaultLogger::get()->info("FindInvalidDataProcess finished. Found issues ...");
- }
- else DefaultLogger::get()->debug("FindInvalidDataProcess finished. Everything seems to be OK.");
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline const char* ValidateArrayContents(const T* /*arr*/, unsigned int /*size*/,
- const std::vector<bool>& /*dirtyMask*/, bool /*mayBeIdentical = false*/, bool /*mayBeZero = true*/)
-{
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-inline const char* ValidateArrayContents<aiVector3D>(const aiVector3D* arr, unsigned int size,
- const std::vector<bool>& dirtyMask, bool mayBeIdentical , bool mayBeZero )
-{
- bool b = false;
- unsigned int cnt = 0;
- for (unsigned int i = 0; i < size;++i) {
-
- if (dirtyMask.size() && dirtyMask[i]) {
- continue;
- }
- ++cnt;
-
- const aiVector3D& v = arr[i];
- if (is_special_float(v.x) || is_special_float(v.y) || is_special_float(v.z)) {
- return "INF/NAN was found in a vector component";
- }
- if (!mayBeZero && !v.x && !v.y && !v.z ) {
- return "Found zero-length vector";
- }
- if (i && v != arr[i-1])b = true;
- }
- if (cnt > 1 && !b && !mayBeIdentical) {
- return "All vectors are identical";
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline bool ProcessArray(T*& in, unsigned int num,const char* name,
- const std::vector<bool>& dirtyMask, bool mayBeIdentical = false, bool mayBeZero = true)
-{
- const char* err = ValidateArrayContents(in,num,dirtyMask,mayBeIdentical,mayBeZero);
- if (err) {
- DefaultLogger::get()->error(std::string("FindInvalidDataProcess fails on mesh ") + name + ": " + err);
-
- delete[] in;
- in = NULL;
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-AI_FORCE_INLINE bool EpsilonCompare(const T& n, const T& s, ai_real epsilon);
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE bool EpsilonCompare(ai_real n, ai_real s, ai_real epsilon) {
- return std::fabs(n-s)>epsilon;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-bool EpsilonCompare<aiVectorKey>(const aiVectorKey& n, const aiVectorKey& s, ai_real epsilon) {
- return
- EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
- EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
- EpsilonCompare(n.mValue.z,s.mValue.z,epsilon);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <>
-bool EpsilonCompare<aiQuatKey>(const aiQuatKey& n, const aiQuatKey& s, ai_real epsilon) {
- return
- EpsilonCompare(n.mValue.x,s.mValue.x,epsilon) &&
- EpsilonCompare(n.mValue.y,s.mValue.y,epsilon) &&
- EpsilonCompare(n.mValue.z,s.mValue.z,epsilon) &&
- EpsilonCompare(n.mValue.w,s.mValue.w,epsilon);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline bool AllIdentical(T* in, unsigned int num, ai_real epsilon)
-{
- if (num <= 1) {
- return true;
- }
-
- if (epsilon > 0.f) {
- for (unsigned int i = 0; i < num-1;++i) {
-
- if (!EpsilonCompare(in[i],in[i+1],epsilon)) {
- return false;
- }
- }
- }
- else {
- for (unsigned int i = 0; i < num-1;++i) {
-
- if (in[i] != in[i+1]) {
- return false;
- }
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search an animation for invalid content
-void FindInvalidDataProcess::ProcessAnimation (aiAnimation* anim)
-{
- // Process all animation channels
- for (unsigned int a = 0; a < anim->mNumChannels;++a) {
- ProcessAnimationChannel( anim->mChannels[a]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
-{
- int i = 0;
-
- // ScenePreprocessor's work ...
- ai_assert((0 != anim->mPositionKeys && 0 != anim->mRotationKeys && 0 != anim->mScalingKeys));
-
- // Check whether all values in a tracks are identical - in this case
- // we can remove al keys except one.
- // POSITIONS
- if (anim->mNumPositionKeys > 1 && AllIdentical(anim->mPositionKeys,anim->mNumPositionKeys,configEpsilon))
- {
- aiVectorKey v = anim->mPositionKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mPositionKeys;
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys = 1];
- anim->mPositionKeys[0] = v;
- i = 1;
- }
-
- // ROTATIONS
- if (anim->mNumRotationKeys > 1 && AllIdentical(anim->mRotationKeys,anim->mNumRotationKeys,configEpsilon))
- {
- aiQuatKey v = anim->mRotationKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mRotationKeys;
- anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys = 1];
- anim->mRotationKeys[0] = v;
- i = 1;
- }
-
- // SCALINGS
- if (anim->mNumScalingKeys > 1 && AllIdentical(anim->mScalingKeys,anim->mNumScalingKeys,configEpsilon))
- {
- aiVectorKey v = anim->mScalingKeys[0];
-
- // Reallocate ... we need just ONE element, it makes no sense to reuse the array
- delete[] anim->mScalingKeys;
- anim->mScalingKeys = new aiVectorKey[anim->mNumScalingKeys = 1];
- anim->mScalingKeys[0] = v;
- i = 1;
- }
- if (1 == i)
- DefaultLogger::get()->warn("Simplified dummy tracks with just one key");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search a mesh for invalid contents
-int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
-{
- bool ret = false;
- std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0);
-
- // Ignore elements that are not referenced by vertices.
- // (they are, for example, caused by the FindDegenerates step)
- for (unsigned int m = 0; m < pMesh->mNumFaces; ++m) {
- const aiFace& f = pMesh->mFaces[m];
-
- for (unsigned int i = 0; i < f.mNumIndices; ++i) {
- dirtyMask[f.mIndices[i]] = false;
- }
- }
-
- // Process vertex positions
- if (pMesh->mVertices && ProcessArray(pMesh->mVertices, pMesh->mNumVertices, "positions", dirtyMask)) {
- DefaultLogger::get()->error("Deleting mesh: Unable to continue without vertex positions");
-
- return 2;
- }
-
- // process texture coordinates
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS && pMesh->mTextureCoords[i]; ++i) {
- if (ProcessArray(pMesh->mTextureCoords[i], pMesh->mNumVertices, "uvcoords", dirtyMask)) {
- pMesh->mNumUVComponents[i] = 0;
-
- // delete all subsequent texture coordinate sets.
- for (unsigned int a = i + 1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
- delete[] pMesh->mTextureCoords[a];
- pMesh->mTextureCoords[a] = NULL;
- pMesh->mNumUVComponents[a] = 0;
- }
-
- ret = true;
- }
- }
-
- // -- we don't validate vertex colors, it's difficult to say whether
- // they are invalid or not.
-
- // Normals and tangents are undefined for point and line faces.
- if (pMesh->mNormals || pMesh->mTangents) {
-
- if (aiPrimitiveType_POINT & pMesh->mPrimitiveTypes ||
- aiPrimitiveType_LINE & pMesh->mPrimitiveTypes)
- {
- if (aiPrimitiveType_TRIANGLE & pMesh->mPrimitiveTypes ||
- aiPrimitiveType_POLYGON & pMesh->mPrimitiveTypes)
- {
- // We need to update the lookup-table
- for (unsigned int m = 0; m < pMesh->mNumFaces;++m)
- {
- const aiFace& f = pMesh->mFaces[m];
-
- if (f.mNumIndices < 3) {
- dirtyMask[f.mIndices[0]] = true;
-
- if (f.mNumIndices == 2) {
- dirtyMask[f.mIndices[1]] = true;
- }
- }
- }
- }
- // Normals, tangents and bitangents are undefined for
- // the whole mesh (and should not even be there)
- else return ret;
- }
-
- // Process mesh normals
- if (pMesh->mNormals && ProcessArray(pMesh->mNormals,pMesh->mNumVertices,
- "normals",dirtyMask,true,false))
- ret = true;
-
- // Process mesh tangents
- if (pMesh->mTangents && ProcessArray(pMesh->mTangents,pMesh->mNumVertices,"tangents",dirtyMask)) {
- delete[] pMesh->mBitangents; pMesh->mBitangents = NULL;
- ret = true;
- }
-
- // Process mesh bitangents
- if (pMesh->mBitangents && ProcessArray(pMesh->mBitangents,pMesh->mNumVertices,"bitangents",dirtyMask)) {
- delete[] pMesh->mTangents; pMesh->mTangents = NULL;
- ret = true;
- }
- }
- return ret ? 1 : 0;
-}
-
-
-#endif // !! ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
diff --git a/src/3rdparty/assimp/code/FindInvalidDataProcess.h b/src/3rdparty/assimp/code/FindInvalidDataProcess.h
deleted file mode 100644
index cc0ef946d..000000000
--- a/src/3rdparty/assimp/code/FindInvalidDataProcess.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to search an importer's output
- for data that is obviously invalid */
-#ifndef AI_FINDINVALIDDATA_H_INC
-#define AI_FINDINVALIDDATA_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/types.h>
-#include <assimp/anim.h>
-
-struct aiMesh;
-class FindInvalidDataProcessTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** 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 ASSIMP_API FindInvalidDataProcess : public BaseProcess
-{
-public:
-
- FindInvalidDataProcess();
- ~FindInvalidDataProcess();
-
-public:
-
- // -------------------------------------------------------------------
- //
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- // Run the step
- void Execute( aiScene* pScene);
-
-public:
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given mesh
- * @param pMesh The mesh to process.
- * @return 0 - nothing, 1 - removed sth, 2 - please delete me */
- int ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given animation
- * @param anim The animation to process. */
- void ProcessAnimation (aiAnimation* anim);
-
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given anim channel
- * @param anim The animation channel to process.*/
- void ProcessAnimationChannel (aiNodeAnim* anim);
-
-private:
- ai_real configEpsilon;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_AI_FINDINVALIDDATA_H_INC
diff --git a/src/3rdparty/assimp/code/FixNormalsStep.cpp b/src/3rdparty/assimp/code/FixNormalsStep.cpp
deleted file mode 100644
index 05d05e873..000000000
--- a/src/3rdparty/assimp/code/FixNormalsStep.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to invert
- * all normals in meshes with infacing normals.
- */
-
-// internal headers
-#include "FixNormalsStep.h"
-#include "StringUtils.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/postprocess.h>
-#include <assimp/scene.h>
-#include <stdio.h>
-
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-FixInfacingNormalsProcess::FixInfacingNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-FixInfacingNormalsProcess::~FixInfacingNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool FixInfacingNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_FixInfacingNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void FixInfacingNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("FixInfacingNormalsProcess begin");
-
- bool bHas = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- if(ProcessMesh( pScene->mMeshes[a],a))bHas = true;
-
- if (bHas)
- DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. Found issues.");
- else DefaultLogger::get()->debug("FixInfacingNormalsProcess finished. No changes to the scene.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apply the step to the mesh
-bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
-{
- ai_assert(NULL != pcMesh);
-
- // Nothing to do if there are no model normals
- if (!pcMesh->HasNormals())return false;
-
- // Compute the bounding box of both the model vertices + normals and
- // the umodified model vertices. Then check whether the first BB
- // is smaller than the second. In this case we can assume that the
- // normals need to be flipped, although there are a few special cases ..
- // convex, concave, planar models ...
-
- aiVector3D vMin0 (1e10f,1e10f,1e10f);
- aiVector3D vMin1 (1e10f,1e10f,1e10f);
- aiVector3D vMax0 (-1e10f,-1e10f,-1e10f);
- aiVector3D vMax1 (-1e10f,-1e10f,-1e10f);
-
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- {
- vMin1.x = std::min(vMin1.x,pcMesh->mVertices[i].x);
- vMin1.y = std::min(vMin1.y,pcMesh->mVertices[i].y);
- vMin1.z = std::min(vMin1.z,pcMesh->mVertices[i].z);
-
- vMax1.x = std::max(vMax1.x,pcMesh->mVertices[i].x);
- vMax1.y = std::max(vMax1.y,pcMesh->mVertices[i].y);
- vMax1.z = std::max(vMax1.z,pcMesh->mVertices[i].z);
-
- const aiVector3D vWithNormal = pcMesh->mVertices[i] + pcMesh->mNormals[i];
-
- vMin0.x = std::min(vMin0.x,vWithNormal.x);
- vMin0.y = std::min(vMin0.y,vWithNormal.y);
- vMin0.z = std::min(vMin0.z,vWithNormal.z);
-
- vMax0.x = std::max(vMax0.x,vWithNormal.x);
- vMax0.y = std::max(vMax0.y,vWithNormal.y);
- vMax0.z = std::max(vMax0.z,vWithNormal.z);
- }
-
- const float fDelta0_x = (vMax0.x - vMin0.x);
- const float fDelta0_y = (vMax0.y - vMin0.y);
- const float fDelta0_z = (vMax0.z - vMin0.z);
-
- const float fDelta1_x = (vMax1.x - vMin1.x);
- const float fDelta1_y = (vMax1.y - vMin1.y);
- const float fDelta1_z = (vMax1.z - vMin1.z);
-
- // Check whether the boxes are overlapping
- if ((fDelta0_x > 0.0f) != (fDelta1_x > 0.0f))return false;
- if ((fDelta0_y > 0.0f) != (fDelta1_y > 0.0f))return false;
- if ((fDelta0_z > 0.0f) != (fDelta1_z > 0.0f))return false;
-
- // Check whether this is a planar surface
- const float fDelta1_yz = fDelta1_y * fDelta1_z;
-
- if (fDelta1_x < 0.05f * std::sqrt( fDelta1_yz ))return false;
- if (fDelta1_y < 0.05f * std::sqrt( fDelta1_z * fDelta1_x ))return false;
- if (fDelta1_z < 0.05f * std::sqrt( fDelta1_y * fDelta1_x ))return false;
-
- // now compare the volumes of the bounding boxes
- if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) <
- std::fabs(fDelta1_x * fDelta1_yz))
- {
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[128]; // should be sufficiently large
- ai_snprintf(buffer,128,"Mesh %u: Normals are facing inwards (or the mesh is planar)",index);
- DefaultLogger::get()->info(buffer);
- }
-
- // Invert normals
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- pcMesh->mNormals[i] *= -1.0f;
-
- // ... and flip faces
- for (unsigned int i = 0; i < pcMesh->mNumFaces;++i)
- {
- aiFace& face = pcMesh->mFaces[i];
- for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
- std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
- }
- return true;
- }
- return false;
-}
diff --git a/src/3rdparty/assimp/code/FixNormalsStep.h b/src/3rdparty/assimp/code/FixNormalsStep.h
deleted file mode 100644
index 71309c7e5..000000000
--- a/src/3rdparty/assimp/code/FixNormalsStep.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to fix infacing normals */
-#ifndef AI_FIXNORMALSPROCESS_H_INC
-#define AI_FIXNORMALSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The FixInfacingNormalsProcess tries to determine whether the normal
- * vectors of an object are facing inwards. In this case they will be
- * flipped.
- */
-class FixInfacingNormalsProcess : public BaseProcess {
-public:
- FixInfacingNormalsProcess();
- ~FixInfacingNormalsProcess();
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Executes the step on the given mesh
- * @param pMesh The mesh to process.
- */
- bool ProcessMesh( aiMesh* pMesh, unsigned int index);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_FIXNORMALSPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/GenFaceNormalsProcess.cpp b/src/3rdparty/assimp/code/GenFaceNormalsProcess.cpp
deleted file mode 100644
index 82d80db77..000000000
--- a/src/3rdparty/assimp/code/GenFaceNormalsProcess.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to generate face
-* normals for all imported faces.
-*/
-
-
-#include "GenFaceNormalsProcess.h"
-#include <assimp/postprocess.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include "Exceptional.h"
-#include "qnan.h"
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-GenFaceNormalsProcess::GenFaceNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenFaceNormalsProcess::~GenFaceNormalsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool GenFaceNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenFaceNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenFaceNormalsProcess begin");
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
- }
-
- bool bHas = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- if(this->GenMeshFaceNormals( pScene->mMeshes[a])) {
- bHas = true;
- }
- }
- if (bHas) {
- DefaultLogger::get()->info("GenFaceNormalsProcess finished. "
- "Face normals have been calculated");
- }
- else DefaultLogger::get()->debug("GenFaceNormalsProcess finished. "
- "Normals are already there");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool GenFaceNormalsProcess::GenMeshFaceNormals (aiMesh* pMesh)
-{
- if (NULL != pMesh->mNormals) {
- return false;
- }
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON))) {
- DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
- return false;
- }
-
- // allocate an array to hold the output normals
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- const float qnan = get_qnan();
-
- // iterate through all faces and compute per-face normals but store them per-vertex.
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3) {
- // either a point or a line -> no well-defined normal vector
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
- }
- continue;
- }
-
- 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();
-
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = vNor;
- }
- }
- return true;
-}
diff --git a/src/3rdparty/assimp/code/GenFaceNormalsProcess.h b/src/3rdparty/assimp/code/GenFaceNormalsProcess.h
deleted file mode 100644
index 024c74a28..000000000
--- a/src/3rdparty/assimp/code/GenFaceNormalsProcess.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to compute face normals for all loaded faces*/
-#ifndef AI_GENFACENORMALPROCESS_H_INC
-#define AI_GENFACENORMALPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes face normals for all faces of all meshes
-*/
-class ASSIMP_API_WINONLY GenFaceNormalsProcess : public BaseProcess
-{
-public:
-
- GenFaceNormalsProcess();
- ~GenFaceNormalsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
-private:
- bool GenMeshFaceNormals (aiMesh* pcMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENFACENORMALPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp b/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp
deleted file mode 100644
index 93c0e1351..000000000
--- a/src/3rdparty/assimp/code/GenVertexNormalsProcess.cpp
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to generate face
-* normals for all imported faces.
-*/
-
-
-
-// internal headers
-#include "GenVertexNormalsProcess.h"
-#include "ProcessHelper.h"
-#include "Exceptional.h"
-#include "qnan.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-GenVertexNormalsProcess::GenVertexNormalsProcess()
-: configMaxAngle( AI_DEG_TO_RAD( 175.f ) ) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-GenVertexNormalsProcess::~GenVertexNormalsProcess() {
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool GenVertexNormalsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_GenSmoothNormals) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenVertexNormalsProcess::SetupProperties(const Importer* pImp)
-{
- // Get the current value of the AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE property
- configMaxAngle = pImp->GetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE,(ai_real)175.0);
- configMaxAngle = AI_DEG_TO_RAD(std::max(std::min(configMaxAngle,(ai_real)175.0),(ai_real)0.0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void GenVertexNormalsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("GenVertexNormalsProcess begin");
-
- if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT)
- throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here");
-
- bool bHas = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if(GenMeshVertexNormals( pScene->mMeshes[a],a))
- bHas = true;
- }
-
- if (bHas) {
- DefaultLogger::get()->info("GenVertexNormalsProcess finished. "
- "Vertex normals have been calculated");
- }
- else DefaultLogger::get()->debug("GenVertexNormalsProcess finished. "
- "Normals are already there");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool GenVertexNormalsProcess::GenMeshVertexNormals (aiMesh* pMesh, unsigned int meshIndex)
-{
- if (NULL != pMesh->mNormals)
- return false;
-
- // If the mesh consists of lines and/or points but not of
- // triangles or higher-order polygons the normal vectors
- // are undefined.
- if (!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
- {
- DefaultLogger::get()->info("Normal vectors are undefined for line and point meshes");
- return false;
- }
-
- // Allocate the array to hold the output normals
- const float qnan = std::numeric_limits<ai_real>::quiet_NaN();
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-
- // Compute per-face normals but store them per-vertex
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- const aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices < 3)
- {
- // either a point or a line -> no normal vector
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = aiVector3D(qnan);
- }
-
- continue;
- }
-
- 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));
-
- for (unsigned int i = 0;i < face.mNumIndices;++i) {
- pMesh->mNormals[face.mIndices[i]] = vNor;
- }
- }
-
- // Set up a SpatialSort to quickly find all vertices close to a given position
- // check whether we can reuse the SpatialSort of a previous step.
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
- ai_real posEpsilon = ai_real( 1e-5 );
- if (shared) {
- std::vector<std::pair<SpatialSort,ai_real> >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf)
- {
- std::pair<SpatialSort,ai_real>& blubb = avf->operator [] (meshIndex);
- vertexFinder = &blubb.first;
- posEpsilon = blubb.second;
- }
- }
- if (!vertexFinder) {
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- posEpsilon = ComputePositionEpsilon(pMesh);
- }
- std::vector<unsigned int> verticesFound;
- aiVector3D* pcNew = new aiVector3D[pMesh->mNumVertices];
-
- if (configMaxAngle >= AI_DEG_TO_RAD( 175.f )) {
- // There is no angle limit. Thus all vertices with positions close
- // to each other will receive the same vertex normal. This allows us
- // to optimize the whole algorithm a little bit ...
- std::vector<bool> abHad(pMesh->mNumVertices,false);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- if (abHad[i]) {
- continue;
- }
-
- // Get all vertices that share this one ...
- vertexFinder->FindPositions( pMesh->mVertices[i], posEpsilon, verticesFound);
-
- aiVector3D pcNor;
- for (unsigned int a = 0; a < verticesFound.size(); ++a) {
- const aiVector3D& v = pMesh->mNormals[verticesFound[a]];
- if (is_not_qnan(v.x))pcNor += v;
- }
- pcNor.NormalizeSafe();
-
- // Write the smoothed normal back to all affected normals
- for (unsigned int a = 0; a < verticesFound.size(); ++a)
- {
- unsigned int vidx = verticesFound[a];
- pcNew[vidx] = pcNor;
- abHad[vidx] = true;
- }
- }
- }
- // Slower code path if a smooth angle is set. There are many ways to achieve
- // the effect, this one is the most straightforward one.
- else {
- const ai_real fLimit = std::cos(configMaxAngle);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- // Get all vertices that share this one ...
- vertexFinder->FindPositions( pMesh->mVertices[i] , posEpsilon, verticesFound);
-
- aiVector3D vr = pMesh->mNormals[i];
- ai_real vrlen = vr.Length();
-
- aiVector3D pcNor;
- for (unsigned int a = 0; a < verticesFound.size(); ++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 * vr >= fLimit * vrlen * v.Length())
- pcNor += v;
- }
- pcNew[i] = pcNor.NormalizeSafe();
- }
- }
-
- delete[] pMesh->mNormals;
- pMesh->mNormals = pcNew;
-
- return true;
-}
diff --git a/src/3rdparty/assimp/code/GenVertexNormalsProcess.h b/src/3rdparty/assimp/code/GenVertexNormalsProcess.h
deleted file mode 100644
index 0471ed6b0..000000000
--- a/src/3rdparty/assimp/code/GenVertexNormalsProcess.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to compute vertex normals
- for all loaded vertizes */
-#ifndef AI_GENVERTEXNORMALPROCESS_H_INC
-#define AI_GENVERTEXNORMALPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-class GenNormalsTest;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** The GenFaceNormalsProcess computes vertex normals for all vertizes
-*/
-class ASSIMP_API GenVertexNormalsProcess : public BaseProcess
-{
-public:
-
- GenVertexNormalsProcess();
- ~GenVertexNormalsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
- // setter for configMaxAngle
- inline void SetMaxSmoothAngle(ai_real f)
- {
- configMaxAngle =f;
- }
-
-public:
-
- // -------------------------------------------------------------------
- /** Computes normals for a specific mesh
- * @param pcMesh Mesh
- * @param meshIndex Index of the mesh
- * @return true if vertex normals have been computed
- */
- bool GenMeshVertexNormals (aiMesh* pcMesh, unsigned int meshIndex);
-
-private:
-
- /** Configuration option: maximum smoothing angle, in radians*/
- ai_real configMaxAngle;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENVERTEXNORMALPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/GenericProperty.h b/src/3rdparty/assimp/code/GenericProperty.h
deleted file mode 100644
index 454f4952b..000000000
--- a/src/3rdparty/assimp/code/GenericProperty.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_GENERIC_PROPERTY_H_INCLUDED
-#define AI_GENERIC_PROPERTY_H_INCLUDED
-
-#include <assimp/Importer.hpp>
-#include <assimp/ai_assert.h>
-#include "Hash.h"
-#include <map>
-
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline bool SetGenericProperty(std::map< unsigned int, T >& list,
- const char* szName, const T& value)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T>::iterator it = list.find(hash);
- if (it == list.end()) {
- list.insert(std::pair<unsigned int, T>( hash, value ));
- return false;
- }
- (*it).second = value;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
- const char* szName, const T& errorReturn)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
- if (it == list.end())
- return errorReturn;
-
- return (*it).second;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Special version for pointer types - they will be deleted when replaced with another value
-// passing NULL removes the whole property
-template <class T>
-inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
- const char* szName, T* value, bool* bWasExisting = NULL)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T*>::iterator it = list.find(hash);
- if (it == list.end()) {
- if (bWasExisting)
- *bWasExisting = false;
-
- list.insert(std::pair<unsigned int,T*>( hash, value ));
- return;
- }
- if ((*it).second != value) {
- delete (*it).second;
- (*it).second = value;
- }
- if (!value) {
- list.erase(it);
- }
- if (bWasExisting)
- *bWasExisting = true;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
- const char* szName)
-{
- ai_assert(NULL != szName);
- const uint32_t hash = SuperFastHash(szName);
-
- typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
- if (it == list.end()) return false;
-
- return true;
-}
-
-#endif // !! AI_GENERIC_PROPERTY_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/HMPFileData.h b/src/3rdparty/assimp/code/HMPFileData.h
deleted file mode 100644
index 3c060ba1a..000000000
--- a/src/3rdparty/assimp/code/HMPFileData.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Data structures for the 3D Game Studio Heightmap format (HMP)
-//!
-
-namespace Assimp {
-namespace HMP {
-
-#include "./../include/assimp/Compiler/pushpack1.h"
-#include <stdint.h>
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_HMP_MAGIC_NUMBER_BE_4 AI_MAKE_MAGIC("HMP4")
-#define AI_HMP_MAGIC_NUMBER_LE_4 AI_MAKE_MAGIC("4PMH")
-
-#define AI_HMP_MAGIC_NUMBER_BE_5 AI_MAKE_MAGIC("HMP5")
-#define AI_HMP_MAGIC_NUMBER_LE_5 AI_MAKE_MAGIC("5PMH")
-
-#define AI_HMP_MAGIC_NUMBER_BE_7 AI_MAKE_MAGIC("HMP7")
-#define AI_HMP_MAGIC_NUMBER_LE_7 AI_MAKE_MAGIC("7PMH")
-
-// ---------------------------------------------------------------------------
-/** Data structure for the header of a HMP5 file.
- * This is also used by HMP4 and HMP7, but with modifications
-*/
-struct Header_HMP5
-{
- int8_t ident[4]; // "HMP5"
- int32_t version;
-
- // ignored
- float scale[3];
- float scale_origin[3];
- float boundingradius;
-
- //! Size of one triangle in x direction
- float ftrisize_x;
- //! Size of one triangle in y direction
- float ftrisize_y;
- //! Number of vertices in x direction
- float fnumverts_x;
-
- //! Number of skins in the file
- int32_t numskins;
-
- // can ignore this?
- int32_t skinwidth;
- int32_t skinheight;
-
- //!Number of vertices in the file
- int32_t numverts;
-
- // ignored and zero
- int32_t numtris;
-
- //! only one supported ...
- int32_t numframes;
-
- //! Always 0 ...
- int32_t num_stverts;
- int32_t flags;
- float size;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP4 file
-*/
-struct Vertex_HMP4
-{
- uint16_t p_pos[3];
- uint8_t normals162index;
- uint8_t pad;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP5 file
-*/
-struct Vertex_HMP5
-{
- uint16_t z;
- uint8_t normals162index;
- uint8_t pad;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** Data structure for a terrain vertex in a HMP7 file
-*/
-struct Vertex_HMP7
-{
- uint16_t z;
- int8_t normal_x,normal_y;
-} PACK_STRUCT;
-
-#include "./../include/assimp/Compiler/poppack1.h"
-
-} //! namespace HMP
-} //! namespace Assimp
diff --git a/src/3rdparty/assimp/code/HMPLoader.cpp b/src/3rdparty/assimp/code/HMPLoader.cpp
deleted file mode 100644
index 2a669201e..000000000
--- a/src/3rdparty/assimp/code/HMPLoader.cpp
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the MDL importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-
-// internal headers
-#include "HMPLoader.h"
-#include "MD2FileData.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "3D GameStudio Heightmap (HMP) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "hmp"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-HMPImporter::HMPImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-HMPImporter::~HMPImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool HMPImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "hmp" )
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || cs) {
- uint32_t tokens[3];
- tokens[0] = AI_HMP_MAGIC_NUMBER_LE_4;
- tokens[1] = AI_HMP_MAGIC_NUMBER_LE_5;
- tokens[2] = AI_HMP_MAGIC_NUMBER_LE_7;
- return CheckMagicToken(pIOHandler,pFile,tokens,3,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of all file extensions that are handled by this loader
-const aiImporterDesc* HMPImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void HMPImporter::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pScene = _pScene;
- pIOHandler = _pIOHandler;
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open HMP file " + pFile + ".");
-
- // Check whether the HMP file is large enough to contain
- // at least the file header
- const size_t fileSize = file->FileSize();
- if( fileSize < 50)
- throw DeadlyImportError( "HMP File is too small.");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- mBuffer = new uint8_t[fileSize];
- file->Read( (void*)mBuffer, 1, fileSize);
- iFileSize = (unsigned int)fileSize;
-
- // Determine the file subtype and call the appropriate member function
- const uint32_t iMagic = *((uint32_t*)this->mBuffer);
-
- // HMP4 format
- if (AI_HMP_MAGIC_NUMBER_LE_4 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_4 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A4, magic word is HMP4");
- InternReadFile_HMP4();
- }
- // HMP5 format
- else if (AI_HMP_MAGIC_NUMBER_LE_5 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_5 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A5, magic word is HMP5");
- InternReadFile_HMP5();
- }
- // HMP7 format
- else if (AI_HMP_MAGIC_NUMBER_LE_7 == iMagic ||
- AI_HMP_MAGIC_NUMBER_BE_7 == iMagic)
- {
- DefaultLogger::get()->debug("HMP subtype: 3D GameStudio A7, magic word is HMP7");
- InternReadFile_HMP7();
- }
- else
- {
- // Print the magic word to the logger
- char szBuffer[5];
- szBuffer[0] = ((char*)&iMagic)[0];
- szBuffer[1] = ((char*)&iMagic)[1];
- szBuffer[2] = ((char*)&iMagic)[2];
- szBuffer[3] = ((char*)&iMagic)[3];
- szBuffer[4] = '\0';
-
- // We're definitely unable to load this file
- throw DeadlyImportError( "Unknown HMP subformat " + pFile +
- ". Magic word (" + szBuffer + ") is not known");
- }
-
- // Set the AI_SCENE_FLAGS_TERRAIN bit
- pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
-
- delete[] mBuffer;
- mBuffer= nullptr;
-
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::ValidateHeader_HMP457( )
-{
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
-
- if (120 > iFileSize)
- {
- throw DeadlyImportError("HMP file is too small (header size is "
- "120 bytes, this file is smaller)");
- }
-
- if (!pcHeader->ftrisize_x || !pcHeader->ftrisize_y)
- throw DeadlyImportError("Size of triangles in either x or y direction is zero");
-
- if(pcHeader->fnumverts_x < 1.0f || (pcHeader->numverts/pcHeader->fnumverts_x) < 1.0f)
- throw DeadlyImportError("Number of triangles in either x or y direction is zero");
-
- if(!pcHeader->numframes)
- throw DeadlyImportError("There are no frames. At least one should be there");
-
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP4( )
-{
- throw DeadlyImportError("HMP4 is currently not supported");
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP5( )
-{
- // read the file header and skip everything to byte 84
- const HMP::Header_HMP5* pcHeader = (const HMP::Header_HMP5*)mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
- ValidateHeader_HMP457();
-
- // generate an output mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
-
- pcMesh->mMaterialIndex = 0;
- pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
- pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
-
- const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
- const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
-
- // generate/load a material for the terrain
- CreateMaterial(szCurrent,&szCurrent);
-
- // goto offset 120, I don't know why ...
- // (fixme) is this the frame header? I assume yes since it starts with 2.
- szCurrent += 36;
- SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
-
- // now load all vertices from the file
- aiVector3D* pcVertOut = pcMesh->mVertices;
- aiVector3D* pcNorOut = pcMesh->mNormals;
- const HMP::Vertex_HMP5* src = (const HMP::Vertex_HMP5*) szCurrent;
- for (unsigned int y = 0; y < height;++y)
- {
- for (unsigned int x = 0; x < width;++x)
- {
- pcVertOut->x = x * pcHeader->ftrisize_x;
- pcVertOut->y = y * pcHeader->ftrisize_y;
- pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
- MD2::LookupNormalIndex(src->normals162index, *pcNorOut );
- ++pcVertOut;++pcNorOut;++src;
- }
- }
-
- // generate texture coordinates if necessary
- if (pcHeader->numskins)
- GenerateTextureCoords(width,height);
-
- // now build a list of faces
- CreateOutputFaceList(width,height);
-
- // there is no nodegraph in HMP files. Simply assign the one mesh
- // (no, not the one ring) to the root node
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("terrain_root");
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::InternReadFile_HMP7( )
-{
- // read the file header and skip everything to byte 84
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(mBuffer+84);
- ValidateHeader_HMP457();
-
- // generate an output mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
-
- pcMesh->mMaterialIndex = 0;
- pcMesh->mVertices = new aiVector3D[pcHeader->numverts];
- pcMesh->mNormals = new aiVector3D[pcHeader->numverts];
-
- const unsigned int height = (unsigned int)(pcHeader->numverts / pcHeader->fnumverts_x);
- const unsigned int width = (unsigned int)pcHeader->fnumverts_x;
-
- // generate/load a material for the terrain
- CreateMaterial(szCurrent,&szCurrent);
-
- // goto offset 120, I don't know why ...
- // (fixme) is this the frame header? I assume yes since it starts with 2.
- szCurrent += 36;
-
- SizeCheck(szCurrent + sizeof(const HMP::Vertex_HMP7)*height*width);
-
- // now load all vertices from the file
- aiVector3D* pcVertOut = pcMesh->mVertices;
- aiVector3D* pcNorOut = pcMesh->mNormals;
- const HMP::Vertex_HMP7* src = (const HMP::Vertex_HMP7*) szCurrent;
- for (unsigned int y = 0; y < height;++y)
- {
- for (unsigned int x = 0; x < width;++x)
- {
- pcVertOut->x = x * pcHeader->ftrisize_x;
- pcVertOut->y = y * pcHeader->ftrisize_y;
-
- // FIXME: What exctly is the correct scaling factor to use?
- // possibly pcHeader->scale_origin[2] in combination with a
- // signed interpretation of src->z?
- pcVertOut->z = (((float)src->z / 0xffff)-0.5f) * pcHeader->ftrisize_x * 8.0f;
-
- pcNorOut->x = ((float)src->normal_x / 0x80 ); // * pcHeader->scale_origin[0];
- pcNorOut->y = ((float)src->normal_y / 0x80 ); // * pcHeader->scale_origin[1];
- pcNorOut->z = 1.0f;
- pcNorOut->Normalize();
-
- ++pcVertOut;++pcNorOut;++src;
- }
- }
-
- // generate texture coordinates if necessary
- if (pcHeader->numskins)GenerateTextureCoords(width,height);
-
- // now build a list of faces
- CreateOutputFaceList(width,height);
-
- // there is no nodegraph in HMP files. Simply assign the one mesh
- // (no, not the One Ring) to the root node
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("terrain_root");
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::CreateMaterial(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut)
-{
- aiMesh* const pcMesh = pScene->mMeshes[0];
- const HMP::Header_HMP5* const pcHeader = (const HMP::Header_HMP5*)mBuffer;
-
- // we don't need to generate texture coordinates if
- // we have no textures in the file ...
- if (pcHeader->numskins)
- {
- pcMesh->mTextureCoords[0] = new aiVector3D[pcHeader->numverts];
- pcMesh->mNumUVComponents[0] = 2;
-
- // now read the first skin and skip all others
- ReadFirstSkin(pcHeader->numskins,szCurrent,&szCurrent);
- }
- else
- {
- // generate a default material
- const int iMode = (int)aiShadingMode_Gouraud;
- aiMaterial* pcHelper = new aiMaterial();
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- // add the material to the scene
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcHelper;
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::CreateOutputFaceList(unsigned int width,unsigned int height)
-{
- aiMesh* const pcMesh = this->pScene->mMeshes[0];
-
- // Allocate enough storage
- pcMesh->mNumFaces = (width-1) * (height-1);
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- pcMesh->mNumVertices = pcMesh->mNumFaces*4;
- aiVector3D* pcVertices = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcNormals = new aiVector3D[pcMesh->mNumVertices];
-
- aiFace* pcFaceOut(pcMesh->mFaces);
- aiVector3D* pcVertOut = pcVertices;
- aiVector3D* pcNorOut = pcNormals;
-
- aiVector3D* pcUVs = pcMesh->mTextureCoords[0] ? new aiVector3D[pcMesh->mNumVertices] : NULL;
- aiVector3D* pcUVOut(pcUVs);
-
- // Build the terrain square
- unsigned int iCurrent = 0;
- for (unsigned int y = 0; y < height-1;++y) {
- for (unsigned int x = 0; x < width-1;++x,++pcFaceOut) {
- pcFaceOut->mNumIndices = 4;
- pcFaceOut->mIndices = new unsigned int[4];
-
- *pcVertOut++ = pcMesh->mVertices[y*width+x];
- *pcVertOut++ = pcMesh->mVertices[(y+1)*width+x];
- *pcVertOut++ = pcMesh->mVertices[(y+1)*width+x+1];
- *pcVertOut++ = pcMesh->mVertices[y*width+x+1];
-
-
- *pcNorOut++ = pcMesh->mNormals[y*width+x];
- *pcNorOut++ = pcMesh->mNormals[(y+1)*width+x];
- *pcNorOut++ = pcMesh->mNormals[(y+1)*width+x+1];
- *pcNorOut++ = pcMesh->mNormals[y*width+x+1];
-
- if (pcMesh->mTextureCoords[0])
- {
- *pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x];
- *pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x];
- *pcUVOut++ = pcMesh->mTextureCoords[0][(y+1)*width+x+1];
- *pcUVOut++ = pcMesh->mTextureCoords[0][y*width+x+1];
- }
-
- for (unsigned int i = 0; i < 4;++i)
- pcFaceOut->mIndices[i] = iCurrent++;
- }
- }
- delete[] pcMesh->mVertices;
- pcMesh->mVertices = pcVertices;
-
- delete[] pcMesh->mNormals;
- pcMesh->mNormals = pcNormals;
-
- if (pcMesh->mTextureCoords[0])
- {
- delete[] pcMesh->mTextureCoords[0];
- pcMesh->mTextureCoords[0] = pcUVs;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void HMPImporter::ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
- const unsigned char** szCursorOut)
-{
- ai_assert( 0 != iNumSkins );
- ai_assert( nullptr != szCursor);
-
- // read the type of the skin ...
- // sometimes we need to skip 12 bytes here, I don't know why ...
- uint32_t iType = *((uint32_t*)szCursor);
- szCursor += sizeof(uint32_t);
- if (0 == iType)
- {
- szCursor += sizeof(uint32_t) * 2;
- iType = *((uint32_t*)szCursor);
- szCursor += sizeof(uint32_t);
- if (!iType)
- throw DeadlyImportError("Unable to read HMP7 skin chunk");
-
- }
- // read width and height
- uint32_t iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- uint32_t iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
-
- // allocate an output material
- aiMaterial* pcMat = new aiMaterial();
-
- // read the skin, this works exactly as for MDL7
- ParseSkinLump_3DGS_MDL7(szCursor,&szCursor,
- pcMat,iType,iWidth,iHeight);
-
- // now we need to skip any other skins ...
- for (unsigned int i = 1; i< iNumSkins;++i)
- {
- iType = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- iWidth = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
- iHeight = *((uint32_t*)szCursor); szCursor += sizeof(uint32_t);
-
- SkipSkinLump_3DGS_MDL7(szCursor,&szCursor,iType,iWidth,iHeight);
- SizeCheck(szCursor);
- }
-
- // setup the material ...
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-
- *szCursorOut = szCursor;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Generate proepr texture coords
-void HMPImporter::GenerateTextureCoords(
- const unsigned int width, const unsigned int height)
-{
- ai_assert(NULL != pScene->mMeshes && NULL != pScene->mMeshes[0] &&
- NULL != pScene->mMeshes[0]->mTextureCoords[0]);
-
- aiVector3D* uv = pScene->mMeshes[0]->mTextureCoords[0];
-
- const float fY = (1.0f / height) + (1.0f / height) / (height-1);
- const float fX = (1.0f / width) + (1.0f / width) / (width-1);
-
- for (unsigned int y = 0; y < height;++y) {
- for (unsigned int x = 0; x < width;++x,++uv) {
- uv->y = fY*y;
- uv->x = fX*x;
- uv->z = 0.0f;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_HMP_IMPORTER
diff --git a/src/3rdparty/assimp/code/HMPLoader.h b/src/3rdparty/assimp/code/HMPLoader.h
deleted file mode 100644
index 546643e8d..000000000
--- a/src/3rdparty/assimp/code/HMPLoader.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 HMPLoader.h
- * @brief Declaration of the HMP importer class
- */
-
-#ifndef AI_HMPLOADER_H_INCLUDED
-#define AI_HMPLOADER_H_INCLUDED
-
-// internal headers
-#include "BaseImporter.h"
-#include "MDLLoader.h"
-#include "HMPFileData.h"
-
-namespace Assimp {
-using namespace HMP;
-
-// ---------------------------------------------------------------------------
-/** Used to load 3D GameStudio HMP files (terrains)
-*/
-class HMPImporter : public MDLImporter
-{
-public:
- HMPImporter();
- ~HMPImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Import a HMP4 file
- */
- void InternReadFile_HMP4( );
-
- // -------------------------------------------------------------------
- /** Import a HMP5 file
- */
- void InternReadFile_HMP5( );
-
- // -------------------------------------------------------------------
- /** Import a HMP7 file
- */
- void InternReadFile_HMP7( );
-
- // -------------------------------------------------------------------
- /** Validate a HMP 5,4,7 file header
- */
- void ValidateHeader_HMP457( );
-
- // -------------------------------------------------------------------
- /** Try to load one material from the file, if this fails create
- * a default material
- */
- void CreateMaterial(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Build a list of output faces and vertices. The function
- * triangulates the height map read from the file
- * \param width Width of the height field
- * \param width Height of the height field
- */
- void CreateOutputFaceList(unsigned int width,unsigned int height);
-
- // -------------------------------------------------------------------
- /** Generate planar texture coordinates for a terrain
- * \param width Width of the terrain, in vertices
- * \param height Height of the terrain, in vertices
- */
- void GenerateTextureCoords(const unsigned int width,
- const unsigned int height);
-
- // -------------------------------------------------------------------
- /** Read the first skin from the file and skip all others ...
- * \param iNumSkins Number of skins in the file
- * \param szCursor Position of the first skin (offset 84)
- */
- void ReadFirstSkin(unsigned int iNumSkins, const unsigned char* szCursor,
- const unsigned char** szCursorOut);
-
-private:
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_HMPIMPORTER_H_INC
-
diff --git a/src/3rdparty/assimp/code/HalfLifeFileData.h b/src/3rdparty/assimp/code/HalfLifeFileData.h
deleted file mode 100644
index 3a36d2422..000000000
--- a/src/3rdparty/assimp/code/HalfLifeFileData.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Definition of in-memory structures for the HL2 MDL file format
-// and for the HalfLife text format (SMD)
-//
-// The specification has been taken from various sources on the internet.
-
-
-#ifndef AI_MDLFILEHELPER2_H_INC
-#define AI_MDLFILEHELPER2_H_INC
-
-#include "./../include/assimp/Compiler/pushpack1.h"
-
-namespace Assimp {
-namespace MDL {
-
-// magic bytes used in Half Life 2 MDL models
-#define AI_MDL_MAGIC_NUMBER_BE_HL2a AI_MAKE_MAGIC("IDST")
-#define AI_MDL_MAGIC_NUMBER_LE_HL2a AI_MAKE_MAGIC("TSDI")
-#define AI_MDL_MAGIC_NUMBER_BE_HL2b AI_MAKE_MAGIC("IDSQ")
-#define AI_MDL_MAGIC_NUMBER_LE_HL2b AI_MAKE_MAGIC("QSDI")
-
-// ---------------------------------------------------------------------------
-/** \struct Header_HL2
- * \brief Data structure for the HL2 main header
- */
-// ---------------------------------------------------------------------------
-struct Header_HL2 {
- //! magic number: "IDST"/"IDSQ"
- char ident[4];
-
- //! Version number
- int32_t version;
-
- //! Original file name in pak ?
- char name[64];
-
- //! Length of file name/length of file?
- int32_t length;
-
- //! For viewer, ignored
- aiVector3D eyeposition;
- aiVector3D min;
- aiVector3D max;
-
- //! AABB of the model
- aiVector3D bbmin;
- aiVector3D bbmax;
-
- // File flags
- int32_t flags;
-
- //! NUmber of bones contained in the file
- int32_t numbones;
- int32_t boneindex;
-
- //! Number of bone controllers for bone animation
- int32_t numbonecontrollers;
- int32_t bonecontrollerindex;
-
- //! More bounding boxes ...
- int32_t numhitboxes;
- int32_t hitboxindex;
-
- //! Animation sequences in the file
- int32_t numseq;
- int32_t seqindex;
-
- //! Loaded sequences. Ignored
- int32_t numseqgroups;
- int32_t seqgroupindex;
-
- //! Raw texture data
- int32_t numtextures;
- int32_t textureindex;
- int32_t texturedataindex;
-
- //! Number of skins (=textures?)
- int32_t numskinref;
- int32_t numskinfamilies;
- int32_t skinindex;
-
- //! Number of parts
- int32_t numbodyparts;
- int32_t bodypartindex;
-
- //! attachable points for gameplay and physics
- int32_t numattachments;
- int32_t attachmentindex;
-
- //! Table of sound effects associated with the model
- int32_t soundtable;
- int32_t soundindex;
- int32_t soundgroups;
- int32_t soundgroupindex;
-
- //! Number of animation transitions
- int32_t numtransitions;
- int32_t transitionindex;
-} /* PACK_STRUCT */;
-
-#include "./../include/assimp/Compiler/poppack1.h"
-
-}
-} // end namespaces
-
-#endif // ! AI_MDLFILEHELPER2_H_INC
diff --git a/src/3rdparty/assimp/code/Hash.h b/src/3rdparty/assimp/code/Hash.h
deleted file mode 100644
index a567adbc3..000000000
--- a/src/3rdparty/assimp/code/Hash.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_HASH_H_INCLUDED
-#define AI_HASH_H_INCLUDED
-
-#include <stdint.h>
-#include <string.h>
-
-// ------------------------------------------------------------------------------------------------
-// Hashing function taken from
-// http://www.azillionmonkeys.com/qed/hash.html
-// (incremental version)
-//
-// This code is Copyright 2004-2008 by Paul Hsieh. It is used here in the belief that
-// Assimp's license is considered compatible with Pauls's derivative license as specified
-// on his web page.
-//
-// (stdint.h should have been been included here)
-// ------------------------------------------------------------------------------------------------
-#undef get16bits
-#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
- || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
-#define get16bits(d) (*((const uint16_t *) (d)))
-#endif
-
-#if !defined (get16bits)
-#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
- +(uint32_t)(((const uint8_t *)(d))[0]) )
-#endif
-
-// ------------------------------------------------------------------------------------------------
-inline uint32_t SuperFastHash (const char * data, uint32_t len = 0, uint32_t hash = 0) {
-uint32_t tmp;
-int rem;
-
- if (!data) return 0;
- if (!len)len = (uint32_t)::strlen(data);
-
- rem = len & 3;
- len >>= 2;
-
- /* Main loop */
- for (;len > 0; len--) {
- hash += get16bits (data);
- tmp = (get16bits (data+2) << 11) ^ hash;
- hash = (hash << 16) ^ tmp;
- data += 2*sizeof (uint16_t);
- hash += hash >> 11;
- }
-
- /* Handle end cases */
- switch (rem) {
- case 3: hash += get16bits (data);
- hash ^= hash << 16;
- hash ^= data[sizeof (uint16_t)] << 18;
- hash += hash >> 11;
- break;
- case 2: hash += get16bits (data);
- hash ^= hash << 11;
- hash += hash >> 17;
- break;
- case 1: hash += *data;
- hash ^= hash << 10;
- hash += hash >> 1;
- }
-
- /* Force "avalanching" of final 127 bits */
- hash ^= hash << 3;
- hash += hash >> 5;
- hash ^= hash << 4;
- hash += hash >> 17;
- hash ^= hash << 25;
- hash += hash >> 6;
-
- return hash;
-}
-
-#endif // !! AI_HASH_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/IFCBoolean.cpp b/src/3rdparty/assimp/code/IFCBoolean.cpp
deleted file mode 100644
index d250fbe36..000000000
--- a/src/3rdparty/assimp/code/IFCBoolean.cpp
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
-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
- */
-
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-#include "IFCUtil.h"
-#include "PolyTools.h"
-#include "ProcessHelper.h"
-#include <assimp/Defines.h>
-
-#include <iterator>
-#include <tuple>
-
-
-namespace Assimp {
- namespace IFC {
-
-// ------------------------------------------------------------------------------------------------
-// Calculates intersection between line segment and plane. To catch corner cases, specify which side you prefer.
-// The function then generates a hit only if the end is beyond a certain margin in that direction, filtering out
-// "very close to plane" ghost hits as long as start and end stay directly on or within the given plane side.
-bool IntersectSegmentPlane(const IfcVector3& p,const IfcVector3& n, const IfcVector3& e0,
- const IfcVector3& e1, bool assumeStartOnWhiteSide, IfcVector3& out)
-{
- const IfcVector3 pdelta = e0 - p, seg = e1 - e0;
- const IfcFloat dotOne = n*seg, dotTwo = -(n*pdelta);
-
- // if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
- // point leaves the plane through the other side
- if( std::abs(dotOne + dotTwo) < 1e-6 )
- return false;
-
- // if segment starts on the plane, report a hit only if the end lies on the *other* side
- if( std::abs(dotTwo) < 1e-6 )
- {
- if( (assumeStartOnWhiteSide && dotOne + dotTwo < 1e-6) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -1e-6) )
- {
- out = e0;
- return true;
- }
- else
- {
- return false;
- }
- }
-
- // ignore if segment is parallel to plane and far away from it on either side
- // Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
- if( std::abs(dotOne) < 1e-6 )
- return false;
-
- // t must be in [0..1] if the intersection point is within the given segment
- const IfcFloat t = dotTwo / dotOne;
- if( t > 1.0 || t < 0.0 )
- return false;
-
- out = e0 + t*seg;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void FilterPolygon(std::vector<IfcVector3>& resultpoly)
-{
- if( resultpoly.size() < 3 )
- {
- resultpoly.clear();
- return;
- }
-
- IfcVector3 vmin, vmax;
- ArrayBounds(resultpoly.data(), static_cast<unsigned int>(resultpoly.size()), vmin, vmax);
-
- // filter our IfcFloat points - those may happen if a point lies
- // directly on the intersection line or directly on the clipping plane
- const IfcFloat epsilon = (vmax - vmin).SquareLength() / 1e6f;
- FuzzyVectorCompare fz(epsilon);
- std::vector<IfcVector3>::iterator e = std::unique(resultpoly.begin(), resultpoly.end(), fz);
-
- if( e != resultpoly.end() )
- resultpoly.erase(e, resultpoly.end());
-
- if( !resultpoly.empty() && fz(resultpoly.front(), resultpoly.back()) )
- resultpoly.pop_back();
-}
-
-// ------------------------------------------------------------------------------------------------
-void WritePolygon(std::vector<IfcVector3>& resultpoly, TempMesh& result)
-{
- FilterPolygon(resultpoly);
-
- if( resultpoly.size() > 2 )
- {
- result.verts.insert(result.verts.end(), resultpoly.begin(), resultpoly.end());
- result.vertcnt.push_back(static_cast<unsigned int>(resultpoly.size()));
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-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;
- bool isAtWhiteSide = (in[vidx] - p) * n > -1e-6;
- 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;
- if( IntersectSegmentPlane(p, n, e0, e1, isAtWhiteSide, isectpos) ) {
- if( isAtWhiteSide ) {
- // 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;
- }
- isAtWhiteSide = !isAtWhiteSide;
- }
- else
- {
- if( isAtWhiteSide ) {
- outvert.push_back(e0);
- ++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.
-// New version takes the supposed inside/outside state as a parameter and treats corner cases as if
-// the line stays on that side. This should make corner cases more stable.
-// Two million assumptions! Boundary should have all z at 0.0, will be treated as closed, should not have
-// segments with length <1e-6, self-intersecting might break the corner case handling... just don't go there, ok?
-bool IntersectsBoundaryProfile(const IfcVector3& e0, const IfcVector3& e1, const std::vector<IfcVector3>& boundary,
- const bool isStartAssumedInside, std::vector<std::pair<size_t, IfcVector3> >& intersect_results,
- const bool halfOpen = false)
-{
- ai_assert(intersect_results.empty());
-
- // determine winding order - necessary to detect segments going "inwards" or "outwards" from a point directly on the border
- // positive sum of angles means clockwise order when looking down the -Z axis
- IfcFloat windingOrder = 0.0;
- for( size_t i = 0, bcount = boundary.size(); i < bcount; ++i ) {
- IfcVector3 b01 = boundary[(i + 1) % bcount] - boundary[i];
- IfcVector3 b12 = boundary[(i + 2) % bcount] - boundary[(i + 1) % bcount];
- IfcVector3 b1_side = IfcVector3(b01.y, -b01.x, 0.0); // rotated 90° clockwise in Z plane
- // Warning: rough estimate only. A concave poly with lots of small segments each featuring a small counter rotation
- // could fool the accumulation. Correct implementation would be sum( acos( b01 * b2) * sign( b12 * b1_side))
- windingOrder += (b1_side.x*b12.x + b1_side.y*b12.y);
- }
- windingOrder = windingOrder > 0.0 ? 1.0 : -1.0;
-
- 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];
- 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( std::abs(det) < 1e-6 ) {
- // no solutions (parallel lines)
- continue;
- }
- IfcFloat b_sqlen_inv = 1.0 / b.SquareLength();
-
- const IfcFloat x = b0.x - e0.x;
- const IfcFloat y = b0.y - e0.y;
- const IfcFloat s = (x*e.y - e.x*y) / det; // scale along boundary edge
- const IfcFloat t = (x*b.y - b.x*y) / det; // scale along given segment
- const IfcVector3 p = e0 + e*t;
-#ifdef ASSIMP_BUILD_DEBUG
- const IfcVector3 check = b0 + b*s - p;
- ai_assert((IfcVector2(check.x, check.y)).SquareLength() < 1e-5);
-#endif
-
- // also calculate the distance of e0 and e1 to the segment. We need to detect the "starts directly on segment"
- // and "ends directly at segment" cases
- bool startsAtSegment, endsAtSegment;
- {
- // calculate closest point to each end on the segment, clamp that point to the segment's length, then check
- // distance to that point. This approach is like testing if e0 is inside a capped cylinder.
- IfcFloat et0 = (b.x*(e0.x - b0.x) + b.y*(e0.y - b0.y)) * b_sqlen_inv;
- IfcVector3 closestPosToE0OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et0)) * b;
- startsAtSegment = (closestPosToE0OnBoundary - IfcVector3(e0.x, e0.y, 0.0)).SquareLength() < 1e-12;
- IfcFloat et1 = (b.x*(e1.x - b0.x) + b.y*(e1.y - b0.y)) * b_sqlen_inv;
- IfcVector3 closestPosToE1OnBoundary = b0 + std::max(IfcFloat(0.0), std::min(IfcFloat(1.0), et1)) * b;
- endsAtSegment = (closestPosToE1OnBoundary - IfcVector3(e1.x, e1.y, 0.0)).SquareLength() < 1e-12;
- }
-
- // Line segment ends at boundary -> ignore any hit, it will be handled by possibly following segments
- if( endsAtSegment && !halfOpen )
- continue;
-
- // Line segment starts at boundary -> generate a hit only if following that line would change the INSIDE/OUTSIDE
- // state. This should catch the case where a connected set of segments has a point directly on the boundary,
- // one segment not hitting it because it ends there and the next segment not hitting it because it starts there
- // Should NOT generate a hit if the segment only touches the boundary but turns around and stays inside.
- if( startsAtSegment )
- {
- IfcVector3 inside_dir = IfcVector3(b.y, -b.x, 0.0) * windingOrder;
- bool isGoingInside = (inside_dir * e) > 0.0;
- if( isGoingInside == isStartAssumedInside )
- continue;
-
- // 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( !intersect_results.empty() && intersect_results.back().first == i - 1 )
- {
- const IfcVector3 diff = intersect_results.back().second - e0;
- if( IfcVector2(diff.x, diff.y).SquareLength() < 1e-10 )
- continue;
- }
- intersect_results.push_back(std::make_pair(i, e0));
- continue;
- }
-
- // for a valid intersection, s and t should be in range [0,1]. Including a bit of epsilon on s, potential double
- // hits on two consecutive boundary segments are filtered
- if( s >= -1e-6 * b_sqlen_inv && s <= 1.0 + 1e-6*b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen) )
- {
- // 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( !intersect_results.empty() && intersect_results.back().first == i - 1 )
- {
- const IfcVector3 diff = intersect_results.back().second - p;
- if( IfcVector2(diff.x, diff.y).SquareLength() < 1e-10 )
- continue;
- }
- intersect_results.push_back(std::make_pair(i, p));
- }
- }
-
- return !intersect_results.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<std::pair<size_t, IfcVector3> > intersected_boundary;
- size_t votes = 0;
-
- IntersectsBoundaryProfile(p, p + IfcVector3(1.0, 0, 0), boundary, true, intersected_boundary, true);
- votes += intersected_boundary.size() % 2;
-
- intersected_boundary.clear();
- IntersectsBoundaryProfile(p, p + IfcVector3(0, 1.0, 0), boundary, true, intersected_boundary, true);
- votes += intersected_boundary.size() % 2;
-
- intersected_boundary.clear();
- IntersectsBoundaryProfile(p, p + IfcVector3(0.6, -0.6, 0.0), boundary, true, intersected_boundary, true);
- votes += intersected_boundary.size() % 2;
-
- 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
- std::shared_ptr<TempMesh> profile = std::shared_ptr<TempMesh>(new TempMesh());
- if(!ProcessCurve(hs->PolygonalBoundary, *profile.get(), conv)) {
- IFCImporter::LogError("expected valid polyline for boundary of boolean halfspace");
- return;
- }
-
- // determine winding order by calculating the normal.
- IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(profile->verts.data(), profile->verts.size());
-
- 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>& outvertcnt = result.vertcnt;
-
- outvert.reserve(in.size());
- outvertcnt.reserve(first_operand.vertcnt.size());
-
- unsigned int vidx = 0;
- std::vector<unsigned int>::const_iterator begin = first_operand.vertcnt.begin();
- std::vector<unsigned int>::const_iterator end = first_operand.vertcnt.end();
- std::vector<unsigned int>::const_iterator iit;
- for( iit = begin; iit != end; vidx += *iit++ )
- {
- // Our new approach: we cut the poly along the plane, then we intersect the part on the black side of the plane
- // against the bounding polygon. All the white parts, and the black part outside the boundary polygon, are kept.
- std::vector<IfcVector3> whiteside, blackside;
-
- {
- const IfcVector3* srcVertices = &in[vidx];
- const size_t srcVtxCount = *iit;
- if( srcVtxCount == 0 )
- continue;
-
- IfcVector3 polyNormal = TempMesh::ComputePolygonNormal(srcVertices, srcVtxCount, true);
-
- // if the poly is parallel to the plane, put it completely on the black or white side
- if( std::abs(polyNormal * n) > 0.9999 )
- {
- bool isOnWhiteSide = (srcVertices[0] - p) * n > -1e-6;
- std::vector<IfcVector3>& targetSide = isOnWhiteSide ? whiteside : blackside;
- targetSide.insert(targetSide.end(), srcVertices, srcVertices + srcVtxCount);
- }
- else
- {
- // otherwise start building one polygon for each side. Whenever the current line segment intersects the plane
- // we put a point there as an end of the current segment. Then we switch to the other side, put a point there, too,
- // as a beginning of the current segment, and simply continue accumulating vertices.
- bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -1e-6;
- for( size_t a = 0; a < srcVtxCount; ++a )
- {
- IfcVector3 e0 = srcVertices[a];
- IfcVector3 e1 = srcVertices[(a + 1) % srcVtxCount];
- IfcVector3 ei;
-
- // put starting point to the current mesh
- std::vector<IfcVector3>& trgt = isCurrentlyOnWhiteSide ? whiteside : blackside;
- trgt.push_back(srcVertices[a]);
-
- // if there's an intersection, put an end vertex there, switch to the other side's mesh,
- // and add a starting vertex there, too
- bool isPlaneHit = IntersectSegmentPlane(p, n, e0, e1, isCurrentlyOnWhiteSide, ei);
- if( isPlaneHit )
- {
- if( trgt.empty() || (trgt.back() - ei).SquareLength() > 1e-12 )
- trgt.push_back(ei);
- isCurrentlyOnWhiteSide = !isCurrentlyOnWhiteSide;
- std::vector<IfcVector3>& newtrgt = isCurrentlyOnWhiteSide ? whiteside : blackside;
- newtrgt.push_back(ei);
- }
- }
- }
- }
-
- // the part on the white side can be written into the target mesh right away
- WritePolygon(whiteside, result);
-
- // The black part is the piece we need to get rid of, but only the part of it within the boundary polygon.
- // So we now need to construct all the polygons that result from BlackSidePoly minus BoundaryPoly.
- FilterPolygon(blackside);
-
- // Complicated, II. We run along the polygon. a) When we're inside the boundary, we run on until we hit an
- // intersection, which means we're leaving it. We then start a new out poly there. b) When we're outside the
- // boundary, we start collecting vertices until we hit an intersection, then we run along the boundary until we hit
- // an intersection, then we switch back to the poly and run on on this one again, and so on until we got a closed
- // loop. Then we continue with the path we left to catch potential additional polys on the other side of the
- // boundary as described in a)
- if( !blackside.empty() )
- {
- // poly edge index, intersection point, edge index in boundary poly
- std::vector<std::tuple<size_t, IfcVector3, size_t> > intersections;
- bool startedInside = PointInPoly(proj * blackside.front(), profile->verts);
- bool isCurrentlyInside = startedInside;
-
- std::vector<std::pair<size_t, IfcVector3> > intersected_boundary;
-
- for( size_t a = 0; a < blackside.size(); ++a )
- {
- const IfcVector3 e0 = proj * blackside[a];
- const IfcVector3 e1 = proj * blackside[(a + 1) % blackside.size()];
-
- intersected_boundary.clear();
- IntersectsBoundaryProfile(e0, e1, profile->verts, isCurrentlyInside, intersected_boundary);
- // sort the hits by distance from e0 to get the correct in/out/in sequence. Manually :-( I miss you, C++11.
- if( intersected_boundary.size() > 1 )
- {
- bool keepSorting = true;
- while( keepSorting )
- {
- keepSorting = false;
- for( size_t b = 0; b < intersected_boundary.size() - 1; ++b )
- {
- if( (intersected_boundary[b + 1].second - e0).SquareLength() < (intersected_boundary[b].second - e0).SquareLength() )
- {
- keepSorting = true;
- std::swap(intersected_boundary[b + 1], intersected_boundary[b]);
- }
- }
- }
- }
- // now add them to the list of intersections
- for( size_t b = 0; b < intersected_boundary.size(); ++b )
- intersections.push_back(std::make_tuple(a, proj_inv * intersected_boundary[b].second, intersected_boundary[b].first));
-
- // and calculate our new inside/outside state
- if( intersected_boundary.size() & 1 )
- isCurrentlyInside = !isCurrentlyInside;
- }
-
- // we got a list of in-out-combinations of intersections. That should be an even number of intersections, or
- // we're fucked.
- if( (intersections.size() & 1) != 0 )
- {
- IFCImporter::LogWarn("Odd number of intersections, can't work with that. Omitting half space boundary check.");
- continue;
- }
-
- if( intersections.size() > 1 )
- {
- // If we started outside, the first intersection is a out->in intersection. Cycle them so that it
- // starts with an intersection leaving the boundary
- if( !startedInside )
- for( size_t b = 0; b < intersections.size() - 1; ++b )
- std::swap(intersections[b], intersections[(b + intersections.size() - 1) % intersections.size()]);
-
- // Filter pairs of out->in->out that lie too close to each other.
- for( size_t a = 0; intersections.size() > 0 && a < intersections.size() - 1; /**/ )
- {
- if( (std::get<1>(intersections[a]) - std::get<1>(intersections[(a + 1) % intersections.size()])).SquareLength() < 1e-10 )
- intersections.erase(intersections.begin() + a, intersections.begin() + a + 2);
- else
- a++;
- }
- if( intersections.size() > 1 && (std::get<1>(intersections.back()) - std::get<1>(intersections.front())).SquareLength() < 1e-10 )
- {
- intersections.pop_back(); intersections.erase(intersections.begin());
- }
- }
-
-
- // no intersections at all: either completely inside the boundary, so everything gets discarded, or completely outside.
- // in the latter case we're implementional lost. I'm simply going to ignore this, so a large poly will not get any
- // holes if the boundary is smaller and does not touch it anywhere.
- if( intersections.empty() )
- {
- // starting point was outside -> everything is outside the boundary -> nothing is clipped -> add black side
- // to result mesh unchanged
- if( !startedInside )
- {
- outvertcnt.push_back(static_cast<unsigned int>(blackside.size()));
- outvert.insert(outvert.end(), blackside.begin(), blackside.end());
- continue;
- }
- else
- {
- // starting point was inside the boundary -> everything is inside the boundary -> nothing is spared from the
- // clipping -> nothing left to add to the result mesh
- continue;
- }
- }
-
- // determine the direction in which we're marching along the boundary polygon. If the src poly is faced upwards
- // and the boundary is also winded this way, we need to march *backwards* on the boundary.
- const IfcVector3 polyNormal = IfcMatrix3(proj) * TempMesh::ComputePolygonNormal(blackside.data(), blackside.size());
- bool marchBackwardsOnBoundary = (profileNormal * polyNormal) >= 0.0;
-
- // Build closed loops from these intersections. Starting from an intersection leaving the boundary we
- // walk along the polygon to the next intersection (which should be an IS entering the boundary poly).
- // From there we walk along the boundary until we hit another intersection leaving the boundary,
- // walk along the poly to the next IS and so on until we're back at the starting point.
- // We remove every intersection we "used up", so any remaining intersection is the start of a new loop.
- while( !intersections.empty() )
- {
- std::vector<IfcVector3> resultpoly;
- size_t currentIntersecIdx = 0;
-
- while( true )
- {
- ai_assert(intersections.size() > currentIntersecIdx + 1);
- std::tuple<size_t, IfcVector3, size_t> currintsec = intersections[currentIntersecIdx + 0];
- std::tuple<size_t, IfcVector3, size_t> nextintsec = intersections[currentIntersecIdx + 1];
- intersections.erase(intersections.begin() + currentIntersecIdx, intersections.begin() + currentIntersecIdx + 2);
-
- // we start with an in->out intersection
- resultpoly.push_back(std::get<1>(currintsec));
- // climb along the polygon to the next intersection, which should be an out->in
- size_t numPolyPoints = (std::get<0>(currintsec) > std::get<0>(nextintsec) ? blackside.size() : 0)
- + std::get<0>(nextintsec) - std::get<0>(currintsec);
- for( size_t a = 1; a <= numPolyPoints; ++a )
- resultpoly.push_back(blackside[(std::get<0>(currintsec) + a) % blackside.size()]);
- // put the out->in intersection
- resultpoly.push_back(std::get<1>(nextintsec));
-
- // generate segments along the boundary polygon that lie in the poly's plane until we hit another intersection
- IfcVector3 startingPoint = proj * std::get<1>(nextintsec);
- size_t currentBoundaryEdgeIdx = (std::get<2>(nextintsec) + (marchBackwardsOnBoundary ? 1 : 0)) % profile->verts.size();
- size_t nextIntsecIdx = SIZE_MAX;
- while( nextIntsecIdx == SIZE_MAX )
- {
- IfcFloat t = 1e10;
-
- size_t nextBoundaryEdgeIdx = marchBackwardsOnBoundary ? (currentBoundaryEdgeIdx + profile->verts.size() - 1) : currentBoundaryEdgeIdx + 1;
- nextBoundaryEdgeIdx %= profile->verts.size();
- // vertices of the current boundary segments
- IfcVector3 currBoundaryPoint = profile->verts[currentBoundaryEdgeIdx];
- IfcVector3 nextBoundaryPoint = profile->verts[nextBoundaryEdgeIdx];
- // project the two onto the polygon
- if( std::abs(polyNormal.z) > 1e-5 )
- {
- currBoundaryPoint.z = startingPoint.z + (currBoundaryPoint.x - startingPoint.x) * polyNormal.x/polyNormal.z + (currBoundaryPoint.y - startingPoint.y) * polyNormal.y/polyNormal.z;
- nextBoundaryPoint.z = startingPoint.z + (nextBoundaryPoint.x - startingPoint.x) * polyNormal.x/polyNormal.z + (nextBoundaryPoint.y - startingPoint.y) * polyNormal.y/polyNormal.z;
- }
-
- // build a direction that goes along the boundary border but lies in the poly plane
- IfcVector3 boundaryPlaneNormal = ((nextBoundaryPoint - currBoundaryPoint) ^ profileNormal).Normalize();
- IfcVector3 dirAtPolyPlane = (boundaryPlaneNormal ^ polyNormal).Normalize() * (marchBackwardsOnBoundary ? -1.0 : 1.0);
- // if we can project the direction to the plane, we can calculate a maximum marching distance along that dir
- // until we finish that boundary segment and continue on the next
- if( std::abs(polyNormal.z) > 1e-5 )
- {
- t = std::min(t, (nextBoundaryPoint - startingPoint).Length());
- }
-
- // check if the direction hits the loop start - if yes, we got a poly to output
- IfcVector3 dirToThatPoint = proj * resultpoly.front() - startingPoint;
- IfcFloat tpt = dirToThatPoint * dirAtPolyPlane;
- if( tpt > -1e-6 && tpt <= t && (dirToThatPoint - tpt * dirAtPolyPlane).SquareLength() < 1e-10 )
- {
- nextIntsecIdx = intersections.size(); // dirty hack to end marching along the boundary and signal the end of the loop
- t = tpt;
- }
-
- // also check if the direction hits any in->out intersections earlier. If we hit one, we can switch back
- // to marching along the poly border from that intersection point
- for( size_t a = 0; a < intersections.size(); a += 2 )
- {
- dirToThatPoint = proj * std::get<1>(intersections[a]) - startingPoint;
- tpt = dirToThatPoint * dirAtPolyPlane;
- if( tpt > -1e-6 && tpt <= t && (dirToThatPoint - tpt * dirAtPolyPlane).SquareLength() < 1e-10 )
- {
- nextIntsecIdx = a; // switch back to poly and march on from this in->out intersection
- t = tpt;
- }
- }
-
- // if we keep marching on the boundary, put the segment end point to the result poly and well... keep marching
- if( nextIntsecIdx == SIZE_MAX )
- {
- resultpoly.push_back(proj_inv * nextBoundaryPoint);
- currentBoundaryEdgeIdx = nextBoundaryEdgeIdx;
- startingPoint = nextBoundaryPoint;
- }
-
- // quick endless loop check
- if( resultpoly.size() > blackside.size() + profile->verts.size() )
- {
- IFCImporter::LogError("Encountered endless loop while clipping polygon against poly-bounded half space.");
- break;
- }
- }
-
- // we're back on the poly - if this is the intersection we started from, we got a closed loop.
- if( nextIntsecIdx >= intersections.size() )
- {
- break;
- }
-
- // otherwise it's another intersection. Continue marching from there.
- currentIntersecIdx = nextIntsecIdx;
- }
-
- WritePolygon(resultpoly, result);
- }
- }
- }
- 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.
-
- std::shared_ptr<TempMesh> meshtmp = std::shared_ptr<TempMesh>(new TempMesh());
- ProcessExtrudedAreaSolid(*as,*meshtmp,conv,false);
-
- std::vector<TempOpening> openings(1, TempOpening(as,IfcVector3(0,0,0),meshtmp,std::shared_ptr<TempMesh>()));
-
- result = first_operand;
-
- TempMesh temp;
-
- std::vector<IfcVector3>::const_iterator vit = first_operand.verts.begin();
- for(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
deleted file mode 100644
index 2aa3ef6a4..000000000
--- a/src/3rdparty/assimp/code/IFCCurve.cpp
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFCProfile.cpp
- * @brief Read profile and curves entities from IFC files
- */
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-#include "IFCUtil.h"
-
-namespace Assimp {
-namespace IFC {
-namespace {
-
-
-// --------------------------------------------------------------------------------
-// Conic is the base class for Circle and Ellipse
-// --------------------------------------------------------------------------------
-class Conic : public Curve {
-public:
- // --------------------------------------------------
- Conic(const IfcConic& entity, ConversionData& conv)
- : Curve(entity,conv) {
- IfcMatrix4 trafo;
- ConvertAxisPlacement(trafo,*entity.Position,conv);
-
- // for convenience, extract the matrix rows
- location = IfcVector3(trafo.a4,trafo.b4,trafo.c4);
- p[0] = IfcVector3(trafo.a1,trafo.b1,trafo.c1);
- p[1] = IfcVector3(trafo.a2,trafo.b2,trafo.c2);
- p[2] = IfcVector3(trafo.a3,trafo.b3,trafo.c3);
- }
-
- // --------------------------------------------------
- bool IsClosed() const {
- return true;
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
-
- a *= conv.angle_scale;
- b *= conv.angle_scale;
-
- a = std::fmod(a,static_cast<IfcFloat>( AI_MATH_TWO_PI ));
- b = std::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>( std::ceil(std::abs( b-a)) / setting);
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ), static_cast<IfcFloat>( AI_MATH_TWO_PI / conv.angle_scale ));
- }
-
-protected:
- IfcVector3 location, p[3];
-};
-
-// --------------------------------------------------------------------------------
-// Circle
-// --------------------------------------------------------------------------------
-class Circle : public Conic {
-public:
- // --------------------------------------------------
- Circle(const IfcCircle& entity, ConversionData& conv)
- : Conic(entity,conv)
- , entity(entity)
- {
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- u = -conv.angle_scale * u;
- return location + static_cast<IfcFloat>(entity.Radius)*(static_cast<IfcFloat>(std::cos(u))*p[0] +
- static_cast<IfcFloat>(std::sin(u))*p[1]);
- }
-
-private:
- const IfcCircle& entity;
-};
-
-
-// --------------------------------------------------------------------------------
-// Ellipse
-// --------------------------------------------------------------------------------
-class Ellipse : public Conic {
-public:
- // --------------------------------------------------
- Ellipse(const IfcEllipse& entity, ConversionData& conv)
- : Conic(entity,conv)
- , entity(entity) {
- // empty
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- u = -conv.angle_scale * u;
- return location + static_cast<IfcFloat>(entity.SemiAxis1)*static_cast<IfcFloat>(std::cos(u))*p[0] +
- static_cast<IfcFloat>(entity.SemiAxis2)*static_cast<IfcFloat>(std::sin(u))*p[1];
- }
-
-private:
- const IfcEllipse& entity;
-};
-
-// --------------------------------------------------------------------------------
-// Line
-// --------------------------------------------------------------------------------
-class Line : public Curve {
-public:
- // --------------------------------------------------
- Line(const IfcLine& entity, ConversionData& conv)
- : Curve(entity,conv) {
- ConvertCartesianPoint(p,entity.Pnt);
- ConvertVector(v,entity.Dir);
- }
-
- // --------------------------------------------------
- bool IsClosed() const {
- return false;
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- return p + u*v;
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
- // two points are always sufficient for a line segment
- return a==b ? 1 : 2;
- }
-
-
- // --------------------------------------------------
- void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
-
- if (a == b) {
- out.verts.push_back(Eval(a));
- return;
- }
- out.verts.reserve(out.verts.size()+2);
- out.verts.push_back(Eval(a));
- out.verts.push_back(Eval(b));
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- const IfcFloat inf = std::numeric_limits<IfcFloat>::infinity();
-
- return std::make_pair(-inf,+inf);
- }
-
-private:
- IfcVector3 p,v;
-};
-
-// --------------------------------------------------------------------------------
-// CompositeCurve joins multiple smaller, bounded curves
-// --------------------------------------------------------------------------------
-class CompositeCurve : public BoundedCurve {
- typedef std::pair< std::shared_ptr< BoundedCurve >, bool > CurveEntry;
-
-public:
- // --------------------------------------------------
- CompositeCurve(const IfcCompositeCurve& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- , total() {
- curves.reserve(entity.Segments.size());
- for(const IfcCompositeCurveSegment& curveSegment :entity.Segments) {
- // according to the specification, this must be a bounded curve
- std::shared_ptr< Curve > cv(Curve::Convert(curveSegment.ParentCurve,conv));
- std::shared_ptr< BoundedCurve > bc = std::dynamic_pointer_cast<BoundedCurve>(cv);
-
- if (!bc) {
- IFCImporter::LogError("expected segment of composite curve to be a bounded curve");
- continue;
- }
-
- if ( (std::string)curveSegment.Transition != "CONTINUOUS" ) {
- IFCImporter::LogDebug("ignoring transition code on composite curve segment, only continuous transitions are supported");
- }
-
- curves.push_back( CurveEntry(bc,IsTrue(curveSegment.SameSense)) );
- total += bc->GetParametricRangeDelta();
- }
-
- if (curves.empty()) {
- throw CurveError("empty composite curve");
- }
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat u) const {
- if (curves.empty()) {
- return IfcVector3();
- }
-
- IfcFloat acc = 0;
- for(const CurveEntry& entry : curves) {
- const ParamRange& range = entry.first->GetParametricRange();
- const IfcFloat delta = std::abs(range.second-range.first);
- if (u < acc+delta) {
- return entry.first->Eval( entry.second ? (u-acc) + range.first : range.second-(u-acc));
- }
-
- acc += delta;
- }
- // clamp to end
- return curves.back().first->Eval(curves.back().first->GetParametricRange().second);
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
- size_t cnt = 0;
-
- IfcFloat acc = 0;
- for(const CurveEntry& entry : curves) {
- const ParamRange& range = entry.first->GetParametricRange();
- const IfcFloat delta = std::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 );
- }
-
- acc += delta;
- }
-
- return cnt;
- }
-
- // --------------------------------------------------
- void SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
-
- const size_t cnt = EstimateSampleCount(a,b);
- out.verts.reserve(out.verts.size() + cnt);
-
- for(const CurveEntry& entry : curves) {
- const size_t cnt = out.verts.size();
- entry.first->SampleDiscrete(out);
-
- if (!entry.second && cnt != out.verts.size()) {
- std::reverse(out.verts.begin()+cnt,out.verts.end());
- }
- }
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ),total);
- }
-
-private:
- std::vector< CurveEntry > curves;
- IfcFloat total;
-};
-
-// --------------------------------------------------------------------------------
-// TrimmedCurve can be used to trim an unbounded curve to a bounded range
-// --------------------------------------------------------------------------------
-class TrimmedCurve : public BoundedCurve {
-public:
- // --------------------------------------------------
- TrimmedCurve(const IfcTrimmedCurve& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- {
- base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
-
- typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
-
- // for some reason, trimmed curves can either specify a parametric value
- // or a point on the curve, or both. And they can even specify which of the
- // two representations they prefer, even though an information invariant
- // claims that they must be identical if both are present.
- // oh well.
- bool have_param = false, have_point = false;
- IfcVector3 point;
- for(const Entry sel :entity.Trim1) {
- if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
- range.first = *r;
- have_param = true;
- break;
- }
- else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
- ConvertCartesianPoint(point,*r);
- have_point = true;
- }
- }
- if (!have_param) {
- if (!have_point || !base->ReverseEval(point,range.first)) {
- throw CurveError("IfcTrimmedCurve: failed to read first trim parameter, ignoring curve");
- }
- }
- have_param = false, have_point = false;
- for(const Entry sel :entity.Trim2) {
- if (const EXPRESS::REAL* const r = sel->ToPtr<EXPRESS::REAL>()) {
- range.second = *r;
- have_param = true;
- break;
- }
- else if (const IfcCartesianPoint* const r = sel->ResolveSelectPtr<IfcCartesianPoint>(conv.db)) {
- ConvertCartesianPoint(point,*r);
- have_point = true;
- }
- }
- if (!have_param) {
- if (!have_point || !base->ReverseEval(point,range.second)) {
- throw CurveError("IfcTrimmedCurve: failed to read second trim parameter, ignoring curve");
- }
- }
-
- agree_sense = IsTrue(entity.SenseAgreement);
- if( !agree_sense ) {
- std::swap(range.first,range.second);
- }
-
- // "NOTE In case of a closed curve, it may be necessary to increment t1 or t2
- // by the parametric length for consistency with the sense flag."
- if (base->IsClosed()) {
- if( range.first > range.second ) {
- range.second += base->GetParametricRangeDelta();
- }
- }
-
- maxval = range.second-range.first;
- ai_assert(maxval >= 0);
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat p) const {
- ai_assert(InRange(p));
- return base->Eval( TrimParam(p) );
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
- return base->EstimateSampleCount(TrimParam(a),TrimParam(b));
- }
-
- // --------------------------------------------------
- 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);
- }
-
-private:
- // --------------------------------------------------
- IfcFloat TrimParam(IfcFloat f) const {
- return agree_sense ? f + range.first : range.second - f;
- }
-
-private:
- ParamRange range;
- IfcFloat maxval;
- bool agree_sense;
-
- std::shared_ptr<const Curve> base;
-};
-
-
-// --------------------------------------------------------------------------------
-// PolyLine is a 'curve' defined by linear interpolation over a set of discrete points
-// --------------------------------------------------------------------------------
-class PolyLine : public BoundedCurve {
-public:
- // --------------------------------------------------
- PolyLine(const IfcPolyline& entity, ConversionData& conv)
- : BoundedCurve(entity,conv)
- {
- points.reserve(entity.Points.size());
-
- IfcVector3 t;
- for(const IfcCartesianPoint& cp : entity.Points) {
- ConvertCartesianPoint(t,cp);
- points.push_back(t);
- }
- }
-
- // --------------------------------------------------
- IfcVector3 Eval(IfcFloat p) const {
- ai_assert(InRange(p));
-
- const size_t b = static_cast<size_t>(std::floor(p));
- if (b == points.size()-1) {
- return points.back();
- }
-
- const IfcFloat d = p-static_cast<IfcFloat>(b);
- return points[b+1] * d + points[b] * (static_cast<IfcFloat>( 1. )-d);
- }
-
- // --------------------------------------------------
- size_t EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- ai_assert(InRange(a) && InRange(b));
- return static_cast<size_t>( std::ceil(b) - std::floor(a) );
- }
-
- // --------------------------------------------------
- ParamRange GetParametricRange() const {
- return std::make_pair(static_cast<IfcFloat>( 0. ),static_cast<IfcFloat>(points.size()-1));
- }
-
-private:
- std::vector<IfcVector3> points;
-};
-
-} // anon
-
-// ------------------------------------------------------------------------------------------------
-Curve* Curve::Convert(const IFC::IfcCurve& curve,ConversionData& conv) {
- if(curve.ToPtr<IfcBoundedCurve>()) {
- if(const IfcPolyline* c = curve.ToPtr<IfcPolyline>()) {
- return new PolyLine(*c,conv);
- }
- if(const IfcTrimmedCurve* c = curve.ToPtr<IfcTrimmedCurve>()) {
- return new TrimmedCurve(*c,conv);
- }
- if(const IfcCompositeCurve* c = curve.ToPtr<IfcCompositeCurve>()) {
- return new CompositeCurve(*c,conv);
- }
- }
-
- if(curve.ToPtr<IfcConic>()) {
- if(const IfcCircle* c = curve.ToPtr<IfcCircle>()) {
- return new Circle(*c,conv);
- }
- if(const IfcEllipse* c = curve.ToPtr<IfcEllipse>()) {
- return new Ellipse(*c,conv);
- }
- }
-
- if(const IfcLine* c = curve.ToPtr<IfcLine>()) {
- return new Line(*c,conv);
- }
-
- // XXX OffsetCurve2D, OffsetCurve3D not currently supported
- return NULL;
-}
-
-#ifdef ASSIMP_BUILD_DEBUG
-// ------------------------------------------------------------------------------------------------
-bool Curve::InRange(IfcFloat u) const {
- const ParamRange range = GetParametricRange();
- if (IsClosed()) {
- return true;
- }
- const IfcFloat epsilon = 1e-5;
- return u - range.first > -epsilon && range.second - u > -epsilon;
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-IfcFloat Curve::GetParametricRangeDelta() const {
- const ParamRange& range = GetParametricRange();
- return std::abs(range.second - range.first);
-}
-
-// ------------------------------------------------------------------------------------------------
-size_t Curve::EstimateSampleCount(IfcFloat a, IfcFloat b) const {
- (void)(a); (void)(b);
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
-
- // arbitrary default value, deriving classes should supply better suited values
- return 16;
-}
-
-// ------------------------------------------------------------------------------------------------
-IfcFloat RecursiveSearch(const Curve* cv, const IfcVector3& val, IfcFloat a, IfcFloat b,
- unsigned int samples, IfcFloat threshold, unsigned int recurse = 0, unsigned int max_recurse = 15) {
- ai_assert(samples>1);
-
- const IfcFloat delta = (b-a)/samples, inf = std::numeric_limits<IfcFloat>::infinity();
- IfcFloat min_point[2] = {a,b}, min_diff[2] = {inf,inf};
- IfcFloat runner = a;
-
- for (unsigned int i = 0; i < samples; ++i, runner += delta) {
- const IfcFloat diff = (cv->Eval(runner)-val).SquareLength();
- if (diff < min_diff[0]) {
- min_diff[1] = min_diff[0];
- min_point[1] = min_point[0];
-
- min_diff[0] = diff;
- min_point[0] = runner;
- }
- else if (diff < min_diff[1]) {
- min_diff[1] = diff;
- min_point[1] = runner;
- }
- }
-
- ai_assert( min_diff[ 0 ] != inf );
- ai_assert( min_diff[ 1 ] != inf );
- if ( std::fabs(a-min_point[0]) < threshold || recurse >= max_recurse) {
- return min_point[0];
- }
-
- // fix for closed curves to take their wrap-over into account
- if (cv->IsClosed() && std::fabs(min_point[0]-min_point[1]) > cv->GetParametricRangeDelta()*0.5 ) {
- const Curve::ParamRange& range = cv->GetParametricRange();
- const IfcFloat wrapdiff = (cv->Eval(range.first)-val).SquareLength();
-
- if (wrapdiff < min_diff[0]) {
- const IfcFloat t = min_point[0];
- min_point[0] = min_point[1] > min_point[0] ? range.first : range.second;
- min_point[1] = t;
- }
- }
-
- return RecursiveSearch(cv,val,min_point[0],min_point[1],samples,threshold,recurse+1,max_recurse);
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Curve::ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const
-{
- // note: the following algorithm is not guaranteed to find the 'right' parameter value
- // in all possible cases, but it will always return at least some value so this function
- // will never fail in the default implementation.
-
- // XXX derive threshold from curve topology
- static const IfcFloat threshold = 1e-4f;
- static const unsigned int samples = 16;
-
- const ParamRange& range = GetParametricRange();
- paramOut = RecursiveSearch(this,val,range.first,range.second,samples,threshold);
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Curve::SampleDiscrete(TempMesh& out,IfcFloat a, IfcFloat b) const {
- ai_assert( InRange( a ) );
- ai_assert( InRange( b ) );
-
- const size_t cnt = std::max(static_cast<size_t>(0),EstimateSampleCount(a,b));
- out.verts.reserve( out.verts.size() + cnt + 1);
-
- IfcFloat p = a, delta = (b-a)/cnt;
- for(size_t i = 0; i <= cnt; ++i, p += delta) {
- out.verts.push_back(Eval(p));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool BoundedCurve::IsClosed() const {
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void BoundedCurve::SampleDiscrete(TempMesh& out) const {
- const ParamRange& range = GetParametricRange();
- ai_assert( range.first != std::numeric_limits<IfcFloat>::infinity() );
- ai_assert( range.second != std::numeric_limits<IfcFloat>::infinity() );
-
- return SampleDiscrete(out,range.first,range.second);
-}
-
-} // IFC
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
diff --git a/src/3rdparty/assimp/code/IFCGeometry.cpp b/src/3rdparty/assimp/code/IFCGeometry.cpp
deleted file mode 100644
index 908f5e065..000000000
--- a/src/3rdparty/assimp/code/IFCGeometry.cpp
+++ /dev/null
@@ -1,885 +0,0 @@
-/*
-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 IFCGeometry.cpp
- * @brief Geometry conversion and synthesis for IFC
- */
-
-
-
-#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 <memory>
-
-#include <iterator>
-
-namespace Assimp {
- namespace IFC {
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessPolyloop(const IfcPolyLoop& loop, TempMesh& meshout, ConversionData& /*conv*/)
-{
- size_t cnt = 0;
- for(const IfcCartesianPoint& c : loop.Polygon) {
- IfcVector3 tmp;
- ConvertCartesianPoint(tmp,c);
-
- meshout.verts.push_back(tmp);
- ++cnt;
- }
-
- meshout.vertcnt.push_back(static_cast<unsigned int>(cnt));
-
- // zero- or one- vertex polyloops simply ignored
- if (meshout.vertcnt.back() > 1) {
- return true;
- }
-
- if (meshout.vertcnt.back()==1) {
- meshout.vertcnt.pop_back();
- meshout.verts.pop_back();
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessPolygonBoundaries(TempMesh& result, const TempMesh& inmesh, size_t master_bounds = (size_t)-1)
-{
- // handle all trivial cases
- if(inmesh.vertcnt.empty()) {
- return;
- }
- if(inmesh.vertcnt.size() == 1) {
- result.Append(inmesh);
- return;
- }
-
- ai_assert(std::count(inmesh.vertcnt.begin(), inmesh.vertcnt.end(), 0) == 0);
-
- typedef std::vector<unsigned int>::const_iterator face_iter;
-
- face_iter begin = inmesh.vertcnt.begin(), end = inmesh.vertcnt.end(), iit;
- std::vector<unsigned int>::const_iterator outer_polygon_it = end;
-
- // 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;
- inmesh.ComputePolygonNormals(normals,false);
-
- // 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) {
- ai_assert(master_bounds < inmesh.vertcnt.size());
- outer_polygon_it = begin + master_bounds;
- }
- else {
- 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_it = iit;
- }
- }
- }
-
- ai_assert(outer_polygon_it != end);
-
- const size_t outer_polygon_size = *outer_polygon_it;
- const IfcVector3& master_normal = normals[std::distance(begin, outer_polygon_it)];
-
- // 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);
-
- 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;
- }
-
- // 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;
- }
-
- fake_openings.push_back(TempOpening());
- TempOpening& opening = fake_openings.back();
-
- opening.extrusionDir = master_normal;
- opening.solid = NULL;
-
- opening.profileMesh = std::make_shared<TempMesh>();
- opening.profileMesh->verts.reserve(*iit);
- opening.profileMesh->vertcnt.push_back(*iit);
-
- std::copy(vit, vit + *iit, std::back_inserter(opening.profileMesh->verts));
- }
-
- // fill a mesh with ONLY the main polygon
- TempMesh temp;
- temp.verts.reserve(outer_polygon_size);
- temp.vertcnt.push_back(static_cast<unsigned int>(outer_polygon_size));
- std::copy(outer_vit, outer_vit+outer_polygon_size,
- std::back_inserter(temp.verts));
-
- GenerateOpenings(fake_openings, normals, temp, false, false);
- result.Append(temp);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessConnectedFaceSet(const IfcConnectedFaceSet& fset, TempMesh& result, ConversionData& conv)
-{
- for(const IfcFace& face : fset.CfsFaces) {
- // size_t ob = -1, cnt = 0;
- TempMesh meshout;
- for(const IfcFaceBound& bound : face.Bounds) {
-
- 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;
- //}
- //++cnt;
-
- }
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcFaceBound entity, type is " + bound.Bound->GetClassName());
- 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;
- for(unsigned int& c : meshout.vertcnt) {
- std::reverse(result.verts.begin() + cnt,result.verts.begin() + cnt + c);
- cnt += c;
- }
- }*/
- }
- ProcessPolygonBoundaries(result, meshout);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessRevolvedAreaSolid(const IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv)
-{
- TempMesh meshout;
-
- // first read the profile description
- if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
- return;
- }
-
- IfcVector3 axis, pos;
- ConvertAxisPlacement(axis,pos,solid.Axis);
-
- IfcMatrix4 tb0,tb1;
- IfcMatrix4::Translation(pos,tb0);
- IfcMatrix4::Translation(-pos,tb1);
-
- const std::vector<IfcVector3>& in = meshout.verts;
- const size_t size=in.size();
-
- bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2;
- const IfcFloat max_angle = solid.Angle*conv.angle_scale;
- if(std::fabs(max_angle) < 1e-3) {
- if(has_area) {
- result = meshout;
- }
- return;
- }
-
- const unsigned int cnt_segments = std::max(2u,static_cast<unsigned int>(conv.settings.cylindricalTessellation * std::fabs(max_angle)/AI_MATH_HALF_PI_F));
- const IfcFloat delta = max_angle/cnt_segments;
-
- has_area = has_area && std::fabs(max_angle) < AI_MATH_TWO_PI_F*0.99;
-
- result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0)));
- result.vertcnt.reserve(size*cnt_segments+2);
-
- IfcMatrix4 rot;
- rot = tb0 * IfcMatrix4::Rotation(delta,axis,rot) * tb1;
-
- size_t base = 0;
- std::vector<IfcVector3>& out = result.verts;
-
- // dummy data to simplify later processing
- for(size_t i = 0; i < size; ++i) {
- out.insert(out.end(),4,in[i]);
- }
-
- for(unsigned int seg = 0; seg < cnt_segments; ++seg) {
- for(size_t i = 0; i < size; ++i) {
- const size_t next = (i+1)%size;
-
- result.vertcnt.push_back(4);
- const IfcVector3 base_0 = out[base+i*4+3],base_1 = out[base+next*4+3];
-
- out.push_back(base_0);
- out.push_back(base_1);
- out.push_back(rot*base_1);
- out.push_back(rot*base_0);
- }
- base += size*4;
- }
-
- out.erase(out.begin(),out.begin()+size*4);
-
- if(has_area) {
- // leave the triangulation of the profile area to the ear cutting
- // implementation in aiProcess_Triangulate - for now we just
- // feed in two huge polygons.
- base -= size*8;
- for(size_t i = size; i--; ) {
- out.push_back(out[base+i*4+3]);
- }
- for(size_t i = 0; i < size; ++i ) {
- out.push_back(out[i*4]);
- }
- result.vertcnt.push_back(static_cast<unsigned int>(size));
- result.vertcnt.push_back(static_cast<unsigned int>(size));
- }
-
- IfcMatrix4 trafo;
- ConvertAxisPlacement(trafo, solid.Position);
-
- result.Transform(trafo);
- IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)");
-}
-
-
-
-// ------------------------------------------------------------------------------------------------
-void ProcessSweptDiskSolid(const IfcSweptDiskSolid solid, TempMesh& result, ConversionData& conv)
-{
- const Curve* const curve = Curve::Convert(*solid.Directrix, conv);
- if(!curve) {
- IFCImporter::LogError("failed to convert Directrix curve (IfcSweptDiskSolid)");
- return;
- }
-
- const unsigned int cnt_segments = conv.settings.cylindricalTessellation;
- const IfcFloat deltaAngle = AI_MATH_TWO_PI/cnt_segments;
-
- const size_t samples = curve->EstimateSampleCount(solid.StartParam,solid.EndParam);
-
- result.verts.reserve(cnt_segments * samples * 4);
- result.vertcnt.reserve((cnt_segments - 1) * samples);
-
- std::vector<IfcVector3> points;
- points.reserve(cnt_segments * samples);
-
- TempMesh temp;
- curve->SampleDiscrete(temp,solid.StartParam,solid.EndParam);
- const std::vector<IfcVector3>& curve_points = temp.verts;
-
- if(curve_points.empty()) {
- IFCImporter::LogWarn("curve evaluation yielded no points (IfcSweptDiskSolid)");
- return;
- }
-
- IfcVector3 current = curve_points[0];
- IfcVector3 previous = current;
- IfcVector3 next;
-
- IfcVector3 startvec;
- startvec.x = 1.0f;
- startvec.y = 1.0f;
- startvec.z = 1.0f;
-
- unsigned int last_dir = 0;
-
- // generate circles at the sweep positions
- for(size_t i = 0; i < samples; ++i) {
-
- if(i != samples - 1) {
- next = curve_points[i + 1];
- }
-
- // get a direction vector reflecting the approximate curvature (i.e. tangent)
- IfcVector3 d = (current-previous) + (next-previous);
-
- 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) && std::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;
- }
- else if ((last_dir == 1 || take_any) && std::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 && std::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;
- }
- }
-
- q *= solid.Radius / q.Length();
- startvec = q;
-
- // generate a rotation matrix to rotate q around d
- IfcMatrix4 rot;
- IfcMatrix4::Rotation(deltaAngle,d,rot);
-
- for (unsigned int seg = 0; seg < cnt_segments; ++seg, q *= rot ) {
- points.push_back(q + current);
- }
-
- previous = current;
- current = next;
- }
-
- // make quads
- for(size_t i = 0; i < samples - 1; ++i) {
-
- const aiVector3D& this_start = points[ i * cnt_segments ];
-
- // 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();
-
- if(l < best_distance_squared) {
- best_pair_offset = seg;
- best_distance_squared = l;
- }
- }
-
- for (unsigned int seg = 0; seg < cnt_segments; ++seg) {
-
- 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)]);
-
- IfcVector3& v1 = *(result.verts.end()-1);
- IfcVector3& v2 = *(result.verts.end()-2);
- IfcVector3& v3 = *(result.verts.end()-3);
- IfcVector3& v4 = *(result.verts.end()-4);
-
- if (((v4-v3) ^ (v4-v1)) * (v4 - curve_points[i]) < 0.0f) {
- std::swap(v4, v1);
- std::swap(v3, v2);
- }
-
- result.vertcnt.push_back(4);
- }
- }
-
- IFCImporter::LogDebug("generate mesh procedurally by sweeping a disk along a curve (IfcSweptDiskSolid)");
-}
-
-// ------------------------------------------------------------------------------------------------
-IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut)
-{
- const std::vector<IfcVector3>& out = curmesh.verts;
- IfcMatrix3 m;
-
- ok = true;
-
- // The input "mesh" must be a single polygon
- 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, 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(std::fabs(nor.Length()) > 1e-8f) {
- done = true;
- break;
- }
- }
- }
-
- if(!done) {
- ok = false;
- return m;
- }
-
- nor.Normalize();
- norOut = nor;
-
- IfcVector3 r = (out[i]-any_point);
- r.Normalize();
-
- //if(d) {
- // *d = -any_point * nor;
- //}
-
- // Reconstruct orthonormal basis
- // XXX use Gram Schmidt for increased robustness
- 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;
-}
-
-// Extrudes the given polygon along the direction, converts it into an opening or applies all openings as necessary.
-void ProcessExtrudedArea(const IfcExtrudedAreaSolid& solid, const TempMesh& curve,
- const IfcVector3& extrusionDir, TempMesh& result, ConversionData &conv, bool collect_openings)
-{
- // Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
- // forming new triangles.
- const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.verts.size() > 2;
- if( solid.Depth < 1e-6 ) {
- if( has_area ) {
- result.Append(curve);
- }
- return;
- }
-
- result.verts.reserve(curve.verts.size()*(has_area ? 4 : 2));
- result.vertcnt.reserve(curve.verts.size() + 2);
- std::vector<IfcVector3> in = curve.verts;
-
- // First step: transform all vertices into the target coordinate space
- IfcMatrix4 trafo;
- ConvertAxisPlacement(trafo, solid.Position);
-
- IfcVector3 vmin, vmax;
- MinMaxChooser<IfcVector3>()(vmin, vmax);
- for(IfcVector3& v : in) {
- v *= trafo;
-
- vmin = std::min(vmin, v);
- vmax = std::max(vmax, v);
- }
-
- vmax -= vmin;
- const IfcFloat diag = vmax.Length();
- IfcVector3 dir = IfcMatrix3(trafo) * extrusionDir;
-
- // reverse profile polygon if it's winded in the wrong direction in relation to the extrusion direction
- IfcVector3 profileNormal = TempMesh::ComputePolygonNormal(in.data(), in.size());
- if( profileNormal * dir < 0.0 )
- std::reverse(in.begin(), in.end());
-
- std::vector<IfcVector3> nors;
- const bool openings = !!conv.apply_openings && conv.apply_openings->size();
-
- // 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 ) {
- // it is essential to apply the openings in the correct spatial order. The direction
- // 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(), TempOpening::DistanceSorter(in[0]));
- }
-
- nors.reserve(conv.apply_openings->size());
- for(TempOpening& t : *conv.apply_openings) {
- TempMesh& bounds = *t.profileMesh.get();
-
- if( bounds.verts.size() <= 2 ) {
- nors.push_back(IfcVector3());
- continue;
- }
- nors.push_back(((bounds.verts[2] - bounds.verts[0]) ^ (bounds.verts[1] - bounds.verts[0])).Normalize());
- }
- }
-
-
- TempMesh temp;
- TempMesh& curmesh = openings ? temp : result;
- std::vector<IfcVector3>& out = curmesh.verts;
-
- size_t sides_with_openings = 0;
- for( size_t i = 0; i < in.size(); ++i ) {
- const size_t next = (i + 1) % in.size();
-
- curmesh.vertcnt.push_back(4);
-
- out.push_back(in[i]);
- out.push_back(in[next]);
- out.push_back(in[next] + dir);
- out.push_back(in[i] + dir);
-
- if( openings ) {
- if( (in[i] - in[next]).Length() > diag * 0.1 && GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
- ++sides_with_openings;
- }
-
- result.Append(temp);
- temp.Clear();
- }
- }
-
- if( openings ) {
- for(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 ) {
-
- for( size_t n = 0; n < 2; ++n ) {
- if( n > 0 ) {
- for( size_t i = 0; i < in.size(); ++i )
- out.push_back(in[i] + dir);
- }
- else {
- for( size_t i = in.size(); i--; )
- out.push_back(in[i]);
- }
-
- curmesh.vertcnt.push_back(static_cast<unsigned int>(in.size()));
- if( openings && in.size() > 2 ) {
- if( GenerateOpenings(*conv.apply_openings, nors, temp, true, true, dir) ) {
- ++sides_with_v_openings;
- }
-
- result.Append(temp);
- temp.Clear();
- }
- }
- }
-
- 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);
- std::shared_ptr<TempMesh> profile = std::shared_ptr<TempMesh>(new TempMesh());
- profile->Swap(result);
-
- std::shared_ptr<TempMesh> profile2D = std::shared_ptr<TempMesh>(new TempMesh());
- profile2D->verts.insert(profile2D->verts.end(), in.begin(), in.end());
- profile2D->vertcnt.push_back(static_cast<unsigned int>(in.size()));
- conv.collect_openings->push_back(TempOpening(&solid, dir, profile, profile2D));
-
- ai_assert(result.IsEmpty());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessExtrudedAreaSolid(const IfcExtrudedAreaSolid& solid, TempMesh& result,
- ConversionData& conv, bool collect_openings)
-{
- TempMesh meshout;
-
- // First read the profile description.
- if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) {
- return;
- }
-
- IfcVector3 dir;
- ConvertDirection(dir,solid.ExtrudedDirection);
- dir *= solid.Depth;
-
- // Some profiles bring their own holes, for which we need to provide a container. This all is somewhat backwards,
- // and there's still so many corner cases uncovered - we really need a generic solution to all of this hole carving.
- std::vector<TempOpening> fisherPriceMyFirstOpenings;
- std::vector<TempOpening>* oldApplyOpenings = conv.apply_openings;
- if( const IfcArbitraryProfileDefWithVoids* const cprofile = solid.SweptArea->ToPtr<IfcArbitraryProfileDefWithVoids>() ) {
- if( !cprofile->InnerCurves.empty() ) {
- // read all inner curves and extrude them to form proper openings.
- std::vector<TempOpening>* oldCollectOpenings = conv.collect_openings;
- conv.collect_openings = &fisherPriceMyFirstOpenings;
-
- for(const IfcCurve* curve : cprofile->InnerCurves) {
- TempMesh curveMesh, tempMesh;
- ProcessCurve(*curve, curveMesh, conv);
- ProcessExtrudedArea(solid, curveMesh, dir, tempMesh, conv, true);
- }
- // and then apply those to the geometry we're about to generate
- conv.apply_openings = conv.collect_openings;
- conv.collect_openings = oldCollectOpenings;
- }
- }
-
- ProcessExtrudedArea(solid, meshout, dir, result, conv, collect_openings);
- conv.apply_openings = oldApplyOpenings;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessSweptAreaSolid(const IfcSweptAreaSolid& swept, TempMesh& meshout,
- ConversionData& conv)
-{
- if(const IfcExtrudedAreaSolid* const solid = swept.ToPtr<IfcExtrudedAreaSolid>()) {
- ProcessExtrudedAreaSolid(*solid,meshout,conv, !!conv.collect_openings);
- }
- else if(const IfcRevolvedAreaSolid* const rev = swept.ToPtr<IfcRevolvedAreaSolid>()) {
- ProcessRevolvedAreaSolid(*rev,meshout,conv);
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessGeometricItem(const IfcRepresentationItem& geo, unsigned int matid, std::vector<unsigned int>& mesh_indices,
- ConversionData& conv)
-{
- bool fix_orientation = false;
- std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
- if(const IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<IfcShellBasedSurfaceModel>()) {
- for(std::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.get(),conv);
- }
- catch(std::bad_cast&) {
- IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet");
- }
- }
- fix_orientation = true;
- }
- else if(const IfcConnectedFaceSet* fset = geo.ToPtr<IfcConnectedFaceSet>()) {
- ProcessConnectedFaceSet(*fset,*meshtmp.get(),conv);
- fix_orientation = true;
- }
- else if(const IfcSweptAreaSolid* swept = geo.ToPtr<IfcSweptAreaSolid>()) {
- ProcessSweptAreaSolid(*swept,*meshtmp.get(),conv);
- }
- else if(const IfcSweptDiskSolid* disk = geo.ToPtr<IfcSweptDiskSolid>()) {
- ProcessSweptDiskSolid(*disk,*meshtmp.get(),conv);
- }
- else if(const IfcManifoldSolidBrep* brep = geo.ToPtr<IfcManifoldSolidBrep>()) {
- ProcessConnectedFaceSet(brep->Outer,*meshtmp.get(),conv);
- fix_orientation = true;
- }
- else if(const IfcFaceBasedSurfaceModel* surf = geo.ToPtr<IfcFaceBasedSurfaceModel>()) {
- for(const IfcConnectedFaceSet& fc : surf->FbsmFaces) {
- ProcessConnectedFaceSet(fc,*meshtmp.get(),conv);
- }
- fix_orientation = true;
- }
- else if(const IfcBooleanResult* boolean = geo.ToPtr<IfcBooleanResult>()) {
- ProcessBoolean(*boolean,*meshtmp.get(),conv);
- }
- else if(geo.ToPtr<IfcBoundingBox>()) {
- // silently skip over bounding boxes
- return false;
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcGeometricRepresentationItem entity, type is " + geo.GetClassName());
- return false;
- }
-
- // 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,
- std::shared_ptr<TempMesh>()));
- }
- return true;
- }
-
- if (meshtmp->IsEmpty()) {
- return false;
- }
-
- meshtmp->RemoveAdjacentDuplicates();
- meshtmp->RemoveDegenerates();
-
- if(fix_orientation) {
-// meshtmp->FixupFaceOrientation();
- }
-
- aiMesh* const mesh = meshtmp->ToMesh();
- if(mesh) {
- mesh->mMaterialIndex = matid;
- mesh_indices.push_back(static_cast<unsigned int>(conv.meshes.size()));
- conv.meshes.push_back(mesh);
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void AssignAddedMeshes(std::vector<unsigned int>& mesh_indices,aiNode* nd,
- ConversionData& /*conv*/)
-{
- if (!mesh_indices.empty()) {
-
- // make unique
- std::sort(mesh_indices.begin(),mesh_indices.end());
- std::vector<unsigned int>::iterator it_end = std::unique(mesh_indices.begin(),mesh_indices.end());
-
- nd->mNumMeshes = static_cast<unsigned int>(std::distance(mesh_indices.begin(),it_end));
-
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
- nd->mMeshes[i] = mesh_indices[i];
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool TryQueryMeshCache(const IfcRepresentationItem& item,
- std::vector<unsigned int>& mesh_indices, unsigned int mat_index,
- ConversionData& conv)
-{
- ConversionData::MeshCacheIndex idx(&item, mat_index);
- ConversionData::MeshCache::const_iterator it = conv.cached_meshes.find(idx);
- if (it != conv.cached_meshes.end()) {
- std::copy((*it).second.begin(),(*it).second.end(),std::back_inserter(mesh_indices));
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void PopulateMeshCache(const IfcRepresentationItem& item,
- const std::vector<unsigned int>& mesh_indices, unsigned int mat_index,
- ConversionData& conv)
-{
- ConversionData::MeshCacheIndex idx(&item, mat_index);
- conv.cached_meshes[idx] = mesh_indices;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessRepresentationItem(const IfcRepresentationItem& item, unsigned int matid,
- std::vector<unsigned int>& mesh_indices,
- ConversionData& conv)
-{
- // determine material
- unsigned int localmatid = ProcessMaterials(item.GetID(), matid, conv, true);
-
- if (!TryQueryMeshCache(item,mesh_indices,localmatid,conv)) {
- if(ProcessGeometricItem(item,localmatid,mesh_indices,conv)) {
- if(mesh_indices.size()) {
- PopulateMeshCache(item,mesh_indices,localmatid,conv);
- }
- }
- else return false;
- }
- return true;
-}
-
-
-} // ! IFC
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCLoader.cpp b/src/3rdparty/assimp/code/IFCLoader.cpp
deleted file mode 100644
index 85382d467..000000000
--- a/src/3rdparty/assimp/code/IFCLoader.cpp
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFCLoad.cpp
- * @brief Implementation of the Industry Foundation Classes loader.
- */
-
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-
-#include <iterator>
-#include <limits>
-#include <tuple>
-
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
-# include <contrib/unzip/unzip.h>
-#endif
-
-#include "IFCLoader.h"
-#include "STEPFileReader.h"
-
-#include "IFCUtil.h"
-
-#include "MemoryIOWrapper.h"
-#include <assimp/scene.h>
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-
-
-namespace Assimp {
- template<> const char* LogFunctions<IFCImporter>::Prefix()
- {
- static auto prefix = "IFC: ";
- return prefix;
- }
-}
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-using namespace Assimp::IFC;
-
-/* DO NOT REMOVE this comment block. The genentitylist.sh script
- * just looks for names adhering to the IfcSomething naming scheme
- * and includes all matches in the whitelist for code-generation. Thus,
- * all entity classes that are only indirectly referenced need to be
- * mentioned explicitly.
-
- IfcRepresentationMap
- IfcProductRepresentation
- IfcUnitAssignment
- IfcClosedShell
- IfcDoor
-
- */
-
-namespace {
-
-
-// forward declarations
-void SetUnits(ConversionData& conv);
-void SetCoordinateSpace(ConversionData& conv);
-void ProcessSpatialStructures(ConversionData& conv);
-void MakeTreeRelative(ConversionData& conv);
-void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv);
-
-} // anon
-
-static const aiImporterDesc desc = {
- "Industry Foundation Classes (IFC) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "ifc ifczip stp"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IFCImporter::IFCImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IFCImporter::~IFCImporter()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool IFCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string& extension = GetExtension(pFile);
- if (extension == "ifc" || extension == "ifczip" || extension == "stp" ) {
- return true;
- } else if ((!extension.length() || checkSig) && pIOHandler) {
- // note: this is the common identification for STEP-encoded files, so
- // it is only unambiguous as long as we don't support any further
- // file formats with STEP as their encoding.
- const char* tokens[] = {"ISO-10303-21"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// List all extensions handled by this loader
-const aiImporterDesc* IFCImporter::GetInfo () const
-{
- return &desc;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void IFCImporter::SetupProperties(const Importer* pImp)
-{
- settings.skipSpaceRepresentations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS,true);
- settings.useCustomTriangulation = pImp->GetPropertyBool(AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION,true);
- settings.conicSamplingAngle = std::min(std::max((float) pImp->GetPropertyFloat(AI_CONFIG_IMPORT_IFC_SMOOTHING_ANGLE, AI_IMPORT_IFC_DEFAULT_SMOOTHING_ANGLE), 5.0f), 120.0f);
- settings.cylindricalTessellation = std::min(std::max(pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IFC_CYLINDRICAL_TESSELLATION, AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION), 3), 180);
- settings.skipAnnotations = true;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void IFCImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile));
- if (!stream) {
- 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
- }
-
- std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(stream));
- const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
-
- if(!head.fileSchema.size() || head.fileSchema.substr(0,3) != "IFC") {
- ThrowException("Unrecognized file schema: " + head.fileSchema);
- }
-
- if (!DefaultLogger::isNullLogger()) {
- LogDebug("File schema is \'" + head.fileSchema + '\'');
- if (head.timestamp.length()) {
- LogDebug("Timestamp \'" + head.timestamp + '\'');
- }
- if (head.app.length()) {
- LogDebug("Application/Exporter identline is \'" + head.app + '\'');
- }
- }
-
- // obtain a copy of the machine-generated IFC scheme
- EXPRESS::ConversionSchema schema;
- GetSchema(schema);
-
- // tell the reader which entity types to track with special care
- static const char* const types_to_track[] = {
- "ifcsite", "ifcbuilding", "ifcproject"
- };
-
- // tell the reader for which types we need to simulate STEPs reverse indices
- static const char* const inverse_indices_to_track[] = {
- "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");
- }
-
- ConversionData conv(*db,proj->To<IfcProject>(),pScene,settings);
- SetUnits(conv);
- SetCoordinateSpace(conv);
- ProcessSpatialStructures(conv);
- MakeTreeRelative(conv);
-
- // NOTE - this is a stress test for the importer, but it works only
- // in a build with no entities disabled. See
- // scripts/IFCImporter/CPPGenerator.py
- // for more information.
- #ifdef ASSIMP_IFC_TEST
- db->EvaluateAll();
- #endif
-
- // do final data copying
- if (conv.meshes.size()) {
- pScene->mNumMeshes = static_cast<unsigned int>(conv.meshes.size());
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- std::copy(conv.meshes.begin(),conv.meshes.end(),pScene->mMeshes);
-
- // needed to keep the d'tor from burning us
- conv.meshes.clear();
- }
-
- if (conv.materials.size()) {
- pScene->mNumMaterials = static_cast<unsigned int>(conv.materials.size());
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
- std::copy(conv.materials.begin(),conv.materials.end(),pScene->mMaterials);
-
- // needed to keep the d'tor from burning us
- conv.materials.clear();
- }
-
- // apply world coordinate system (which includes the scaling to convert to meters and a -90 degrees rotation around x)
- aiMatrix4x4 scale, rot;
- aiMatrix4x4::Scaling(static_cast<aiVector3D>(IfcVector3(conv.len_scale)),scale);
- aiMatrix4x4::RotationX(-AI_MATH_HALF_PI_F,rot);
-
- pScene->mRootNode->mTransformation = rot * scale * conv.wcs * pScene->mRootNode->mTransformation;
-
- // this must be last because objects are evaluated lazily as we process them
- if ( !DefaultLogger::isNullLogger() ){
- LogDebug((Formatter::format(),"STEP: evaluated ",db->GetEvaluatedObjectCount()," object records"));
- }
-}
-
-namespace {
-
-
-// ------------------------------------------------------------------------------------------------
-void ConvertUnit(const IfcNamedUnit& unit,ConversionData& conv)
-{
- if(const IfcSIUnit* const si = unit.ToPtr<IfcSIUnit>()) {
-
- if(si->UnitType == "LENGTHUNIT") {
- conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f;
- IFCImporter::LogDebug("got units used for lengths");
- }
- if(si->UnitType == "PLANEANGLEUNIT") {
- if (si->Name != "RADIAN") {
- IFCImporter::LogWarn("expected base unit for angles to be radian");
- }
- }
- }
- else if(const IfcConversionBasedUnit* const convu = unit.ToPtr<IfcConversionBasedUnit>()) {
-
- if(convu->UnitType == "PLANEANGLEUNIT") {
- try {
- conv.angle_scale = convu->ConversionFactor->ValueComponent->To<EXPRESS::REAL>();
- ConvertUnit(*convu->ConversionFactor->UnitComponent,conv);
- IFCImporter::LogDebug("got units used for angles");
- }
- catch(std::bad_cast&) {
- IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL");
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertUnit(const EXPRESS::DataType& dt,ConversionData& conv)
-{
- try {
- const EXPRESS::ENTITY& e = dt.To<ENTITY>();
-
- const IfcNamedUnit& unit = e.ResolveSelect<IfcNamedUnit>(conv.db);
- if(unit.UnitType != "LENGTHUNIT" && unit.UnitType != "PLANEANGLEUNIT") {
- return;
- }
-
- ConvertUnit(unit,conv);
- }
- catch(std::bad_cast&) {
- // not entity, somehow
- IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SetUnits(ConversionData& conv)
-{
- // see if we can determine the coordinate space used to express.
- for(size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i ) {
- ConvertUnit(*conv.proj.UnitsInContext->Units[i],conv);
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void SetCoordinateSpace(ConversionData& conv)
-{
- const IfcRepresentationContext* fav = NULL;
- for(const IfcRepresentationContext& v : conv.proj.RepresentationContexts) {
- fav = &v;
- // Model should be the most suitable type of context, hence ignore the others
- if (v.ContextType && v.ContextType.Get() == "Model") {
- break;
- }
- }
- if (fav) {
- if(const IfcGeometricRepresentationContext* const geo = fav->ToPtr<IfcGeometricRepresentationContext>()) {
- ConvertAxisPlacement(conv.wcs, *geo->WorldCoordinateSystem, conv);
- IFCImporter::LogDebug("got world coordinate system");
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void ResolveObjectPlacement(aiMatrix4x4& m, const IfcObjectPlacement& place, ConversionData& conv)
-{
- if (const IfcLocalPlacement* const local = place.ToPtr<IfcLocalPlacement>()){
- IfcMatrix4 tmp;
- ConvertAxisPlacement(tmp, *local->RelativePlacement, conv);
-
- m = static_cast<aiMatrix4x4>(tmp);
-
- if (local->PlacementRelTo) {
- aiMatrix4x4 tmp;
- ResolveObjectPlacement(tmp,local->PlacementRelTo.Get(),conv);
- m = tmp * m;
- }
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcObjectPlacement entity, type is " + place.GetClassName());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessMappedItem(const IfcMappedItem& mapped, aiNode* nd_src, std::vector< aiNode* >& subnodes_src, unsigned int matid, ConversionData& conv)
-{
- // insert a custom node here, the cartesian transform operator is simply a conventional transformation matrix
- std::unique_ptr<aiNode> nd(new aiNode());
- nd->mName.Set("IfcMappedItem");
-
- // handle the Cartesian operator
- IfcMatrix4 m;
- ConvertTransformOperator(m, *mapped.MappingTarget);
-
- IfcMatrix4 msrc;
- ConvertAxisPlacement(msrc,*mapped.MappingSource->MappingOrigin,conv);
-
- msrc = m*msrc;
-
- std::vector<unsigned int> meshes;
- const size_t old_openings = conv.collect_openings ? conv.collect_openings->size() : 0;
- if (conv.apply_openings) {
- IfcMatrix4 minv = msrc;
- minv.Inverse();
- for(TempOpening& open :*conv.apply_openings){
- open.Transform(minv);
- }
- }
-
- unsigned int localmatid = ProcessMaterials(mapped.GetID(),matid,conv,false);
- const IfcRepresentation& repr = mapped.MappingSource->MappedRepresentation;
-
- bool got = false;
- for(const IfcRepresentationItem& item : repr.Items) {
- if(!ProcessRepresentationItem(item,localmatid,meshes,conv)) {
- IFCImporter::LogWarn("skipping mapped entity of type " + item.GetClassName() + ", no representations could be generated");
- }
- else got = true;
- }
-
- if (!got) {
- return false;
- }
-
- AssignAddedMeshes(meshes,nd.get(),conv);
- if (conv.collect_openings) {
-
- // if this pass serves us only to collect opening geometry,
- // make sure we transform the TempMesh's which we need to
- // preserve as well.
- if(const size_t diff = conv.collect_openings->size() - old_openings) {
- for(size_t i = 0; i < diff; ++i) {
- (*conv.collect_openings)[old_openings+i].Transform(msrc);
- }
- }
- }
-
- nd->mTransformation = nd_src->mTransformation * static_cast<aiMatrix4x4>( msrc );
- subnodes_src.push_back(nd.release());
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-struct RateRepresentationPredicate {
-
- int Rate(const IfcRepresentation* r) const {
- // the smaller, the better
-
- if (! r->RepresentationIdentifier) {
- // neutral choice if no extra information is specified
- return 0;
- }
-
-
- const std::string& name = r->RepresentationIdentifier.Get();
- if (name == "MappedRepresentation") {
- if (!r->Items.empty()) {
- // take the first item and base our choice on it
- const IfcMappedItem* const m = r->Items.front()->ToPtr<IfcMappedItem>();
- if (m) {
- return Rate(m->MappingSource->MappedRepresentation);
- }
- }
- return 100;
- }
-
- return Rate(name);
- }
-
- int Rate(const std::string& r) const {
-
-
- if (r == "SolidModel") {
- return -3;
- }
-
- // give strong preference to extruded geometry.
- if (r == "SweptSolid") {
- return -10;
- }
-
- if (r == "Clipping") {
- return -5;
- }
-
- // 'Brep' is difficult to get right due to possible voids in the
- // polygon boundaries, so take it only if we are forced to (i.e.
- // if the only alternative is (non-clipping) boolean operations,
- // which are not supported at all).
- if (r == "Brep") {
- return -2;
- }
-
- // Curves, bounding boxes - those will most likely not be loaded
- // as we can't make any use out of this data. So consider them
- // last.
- if (r == "BoundingBox" || r == "Curve2D") {
- return 100;
- }
- return 0;
- }
-
- bool operator() (const IfcRepresentation* a, const IfcRepresentation* b) const {
- return Rate(a) < Rate(b);
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-void ProcessProductRepresentation(const IfcProduct& el, aiNode* nd, std::vector< aiNode* >& subnodes, ConversionData& conv)
-{
- if(!el.Representation) {
- return;
- }
-
- // extract Color from metadata, if present
- unsigned int matid = ProcessMaterials( el.GetID(), std::numeric_limits<uint32_t>::max(), conv, false);
- 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());
- for(const IfcRepresentation* repr : repr_ordered) {
- bool res = false;
- for(const IfcRepresentationItem& item : repr->Items) {
- if(const IfcMappedItem* const geo = item.ToPtr<IfcMappedItem>()) {
- res = ProcessMappedItem(*geo,nd,subnodes,matid,conv) || res;
- }
- else {
- res = ProcessRepresentationItem(item,matid,meshes,conv) || res;
- }
- }
- // if we got something meaningful at this point, skip any further representations
- if(res) {
- 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)
-{
- for(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;
- for(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)
-{
- const STEP::DB::RefMap& refs = conv.db.GetRefs();
-
- // skip over space and annotation nodes - usually, these have no meaning in Assimp's context
- bool skipGeometry = false;
- if(conv.settings.skipSpaceRepresentations) {
- if(el.ToPtr<IfcSpace>()) {
- IFCImporter::LogDebug("skipping IfcSpace entity due to importer settings");
- skipGeometry = true;
- }
- }
-
- if(conv.settings.skipAnnotations) {
- if(el.ToPtr<IfcAnnotation>()) {
- IFCImporter::LogDebug("skipping IfcAnnotation entity due to importer settings");
- return NULL;
- }
- }
-
- // add an output node for this spatial structure
- std::unique_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 = aiMetadata::Alloc( static_cast<unsigned int>(properties.size()) );
- unsigned int index( 0 );
- for ( 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);
- }
-
- std::vector<TempOpening> openings;
-
- IfcMatrix4 myInv;
- bool didinv = false;
-
- // convert everything contained directly within this structure,
- // this may result in more nodes.
- std::vector< aiNode* > subnodes;
- try {
- // locate aggregates and 'contained-in-here'-elements of this spatial structure and add them in recursively
- // on our way, collect openings in *this* element
- 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;
- }
- for(const IfcProduct& pro : cont->RelatedElements) {
- if(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 storey,
- // but we want them for the building elements to which they belong.
- continue;
- }
-
- aiNode* const ndnew = ProcessSpatialStructure(nd.get(),pro,conv,NULL);
- if(ndnew) {
- subnodes.push_back( ndnew );
- }
- }
- }
- // handle openings, which we collect in a list rather than adding them to the node graph
- else if(const IfcRelVoidsElement* const fills = obj->ToPtr<IfcRelVoidsElement>()) {
- if(fills->RelatingBuildingElement->GetID() == el.GetID()) {
- 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());
- nd_aggr->mName.Set("$RelVoidsElement");
- nd_aggr->mParent = nd.get();
-
- nd_aggr->mTransformation = nd->mTransformation;
-
- std::vector<TempOpening> openings_local;
- aiNode* const ndnew = ProcessSpatialStructure( nd_aggr.get(),open, conv,&openings_local);
- if (ndnew) {
-
- nd_aggr->mNumChildren = 1;
- nd_aggr->mChildren = new aiNode*[1]();
-
-
- nd_aggr->mChildren[0] = ndnew;
-
- if(openings_local.size()) {
- if (!didinv) {
- myInv = aiMatrix4x4(nd->mTransformation ).Inverse();
- didinv = true;
- }
-
- // we need all openings to be in the local space of *this* node, so transform them
- for(TempOpening& op :openings_local) {
- op.Transform( myInv*nd_aggr->mChildren[0]->mTransformation);
- openings.push_back(op);
- }
- }
- subnodes.push_back( nd_aggr.release() );
- }
- }
- }
- }
-
- 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());
- nd_aggr->mName.Set("$RelAggregates");
- nd_aggr->mParent = nd.get();
-
- nd_aggr->mTransformation = nd->mTransformation;
-
- nd_aggr->mChildren = new aiNode*[aggr->RelatedObjects.size()]();
- for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
- if(const IfcProduct* const prod = def.ToPtr<IfcProduct>()) {
-
- aiNode* const ndnew = ProcessSpatialStructure(nd_aggr.get(),*prod,conv,NULL);
- if(ndnew) {
- nd_aggr->mChildren[nd_aggr->mNumChildren++] = ndnew;
- }
- }
- }
-
- subnodes.push_back( nd_aggr.release() );
- }
- }
-
- conv.collect_openings = collect_openings;
- if(!conv.collect_openings) {
- conv.apply_openings = &openings;
- }
-
- if (!skipGeometry) {
- ProcessProductRepresentation(el,nd.get(),subnodes,conv);
- conv.apply_openings = conv.collect_openings = NULL;
- }
-
- if (subnodes.size()) {
- nd->mChildren = new aiNode*[subnodes.size()]();
- for(aiNode* nd2 : subnodes) {
- nd->mChildren[nd->mNumChildren++] = nd2;
- nd2->mParent = nd.get();
- }
- }
- }
- catch(...) {
- // it hurts, but I don't want to pull boost::ptr_vector into -noboost only for these few spots here
- std::for_each(subnodes.begin(),subnodes.end(),delete_fun<aiNode>());
- 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();
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessSpatialStructures(ConversionData& conv)
-{
- // XXX add support for multiple sites (i.e. IfcSpatialStructureElements with composition == COMPLEX)
-
-
- // process all products in the file. it is reasonable to assume that a
- // file that is relevant for us contains at least a site or a building.
- const STEP::DB::ObjectMapByType& map = conv.db.GetObjectsByType();
-
- ai_assert(map.find("ifcsite") != map.end());
- const STEP::DB::ObjectSet* range = &map.find("ifcsite")->second;
-
- if (range->empty()) {
- ai_assert(map.find("ifcbuilding") != map.end());
- range = &map.find("ifcbuilding")->second;
- if (range->empty()) {
- // no site, no building - fail;
- IFCImporter::ThrowException("no root element found (expected IfcBuilding or preferably IfcSite)");
- }
- }
-
- std::vector<aiNode*> nodes;
-
- for(const STEP::LazyObject* lz : *range) {
- const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
- if(!prod) {
- continue;
- }
- IFCImporter::LogDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType? " which is of type " + prod->ObjectType.Get():""));
-
- // the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
- const STEP::DB::RefMap& refs = conv.db.GetRefs();
- STEP::DB::RefMapRange ref_range = refs.equal_range(conv.proj.GetID());
- for(; ref_range.first != ref_range.second; ++ref_range.first) {
- if(const IfcRelAggregates* const aggr = conv.db.GetObject((*ref_range.first).second)->ToPtr<IfcRelAggregates>()) {
-
- for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
- // comparing pointer values is not sufficient, we would need to cast them to the same type first
- // as there is multiple inheritance in the game.
- if (def.GetID() == prod->GetID()) {
- IFCImporter::LogDebug("selecting this spatial structure as root structure");
- // got it, this is one primary site.
- nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
- }
- }
-
- }
- }
- }
-
- size_t nb_nodes = nodes.size();
-
- if (nb_nodes == 0) {
- IFCImporter::LogWarn("failed to determine primary site element, taking all the IfcSite");
- for (const STEP::LazyObject* lz : *range) {
- const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
- if (!prod) {
- continue;
- }
-
- nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
- }
-
- nb_nodes = nodes.size();
- }
-
- if (nb_nodes == 1) {
- conv.out->mRootNode = nodes[0];
- }
- else if (nb_nodes > 1) {
- conv.out->mRootNode = new aiNode("Root");
- conv.out->mRootNode->mParent = NULL;
- conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
- conv.out->mRootNode->mChildren = new aiNode*[conv.out->mRootNode->mNumChildren];
-
- for (size_t i = 0; i < nb_nodes; ++i) {
- aiNode* node = nodes[i];
-
- node->mParent = conv.out->mRootNode;
-
- conv.out->mRootNode->mChildren[i] = node;
- }
- }
- else {
- IFCImporter::ThrowException("failed to determine primary site element");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void MakeTreeRelative(aiNode* start, const aiMatrix4x4& combined)
-{
- // combined is the parent's absolute transformation matrix
- const aiMatrix4x4 old = start->mTransformation;
-
- if (!combined.IsIdentity()) {
- start->mTransformation = aiMatrix4x4(combined).Inverse() * start->mTransformation;
- }
-
- // All nodes store absolute transformations right now, so we need to make them relative
- for (unsigned int i = 0; i < start->mNumChildren; ++i) {
- MakeTreeRelative(start->mChildren[i],old);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void MakeTreeRelative(ConversionData& conv)
-{
- MakeTreeRelative(conv.out->mRootNode,IfcMatrix4());
-}
-
-} // !anon
-
-
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCLoader.h b/src/3rdparty/assimp/code/IFCLoader.h
deleted file mode 100644
index 4cf116f8e..000000000
--- a/src/3rdparty/assimp/code/IFCLoader.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFC.h
- * @brief Declaration of the Industry Foundation Classes (IFC) loader main class
- */
-#ifndef INCLUDED_AI_IFC_LOADER_H
-#define INCLUDED_AI_IFC_LOADER_H
-
-#include "BaseImporter.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;
- }
-
- namespace STEP {
- class DB;
- }
-
-
-// -------------------------------------------------------------------------------------------
-/** Load the IFC format, which is an open specification to describe building and construction
- industry data.
-
- See http://en.wikipedia.org/wiki/Industry_Foundation_Classes
-*/
-// -------------------------------------------------------------------------------------------
-class IFCImporter : public BaseImporter, public LogFunctions<IFCImporter>
-{
-public:
- IFCImporter();
- ~IFCImporter();
-
-
-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:
-
-
-public:
-
-
- // loader settings, publicly accessible via their corresponding AI_CONFIG constants
- struct Settings
- {
- Settings()
- : skipSpaceRepresentations()
- , useCustomTriangulation()
- , skipAnnotations()
- , conicSamplingAngle(10.f)
- , cylindricalTessellation(32)
- {}
-
-
- bool skipSpaceRepresentations;
- bool useCustomTriangulation;
- bool skipAnnotations;
- float conicSamplingAngle;
- int cylindricalTessellation;
- };
-
-
-private:
-
- Settings settings;
-
-}; // !class IFCImporter
-
-} // end of namespace Assimp
-#endif // !INCLUDED_AI_IFC_LOADER_H
diff --git a/src/3rdparty/assimp/code/IFCMaterial.cpp b/src/3rdparty/assimp/code/IFCMaterial.cpp
deleted file mode 100644
index aa11c5c22..000000000
--- a/src/3rdparty/assimp/code/IFCMaterial.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFCMaterial.cpp
- * @brief Implementation of conversion routines to convert IFC materials to aiMaterial
- */
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-
-#include "IFCUtil.h"
-#include <limits>
-#include <assimp/material.h>
-
-namespace Assimp {
-namespace IFC {
-
-// ------------------------------------------------------------------------------------------------
-static int ConvertShadingMode(const std::string& name) {
- if (name == "BLINN") {
- return aiShadingMode_Blinn;
- }
- else if (name == "FLAT" || name == "NOTDEFINED") {
- return aiShadingMode_NoShading;
- }
- else if (name == "PHONG") {
- return aiShadingMode_Phong;
- }
- IFCImporter::LogWarn("shading mode "+name+" not recognized by Assimp, using Phong instead");
- return aiShadingMode_Phong;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void FillMaterial(aiMaterial* mat,const IFC::IfcSurfaceStyle* surf,ConversionData& conv) {
- aiString name;
- name.Set((surf->Name? surf->Name.Get() : "IfcSurfaceStyle_Unnamed"));
- mat->AddProperty(&name,AI_MATKEY_NAME);
-
- // now see which kinds of surface information are present
- for(std::shared_ptr< const IFC::IfcSurfaceStyleElementSelect > sel2 : surf->Styles) {
- if (const IFC::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleShading>(conv.db)) {
- aiColor4D col_base,col;
-
- ConvertColor(col_base, shade->SurfaceColour);
- mat->AddProperty(&col_base,1, AI_MATKEY_COLOR_DIFFUSE);
-
- if (const IFC::IfcSurfaceStyleRendering* ren = shade->ToPtr<IFC::IfcSurfaceStyleRendering>()) {
-
- if (ren->Transparency) {
- const float t = 1.f-static_cast<float>(ren->Transparency.Get());
- mat->AddProperty(&t,1, AI_MATKEY_OPACITY);
- }
-
- if (ren->DiffuseColour) {
- ConvertColor(col, *ren->DiffuseColour.Get(),conv,&col_base);
- mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
- }
-
- if (ren->SpecularColour) {
- ConvertColor(col, *ren->SpecularColour.Get(),conv,&col_base);
- mat->AddProperty(&col,1, AI_MATKEY_COLOR_SPECULAR);
- }
-
- if (ren->TransmissionColour) {
- ConvertColor(col, *ren->TransmissionColour.Get(),conv,&col_base);
- mat->AddProperty(&col,1, AI_MATKEY_COLOR_TRANSPARENT);
- }
-
- if (ren->ReflectionColour) {
- ConvertColor(col, *ren->ReflectionColour.Get(),conv,&col_base);
- mat->AddProperty(&col,1, AI_MATKEY_COLOR_REFLECTIVE);
- }
-
- const int shading = (ren->SpecularHighlight && ren->SpecularColour)?ConvertShadingMode(ren->ReflectanceMethod):static_cast<int>(aiShadingMode_Gouraud);
- mat->AddProperty(&shading,1, AI_MATKEY_SHADING_MODEL);
-
- if (ren->SpecularHighlight) {
- if(const EXPRESS::REAL* rt = ren->SpecularHighlight.Get()->ToPtr<EXPRESS::REAL>()) {
- // at this point we don't distinguish between the two distinct ways of
- // specifying highlight intensities. leave this to the user.
- const float e = static_cast<float>(*rt);
- mat->AddProperty(&e,1,AI_MATKEY_SHININESS);
- }
- else {
- IFCImporter::LogWarn("unexpected type error, SpecularHighlight should be a REAL");
- }
- }
- }
- } /*
- else if (const IFC::IfcSurfaceStyleWithTextures* tex = sel2->ResolveSelectPtr<IFC::IfcSurfaceStyleWithTextures>(conv.db)) {
- // XXX
- } */
- }
-
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat) {
- STEP::DB::RefMapRange range = conv.db.GetRefs().equal_range(id);
- for(;range.first != range.second; ++range.first) {
- if(const IFC::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::IfcStyledItem>()) {
- for(const IFC::IfcPresentationStyleAssignment& as : styled->Styles) {
- for(std::shared_ptr<const IFC::IfcPresentationStyleSelect> sel : as.Styles) {
-
- if( const IFC::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::IfcSurfaceStyle>(conv.db) ) {
- // try to satisfy from cache
- ConversionData::MaterialCache::iterator mit = conv.cached_materials.find(surf);
- if( mit != conv.cached_materials.end() )
- return mit->second;
-
- // not found, create new material
- const std::string side = static_cast<std::string>(surf->Side);
- if( side != "BOTH" ) {
- IFCImporter::LogWarn("ignoring surface side marker on IFC::IfcSurfaceStyle: " + side);
- }
-
- std::unique_ptr<aiMaterial> mat(new aiMaterial());
-
- FillMaterial(mat.get(), surf, conv);
-
- conv.materials.push_back(mat.release());
- unsigned int matindex = static_cast<unsigned int>(conv.materials.size() - 1);
- conv.cached_materials[surf] = matindex;
- return matindex;
- }
- }
- }
- }
- }
-
- // no local material defined. If there's global one, use that instead
- if ( prevMatId != std::numeric_limits<uint32_t>::max() ) {
- return prevMatId;
- }
-
- // we're still here - create an default material if required, or simply fail otherwise
- if ( !forceDefaultMat ) {
- return std::numeric_limits<uint32_t>::max();
- }
-
- aiString name;
- name.Set("<IFCDefault>");
- // ConvertColorToString( color, name);
-
- // look if there's already a default material with this base color
- for( size_t a = 0; a < conv.materials.size(); ++a ) {
- aiString mname;
- conv.materials[a]->Get(AI_MATKEY_NAME, mname);
- if ( name == mname ) {
- return ( unsigned int )a;
- }
- }
-
- // we're here, yet - no default material with suitable color available. Generate one
- std::unique_ptr<aiMaterial> mat(new aiMaterial());
- mat->AddProperty(&name,AI_MATKEY_NAME);
-
- const aiColor4D col = aiColor4D( 0.6f, 0.6f, 0.6f, 1.0f); // aiColor4D( color.r, color.g, color.b, 1.0f);
- mat->AddProperty(&col,1, AI_MATKEY_COLOR_DIFFUSE);
-
- conv.materials.push_back(mat.release());
- return (unsigned int) conv.materials.size() - 1;
-}
-
-} // ! IFC
-} // ! Assimp
-
-#endif // ASSIMP_BUILD_NO_IFC_IMPORTER
diff --git a/src/3rdparty/assimp/code/IFCOpenings.cpp b/src/3rdparty/assimp/code/IFCOpenings.cpp
deleted file mode 100644
index 4d57cd473..000000000
--- a/src/3rdparty/assimp/code/IFCOpenings.cpp
+++ /dev/null
@@ -1,1699 +0,0 @@
-/*
-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.
- */
-
-
-#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
- for(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();
- for(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);
-
- for(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 (std::fabs(v.x-bb.first.x)<epsilon) {
- edge.x = bb.first.x;
- hit = true;
- }
- else if (std::fabs(v.x-bb.second.x)<epsilon) {
- edge.x = bb.second.x;
- hit = true;
- }
-
- if (std::fabs(v.y-bb.first.y)<epsilon) {
- edge.y = bb.first.y;
- hit = true;
- }
- else if (std::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 (std::fabs(contour[last_hit].x-bb.first.x)<epsilon) {
- corner.x = bb.first.x;
- }
- else if (std::fabs(contour[last_hit].x-bb.second.x)<epsilon) {
- corner.x = bb.second.x;
- }
-
- if (std::fabs(contour[last_hit].y-bb.first.y)<epsilon) {
- corner.y = bb.first.y;
- }
- else if (std::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(static_cast<unsigned int>(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;
-
- for(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();
-
- for(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;
-
- for(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();
-
- for(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;
-
- for(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 {
- for(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());
- for(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;
- for(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);
-
- for(const ClipperLib::ExPolygon& ex : clipped) {
- iold.push_back(static_cast<unsigned int>(ex.outer.size()));
- for(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 (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
- (std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
- (std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
- (std::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 || std::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 || std::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(std::fabs(n0_to_n1.x) > std::fabs(n0_to_n1.y)) {
- s0 = n0_to_m0.x / n0_to_n1.x;
- s1 = n0_to_m1.x / n0_to_n1.x;
-
- if (std::fabs(s0) == inf && std::fabs(n0_to_m0.x) < smalle) {
- s0 = 0.;
- }
- if (std::fabs(s1) == inf && std::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 (std::fabs(s0) == inf && std::fabs(n0_to_m0.y) < smalle) {
- s0 = 0.;
- }
- if (std::fabs(s1) == inf && std::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 (std::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 std::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 = std::fabs(vdelta.x);
- vdelta.y = std::fabs(vdelta.y);
- return (std::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;
- for(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());
-
- bool reverseCountourFaces = false;
-
- // compare base poly normal and contour normal to detect if we need to reverse the face winding
- if(curmesh.vertcnt.size() > 0) {
- IfcVector3 basePolyNormal = TempMesh::ComputePolygonNormal(curmesh.verts.data(), curmesh.vertcnt.front());
-
- std::vector<IfcVector3> worldSpaceContourVtx(it->contour.size());
-
- for(size_t a = 0; a < it->contour.size(); ++a)
- worldSpaceContourVtx[a] = minv * IfcVector3(it->contour[a].x, it->contour[a].y, 0.0);
-
- IfcVector3 contourNormal = TempMesh::ComputePolygonNormal(worldSpaceContourVtx.data(), worldSpaceContourVtx.size());
-
- reverseCountourFaces = (contourNormal * basePolyNormal) > 0.0;
- }
-
- // 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;
-
- 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;
-
- const IfcVector3 world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f);
-
- for(const TempOpening* opening : refs) {
- for(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) != reverseCountourFaces) ? world_point : bestv);
- curmesh.verts.push_back(((cit == cbegin) != reverseCountourFaces) ? bestv : world_point);
-
- curmesh.vertcnt.push_back(4);
- ++closed;
- }
-
- if (cit == cbegin) {
- start0 = world_point;
- start1 = bestv;
- continue;
- }
-
- curmesh.verts.push_back(reverseCountourFaces ? bestv : world_point);
- curmesh.verts.push_back(reverseCountourFaces ? world_point : 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(reverseCountourFaces ? start0 : start1);
- curmesh.verts.push_back(reverseCountourFaces ? start1 : start0);
- }
- }
- }
- }
- else {
-
- const Contour::const_iterator cbegin = (*it).contour.begin(), cend = (*it).contour.end();
- for(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());
- for(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());
-
- for(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(std::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
- for(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(std::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;
- for(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;
- for(const IfcVector3& x : in_verts) {
- const IfcVector3& vv = m * x;
-
- out_contour2.push_back(IfcVector2(vv.x,vv.y));
- ai_assert(std::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();
-
- for(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(std::fabs(norm_extrusion_dir * wall_extrusion_axis_norm) < 0.1) {
- // horizontal extrusion
- if (std::fabs(norm_extrusion_dir * nor) > 0.9) {
- profile_data = opening.profileMesh2D.get();
- is_2d_source = true;
- }
- }
- else {
- // vertical extrusion
- if (std::fabs(norm_extrusion_dir * nor) > 0.9) {
- profile_data = opening.profileMesh2D.get();
- is_2d_source = true;
- }
- }
- }
- 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 = std::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 || std::fabs(area2.x * area2.y) > std::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 = std::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(std::fabs(vpmax.x - vpmin.x) * std::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
- for(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
- for(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(std::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.
- ai_assert(vmax.Length());
-
- ClipperLib::ExPolygons clipped;
- ClipperLib::Polygons holes_union;
-
-
- IfcVector3 wall_extrusion;
- bool first = true;
-
- try {
-
- ClipperLib::Clipper clipper_holes;
- size_t c = 0;
-
- for(const TempOpening& t :openings) {
- const IfcVector3& outernor = nors[c++];
- const IfcFloat dot = nor * outernor;
- if (std::fabs(dot)<1.f-1e-6f) {
- continue;
- }
-
- const std::vector<IfcVector3>& va = t.profileMesh->verts;
- if(va.size() <= 2) {
- continue;
- }
-
- std::vector<IfcVector2> contour;
-
- for(const IfcVector3& xx : t.profileMesh->verts) {
- IfcVector3 vv = m * xx, vv_extr = m * (xx + t.extrusionDir);
-
- const bool is_extruded_side = std::fabs(vv.z - coord) > std::fabs(vv_extr.z - coord);
- if (first) {
- first = false;
- if (dot > 0.f) {
- 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;
- for(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;
- for(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);
-
- std::vector< std::vector<p2t::Point*> > contours;
- for(ClipperLib::ExPolygon& clip : clipped) {
-
- contours.clear();
-
- // Build the outer polygon contour line for feeding into poly2tri
- std::vector<p2t::Point*> contour_points;
- for(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
- for(ClipperLib::Polygon& opening : clip.holes) {
-
- contours.push_back(std::vector<p2t::Point*>());
- std::vector<p2t::Point*>& contour = contours.back();
-
- for(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
- for(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 )
- );
-
- ai_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
diff --git a/src/3rdparty/assimp/code/IFCProfile.cpp b/src/3rdparty/assimp/code/IFCProfile.cpp
deleted file mode 100644
index 595159a6b..000000000
--- a/src/3rdparty/assimp/code/IFCProfile.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFCProfile.cpp
- * @brief Read profile and curves entities from IFC files
- */
-
-
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-#include "IFCUtil.h"
-
-namespace Assimp {
- namespace IFC {
-
-// ------------------------------------------------------------------------------------------------
-void ProcessPolyLine(const IfcPolyline& def, TempMesh& meshout, ConversionData& /*conv*/)
-{
- // this won't produce a valid mesh, it just spits out a list of vertices
- IfcVector3 t;
- for(const IfcCartesianPoint& cp : def.Points) {
- ConvertCartesianPoint(t,cp);
- meshout.verts.push_back(t);
- }
- meshout.vertcnt.push_back(static_cast<unsigned int>(meshout.verts.size()));
-}
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv)
-{
- std::unique_ptr<const Curve> cv(Curve::Convert(curve,conv));
- if (!cv) {
- IFCImporter::LogWarn("skipping unknown IfcCurve entity, type is " + curve.GetClassName());
- return false;
- }
-
- // we must have a bounded curve at this point
- if (const BoundedCurve* bc = dynamic_cast<const BoundedCurve*>(cv.get())) {
- try {
- bc->SampleDiscrete(meshout);
- }
- catch(const CurveError& cv) {
- IFCImporter::LogError(cv.s+ " (error occurred while processing curve)");
- return false;
- }
- meshout.vertcnt.push_back(static_cast<unsigned int>(meshout.verts.size()));
- return true;
- }
-
- IFCImporter::LogError("cannot use unbounded curve as profile");
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessClosedProfile(const IfcArbitraryClosedProfileDef& def, TempMesh& meshout, ConversionData& conv)
-{
- ProcessCurve(def.OuterCurve,meshout,conv);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ProcessOpenProfile(const IfcArbitraryOpenProfileDef& def, TempMesh& meshout, ConversionData& conv)
-{
- ProcessCurve(def.Curve,meshout,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;
-
- meshout.verts.reserve(meshout.verts.size()+4);
- meshout.verts.push_back( IfcVector3( x, y, 0.f ));
- meshout.verts.push_back( IfcVector3(-x, y, 0.f ));
- meshout.verts.push_back( IfcVector3(-x,-y, 0.f ));
- meshout.verts.push_back( IfcVector3( x,-y, 0.f ));
- meshout.vertcnt.push_back(4);
- }
- else if( const IfcCircleProfileDef* const circle = def.ToPtr<IfcCircleProfileDef>()) {
- if(def.ToPtr<IfcCircleHollowProfileDef>()) {
- // TODO
- }
- const size_t segments = conv.settings.cylindricalTessellation;
- const IfcFloat delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius;
-
- meshout.verts.reserve(segments);
-
- IfcFloat angle = 0.f;
- for(size_t i = 0; i < segments; ++i, angle += delta) {
- meshout.verts.push_back( IfcVector3( std::cos(angle)*radius, std::sin(angle)*radius, 0.f ));
- }
-
- meshout.vertcnt.push_back(static_cast<unsigned int>(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;
- }
-
- IfcMatrix4 trafo;
- ConvertAxisPlacement(trafo, *def.Position);
- meshout.Transform(trafo);
-}
-
-// ------------------------------------------------------------------------------------------------
-bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv)
-{
- if(const IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr<IfcArbitraryClosedProfileDef>()) {
- ProcessClosedProfile(*cprofile,meshout,conv);
- }
- else if(const IfcArbitraryOpenProfileDef* const copen = prof.ToPtr<IfcArbitraryOpenProfileDef>()) {
- ProcessOpenProfile(*copen,meshout,conv);
- }
- else if(const IfcParameterizedProfileDef* const cparam = prof.ToPtr<IfcParameterizedProfileDef>()) {
- ProcessParametrizedProfile(*cparam,meshout,conv);
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName());
- return false;
- }
- meshout.RemoveAdjacentDuplicates();
- if (!meshout.vertcnt.size() || meshout.vertcnt.front() <= 1) {
- return false;
- }
- return true;
-}
-
-} // ! IFC
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCReaderGen.h b/src/3rdparty/assimp/code/IFCReaderGen.h
deleted file mode 100644
index 85c62faac..000000000
--- a/src/3rdparty/assimp/code/IFCReaderGen.h
+++ /dev/null
@@ -1,4368 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development 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 Development 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.
-
-----------------------------------------------------------------------
-*/
-
-/** MACHINE-GENERATED by scripts/ICFImporter/CppGenerator.py */
-
-#ifndef INCLUDED_IFC_READER_GEN_H
-#define INCLUDED_IFC_READER_GEN_H
-
-#include "STEPFile.h"
-
-namespace Assimp {
-namespace IFC {
- using namespace STEP;
- using namespace STEP::EXPRESS;
-
-
- struct NotImplemented : public ObjectHelper<NotImplemented,0> {
-
- };
-
-
- // ******************************************************************************
- // IFC Custom data types
- // ******************************************************************************
-
-
- // C++ wrapper type for IfcAbsorbedDoseMeasure
- typedef REAL IfcAbsorbedDoseMeasure;
- // C++ wrapper type for IfcAccelerationMeasure
- typedef REAL IfcAccelerationMeasure;
- // C++ wrapper type for IfcAmountOfSubstanceMeasure
- typedef REAL IfcAmountOfSubstanceMeasure;
- // C++ wrapper type for IfcAngularVelocityMeasure
- typedef REAL IfcAngularVelocityMeasure;
- // C++ wrapper type for IfcAreaMeasure
- typedef REAL IfcAreaMeasure;
- // C++ wrapper type for IfcBoolean
- typedef BOOLEAN IfcBoolean;
- // C++ wrapper type for IfcBoxAlignment
- typedef STRING IfcBoxAlignment;
- // C++ wrapper type for IfcCompoundPlaneAngleMeasure
- typedef ListOf< INTEGER, 3, 3 > IfcCompoundPlaneAngleMeasure;
- // C++ wrapper type for IfcContextDependentMeasure
- typedef REAL IfcContextDependentMeasure;
- // C++ wrapper type for IfcCountMeasure
- typedef NUMBER IfcCountMeasure;
- // C++ wrapper type for IfcCurvatureMeasure
- typedef REAL IfcCurvatureMeasure;
- // C++ wrapper type for IfcDayInMonthNumber
- typedef INTEGER IfcDayInMonthNumber;
- // C++ wrapper type for IfcDaylightSavingHour
- typedef INTEGER IfcDaylightSavingHour;
- // C++ wrapper type for IfcDescriptiveMeasure
- typedef STRING IfcDescriptiveMeasure;
- // C++ wrapper type for IfcDimensionCount
- typedef INTEGER IfcDimensionCount;
- // C++ wrapper type for IfcDoseEquivalentMeasure
- typedef REAL IfcDoseEquivalentMeasure;
- // C++ wrapper type for IfcDynamicViscosityMeasure
- typedef REAL IfcDynamicViscosityMeasure;
- // C++ wrapper type for IfcElectricCapacitanceMeasure
- typedef REAL IfcElectricCapacitanceMeasure;
- // C++ wrapper type for IfcElectricChargeMeasure
- typedef REAL IfcElectricChargeMeasure;
- // C++ wrapper type for IfcElectricConductanceMeasure
- typedef REAL IfcElectricConductanceMeasure;
- // C++ wrapper type for IfcElectricCurrentMeasure
- typedef REAL IfcElectricCurrentMeasure;
- // C++ wrapper type for IfcElectricResistanceMeasure
- typedef REAL IfcElectricResistanceMeasure;
- // C++ wrapper type for IfcElectricVoltageMeasure
- typedef REAL IfcElectricVoltageMeasure;
- // C++ wrapper type for IfcEnergyMeasure
- typedef REAL IfcEnergyMeasure;
- // C++ wrapper type for IfcFontStyle
- typedef STRING IfcFontStyle;
- // C++ wrapper type for IfcFontVariant
- typedef STRING IfcFontVariant;
- // C++ wrapper type for IfcFontWeight
- typedef STRING IfcFontWeight;
- // C++ wrapper type for IfcForceMeasure
- typedef REAL IfcForceMeasure;
- // C++ wrapper type for IfcFrequencyMeasure
- typedef REAL IfcFrequencyMeasure;
- // C++ wrapper type for IfcGloballyUniqueId
- typedef STRING IfcGloballyUniqueId;
- // C++ wrapper type for IfcHeatFluxDensityMeasure
- typedef REAL IfcHeatFluxDensityMeasure;
- // C++ wrapper type for IfcHeatingValueMeasure
- typedef REAL IfcHeatingValueMeasure;
- // C++ wrapper type for IfcHourInDay
- typedef INTEGER IfcHourInDay;
- // C++ wrapper type for IfcIdentifier
- typedef STRING IfcIdentifier;
- // C++ wrapper type for IfcIlluminanceMeasure
- typedef REAL IfcIlluminanceMeasure;
- // C++ wrapper type for IfcInductanceMeasure
- typedef REAL IfcInductanceMeasure;
- // C++ wrapper type for IfcInteger
- typedef INTEGER IfcInteger;
- // C++ wrapper type for IfcIntegerCountRateMeasure
- typedef INTEGER IfcIntegerCountRateMeasure;
- // C++ wrapper type for IfcIonConcentrationMeasure
- typedef REAL IfcIonConcentrationMeasure;
- // C++ wrapper type for IfcIsothermalMoistureCapacityMeasure
- typedef REAL IfcIsothermalMoistureCapacityMeasure;
- // C++ wrapper type for IfcKinematicViscosityMeasure
- typedef REAL IfcKinematicViscosityMeasure;
- // C++ wrapper type for IfcLabel
- typedef STRING IfcLabel;
- // C++ wrapper type for IfcLengthMeasure
- typedef REAL IfcLengthMeasure;
- // C++ wrapper type for IfcLinearForceMeasure
- typedef REAL IfcLinearForceMeasure;
- // C++ wrapper type for IfcLinearMomentMeasure
- typedef REAL IfcLinearMomentMeasure;
- // C++ wrapper type for IfcLinearStiffnessMeasure
- typedef REAL IfcLinearStiffnessMeasure;
- // C++ wrapper type for IfcLinearVelocityMeasure
- typedef REAL IfcLinearVelocityMeasure;
- // C++ wrapper type for IfcLogical
- typedef LOGICAL IfcLogical;
- // C++ wrapper type for IfcLuminousFluxMeasure
- typedef REAL IfcLuminousFluxMeasure;
- // C++ wrapper type for IfcLuminousIntensityDistributionMeasure
- typedef REAL IfcLuminousIntensityDistributionMeasure;
- // C++ wrapper type for IfcLuminousIntensityMeasure
- typedef REAL IfcLuminousIntensityMeasure;
- // C++ wrapper type for IfcMagneticFluxDensityMeasure
- typedef REAL IfcMagneticFluxDensityMeasure;
- // C++ wrapper type for IfcMagneticFluxMeasure
- typedef REAL IfcMagneticFluxMeasure;
- // C++ wrapper type for IfcMassDensityMeasure
- typedef REAL IfcMassDensityMeasure;
- // C++ wrapper type for IfcMassFlowRateMeasure
- typedef REAL IfcMassFlowRateMeasure;
- // C++ wrapper type for IfcMassMeasure
- typedef REAL IfcMassMeasure;
- // C++ wrapper type for IfcMassPerLengthMeasure
- typedef REAL IfcMassPerLengthMeasure;
- // C++ wrapper type for IfcMinuteInHour
- typedef INTEGER IfcMinuteInHour;
- // C++ wrapper type for IfcModulusOfElasticityMeasure
- typedef REAL IfcModulusOfElasticityMeasure;
- // C++ wrapper type for IfcModulusOfLinearSubgradeReactionMeasure
- typedef REAL IfcModulusOfLinearSubgradeReactionMeasure;
- // C++ wrapper type for IfcModulusOfRotationalSubgradeReactionMeasure
- typedef REAL IfcModulusOfRotationalSubgradeReactionMeasure;
- // C++ wrapper type for IfcModulusOfSubgradeReactionMeasure
- typedef REAL IfcModulusOfSubgradeReactionMeasure;
- // C++ wrapper type for IfcMoistureDiffusivityMeasure
- typedef REAL IfcMoistureDiffusivityMeasure;
- // C++ wrapper type for IfcMolecularWeightMeasure
- typedef REAL IfcMolecularWeightMeasure;
- // C++ wrapper type for IfcMomentOfInertiaMeasure
- typedef REAL IfcMomentOfInertiaMeasure;
- // C++ wrapper type for IfcMonetaryMeasure
- typedef REAL IfcMonetaryMeasure;
- // C++ wrapper type for IfcMonthInYearNumber
- typedef INTEGER IfcMonthInYearNumber;
- // C++ wrapper type for IfcNormalisedRatioMeasure
- typedef REAL IfcNormalisedRatioMeasure;
- // C++ wrapper type for IfcNumericMeasure
- typedef NUMBER IfcNumericMeasure;
- // C++ wrapper type for IfcPHMeasure
- typedef REAL IfcPHMeasure;
- // C++ wrapper type for IfcParameterValue
- typedef REAL IfcParameterValue;
- // C++ wrapper type for IfcPlanarForceMeasure
- typedef REAL IfcPlanarForceMeasure;
- // C++ wrapper type for IfcPlaneAngleMeasure
- typedef REAL IfcPlaneAngleMeasure;
- // C++ wrapper type for IfcPositiveLengthMeasure
- typedef REAL IfcPositiveLengthMeasure;
- // C++ wrapper type for IfcPositivePlaneAngleMeasure
- typedef REAL IfcPositivePlaneAngleMeasure;
- // C++ wrapper type for IfcPositiveRatioMeasure
- typedef REAL IfcPositiveRatioMeasure;
- // C++ wrapper type for IfcPowerMeasure
- typedef REAL IfcPowerMeasure;
- // C++ wrapper type for IfcPresentableText
- typedef STRING IfcPresentableText;
- // C++ wrapper type for IfcPressureMeasure
- typedef REAL IfcPressureMeasure;
- // C++ wrapper type for IfcRadioActivityMeasure
- typedef REAL IfcRadioActivityMeasure;
- // C++ wrapper type for IfcRatioMeasure
- typedef REAL IfcRatioMeasure;
- // C++ wrapper type for IfcReal
- typedef REAL IfcReal;
- // C++ wrapper type for IfcRotationalFrequencyMeasure
- typedef REAL IfcRotationalFrequencyMeasure;
- // C++ wrapper type for IfcRotationalMassMeasure
- typedef REAL IfcRotationalMassMeasure;
- // C++ wrapper type for IfcRotationalStiffnessMeasure
- typedef REAL IfcRotationalStiffnessMeasure;
- // C++ wrapper type for IfcSecondInMinute
- typedef REAL IfcSecondInMinute;
- // C++ wrapper type for IfcSectionModulusMeasure
- typedef REAL IfcSectionModulusMeasure;
- // C++ wrapper type for IfcSectionalAreaIntegralMeasure
- typedef REAL IfcSectionalAreaIntegralMeasure;
- // C++ wrapper type for IfcShearModulusMeasure
- typedef REAL IfcShearModulusMeasure;
- // C++ wrapper type for IfcSolidAngleMeasure
- typedef REAL IfcSolidAngleMeasure;
- // C++ wrapper type for IfcSoundPowerMeasure
- typedef REAL IfcSoundPowerMeasure;
- // C++ wrapper type for IfcSoundPressureMeasure
- typedef REAL IfcSoundPressureMeasure;
- // C++ wrapper type for IfcSpecificHeatCapacityMeasure
- typedef REAL IfcSpecificHeatCapacityMeasure;
- // C++ wrapper type for IfcSpecularExponent
- typedef REAL IfcSpecularExponent;
- // C++ wrapper type for IfcSpecularRoughness
- typedef REAL IfcSpecularRoughness;
- // C++ wrapper type for IfcTemperatureGradientMeasure
- typedef REAL IfcTemperatureGradientMeasure;
- // C++ wrapper type for IfcText
- typedef STRING IfcText;
- // C++ wrapper type for IfcTextAlignment
- typedef STRING IfcTextAlignment;
- // C++ wrapper type for IfcTextDecoration
- typedef STRING IfcTextDecoration;
- // C++ wrapper type for IfcTextFontName
- typedef STRING IfcTextFontName;
- // C++ wrapper type for IfcTextTransformation
- typedef STRING IfcTextTransformation;
- // C++ wrapper type for IfcThermalAdmittanceMeasure
- typedef REAL IfcThermalAdmittanceMeasure;
- // C++ wrapper type for IfcThermalConductivityMeasure
- typedef REAL IfcThermalConductivityMeasure;
- // C++ wrapper type for IfcThermalExpansionCoefficientMeasure
- typedef REAL IfcThermalExpansionCoefficientMeasure;
- // C++ wrapper type for IfcThermalResistanceMeasure
- typedef REAL IfcThermalResistanceMeasure;
- // C++ wrapper type for IfcThermalTransmittanceMeasure
- typedef REAL IfcThermalTransmittanceMeasure;
- // C++ wrapper type for IfcThermodynamicTemperatureMeasure
- typedef REAL IfcThermodynamicTemperatureMeasure;
- // C++ wrapper type for IfcTimeMeasure
- typedef REAL IfcTimeMeasure;
- // C++ wrapper type for IfcTimeStamp
- typedef INTEGER IfcTimeStamp;
- // C++ wrapper type for IfcTorqueMeasure
- typedef REAL IfcTorqueMeasure;
- // C++ wrapper type for IfcVaporPermeabilityMeasure
- typedef REAL IfcVaporPermeabilityMeasure;
- // C++ wrapper type for IfcVolumeMeasure
- typedef REAL IfcVolumeMeasure;
- // C++ wrapper type for IfcVolumetricFlowRateMeasure
- typedef REAL IfcVolumetricFlowRateMeasure;
- // C++ wrapper type for IfcWarpingConstantMeasure
- typedef REAL IfcWarpingConstantMeasure;
- // C++ wrapper type for IfcWarpingMomentMeasure
- typedef REAL IfcWarpingMomentMeasure;
- // C++ wrapper type for IfcYearNumber
- typedef INTEGER IfcYearNumber;
- // C++ wrapper type for IfcActionSourceTypeEnum
- typedef ENUMERATION IfcActionSourceTypeEnum;
- // C++ wrapper type for IfcActionTypeEnum
- typedef ENUMERATION IfcActionTypeEnum;
- // C++ wrapper type for IfcActuatorTypeEnum
- typedef ENUMERATION IfcActuatorTypeEnum;
- // C++ wrapper type for IfcAddressTypeEnum
- typedef ENUMERATION IfcAddressTypeEnum;
- // C++ wrapper type for IfcAheadOrBehind
- typedef ENUMERATION IfcAheadOrBehind;
- // C++ wrapper type for IfcAirTerminalBoxTypeEnum
- typedef ENUMERATION IfcAirTerminalBoxTypeEnum;
- // C++ wrapper type for IfcAirTerminalTypeEnum
- typedef ENUMERATION IfcAirTerminalTypeEnum;
- // C++ wrapper type for IfcAirToAirHeatRecoveryTypeEnum
- typedef ENUMERATION IfcAirToAirHeatRecoveryTypeEnum;
- // C++ wrapper type for IfcAlarmTypeEnum
- typedef ENUMERATION IfcAlarmTypeEnum;
- // C++ wrapper type for IfcAnalysisModelTypeEnum
- typedef ENUMERATION IfcAnalysisModelTypeEnum;
- // C++ wrapper type for IfcAnalysisTheoryTypeEnum
- typedef ENUMERATION IfcAnalysisTheoryTypeEnum;
- // C++ wrapper type for IfcArithmeticOperatorEnum
- typedef ENUMERATION IfcArithmeticOperatorEnum;
- // C++ wrapper type for IfcAssemblyPlaceEnum
- typedef ENUMERATION IfcAssemblyPlaceEnum;
- // C++ wrapper type for IfcBSplineCurveForm
- typedef ENUMERATION IfcBSplineCurveForm;
- // C++ wrapper type for IfcBeamTypeEnum
- typedef ENUMERATION IfcBeamTypeEnum;
- // C++ wrapper type for IfcBenchmarkEnum
- typedef ENUMERATION IfcBenchmarkEnum;
- // C++ wrapper type for IfcBoilerTypeEnum
- typedef ENUMERATION IfcBoilerTypeEnum;
- // C++ wrapper type for IfcBooleanOperator
- typedef ENUMERATION IfcBooleanOperator;
- // C++ wrapper type for IfcBuildingElementProxyTypeEnum
- typedef ENUMERATION IfcBuildingElementProxyTypeEnum;
- // C++ wrapper type for IfcCableCarrierFittingTypeEnum
- typedef ENUMERATION IfcCableCarrierFittingTypeEnum;
- // C++ wrapper type for IfcCableCarrierSegmentTypeEnum
- typedef ENUMERATION IfcCableCarrierSegmentTypeEnum;
- // C++ wrapper type for IfcCableSegmentTypeEnum
- typedef ENUMERATION IfcCableSegmentTypeEnum;
- // C++ wrapper type for IfcChangeActionEnum
- typedef ENUMERATION IfcChangeActionEnum;
- // C++ wrapper type for IfcChillerTypeEnum
- typedef ENUMERATION IfcChillerTypeEnum;
- // C++ wrapper type for IfcCoilTypeEnum
- typedef ENUMERATION IfcCoilTypeEnum;
- // C++ wrapper type for IfcColumnTypeEnum
- typedef ENUMERATION IfcColumnTypeEnum;
- // C++ wrapper type for IfcCompressorTypeEnum
- typedef ENUMERATION IfcCompressorTypeEnum;
- // C++ wrapper type for IfcCondenserTypeEnum
- typedef ENUMERATION IfcCondenserTypeEnum;
- // C++ wrapper type for IfcConnectionTypeEnum
- typedef ENUMERATION IfcConnectionTypeEnum;
- // C++ wrapper type for IfcConstraintEnum
- typedef ENUMERATION IfcConstraintEnum;
- // C++ wrapper type for IfcControllerTypeEnum
- typedef ENUMERATION IfcControllerTypeEnum;
- // C++ wrapper type for IfcCooledBeamTypeEnum
- typedef ENUMERATION IfcCooledBeamTypeEnum;
- // C++ wrapper type for IfcCoolingTowerTypeEnum
- typedef ENUMERATION IfcCoolingTowerTypeEnum;
- // C++ wrapper type for IfcCostScheduleTypeEnum
- typedef ENUMERATION IfcCostScheduleTypeEnum;
- // C++ wrapper type for IfcCoveringTypeEnum
- typedef ENUMERATION IfcCoveringTypeEnum;
- // C++ wrapper type for IfcCurrencyEnum
- typedef ENUMERATION IfcCurrencyEnum;
- // C++ wrapper type for IfcCurtainWallTypeEnum
- typedef ENUMERATION IfcCurtainWallTypeEnum;
- // C++ wrapper type for IfcDamperTypeEnum
- typedef ENUMERATION IfcDamperTypeEnum;
- // C++ wrapper type for IfcDataOriginEnum
- typedef ENUMERATION IfcDataOriginEnum;
- // C++ wrapper type for IfcDerivedUnitEnum
- typedef ENUMERATION IfcDerivedUnitEnum;
- // C++ wrapper type for IfcDimensionExtentUsage
- typedef ENUMERATION IfcDimensionExtentUsage;
- // C++ wrapper type for IfcDirectionSenseEnum
- typedef ENUMERATION IfcDirectionSenseEnum;
- // C++ wrapper type for IfcDistributionChamberElementTypeEnum
- typedef ENUMERATION IfcDistributionChamberElementTypeEnum;
- // C++ wrapper type for IfcDocumentConfidentialityEnum
- typedef ENUMERATION IfcDocumentConfidentialityEnum;
- // C++ wrapper type for IfcDocumentStatusEnum
- typedef ENUMERATION IfcDocumentStatusEnum;
- // C++ wrapper type for IfcDoorPanelOperationEnum
- typedef ENUMERATION IfcDoorPanelOperationEnum;
- // C++ wrapper type for IfcDoorPanelPositionEnum
- typedef ENUMERATION IfcDoorPanelPositionEnum;
- // C++ wrapper type for IfcDoorStyleConstructionEnum
- typedef ENUMERATION IfcDoorStyleConstructionEnum;
- // C++ wrapper type for IfcDoorStyleOperationEnum
- typedef ENUMERATION IfcDoorStyleOperationEnum;
- // C++ wrapper type for IfcDuctFittingTypeEnum
- typedef ENUMERATION IfcDuctFittingTypeEnum;
- // C++ wrapper type for IfcDuctSegmentTypeEnum
- typedef ENUMERATION IfcDuctSegmentTypeEnum;
- // C++ wrapper type for IfcDuctSilencerTypeEnum
- typedef ENUMERATION IfcDuctSilencerTypeEnum;
- // C++ wrapper type for IfcElectricApplianceTypeEnum
- typedef ENUMERATION IfcElectricApplianceTypeEnum;
- // C++ wrapper type for IfcElectricCurrentEnum
- typedef ENUMERATION IfcElectricCurrentEnum;
- // C++ wrapper type for IfcElectricDistributionPointFunctionEnum
- typedef ENUMERATION IfcElectricDistributionPointFunctionEnum;
- // C++ wrapper type for IfcElectricFlowStorageDeviceTypeEnum
- typedef ENUMERATION IfcElectricFlowStorageDeviceTypeEnum;
- // C++ wrapper type for IfcElectricGeneratorTypeEnum
- typedef ENUMERATION IfcElectricGeneratorTypeEnum;
- // C++ wrapper type for IfcElectricHeaterTypeEnum
- typedef ENUMERATION IfcElectricHeaterTypeEnum;
- // C++ wrapper type for IfcElectricMotorTypeEnum
- typedef ENUMERATION IfcElectricMotorTypeEnum;
- // C++ wrapper type for IfcElectricTimeControlTypeEnum
- typedef ENUMERATION IfcElectricTimeControlTypeEnum;
- // C++ wrapper type for IfcElementAssemblyTypeEnum
- typedef ENUMERATION IfcElementAssemblyTypeEnum;
- // C++ wrapper type for IfcElementCompositionEnum
- typedef ENUMERATION IfcElementCompositionEnum;
- // C++ wrapper type for IfcEnergySequenceEnum
- typedef ENUMERATION IfcEnergySequenceEnum;
- // C++ wrapper type for IfcEnvironmentalImpactCategoryEnum
- typedef ENUMERATION IfcEnvironmentalImpactCategoryEnum;
- // C++ wrapper type for IfcEvaporativeCoolerTypeEnum
- typedef ENUMERATION IfcEvaporativeCoolerTypeEnum;
- // C++ wrapper type for IfcEvaporatorTypeEnum
- typedef ENUMERATION IfcEvaporatorTypeEnum;
- // C++ wrapper type for IfcFanTypeEnum
- typedef ENUMERATION IfcFanTypeEnum;
- // C++ wrapper type for IfcFilterTypeEnum
- typedef ENUMERATION IfcFilterTypeEnum;
- // C++ wrapper type for IfcFireSuppressionTerminalTypeEnum
- typedef ENUMERATION IfcFireSuppressionTerminalTypeEnum;
- // C++ wrapper type for IfcFlowDirectionEnum
- typedef ENUMERATION IfcFlowDirectionEnum;
- // C++ wrapper type for IfcFlowInstrumentTypeEnum
- typedef ENUMERATION IfcFlowInstrumentTypeEnum;
- // C++ wrapper type for IfcFlowMeterTypeEnum
- typedef ENUMERATION IfcFlowMeterTypeEnum;
- // C++ wrapper type for IfcFootingTypeEnum
- typedef ENUMERATION IfcFootingTypeEnum;
- // C++ wrapper type for IfcGasTerminalTypeEnum
- typedef ENUMERATION IfcGasTerminalTypeEnum;
- // C++ wrapper type for IfcGeometricProjectionEnum
- typedef ENUMERATION IfcGeometricProjectionEnum;
- // C++ wrapper type for IfcGlobalOrLocalEnum
- typedef ENUMERATION IfcGlobalOrLocalEnum;
- // C++ wrapper type for IfcHeatExchangerTypeEnum
- typedef ENUMERATION IfcHeatExchangerTypeEnum;
- // C++ wrapper type for IfcHumidifierTypeEnum
- typedef ENUMERATION IfcHumidifierTypeEnum;
- // C++ wrapper type for IfcInternalOrExternalEnum
- typedef ENUMERATION IfcInternalOrExternalEnum;
- // C++ wrapper type for IfcInventoryTypeEnum
- typedef ENUMERATION IfcInventoryTypeEnum;
- // C++ wrapper type for IfcJunctionBoxTypeEnum
- typedef ENUMERATION IfcJunctionBoxTypeEnum;
- // C++ wrapper type for IfcLampTypeEnum
- typedef ENUMERATION IfcLampTypeEnum;
- // C++ wrapper type for IfcLayerSetDirectionEnum
- typedef ENUMERATION IfcLayerSetDirectionEnum;
- // C++ wrapper type for IfcLightDistributionCurveEnum
- typedef ENUMERATION IfcLightDistributionCurveEnum;
- // C++ wrapper type for IfcLightEmissionSourceEnum
- typedef ENUMERATION IfcLightEmissionSourceEnum;
- // C++ wrapper type for IfcLightFixtureTypeEnum
- typedef ENUMERATION IfcLightFixtureTypeEnum;
- // C++ wrapper type for IfcLoadGroupTypeEnum
- typedef ENUMERATION IfcLoadGroupTypeEnum;
- // C++ wrapper type for IfcLogicalOperatorEnum
- typedef ENUMERATION IfcLogicalOperatorEnum;
- // C++ wrapper type for IfcMemberTypeEnum
- typedef ENUMERATION IfcMemberTypeEnum;
- // C++ wrapper type for IfcMotorConnectionTypeEnum
- typedef ENUMERATION IfcMotorConnectionTypeEnum;
- // C++ wrapper type for IfcNullStyle
- typedef ENUMERATION IfcNullStyle;
- // C++ wrapper type for IfcObjectTypeEnum
- typedef ENUMERATION IfcObjectTypeEnum;
- // C++ wrapper type for IfcObjectiveEnum
- typedef ENUMERATION IfcObjectiveEnum;
- // C++ wrapper type for IfcOccupantTypeEnum
- typedef ENUMERATION IfcOccupantTypeEnum;
- // C++ wrapper type for IfcOutletTypeEnum
- typedef ENUMERATION IfcOutletTypeEnum;
- // C++ wrapper type for IfcPermeableCoveringOperationEnum
- typedef ENUMERATION IfcPermeableCoveringOperationEnum;
- // C++ wrapper type for IfcPhysicalOrVirtualEnum
- typedef ENUMERATION IfcPhysicalOrVirtualEnum;
- // C++ wrapper type for IfcPileConstructionEnum
- typedef ENUMERATION IfcPileConstructionEnum;
- // C++ wrapper type for IfcPileTypeEnum
- typedef ENUMERATION IfcPileTypeEnum;
- // C++ wrapper type for IfcPipeFittingTypeEnum
- typedef ENUMERATION IfcPipeFittingTypeEnum;
- // C++ wrapper type for IfcPipeSegmentTypeEnum
- typedef ENUMERATION IfcPipeSegmentTypeEnum;
- // C++ wrapper type for IfcPlateTypeEnum
- typedef ENUMERATION IfcPlateTypeEnum;
- // C++ wrapper type for IfcProcedureTypeEnum
- typedef ENUMERATION IfcProcedureTypeEnum;
- // C++ wrapper type for IfcProfileTypeEnum
- typedef ENUMERATION IfcProfileTypeEnum;
- // C++ wrapper type for IfcProjectOrderRecordTypeEnum
- typedef ENUMERATION IfcProjectOrderRecordTypeEnum;
- // C++ wrapper type for IfcProjectOrderTypeEnum
- typedef ENUMERATION IfcProjectOrderTypeEnum;
- // C++ wrapper type for IfcProjectedOrTrueLengthEnum
- typedef ENUMERATION IfcProjectedOrTrueLengthEnum;
- // C++ wrapper type for IfcPropertySourceEnum
- typedef ENUMERATION IfcPropertySourceEnum;
- // C++ wrapper type for IfcProtectiveDeviceTypeEnum
- typedef ENUMERATION IfcProtectiveDeviceTypeEnum;
- // C++ wrapper type for IfcPumpTypeEnum
- typedef ENUMERATION IfcPumpTypeEnum;
- // C++ wrapper type for IfcRailingTypeEnum
- typedef ENUMERATION IfcRailingTypeEnum;
- // C++ wrapper type for IfcRampFlightTypeEnum
- typedef ENUMERATION IfcRampFlightTypeEnum;
- // C++ wrapper type for IfcRampTypeEnum
- typedef ENUMERATION IfcRampTypeEnum;
- // C++ wrapper type for IfcReflectanceMethodEnum
- typedef ENUMERATION IfcReflectanceMethodEnum;
- // C++ wrapper type for IfcReinforcingBarRoleEnum
- typedef ENUMERATION IfcReinforcingBarRoleEnum;
- // C++ wrapper type for IfcReinforcingBarSurfaceEnum
- typedef ENUMERATION IfcReinforcingBarSurfaceEnum;
- // C++ wrapper type for IfcResourceConsumptionEnum
- typedef ENUMERATION IfcResourceConsumptionEnum;
- // C++ wrapper type for IfcRibPlateDirectionEnum
- typedef ENUMERATION IfcRibPlateDirectionEnum;
- // C++ wrapper type for IfcRoleEnum
- typedef ENUMERATION IfcRoleEnum;
- // C++ wrapper type for IfcRoofTypeEnum
- typedef ENUMERATION IfcRoofTypeEnum;
- // C++ wrapper type for IfcSIPrefix
- typedef ENUMERATION IfcSIPrefix;
- // C++ wrapper type for IfcSIUnitName
- typedef ENUMERATION IfcSIUnitName;
- // C++ wrapper type for IfcSanitaryTerminalTypeEnum
- typedef ENUMERATION IfcSanitaryTerminalTypeEnum;
- // C++ wrapper type for IfcSectionTypeEnum
- typedef ENUMERATION IfcSectionTypeEnum;
- // C++ wrapper type for IfcSensorTypeEnum
- typedef ENUMERATION IfcSensorTypeEnum;
- // C++ wrapper type for IfcSequenceEnum
- typedef ENUMERATION IfcSequenceEnum;
- // C++ wrapper type for IfcServiceLifeFactorTypeEnum
- typedef ENUMERATION IfcServiceLifeFactorTypeEnum;
- // C++ wrapper type for IfcServiceLifeTypeEnum
- typedef ENUMERATION IfcServiceLifeTypeEnum;
- // C++ wrapper type for IfcSlabTypeEnum
- typedef ENUMERATION IfcSlabTypeEnum;
- // C++ wrapper type for IfcSoundScaleEnum
- typedef ENUMERATION IfcSoundScaleEnum;
- // C++ wrapper type for IfcSpaceHeaterTypeEnum
- typedef ENUMERATION IfcSpaceHeaterTypeEnum;
- // C++ wrapper type for IfcSpaceTypeEnum
- typedef ENUMERATION IfcSpaceTypeEnum;
- // C++ wrapper type for IfcStackTerminalTypeEnum
- typedef ENUMERATION IfcStackTerminalTypeEnum;
- // C++ wrapper type for IfcStairFlightTypeEnum
- typedef ENUMERATION IfcStairFlightTypeEnum;
- // C++ wrapper type for IfcStairTypeEnum
- typedef ENUMERATION IfcStairTypeEnum;
- // C++ wrapper type for IfcStateEnum
- typedef ENUMERATION IfcStateEnum;
- // C++ wrapper type for IfcStructuralCurveTypeEnum
- typedef ENUMERATION IfcStructuralCurveTypeEnum;
- // C++ wrapper type for IfcStructuralSurfaceTypeEnum
- typedef ENUMERATION IfcStructuralSurfaceTypeEnum;
- // C++ wrapper type for IfcSurfaceSide
- typedef ENUMERATION IfcSurfaceSide;
- // C++ wrapper type for IfcSurfaceTextureEnum
- typedef ENUMERATION IfcSurfaceTextureEnum;
- // C++ wrapper type for IfcSwitchingDeviceTypeEnum
- typedef ENUMERATION IfcSwitchingDeviceTypeEnum;
- // C++ wrapper type for IfcTankTypeEnum
- typedef ENUMERATION IfcTankTypeEnum;
- // C++ wrapper type for IfcTendonTypeEnum
- typedef ENUMERATION IfcTendonTypeEnum;
- // C++ wrapper type for IfcTextPath
- typedef ENUMERATION IfcTextPath;
- // C++ wrapper type for IfcThermalLoadSourceEnum
- typedef ENUMERATION IfcThermalLoadSourceEnum;
- // C++ wrapper type for IfcThermalLoadTypeEnum
- typedef ENUMERATION IfcThermalLoadTypeEnum;
- // C++ wrapper type for IfcTimeSeriesDataTypeEnum
- typedef ENUMERATION IfcTimeSeriesDataTypeEnum;
- // C++ wrapper type for IfcTimeSeriesScheduleTypeEnum
- typedef ENUMERATION IfcTimeSeriesScheduleTypeEnum;
- // C++ wrapper type for IfcTransformerTypeEnum
- typedef ENUMERATION IfcTransformerTypeEnum;
- // C++ wrapper type for IfcTransitionCode
- typedef ENUMERATION IfcTransitionCode;
- // C++ wrapper type for IfcTransportElementTypeEnum
- typedef ENUMERATION IfcTransportElementTypeEnum;
- // C++ wrapper type for IfcTrimmingPreference
- typedef ENUMERATION IfcTrimmingPreference;
- // C++ wrapper type for IfcTubeBundleTypeEnum
- typedef ENUMERATION IfcTubeBundleTypeEnum;
- // C++ wrapper type for IfcUnitEnum
- typedef ENUMERATION IfcUnitEnum;
- // C++ wrapper type for IfcUnitaryEquipmentTypeEnum
- typedef ENUMERATION IfcUnitaryEquipmentTypeEnum;
- // C++ wrapper type for IfcValveTypeEnum
- typedef ENUMERATION IfcValveTypeEnum;
- // C++ wrapper type for IfcVibrationIsolatorTypeEnum
- typedef ENUMERATION IfcVibrationIsolatorTypeEnum;
- // C++ wrapper type for IfcWallTypeEnum
- typedef ENUMERATION IfcWallTypeEnum;
- // C++ wrapper type for IfcWasteTerminalTypeEnum
- typedef ENUMERATION IfcWasteTerminalTypeEnum;
- // C++ wrapper type for IfcWindowPanelOperationEnum
- typedef ENUMERATION IfcWindowPanelOperationEnum;
- // C++ wrapper type for IfcWindowPanelPositionEnum
- typedef ENUMERATION IfcWindowPanelPositionEnum;
- // C++ wrapper type for IfcWindowStyleConstructionEnum
- typedef ENUMERATION IfcWindowStyleConstructionEnum;
- // C++ wrapper type for IfcWindowStyleOperationEnum
- typedef ENUMERATION IfcWindowStyleOperationEnum;
- // C++ wrapper type for IfcWorkControlTypeEnum
- typedef ENUMERATION IfcWorkControlTypeEnum;
- // C++ wrapper type for IfcActorSelect
- typedef SELECT IfcActorSelect;
- // C++ wrapper type for IfcAppliedValueSelect
- typedef SELECT IfcAppliedValueSelect;
- // C++ wrapper type for IfcAxis2Placement
- typedef SELECT IfcAxis2Placement;
- // C++ wrapper type for IfcBooleanOperand
- typedef SELECT IfcBooleanOperand;
- // C++ wrapper type for IfcCharacterStyleSelect
- typedef SELECT IfcCharacterStyleSelect;
- // C++ wrapper type for IfcClassificationNotationSelect
- typedef SELECT IfcClassificationNotationSelect;
- // C++ wrapper type for IfcColour
- typedef SELECT IfcColour;
- // C++ wrapper type for IfcColourOrFactor
- typedef SELECT IfcColourOrFactor;
- // C++ wrapper type for IfcConditionCriterionSelect
- typedef SELECT IfcConditionCriterionSelect;
- // C++ wrapper type for IfcCsgSelect
- typedef SELECT IfcCsgSelect;
- // C++ wrapper type for IfcCurveFontOrScaledCurveFontSelect
- typedef SELECT IfcCurveFontOrScaledCurveFontSelect;
- // C++ wrapper type for IfcCurveOrEdgeCurve
- typedef SELECT IfcCurveOrEdgeCurve;
- // C++ wrapper type for IfcCurveStyleFontSelect
- typedef SELECT IfcCurveStyleFontSelect;
- // C++ wrapper type for IfcDateTimeSelect
- typedef SELECT IfcDateTimeSelect;
- // C++ wrapper type for IfcDefinedSymbolSelect
- typedef SELECT IfcDefinedSymbolSelect;
- // C++ wrapper type for IfcDerivedMeasureValue
- typedef SELECT IfcDerivedMeasureValue;
- // C++ wrapper type for IfcDocumentSelect
- typedef SELECT IfcDocumentSelect;
- // C++ wrapper type for IfcDraughtingCalloutElement
- typedef SELECT IfcDraughtingCalloutElement;
- // C++ wrapper type for IfcFillAreaStyleTileShapeSelect
- typedef SELECT IfcFillAreaStyleTileShapeSelect;
- // C++ wrapper type for IfcFillStyleSelect
- typedef SELECT IfcFillStyleSelect;
- // C++ wrapper type for IfcGeometricSetSelect
- typedef SELECT IfcGeometricSetSelect;
- // C++ wrapper type for IfcHatchLineDistanceSelect
- typedef SELECT IfcHatchLineDistanceSelect;
- // C++ wrapper type for IfcLayeredItem
- typedef SELECT IfcLayeredItem;
- // C++ wrapper type for IfcLibrarySelect
- typedef SELECT IfcLibrarySelect;
- // C++ wrapper type for IfcLightDistributionDataSourceSelect
- typedef SELECT IfcLightDistributionDataSourceSelect;
- // C++ wrapper type for IfcMaterialSelect
- typedef SELECT IfcMaterialSelect;
- // C++ wrapper type for IfcMeasureValue
- typedef SELECT IfcMeasureValue;
- // C++ wrapper type for IfcMetricValueSelect
- typedef SELECT IfcMetricValueSelect;
- // C++ wrapper type for IfcObjectReferenceSelect
- typedef SELECT IfcObjectReferenceSelect;
- // C++ wrapper type for IfcOrientationSelect
- typedef SELECT IfcOrientationSelect;
- // C++ wrapper type for IfcPointOrVertexPoint
- typedef SELECT IfcPointOrVertexPoint;
- // C++ wrapper type for IfcPresentationStyleSelect
- typedef SELECT IfcPresentationStyleSelect;
- // C++ wrapper type for IfcShell
- typedef SELECT IfcShell;
- // C++ wrapper type for IfcSimpleValue
- typedef SELECT IfcSimpleValue;
- // C++ wrapper type for IfcSizeSelect
- typedef SELECT IfcSizeSelect;
- // C++ wrapper type for IfcSpecularHighlightSelect
- typedef SELECT IfcSpecularHighlightSelect;
- // C++ wrapper type for IfcStructuralActivityAssignmentSelect
- typedef SELECT IfcStructuralActivityAssignmentSelect;
- // C++ wrapper type for IfcSurfaceOrFaceSurface
- typedef SELECT IfcSurfaceOrFaceSurface;
- // C++ wrapper type for IfcSurfaceStyleElementSelect
- typedef SELECT IfcSurfaceStyleElementSelect;
- // C++ wrapper type for IfcSymbolStyleSelect
- typedef SELECT IfcSymbolStyleSelect;
- // C++ wrapper type for IfcTextFontSelect
- typedef SELECT IfcTextFontSelect;
- // C++ wrapper type for IfcTextStyleSelect
- typedef SELECT IfcTextStyleSelect;
- // C++ wrapper type for IfcTrimmingSelect
- typedef SELECT IfcTrimmingSelect;
- // C++ wrapper type for IfcUnit
- typedef SELECT IfcUnit;
- // C++ wrapper type for IfcValue
- typedef SELECT IfcValue;
- // C++ wrapper type for IfcVectorOrDirection
- typedef SELECT IfcVectorOrDirection;
-
-
- // ******************************************************************************
- // IFC Entities
- // ******************************************************************************
-
- struct IfcRepresentationItem;
- struct IfcGeometricRepresentationItem;
- struct IfcCurve;
- struct IfcBoundedCurve;
- struct IfcCompositeCurve;
- struct Ifc2DCompositeCurve;
- struct IfcRoot;
- struct IfcObjectDefinition;
- struct IfcObject;
- struct IfcControl;
- struct IfcActionRequest;
- struct IfcActor;
- typedef NotImplemented IfcActorRole; // (not currently used by Assimp)
- struct IfcTypeObject;
- struct IfcTypeProduct;
- struct IfcElementType;
- struct IfcDistributionElementType;
- struct IfcDistributionControlElementType;
- struct IfcActuatorType;
- typedef NotImplemented IfcAddress; // (not currently used by Assimp)
- struct IfcDistributionFlowElementType;
- struct IfcFlowControllerType;
- struct IfcAirTerminalBoxType;
- struct IfcFlowTerminalType;
- struct IfcAirTerminalType;
- struct IfcEnergyConversionDeviceType;
- struct IfcAirToAirHeatRecoveryType;
- struct IfcAlarmType;
- struct IfcDraughtingCallout;
- struct IfcDimensionCurveDirectedCallout;
- struct IfcAngularDimension;
- struct IfcProduct;
- struct IfcAnnotation;
- struct IfcStyledItem;
- struct IfcAnnotationOccurrence;
- struct IfcAnnotationCurveOccurrence;
- struct IfcAnnotationFillArea;
- struct IfcAnnotationFillAreaOccurrence;
- struct IfcAnnotationSurface;
- struct IfcAnnotationSurfaceOccurrence;
- struct IfcAnnotationSymbolOccurrence;
- struct IfcAnnotationTextOccurrence;
- typedef NotImplemented IfcApplication; // (not currently used by Assimp)
- typedef NotImplemented IfcAppliedValue; // (not currently used by Assimp)
- typedef NotImplemented IfcAppliedValueRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcApproval; // (not currently used by Assimp)
- typedef NotImplemented IfcApprovalActorRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcApprovalPropertyRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcApprovalRelationship; // (not currently used by Assimp)
- struct IfcProfileDef;
- struct IfcArbitraryClosedProfileDef;
- struct IfcArbitraryOpenProfileDef;
- struct IfcArbitraryProfileDefWithVoids;
- struct IfcGroup;
- struct IfcAsset;
- struct IfcParameterizedProfileDef;
- struct IfcIShapeProfileDef;
- struct IfcAsymmetricIShapeProfileDef;
- struct IfcPlacement;
- struct IfcAxis1Placement;
- struct IfcAxis2Placement2D;
- struct IfcAxis2Placement3D;
- struct IfcBSplineCurve;
- struct IfcElement;
- struct IfcBuildingElement;
- struct IfcBeam;
- struct IfcBuildingElementType;
- struct IfcBeamType;
- struct IfcBezierCurve;
- typedef NotImplemented IfcSurfaceTexture; // (not currently used by Assimp)
- typedef NotImplemented IfcBlobTexture; // (not currently used by Assimp)
- struct IfcCsgPrimitive3D;
- struct IfcBlock;
- struct IfcBoilerType;
- struct IfcBooleanResult;
- struct IfcBooleanClippingResult;
- typedef NotImplemented IfcBoundaryCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcBoundaryEdgeCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcBoundaryFaceCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcBoundaryNodeCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcBoundaryNodeConditionWarping; // (not currently used by Assimp)
- struct IfcSurface;
- struct IfcBoundedSurface;
- struct IfcBoundingBox;
- struct IfcHalfSpaceSolid;
- struct IfcBoxedHalfSpace;
- struct IfcSpatialStructureElement;
- struct IfcBuilding;
- struct IfcBuildingElementComponent;
- struct IfcBuildingElementPart;
- struct IfcBuildingElementProxy;
- struct IfcBuildingElementProxyType;
- struct IfcBuildingStorey;
- struct IfcCShapeProfileDef;
- struct IfcFlowFittingType;
- struct IfcCableCarrierFittingType;
- struct IfcFlowSegmentType;
- struct IfcCableCarrierSegmentType;
- struct IfcCableSegmentType;
- typedef NotImplemented IfcCalendarDate; // (not currently used by Assimp)
- struct IfcPoint;
- struct IfcCartesianPoint;
- struct IfcCartesianTransformationOperator;
- struct IfcCartesianTransformationOperator2D;
- struct IfcCartesianTransformationOperator2DnonUniform;
- struct IfcCartesianTransformationOperator3D;
- struct IfcCartesianTransformationOperator3DnonUniform;
- struct IfcCenterLineProfileDef;
- struct IfcFeatureElement;
- struct IfcFeatureElementSubtraction;
- struct IfcEdgeFeature;
- struct IfcChamferEdgeFeature;
- struct IfcChillerType;
- struct IfcConic;
- struct IfcCircle;
- struct IfcCircleProfileDef;
- struct IfcCircleHollowProfileDef;
- typedef NotImplemented IfcClassification; // (not currently used by Assimp)
- typedef NotImplemented IfcClassificationItem; // (not currently used by Assimp)
- typedef NotImplemented IfcClassificationItemRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcClassificationNotation; // (not currently used by Assimp)
- typedef NotImplemented IfcClassificationNotationFacet; // (not currently used by Assimp)
- typedef NotImplemented IfcExternalReference; // (not currently used by Assimp)
- typedef NotImplemented IfcClassificationReference; // (not currently used by Assimp)
- struct IfcTopologicalRepresentationItem;
- struct IfcConnectedFaceSet;
- struct IfcClosedShell;
- struct IfcCoilType;
- struct IfcColourSpecification;
- struct IfcColourRgb;
- struct IfcColumn;
- struct IfcColumnType;
- struct IfcProperty;
- struct IfcComplexProperty;
- struct IfcCompositeCurveSegment;
- struct IfcCompositeProfileDef;
- struct IfcFlowMovingDeviceType;
- struct IfcCompressorType;
- struct IfcCondenserType;
- struct IfcCondition;
- struct IfcConditionCriterion;
- typedef NotImplemented IfcConnectionGeometry; // (not currently used by Assimp)
- typedef NotImplemented IfcConnectionCurveGeometry; // (not currently used by Assimp)
- typedef NotImplemented IfcConnectionPointGeometry; // (not currently used by Assimp)
- typedef NotImplemented IfcConnectionPointEccentricity; // (not currently used by Assimp)
- typedef NotImplemented IfcConnectionPortGeometry; // (not currently used by Assimp)
- typedef NotImplemented IfcConnectionSurfaceGeometry; // (not currently used by Assimp)
- typedef NotImplemented IfcConstraint; // (not currently used by Assimp)
- typedef NotImplemented IfcConstraintAggregationRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcConstraintClassificationRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcConstraintRelationship; // (not currently used by Assimp)
- struct IfcResource;
- struct IfcConstructionResource;
- struct IfcConstructionEquipmentResource;
- struct IfcConstructionMaterialResource;
- struct IfcConstructionProductResource;
- struct IfcNamedUnit;
- struct IfcContextDependentUnit;
- struct IfcControllerType;
- struct IfcConversionBasedUnit;
- struct IfcCooledBeamType;
- struct IfcCoolingTowerType;
- typedef NotImplemented IfcCoordinatedUniversalTimeOffset; // (not currently used by Assimp)
- struct IfcCostItem;
- struct IfcCostSchedule;
- typedef NotImplemented IfcCostValue; // (not currently used by Assimp)
- struct IfcCovering;
- struct IfcCoveringType;
- struct IfcCraneRailAShapeProfileDef;
- struct IfcCraneRailFShapeProfileDef;
- struct IfcCrewResource;
- struct IfcSolidModel;
- struct IfcCsgSolid;
- typedef NotImplemented IfcCurrencyRelationship; // (not currently used by Assimp)
- struct IfcCurtainWall;
- struct IfcCurtainWallType;
- struct IfcCurveBoundedPlane;
- struct IfcPresentationStyle;
- typedef NotImplemented IfcCurveStyle; // (not currently used by Assimp)
- typedef NotImplemented IfcCurveStyleFont; // (not currently used by Assimp)
- typedef NotImplemented IfcCurveStyleFontAndScaling; // (not currently used by Assimp)
- typedef NotImplemented IfcCurveStyleFontPattern; // (not currently used by Assimp)
- struct IfcDamperType;
- typedef NotImplemented IfcDateAndTime; // (not currently used by Assimp)
- struct IfcDefinedSymbol;
- struct IfcDerivedProfileDef;
- typedef NotImplemented IfcDerivedUnit; // (not currently used by Assimp)
- typedef NotImplemented IfcDerivedUnitElement; // (not currently used by Assimp)
- struct IfcDiameterDimension;
- typedef NotImplemented IfcDraughtingCalloutRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcDimensionCalloutRelationship; // (not currently used by Assimp)
- struct IfcDimensionCurve;
- struct IfcTerminatorSymbol;
- struct IfcDimensionCurveTerminator;
- typedef NotImplemented IfcDimensionPair; // (not currently used by Assimp)
- typedef NotImplemented IfcDimensionalExponents; // (not currently used by Assimp)
- struct IfcDirection;
- struct IfcElementComponent;
- struct IfcDiscreteAccessory;
- struct IfcElementComponentType;
- struct IfcDiscreteAccessoryType;
- struct IfcDistributionElement;
- struct IfcDistributionFlowElement;
- struct IfcDistributionChamberElement;
- struct IfcDistributionChamberElementType;
- struct IfcDistributionControlElement;
- struct IfcPort;
- struct IfcDistributionPort;
- typedef NotImplemented IfcDocumentElectronicFormat; // (not currently used by Assimp)
- typedef NotImplemented IfcDocumentInformation; // (not currently used by Assimp)
- typedef NotImplemented IfcDocumentInformationRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcDocumentReference; // (not currently used by Assimp)
- struct IfcDoor;
- struct IfcPropertyDefinition;
- struct IfcPropertySetDefinition;
- typedef NotImplemented IfcDoorLiningProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcDoorPanelProperties; // (not currently used by Assimp)
- struct IfcDoorStyle;
- typedef NotImplemented IfcPreDefinedItem; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedColour; // (not currently used by Assimp)
- typedef NotImplemented IfcDraughtingPreDefinedColour; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedCurveFont; // (not currently used by Assimp)
- typedef NotImplemented IfcDraughtingPreDefinedCurveFont; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedTextFont; // (not currently used by Assimp)
- typedef NotImplemented IfcDraughtingPreDefinedTextFont; // (not currently used by Assimp)
- struct IfcDuctFittingType;
- struct IfcDuctSegmentType;
- struct IfcFlowTreatmentDeviceType;
- struct IfcDuctSilencerType;
- struct IfcEdge;
- struct IfcEdgeCurve;
- struct IfcLoop;
- struct IfcEdgeLoop;
- struct IfcElectricApplianceType;
- struct IfcFlowController;
- struct IfcElectricDistributionPoint;
- struct IfcFlowStorageDeviceType;
- struct IfcElectricFlowStorageDeviceType;
- struct IfcElectricGeneratorType;
- struct IfcElectricHeaterType;
- struct IfcElectricMotorType;
- struct IfcElectricTimeControlType;
- typedef NotImplemented IfcEnergyProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcElectricalBaseProperties; // (not currently used by Assimp)
- struct IfcSystem;
- struct IfcElectricalCircuit;
- struct IfcElectricalElement;
- struct IfcElementAssembly;
- struct IfcElementQuantity;
- struct IfcElementarySurface;
- struct IfcEllipse;
- struct IfcEllipseProfileDef;
- struct IfcEnergyConversionDevice;
- typedef NotImplemented IfcEnvironmentalImpactValue; // (not currently used by Assimp)
- struct IfcEquipmentElement;
- struct IfcEquipmentStandard;
- struct IfcEvaporativeCoolerType;
- struct IfcEvaporatorType;
- typedef NotImplemented IfcMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcExtendedMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcExternallyDefinedHatchStyle; // (not currently used by Assimp)
- typedef NotImplemented IfcExternallyDefinedSurfaceStyle; // (not currently used by Assimp)
- typedef NotImplemented IfcExternallyDefinedSymbol; // (not currently used by Assimp)
- typedef NotImplemented IfcExternallyDefinedTextFont; // (not currently used by Assimp)
- struct IfcSweptAreaSolid;
- struct IfcExtrudedAreaSolid;
- struct IfcFace;
- struct IfcFaceBasedSurfaceModel;
- struct IfcFaceBound;
- struct IfcFaceOuterBound;
- struct IfcFaceSurface;
- struct IfcManifoldSolidBrep;
- struct IfcFacetedBrep;
- struct IfcFacetedBrepWithVoids;
- typedef NotImplemented IfcStructuralConnectionCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcFailureConnectionCondition; // (not currently used by Assimp)
- struct IfcFanType;
- struct IfcFastener;
- struct IfcFastenerType;
- struct IfcFeatureElementAddition;
- typedef NotImplemented IfcFillAreaStyle; // (not currently used by Assimp)
- struct IfcFillAreaStyleHatching;
- struct IfcFillAreaStyleTileSymbolWithStyle;
- struct IfcFillAreaStyleTiles;
- struct IfcFilterType;
- struct IfcFireSuppressionTerminalType;
- struct IfcFlowFitting;
- struct IfcFlowInstrumentType;
- struct IfcFlowMeterType;
- struct IfcFlowMovingDevice;
- struct IfcFlowSegment;
- struct IfcFlowStorageDevice;
- struct IfcFlowTerminal;
- struct IfcFlowTreatmentDevice;
- typedef NotImplemented IfcFluidFlowProperties; // (not currently used by Assimp)
- struct IfcFooting;
- typedef NotImplemented IfcFuelProperties; // (not currently used by Assimp)
- struct IfcFurnishingElement;
- struct IfcFurnishingElementType;
- struct IfcFurnitureStandard;
- struct IfcFurnitureType;
- struct IfcGasTerminalType;
- typedef NotImplemented IfcGeneralMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcProfileProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcGeneralProfileProperties; // (not currently used by Assimp)
- struct IfcGeometricSet;
- struct IfcGeometricCurveSet;
- struct IfcRepresentationContext;
- struct IfcGeometricRepresentationContext;
- struct IfcGeometricRepresentationSubContext;
- struct IfcGrid;
- typedef NotImplemented IfcGridAxis; // (not currently used by Assimp)
- struct IfcObjectPlacement;
- struct IfcGridPlacement;
- struct IfcHeatExchangerType;
- struct IfcHumidifierType;
- typedef NotImplemented IfcHygroscopicMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcImageTexture; // (not currently used by Assimp)
- struct IfcInventory;
- typedef NotImplemented IfcTimeSeries; // (not currently used by Assimp)
- typedef NotImplemented IfcIrregularTimeSeries; // (not currently used by Assimp)
- typedef NotImplemented IfcIrregularTimeSeriesValue; // (not currently used by Assimp)
- struct IfcJunctionBoxType;
- struct IfcLShapeProfileDef;
- struct IfcLaborResource;
- struct IfcLampType;
- typedef NotImplemented IfcLibraryInformation; // (not currently used by Assimp)
- typedef NotImplemented IfcLibraryReference; // (not currently used by Assimp)
- typedef NotImplemented IfcLightDistributionData; // (not currently used by Assimp)
- struct IfcLightFixtureType;
- typedef NotImplemented IfcLightIntensityDistribution; // (not currently used by Assimp)
- struct IfcLightSource;
- struct IfcLightSourceAmbient;
- struct IfcLightSourceDirectional;
- struct IfcLightSourceGoniometric;
- struct IfcLightSourcePositional;
- struct IfcLightSourceSpot;
- struct IfcLine;
- struct IfcLinearDimension;
- struct IfcLocalPlacement;
- typedef NotImplemented IfcLocalTime; // (not currently used by Assimp)
- struct IfcMappedItem;
- typedef NotImplemented IfcMaterial; // (not currently used by Assimp)
- typedef NotImplemented IfcMaterialClassificationRelationship; // (not currently used by Assimp)
- struct IfcProductRepresentation;
- struct IfcMaterialDefinitionRepresentation;
- typedef NotImplemented IfcMaterialLayer; // (not currently used by Assimp)
- typedef NotImplemented IfcMaterialLayerSet; // (not currently used by Assimp)
- typedef NotImplemented IfcMaterialLayerSetUsage; // (not currently used by Assimp)
- typedef NotImplemented IfcMaterialList; // (not currently used by Assimp)
- struct IfcMeasureWithUnit;
- typedef NotImplemented IfcMechanicalMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcMechanicalConcreteMaterialProperties; // (not currently used by Assimp)
- struct IfcMechanicalFastener;
- struct IfcMechanicalFastenerType;
- typedef NotImplemented IfcMechanicalSteelMaterialProperties; // (not currently used by Assimp)
- struct IfcMember;
- struct IfcMemberType;
- typedef NotImplemented IfcMetric; // (not currently used by Assimp)
- typedef NotImplemented IfcMonetaryUnit; // (not currently used by Assimp)
- struct IfcMotorConnectionType;
- struct IfcProcess;
- struct IfcTask;
- struct IfcMove;
- typedef NotImplemented IfcObjective; // (not currently used by Assimp)
- struct IfcOccupant;
- struct IfcOffsetCurve2D;
- struct IfcOffsetCurve3D;
- struct IfcOneDirectionRepeatFactor;
- struct IfcOpenShell;
- struct IfcOpeningElement;
- typedef NotImplemented IfcOpticalMaterialProperties; // (not currently used by Assimp)
- struct IfcOrderAction;
- typedef NotImplemented IfcOrganization; // (not currently used by Assimp)
- typedef NotImplemented IfcOrganizationRelationship; // (not currently used by Assimp)
- struct IfcOrientedEdge;
- struct IfcOutletType;
- typedef NotImplemented IfcOwnerHistory; // (not currently used by Assimp)
- struct IfcPath;
- struct IfcPerformanceHistory;
- typedef NotImplemented IfcPermeableCoveringProperties; // (not currently used by Assimp)
- struct IfcPermit;
- typedef NotImplemented IfcPerson; // (not currently used by Assimp)
- typedef NotImplemented IfcPersonAndOrganization; // (not currently used by Assimp)
- typedef NotImplemented IfcPhysicalQuantity; // (not currently used by Assimp)
- typedef NotImplemented IfcPhysicalComplexQuantity; // (not currently used by Assimp)
- typedef NotImplemented IfcPhysicalSimpleQuantity; // (not currently used by Assimp)
- struct IfcPile;
- struct IfcPipeFittingType;
- struct IfcPipeSegmentType;
- typedef NotImplemented IfcPixelTexture; // (not currently used by Assimp)
- struct IfcPlanarExtent;
- struct IfcPlanarBox;
- struct IfcPlane;
- struct IfcPlate;
- struct IfcPlateType;
- struct IfcPointOnCurve;
- struct IfcPointOnSurface;
- struct IfcPolyLoop;
- struct IfcPolygonalBoundedHalfSpace;
- struct IfcPolyline;
- typedef NotImplemented IfcPostalAddress; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedSymbol; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedDimensionSymbol; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedPointMarkerSymbol; // (not currently used by Assimp)
- typedef NotImplemented IfcPreDefinedTerminatorSymbol; // (not currently used by Assimp)
- typedef NotImplemented IfcPresentationLayerAssignment; // (not currently used by Assimp)
- typedef NotImplemented IfcPresentationLayerWithStyle; // (not currently used by Assimp)
- struct IfcPresentationStyleAssignment;
- struct IfcProcedure;
- struct IfcProductDefinitionShape;
- typedef NotImplemented IfcProductsOfCombustionProperties; // (not currently used by Assimp)
- struct IfcProject;
- struct IfcProjectOrder;
- struct IfcProjectOrderRecord;
- struct IfcProjectionCurve;
- struct IfcProjectionElement;
- struct IfcSimpleProperty;
- struct IfcPropertyBoundedValue;
- typedef NotImplemented IfcPropertyConstraintRelationship; // (not currently used by Assimp)
- typedef NotImplemented IfcPropertyDependencyRelationship; // (not currently used by Assimp)
- struct IfcPropertyEnumeratedValue;
- typedef NotImplemented IfcPropertyEnumeration; // (not currently used by Assimp)
- struct IfcPropertyListValue;
- struct IfcPropertyReferenceValue;
- struct IfcPropertySet;
- struct IfcPropertySingleValue;
- struct IfcPropertyTableValue;
- struct IfcProtectiveDeviceType;
- struct IfcProxy;
- struct IfcPumpType;
- typedef NotImplemented IfcQuantityArea; // (not currently used by Assimp)
- typedef NotImplemented IfcQuantityCount; // (not currently used by Assimp)
- typedef NotImplemented IfcQuantityLength; // (not currently used by Assimp)
- typedef NotImplemented IfcQuantityTime; // (not currently used by Assimp)
- typedef NotImplemented IfcQuantityVolume; // (not currently used by Assimp)
- typedef NotImplemented IfcQuantityWeight; // (not currently used by Assimp)
- struct IfcRadiusDimension;
- struct IfcRailing;
- struct IfcRailingType;
- struct IfcRamp;
- struct IfcRampFlight;
- struct IfcRampFlightType;
- struct IfcRationalBezierCurve;
- struct IfcRectangleProfileDef;
- struct IfcRectangleHollowProfileDef;
- struct IfcRectangularPyramid;
- struct IfcRectangularTrimmedSurface;
- typedef NotImplemented IfcReferencesValueDocument; // (not currently used by Assimp)
- typedef NotImplemented IfcRegularTimeSeries; // (not currently used by Assimp)
- typedef NotImplemented IfcReinforcementBarProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcReinforcementDefinitionProperties; // (not currently used by Assimp)
- struct IfcReinforcingElement;
- struct IfcReinforcingBar;
- struct IfcReinforcingMesh;
- struct IfcRelationship;
- struct IfcRelDecomposes;
- struct IfcRelAggregates;
- typedef NotImplemented IfcRelAssigns; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToControl; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsTasks; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToActor; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToGroup; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToProcess; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToProduct; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToProjectOrder; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssignsToResource; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociates; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesAppliedValue; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesApproval; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesClassification; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesConstraint; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesDocument; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesLibrary; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesMaterial; // (not currently used by Assimp)
- typedef NotImplemented IfcRelAssociatesProfileProperties; // (not currently used by Assimp)
- struct IfcRelConnects;
- typedef NotImplemented IfcRelConnectsElements; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsPathElements; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsPortToElement; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsPorts; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsStructuralActivity; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsStructuralElement; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsStructuralMember; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsWithEccentricity; // (not currently used by Assimp)
- typedef NotImplemented IfcRelConnectsWithRealizingElements; // (not currently used by Assimp)
- struct IfcRelContainedInSpatialStructure;
- typedef NotImplemented IfcRelCoversBldgElements; // (not currently used by Assimp)
- typedef NotImplemented IfcRelCoversSpaces; // (not currently used by Assimp)
- struct IfcRelDefines;
- struct IfcRelDefinesByProperties;
- typedef NotImplemented IfcRelDefinesByType; // (not currently used by Assimp)
- struct IfcRelFillsElement;
- typedef NotImplemented IfcRelFlowControlElements; // (not currently used by Assimp)
- typedef NotImplemented IfcRelInteractionRequirements; // (not currently used by Assimp)
- typedef NotImplemented IfcRelNests; // (not currently used by Assimp)
- typedef NotImplemented IfcRelOccupiesSpaces; // (not currently used by Assimp)
- struct IfcRelOverridesProperties;
- typedef NotImplemented IfcRelProjectsElement; // (not currently used by Assimp)
- typedef NotImplemented IfcRelReferencedInSpatialStructure; // (not currently used by Assimp)
- typedef NotImplemented IfcRelSchedulesCostItems; // (not currently used by Assimp)
- typedef NotImplemented IfcRelSequence; // (not currently used by Assimp)
- typedef NotImplemented IfcRelServicesBuildings; // (not currently used by Assimp)
- typedef NotImplemented IfcRelSpaceBoundary; // (not currently used by Assimp)
- struct IfcRelVoidsElement;
- typedef NotImplemented IfcRelaxation; // (not currently used by Assimp)
- struct IfcRepresentation;
- struct IfcRepresentationMap;
- struct IfcRevolvedAreaSolid;
- typedef NotImplemented IfcRibPlateProfileProperties; // (not currently used by Assimp)
- struct IfcRightCircularCone;
- struct IfcRightCircularCylinder;
- struct IfcRoof;
- struct IfcRoundedEdgeFeature;
- struct IfcRoundedRectangleProfileDef;
- struct IfcSIUnit;
- struct IfcSanitaryTerminalType;
- struct IfcScheduleTimeControl;
- typedef NotImplemented IfcSectionProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcSectionReinforcementProperties; // (not currently used by Assimp)
- struct IfcSectionedSpine;
- struct IfcSensorType;
- struct IfcServiceLife;
- typedef NotImplemented IfcServiceLifeFactor; // (not currently used by Assimp)
- typedef NotImplemented IfcShapeAspect; // (not currently used by Assimp)
- struct IfcShapeModel;
- struct IfcShapeRepresentation;
- struct IfcShellBasedSurfaceModel;
- struct IfcSite;
- struct IfcSlab;
- struct IfcSlabType;
- typedef NotImplemented IfcSlippageConnectionCondition; // (not currently used by Assimp)
- typedef NotImplemented IfcSoundProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcSoundValue; // (not currently used by Assimp)
- struct IfcSpace;
- struct IfcSpaceHeaterType;
- struct IfcSpaceProgram;
- typedef NotImplemented IfcSpaceThermalLoadProperties; // (not currently used by Assimp)
- struct IfcSpatialStructureElementType;
- struct IfcSpaceType;
- struct IfcSphere;
- struct IfcStackTerminalType;
- struct IfcStair;
- struct IfcStairFlight;
- struct IfcStairFlightType;
- struct IfcStructuralActivity;
- struct IfcStructuralAction;
- struct IfcStructuralAnalysisModel;
- struct IfcStructuralItem;
- struct IfcStructuralConnection;
- struct IfcStructuralCurveConnection;
- struct IfcStructuralMember;
- struct IfcStructuralCurveMember;
- struct IfcStructuralCurveMemberVarying;
- struct IfcStructuralLinearAction;
- struct IfcStructuralLinearActionVarying;
- typedef NotImplemented IfcStructuralLoad; // (not currently used by Assimp)
- struct IfcStructuralLoadGroup;
- typedef NotImplemented IfcStructuralLoadStatic; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadLinearForce; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadPlanarForce; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadSingleDisplacement; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadSingleDisplacementDistortion; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadSingleForce; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadSingleForceWarping; // (not currently used by Assimp)
- typedef NotImplemented IfcStructuralLoadTemperature; // (not currently used by Assimp)
- struct IfcStructuralPlanarAction;
- struct IfcStructuralPlanarActionVarying;
- struct IfcStructuralPointAction;
- struct IfcStructuralPointConnection;
- struct IfcStructuralReaction;
- struct IfcStructuralPointReaction;
- typedef NotImplemented IfcStructuralProfileProperties; // (not currently used by Assimp)
- struct IfcStructuralResultGroup;
- typedef NotImplemented IfcStructuralSteelProfileProperties; // (not currently used by Assimp)
- struct IfcStructuralSurfaceConnection;
- struct IfcStructuralSurfaceMember;
- struct IfcStructuralSurfaceMemberVarying;
- struct IfcStructuredDimensionCallout;
- struct IfcStyleModel;
- struct IfcStyledRepresentation;
- struct IfcSubContractResource;
- struct IfcSubedge;
- struct IfcSurfaceCurveSweptAreaSolid;
- struct IfcSweptSurface;
- struct IfcSurfaceOfLinearExtrusion;
- struct IfcSurfaceOfRevolution;
- struct IfcSurfaceStyle;
- typedef NotImplemented IfcSurfaceStyleLighting; // (not currently used by Assimp)
- typedef NotImplemented IfcSurfaceStyleRefraction; // (not currently used by Assimp)
- struct IfcSurfaceStyleShading;
- struct IfcSurfaceStyleRendering;
- struct IfcSurfaceStyleWithTextures;
- struct IfcSweptDiskSolid;
- struct IfcSwitchingDeviceType;
- typedef NotImplemented IfcSymbolStyle; // (not currently used by Assimp)
- struct IfcSystemFurnitureElementType;
- struct IfcTShapeProfileDef;
- typedef NotImplemented IfcTable; // (not currently used by Assimp)
- typedef NotImplemented IfcTableRow; // (not currently used by Assimp)
- struct IfcTankType;
- typedef NotImplemented IfcTelecomAddress; // (not currently used by Assimp)
- struct IfcTendon;
- struct IfcTendonAnchor;
- struct IfcTextLiteral;
- struct IfcTextLiteralWithExtent;
- typedef NotImplemented IfcTextStyle; // (not currently used by Assimp)
- typedef NotImplemented IfcTextStyleFontModel; // (not currently used by Assimp)
- typedef NotImplemented IfcTextStyleForDefinedFont; // (not currently used by Assimp)
- typedef NotImplemented IfcTextStyleTextModel; // (not currently used by Assimp)
- typedef NotImplemented IfcTextStyleWithBoxCharacteristics; // (not currently used by Assimp)
- typedef NotImplemented IfcTextureCoordinate; // (not currently used by Assimp)
- typedef NotImplemented IfcTextureCoordinateGenerator; // (not currently used by Assimp)
- typedef NotImplemented IfcTextureMap; // (not currently used by Assimp)
- typedef NotImplemented IfcTextureVertex; // (not currently used by Assimp)
- typedef NotImplemented IfcThermalMaterialProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcTimeSeriesReferenceRelationship; // (not currently used by Assimp)
- struct IfcTimeSeriesSchedule;
- typedef NotImplemented IfcTimeSeriesValue; // (not currently used by Assimp)
- struct IfcTopologyRepresentation;
- struct IfcTransformerType;
- struct IfcTransportElement;
- struct IfcTransportElementType;
- struct IfcTrapeziumProfileDef;
- struct IfcTrimmedCurve;
- struct IfcTubeBundleType;
- struct IfcTwoDirectionRepeatFactor;
- struct IfcUShapeProfileDef;
- struct IfcUnitAssignment;
- struct IfcUnitaryEquipmentType;
- struct IfcValveType;
- struct IfcVector;
- struct IfcVertex;
- typedef NotImplemented IfcVertexBasedTextureMap; // (not currently used by Assimp)
- struct IfcVertexLoop;
- struct IfcVertexPoint;
- struct IfcVibrationIsolatorType;
- struct IfcVirtualElement;
- typedef NotImplemented IfcVirtualGridIntersection; // (not currently used by Assimp)
- struct IfcWall;
- struct IfcWallStandardCase;
- struct IfcWallType;
- struct IfcWasteTerminalType;
- typedef NotImplemented IfcWaterProperties; // (not currently used by Assimp)
- struct IfcWindow;
- typedef NotImplemented IfcWindowLiningProperties; // (not currently used by Assimp)
- typedef NotImplemented IfcWindowPanelProperties; // (not currently used by Assimp)
- struct IfcWindowStyle;
- struct IfcWorkControl;
- struct IfcWorkPlan;
- struct IfcWorkSchedule;
- struct IfcZShapeProfileDef;
- struct IfcZone;
-
-
-
- // C++ wrapper for IfcRepresentationItem
- struct IfcRepresentationItem : ObjectHelper<IfcRepresentationItem,0> { IfcRepresentationItem() : Object("IfcRepresentationItem") {}
-
- };
-
- // C++ wrapper for IfcGeometricRepresentationItem
- struct IfcGeometricRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcGeometricRepresentationItem,0> { IfcGeometricRepresentationItem() : Object("IfcGeometricRepresentationItem") {}
-
- };
-
- // C++ wrapper for IfcCurve
- struct IfcCurve : IfcGeometricRepresentationItem, ObjectHelper<IfcCurve,0> { IfcCurve() : Object("IfcCurve") {}
-
- };
-
- // C++ wrapper for IfcBoundedCurve
- struct IfcBoundedCurve : IfcCurve, ObjectHelper<IfcBoundedCurve,0> { IfcBoundedCurve() : Object("IfcBoundedCurve") {}
-
- };
-
- // 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 IfcRoot
- struct IfcRoot : ObjectHelper<IfcRoot,4> { IfcRoot() : Object("IfcRoot") {}
- IfcGloballyUniqueId::Out GlobalId;
- Lazy< NotImplemented > OwnerHistory;
- Maybe< IfcLabel::Out > Name;
- Maybe< IfcText::Out > Description;
- };
-
- // C++ wrapper for IfcObjectDefinition
- struct IfcObjectDefinition : IfcRoot, ObjectHelper<IfcObjectDefinition,0> { IfcObjectDefinition() : Object("IfcObjectDefinition") {}
-
- };
-
- // C++ wrapper for IfcObject
- struct IfcObject : IfcObjectDefinition, ObjectHelper<IfcObject,1> { IfcObject() : Object("IfcObject") {}
- Maybe< IfcLabel::Out > ObjectType;
- };
-
- // C++ wrapper for IfcControl
- struct IfcControl : IfcObject, ObjectHelper<IfcControl,0> { IfcControl() : Object("IfcControl") {}
-
- };
-
- // C++ wrapper for IfcActionRequest
- struct IfcActionRequest : IfcControl, ObjectHelper<IfcActionRequest,1> { IfcActionRequest() : Object("IfcActionRequest") {}
- IfcIdentifier::Out RequestID;
- };
-
- // C++ wrapper for IfcActor
- struct IfcActor : IfcObject, ObjectHelper<IfcActor,1> { IfcActor() : Object("IfcActor") {}
- IfcActorSelect::Out TheActor;
- };
-
- // C++ wrapper for IfcTypeObject
- struct IfcTypeObject : IfcObjectDefinition, ObjectHelper<IfcTypeObject,2> { IfcTypeObject() : Object("IfcTypeObject") {}
- Maybe< IfcLabel::Out > ApplicableOccurrence;
- Maybe< ListOf< Lazy< IfcPropertySetDefinition >, 1, 0 > > HasPropertySets;
- };
-
- // C++ wrapper for IfcTypeProduct
- struct IfcTypeProduct : IfcTypeObject, ObjectHelper<IfcTypeProduct,2> { IfcTypeProduct() : Object("IfcTypeProduct") {}
- Maybe< ListOf< Lazy< IfcRepresentationMap >, 1, 0 > > RepresentationMaps;
- Maybe< IfcLabel::Out > Tag;
- };
-
- // C++ wrapper for IfcElementType
- struct IfcElementType : IfcTypeProduct, ObjectHelper<IfcElementType,1> { IfcElementType() : Object("IfcElementType") {}
- Maybe< IfcLabel::Out > ElementType;
- };
-
- // C++ wrapper for IfcDistributionElementType
- struct IfcDistributionElementType : IfcElementType, ObjectHelper<IfcDistributionElementType,0> { IfcDistributionElementType() : Object("IfcDistributionElementType") {}
-
- };
-
- // C++ wrapper for IfcDistributionControlElementType
- struct IfcDistributionControlElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionControlElementType,0> { IfcDistributionControlElementType() : Object("IfcDistributionControlElementType") {}
-
- };
-
- // C++ wrapper for IfcActuatorType
- struct IfcActuatorType : IfcDistributionControlElementType, ObjectHelper<IfcActuatorType,1> { IfcActuatorType() : Object("IfcActuatorType") {}
- IfcActuatorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcDistributionFlowElementType
- struct IfcDistributionFlowElementType : IfcDistributionElementType, ObjectHelper<IfcDistributionFlowElementType,0> { IfcDistributionFlowElementType() : Object("IfcDistributionFlowElementType") {}
-
- };
-
- // C++ wrapper for IfcFlowControllerType
- struct IfcFlowControllerType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowControllerType,0> { IfcFlowControllerType() : Object("IfcFlowControllerType") {}
-
- };
-
- // C++ wrapper for IfcAirTerminalBoxType
- struct IfcAirTerminalBoxType : IfcFlowControllerType, ObjectHelper<IfcAirTerminalBoxType,1> { IfcAirTerminalBoxType() : Object("IfcAirTerminalBoxType") {}
- IfcAirTerminalBoxTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowTerminalType
- struct IfcFlowTerminalType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTerminalType,0> { IfcFlowTerminalType() : Object("IfcFlowTerminalType") {}
-
- };
-
- // C++ wrapper for IfcAirTerminalType
- struct IfcAirTerminalType : IfcFlowTerminalType, ObjectHelper<IfcAirTerminalType,1> { IfcAirTerminalType() : Object("IfcAirTerminalType") {}
- IfcAirTerminalTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcEnergyConversionDeviceType
- struct IfcEnergyConversionDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcEnergyConversionDeviceType,0> { IfcEnergyConversionDeviceType() : Object("IfcEnergyConversionDeviceType") {}
-
- };
-
- // C++ wrapper for IfcAirToAirHeatRecoveryType
- struct IfcAirToAirHeatRecoveryType : IfcEnergyConversionDeviceType, ObjectHelper<IfcAirToAirHeatRecoveryType,1> { IfcAirToAirHeatRecoveryType() : Object("IfcAirToAirHeatRecoveryType") {}
- IfcAirToAirHeatRecoveryTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcAlarmType
- struct IfcAlarmType : IfcDistributionControlElementType, ObjectHelper<IfcAlarmType,1> { IfcAlarmType() : Object("IfcAlarmType") {}
- IfcAlarmTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcDraughtingCallout
- struct IfcDraughtingCallout : IfcGeometricRepresentationItem, ObjectHelper<IfcDraughtingCallout,1> { IfcDraughtingCallout() : Object("IfcDraughtingCallout") {}
- ListOf< IfcDraughtingCalloutElement, 1, 0 >::Out Contents;
- };
-
- // C++ wrapper for IfcDimensionCurveDirectedCallout
- struct IfcDimensionCurveDirectedCallout : IfcDraughtingCallout, ObjectHelper<IfcDimensionCurveDirectedCallout,0> { IfcDimensionCurveDirectedCallout() : Object("IfcDimensionCurveDirectedCallout") {}
-
- };
-
- // C++ wrapper for IfcAngularDimension
- struct IfcAngularDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcAngularDimension,0> { IfcAngularDimension() : Object("IfcAngularDimension") {}
-
- };
-
- // C++ wrapper for IfcProduct
- struct IfcProduct : IfcObject, ObjectHelper<IfcProduct,2> { IfcProduct() : Object("IfcProduct") {}
- Maybe< Lazy< IfcObjectPlacement > > ObjectPlacement;
- Maybe< Lazy< IfcProductRepresentation > > Representation;
- };
-
- // C++ wrapper for IfcAnnotation
- struct IfcAnnotation : IfcProduct, ObjectHelper<IfcAnnotation,0> { IfcAnnotation() : Object("IfcAnnotation") {}
-
- };
-
- // 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 IfcAnnotationCurveOccurrence
- struct IfcAnnotationCurveOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationCurveOccurrence,0> { IfcAnnotationCurveOccurrence() : Object("IfcAnnotationCurveOccurrence") {}
-
- };
-
- // C++ wrapper for IfcAnnotationFillArea
- struct IfcAnnotationFillArea : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationFillArea,2> { IfcAnnotationFillArea() : Object("IfcAnnotationFillArea") {}
- Lazy< IfcCurve > OuterBoundary;
- Maybe< ListOf< Lazy< IfcCurve >, 1, 0 > > InnerBoundaries;
- };
-
- // C++ wrapper for IfcAnnotationFillAreaOccurrence
- struct IfcAnnotationFillAreaOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationFillAreaOccurrence,2> { IfcAnnotationFillAreaOccurrence() : Object("IfcAnnotationFillAreaOccurrence") {}
- Maybe< Lazy< IfcPoint > > FillStyleTarget;
- Maybe< IfcGlobalOrLocalEnum::Out > GlobalOrLocal;
- };
-
- // C++ wrapper for IfcAnnotationSurface
- struct IfcAnnotationSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcAnnotationSurface,2> { IfcAnnotationSurface() : Object("IfcAnnotationSurface") {}
- Lazy< IfcGeometricRepresentationItem > Item;
- Maybe< Lazy< NotImplemented > > TextureCoordinates;
- };
-
- // C++ wrapper for IfcAnnotationSurfaceOccurrence
- struct IfcAnnotationSurfaceOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSurfaceOccurrence,0> { IfcAnnotationSurfaceOccurrence() : Object("IfcAnnotationSurfaceOccurrence") {}
-
- };
-
- // C++ wrapper for IfcAnnotationSymbolOccurrence
- struct IfcAnnotationSymbolOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationSymbolOccurrence,0> { IfcAnnotationSymbolOccurrence() : Object("IfcAnnotationSymbolOccurrence") {}
-
- };
-
- // C++ wrapper for IfcAnnotationTextOccurrence
- struct IfcAnnotationTextOccurrence : IfcAnnotationOccurrence, ObjectHelper<IfcAnnotationTextOccurrence,0> { IfcAnnotationTextOccurrence() : Object("IfcAnnotationTextOccurrence") {}
-
- };
-
- // 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 IfcArbitraryOpenProfileDef
- struct IfcArbitraryOpenProfileDef : IfcProfileDef, ObjectHelper<IfcArbitraryOpenProfileDef,1> { IfcArbitraryOpenProfileDef() : Object("IfcArbitraryOpenProfileDef") {}
- Lazy< IfcBoundedCurve > Curve;
- };
-
- // C++ wrapper for IfcArbitraryProfileDefWithVoids
- struct IfcArbitraryProfileDefWithVoids : IfcArbitraryClosedProfileDef, ObjectHelper<IfcArbitraryProfileDefWithVoids,1> { IfcArbitraryProfileDefWithVoids() : Object("IfcArbitraryProfileDefWithVoids") {}
- ListOf< Lazy< IfcCurve >, 1, 0 > InnerCurves;
- };
-
- // C++ wrapper for IfcGroup
- struct IfcGroup : IfcObject, ObjectHelper<IfcGroup,0> { IfcGroup() : Object("IfcGroup") {}
-
- };
-
- // 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 IfcParameterizedProfileDef
- struct IfcParameterizedProfileDef : IfcProfileDef, ObjectHelper<IfcParameterizedProfileDef,1> { IfcParameterizedProfileDef() : Object("IfcParameterizedProfileDef") {}
- Lazy< IfcAxis2Placement2D > Position;
- };
-
- // 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 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 IfcPlacement
- struct IfcPlacement : IfcGeometricRepresentationItem, ObjectHelper<IfcPlacement,1> { IfcPlacement() : Object("IfcPlacement") {}
- Lazy< IfcCartesianPoint > Location;
- };
-
- // C++ wrapper for IfcAxis1Placement
- struct IfcAxis1Placement : IfcPlacement, ObjectHelper<IfcAxis1Placement,1> { IfcAxis1Placement() : Object("IfcAxis1Placement") {}
- Maybe< Lazy< IfcDirection > > Axis;
- };
-
- // C++ wrapper for IfcAxis2Placement2D
- struct IfcAxis2Placement2D : IfcPlacement, ObjectHelper<IfcAxis2Placement2D,1> { IfcAxis2Placement2D() : Object("IfcAxis2Placement2D") {}
- Maybe< Lazy< IfcDirection > > RefDirection;
- };
-
- // C++ wrapper for IfcAxis2Placement3D
- struct IfcAxis2Placement3D : IfcPlacement, ObjectHelper<IfcAxis2Placement3D,2> { IfcAxis2Placement3D() : Object("IfcAxis2Placement3D") {}
- Maybe< Lazy< IfcDirection > > Axis;
- Maybe< Lazy< IfcDirection > > RefDirection;
- };
-
- // 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 IfcElement
- struct IfcElement : IfcProduct, ObjectHelper<IfcElement,1> { IfcElement() : Object("IfcElement") {}
- Maybe< IfcIdentifier::Out > Tag;
- };
-
- // C++ wrapper for IfcBuildingElement
- struct IfcBuildingElement : IfcElement, ObjectHelper<IfcBuildingElement,0> { IfcBuildingElement() : Object("IfcBuildingElement") {}
-
- };
-
- // C++ wrapper for IfcBeam
- struct IfcBeam : IfcBuildingElement, ObjectHelper<IfcBeam,0> { IfcBeam() : Object("IfcBeam") {}
-
- };
-
- // C++ wrapper for IfcBuildingElementType
- struct IfcBuildingElementType : IfcElementType, ObjectHelper<IfcBuildingElementType,0> { IfcBuildingElementType() : Object("IfcBuildingElementType") {}
-
- };
-
- // C++ wrapper for IfcBeamType
- struct IfcBeamType : IfcBuildingElementType, ObjectHelper<IfcBeamType,1> { IfcBeamType() : Object("IfcBeamType") {}
- IfcBeamTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcBezierCurve
- struct IfcBezierCurve : IfcBSplineCurve, ObjectHelper<IfcBezierCurve,0> { IfcBezierCurve() : Object("IfcBezierCurve") {}
-
- };
-
- // C++ wrapper for IfcCsgPrimitive3D
- struct IfcCsgPrimitive3D : IfcGeometricRepresentationItem, ObjectHelper<IfcCsgPrimitive3D,1> { IfcCsgPrimitive3D() : Object("IfcCsgPrimitive3D") {}
- Lazy< IfcAxis2Placement3D > Position;
- };
-
- // 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 IfcBoilerType
- struct IfcBoilerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcBoilerType,1> { IfcBoilerType() : Object("IfcBoilerType") {}
- IfcBoilerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcBooleanResult
- struct IfcBooleanResult : IfcGeometricRepresentationItem, ObjectHelper<IfcBooleanResult,3> { IfcBooleanResult() : Object("IfcBooleanResult") {}
- IfcBooleanOperator::Out Operator;
- IfcBooleanOperand::Out FirstOperand;
- IfcBooleanOperand::Out SecondOperand;
- };
-
- // C++ wrapper for IfcBooleanClippingResult
- struct IfcBooleanClippingResult : IfcBooleanResult, ObjectHelper<IfcBooleanClippingResult,0> { IfcBooleanClippingResult() : Object("IfcBooleanClippingResult") {}
-
- };
-
- // C++ wrapper for IfcSurface
- struct IfcSurface : IfcGeometricRepresentationItem, ObjectHelper<IfcSurface,0> { IfcSurface() : Object("IfcSurface") {}
-
- };
-
- // C++ wrapper for IfcBoundedSurface
- struct IfcBoundedSurface : IfcSurface, ObjectHelper<IfcBoundedSurface,0> { IfcBoundedSurface() : Object("IfcBoundedSurface") {}
-
- };
-
- // 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 IfcHalfSpaceSolid
- struct IfcHalfSpaceSolid : IfcGeometricRepresentationItem, ObjectHelper<IfcHalfSpaceSolid,2> { IfcHalfSpaceSolid() : Object("IfcHalfSpaceSolid") {}
- Lazy< IfcSurface > BaseSurface;
- BOOLEAN::Out AgreementFlag;
- };
-
- // C++ wrapper for IfcBoxedHalfSpace
- struct IfcBoxedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcBoxedHalfSpace,1> { IfcBoxedHalfSpace() : Object("IfcBoxedHalfSpace") {}
- Lazy< IfcBoundingBox > Enclosure;
- };
-
- // 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 IfcBuildingElementComponent
- struct IfcBuildingElementComponent : IfcBuildingElement, ObjectHelper<IfcBuildingElementComponent,0> { IfcBuildingElementComponent() : Object("IfcBuildingElementComponent") {}
-
- };
-
- // C++ wrapper for IfcBuildingElementPart
- struct IfcBuildingElementPart : IfcBuildingElementComponent, ObjectHelper<IfcBuildingElementPart,0> { IfcBuildingElementPart() : Object("IfcBuildingElementPart") {}
-
- };
-
- // C++ wrapper for IfcBuildingElementProxy
- struct IfcBuildingElementProxy : IfcBuildingElement, ObjectHelper<IfcBuildingElementProxy,1> { IfcBuildingElementProxy() : Object("IfcBuildingElementProxy") {}
- Maybe< IfcElementCompositionEnum::Out > CompositionType;
- };
-
- // C++ wrapper for IfcBuildingElementProxyType
- struct IfcBuildingElementProxyType : IfcBuildingElementType, ObjectHelper<IfcBuildingElementProxyType,1> { IfcBuildingElementProxyType() : Object("IfcBuildingElementProxyType") {}
- IfcBuildingElementProxyTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcBuildingStorey
- struct IfcBuildingStorey : IfcSpatialStructureElement, ObjectHelper<IfcBuildingStorey,1> { IfcBuildingStorey() : Object("IfcBuildingStorey") {}
- Maybe< IfcLengthMeasure::Out > Elevation;
- };
-
- // 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 IfcFlowFittingType
- struct IfcFlowFittingType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowFittingType,0> { IfcFlowFittingType() : Object("IfcFlowFittingType") {}
-
- };
-
- // C++ wrapper for IfcCableCarrierFittingType
- struct IfcCableCarrierFittingType : IfcFlowFittingType, ObjectHelper<IfcCableCarrierFittingType,1> { IfcCableCarrierFittingType() : Object("IfcCableCarrierFittingType") {}
- IfcCableCarrierFittingTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowSegmentType
- struct IfcFlowSegmentType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowSegmentType,0> { IfcFlowSegmentType() : Object("IfcFlowSegmentType") {}
-
- };
-
- // C++ wrapper for IfcCableCarrierSegmentType
- struct IfcCableCarrierSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableCarrierSegmentType,1> { IfcCableCarrierSegmentType() : Object("IfcCableCarrierSegmentType") {}
- IfcCableCarrierSegmentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcCableSegmentType
- struct IfcCableSegmentType : IfcFlowSegmentType, ObjectHelper<IfcCableSegmentType,1> { IfcCableSegmentType() : Object("IfcCableSegmentType") {}
- IfcCableSegmentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcPoint
- struct IfcPoint : IfcGeometricRepresentationItem, ObjectHelper<IfcPoint,0> { IfcPoint() : Object("IfcPoint") {}
-
- };
-
- // C++ wrapper for IfcCartesianPoint
- struct IfcCartesianPoint : IfcPoint, ObjectHelper<IfcCartesianPoint,1> { IfcCartesianPoint() : Object("IfcCartesianPoint") {}
- ListOf< IfcLengthMeasure, 1, 3 >::Out Coordinates;
- };
-
- // 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 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 IfcCartesianTransformationOperator3D
- struct IfcCartesianTransformationOperator3D : IfcCartesianTransformationOperator, ObjectHelper<IfcCartesianTransformationOperator3D,1> { IfcCartesianTransformationOperator3D() : Object("IfcCartesianTransformationOperator3D") {}
- Maybe< Lazy< IfcDirection > > Axis3;
- };
-
- // C++ wrapper for IfcCartesianTransformationOperator3DnonUniform
- struct IfcCartesianTransformationOperator3DnonUniform : IfcCartesianTransformationOperator3D, ObjectHelper<IfcCartesianTransformationOperator3DnonUniform,2> { IfcCartesianTransformationOperator3DnonUniform() : Object("IfcCartesianTransformationOperator3DnonUniform") {}
- Maybe< REAL::Out > Scale2;
- Maybe< REAL::Out > Scale3;
- };
-
- // C++ wrapper for IfcCenterLineProfileDef
- struct IfcCenterLineProfileDef : IfcArbitraryOpenProfileDef, ObjectHelper<IfcCenterLineProfileDef,1> { IfcCenterLineProfileDef() : Object("IfcCenterLineProfileDef") {}
- IfcPositiveLengthMeasure::Out Thickness;
- };
-
- // 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 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 IfcChillerType
- struct IfcChillerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcChillerType,1> { IfcChillerType() : Object("IfcChillerType") {}
- IfcChillerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcConic
- struct IfcConic : IfcCurve, ObjectHelper<IfcConic,1> { IfcConic() : Object("IfcConic") {}
- IfcAxis2Placement::Out Position;
- };
-
- // C++ wrapper for IfcCircle
- struct IfcCircle : IfcConic, ObjectHelper<IfcCircle,1> { IfcCircle() : Object("IfcCircle") {}
- IfcPositiveLengthMeasure::Out Radius;
- };
-
- // C++ wrapper for IfcCircleProfileDef
- struct IfcCircleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcCircleProfileDef,1> { IfcCircleProfileDef() : Object("IfcCircleProfileDef") {}
- IfcPositiveLengthMeasure::Out Radius;
- };
-
- // C++ wrapper for IfcCircleHollowProfileDef
- struct IfcCircleHollowProfileDef : IfcCircleProfileDef, ObjectHelper<IfcCircleHollowProfileDef,1> { IfcCircleHollowProfileDef() : Object("IfcCircleHollowProfileDef") {}
- IfcPositiveLengthMeasure::Out WallThickness;
- };
-
- // C++ wrapper for IfcTopologicalRepresentationItem
- struct IfcTopologicalRepresentationItem : IfcRepresentationItem, ObjectHelper<IfcTopologicalRepresentationItem,0> { IfcTopologicalRepresentationItem() : Object("IfcTopologicalRepresentationItem") {}
-
- };
-
- // C++ wrapper for IfcConnectedFaceSet
- struct IfcConnectedFaceSet : IfcTopologicalRepresentationItem, ObjectHelper<IfcConnectedFaceSet,1> { IfcConnectedFaceSet() : Object("IfcConnectedFaceSet") {}
- ListOf< Lazy< IfcFace >, 1, 0 > CfsFaces;
- };
-
- // C++ wrapper for IfcClosedShell
- struct IfcClosedShell : IfcConnectedFaceSet, ObjectHelper<IfcClosedShell,0> { IfcClosedShell() : Object("IfcClosedShell") {}
-
- };
-
- // C++ wrapper for IfcCoilType
- struct IfcCoilType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoilType,1> { IfcCoilType() : Object("IfcCoilType") {}
- IfcCoilTypeEnum::Out PredefinedType;
- };
-
- // 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 IfcColumn
- struct IfcColumn : IfcBuildingElement, ObjectHelper<IfcColumn,0> { IfcColumn() : Object("IfcColumn") {}
-
- };
-
- // C++ wrapper for IfcColumnType
- struct IfcColumnType : IfcBuildingElementType, ObjectHelper<IfcColumnType,1> { IfcColumnType() : Object("IfcColumnType") {}
- IfcColumnTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcProperty
- struct IfcProperty : ObjectHelper<IfcProperty,2> { IfcProperty() : Object("IfcProperty") {}
- IfcIdentifier::Out Name;
- Maybe< IfcText::Out > Description;
- };
-
- // 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 IfcCompositeCurveSegment
- struct IfcCompositeCurveSegment : IfcGeometricRepresentationItem, ObjectHelper<IfcCompositeCurveSegment,3> { IfcCompositeCurveSegment() : Object("IfcCompositeCurveSegment") {}
- IfcTransitionCode::Out Transition;
- BOOLEAN::Out SameSense;
- Lazy< IfcCurve > ParentCurve;
- };
-
- // 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 IfcFlowMovingDeviceType
- struct IfcFlowMovingDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowMovingDeviceType,0> { IfcFlowMovingDeviceType() : Object("IfcFlowMovingDeviceType") {}
-
- };
-
- // C++ wrapper for IfcCompressorType
- struct IfcCompressorType : IfcFlowMovingDeviceType, ObjectHelper<IfcCompressorType,1> { IfcCompressorType() : Object("IfcCompressorType") {}
- IfcCompressorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcCondenserType
- struct IfcCondenserType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCondenserType,1> { IfcCondenserType() : Object("IfcCondenserType") {}
- IfcCondenserTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcCondition
- struct IfcCondition : IfcGroup, ObjectHelper<IfcCondition,0> { IfcCondition() : Object("IfcCondition") {}
-
- };
-
- // C++ wrapper for IfcConditionCriterion
- struct IfcConditionCriterion : IfcControl, ObjectHelper<IfcConditionCriterion,2> { IfcConditionCriterion() : Object("IfcConditionCriterion") {}
- IfcConditionCriterionSelect::Out Criterion;
- IfcDateTimeSelect::Out CriterionDateTime;
- };
-
- // C++ wrapper for IfcResource
- struct IfcResource : IfcObject, ObjectHelper<IfcResource,0> { IfcResource() : Object("IfcResource") {}
-
- };
-
- // 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 IfcConstructionEquipmentResource
- struct IfcConstructionEquipmentResource : IfcConstructionResource, ObjectHelper<IfcConstructionEquipmentResource,0> { IfcConstructionEquipmentResource() : Object("IfcConstructionEquipmentResource") {}
-
- };
-
- // C++ wrapper for IfcConstructionMaterialResource
- struct IfcConstructionMaterialResource : IfcConstructionResource, ObjectHelper<IfcConstructionMaterialResource,2> { IfcConstructionMaterialResource() : Object("IfcConstructionMaterialResource") {}
- Maybe< ListOf< IfcActorSelect, 1, 0 >::Out > Suppliers;
- Maybe< IfcRatioMeasure::Out > UsageRatio;
- };
-
- // C++ wrapper for IfcConstructionProductResource
- struct IfcConstructionProductResource : IfcConstructionResource, ObjectHelper<IfcConstructionProductResource,0> { IfcConstructionProductResource() : Object("IfcConstructionProductResource") {}
-
- };
-
- // C++ wrapper for IfcNamedUnit
- struct IfcNamedUnit : ObjectHelper<IfcNamedUnit,2> { IfcNamedUnit() : Object("IfcNamedUnit") {}
- Lazy< NotImplemented > Dimensions;
- IfcUnitEnum::Out UnitType;
- };
-
- // C++ wrapper for IfcContextDependentUnit
- struct IfcContextDependentUnit : IfcNamedUnit, ObjectHelper<IfcContextDependentUnit,1> { IfcContextDependentUnit() : Object("IfcContextDependentUnit") {}
- IfcLabel::Out Name;
- };
-
- // C++ wrapper for IfcControllerType
- struct IfcControllerType : IfcDistributionControlElementType, ObjectHelper<IfcControllerType,1> { IfcControllerType() : Object("IfcControllerType") {}
- IfcControllerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcConversionBasedUnit
- struct IfcConversionBasedUnit : IfcNamedUnit, ObjectHelper<IfcConversionBasedUnit,2> { IfcConversionBasedUnit() : Object("IfcConversionBasedUnit") {}
- IfcLabel::Out Name;
- Lazy< IfcMeasureWithUnit > ConversionFactor;
- };
-
- // C++ wrapper for IfcCooledBeamType
- struct IfcCooledBeamType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCooledBeamType,1> { IfcCooledBeamType() : Object("IfcCooledBeamType") {}
- IfcCooledBeamTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcCoolingTowerType
- struct IfcCoolingTowerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcCoolingTowerType,1> { IfcCoolingTowerType() : Object("IfcCoolingTowerType") {}
- IfcCoolingTowerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcCostItem
- struct IfcCostItem : IfcControl, ObjectHelper<IfcCostItem,0> { IfcCostItem() : Object("IfcCostItem") {}
-
- };
-
- // 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 IfcCovering
- struct IfcCovering : IfcBuildingElement, ObjectHelper<IfcCovering,1> { IfcCovering() : Object("IfcCovering") {}
- Maybe< IfcCoveringTypeEnum::Out > PredefinedType;
- };
-
- // C++ wrapper for IfcCoveringType
- struct IfcCoveringType : IfcBuildingElementType, ObjectHelper<IfcCoveringType,1> { IfcCoveringType() : Object("IfcCoveringType") {}
- IfcCoveringTypeEnum::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 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 IfcCrewResource
- struct IfcCrewResource : IfcConstructionResource, ObjectHelper<IfcCrewResource,0> { IfcCrewResource() : Object("IfcCrewResource") {}
-
- };
-
- // C++ wrapper for IfcSolidModel
- struct IfcSolidModel : IfcGeometricRepresentationItem, ObjectHelper<IfcSolidModel,0> { IfcSolidModel() : Object("IfcSolidModel") {}
-
- };
-
- // C++ wrapper for IfcCsgSolid
- struct IfcCsgSolid : IfcSolidModel, ObjectHelper<IfcCsgSolid,1> { IfcCsgSolid() : Object("IfcCsgSolid") {}
- IfcCsgSelect::Out TreeRootExpression;
- };
-
- // C++ wrapper for IfcCurtainWall
- struct IfcCurtainWall : IfcBuildingElement, ObjectHelper<IfcCurtainWall,0> { IfcCurtainWall() : Object("IfcCurtainWall") {}
-
- };
-
- // C++ wrapper for IfcCurtainWallType
- struct IfcCurtainWallType : IfcBuildingElementType, ObjectHelper<IfcCurtainWallType,1> { IfcCurtainWallType() : Object("IfcCurtainWallType") {}
- IfcCurtainWallTypeEnum::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 IfcPresentationStyle
- struct IfcPresentationStyle : ObjectHelper<IfcPresentationStyle,1> { IfcPresentationStyle() : Object("IfcPresentationStyle") {}
- Maybe< IfcLabel::Out > Name;
- };
-
- // C++ wrapper for IfcDamperType
- struct IfcDamperType : IfcFlowControllerType, ObjectHelper<IfcDamperType,1> { IfcDamperType() : Object("IfcDamperType") {}
- IfcDamperTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcDefinedSymbol
- struct IfcDefinedSymbol : IfcGeometricRepresentationItem, ObjectHelper<IfcDefinedSymbol,2> { IfcDefinedSymbol() : Object("IfcDefinedSymbol") {}
- IfcDefinedSymbolSelect::Out Definition;
- Lazy< IfcCartesianTransformationOperator2D > Target;
- };
-
- // 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 IfcDiameterDimension
- struct IfcDiameterDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcDiameterDimension,0> { IfcDiameterDimension() : Object("IfcDiameterDimension") {}
-
- };
-
- // C++ wrapper for IfcDimensionCurve
- struct IfcDimensionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcDimensionCurve,0> { IfcDimensionCurve() : Object("IfcDimensionCurve") {}
-
- };
-
- // C++ wrapper for IfcTerminatorSymbol
- struct IfcTerminatorSymbol : IfcAnnotationSymbolOccurrence, ObjectHelper<IfcTerminatorSymbol,1> { IfcTerminatorSymbol() : Object("IfcTerminatorSymbol") {}
- Lazy< IfcAnnotationCurveOccurrence > AnnotatedCurve;
- };
-
- // C++ wrapper for IfcDimensionCurveTerminator
- struct IfcDimensionCurveTerminator : IfcTerminatorSymbol, ObjectHelper<IfcDimensionCurveTerminator,1> { IfcDimensionCurveTerminator() : Object("IfcDimensionCurveTerminator") {}
- IfcDimensionExtentUsage::Out Role;
- };
-
- // C++ wrapper for IfcDirection
- struct IfcDirection : IfcGeometricRepresentationItem, ObjectHelper<IfcDirection,1> { IfcDirection() : Object("IfcDirection") {}
- ListOf< REAL, 2, 3 >::Out DirectionRatios;
- };
-
- // C++ wrapper for IfcElementComponent
- struct IfcElementComponent : IfcElement, ObjectHelper<IfcElementComponent,0> { IfcElementComponent() : Object("IfcElementComponent") {}
-
- };
-
- // C++ wrapper for IfcDiscreteAccessory
- struct IfcDiscreteAccessory : IfcElementComponent, ObjectHelper<IfcDiscreteAccessory,0> { IfcDiscreteAccessory() : Object("IfcDiscreteAccessory") {}
-
- };
-
- // C++ wrapper for IfcElementComponentType
- struct IfcElementComponentType : IfcElementType, ObjectHelper<IfcElementComponentType,0> { IfcElementComponentType() : Object("IfcElementComponentType") {}
-
- };
-
- // C++ wrapper for IfcDiscreteAccessoryType
- struct IfcDiscreteAccessoryType : IfcElementComponentType, ObjectHelper<IfcDiscreteAccessoryType,0> { IfcDiscreteAccessoryType() : Object("IfcDiscreteAccessoryType") {}
-
- };
-
- // C++ wrapper for IfcDistributionElement
- struct IfcDistributionElement : IfcElement, ObjectHelper<IfcDistributionElement,0> { IfcDistributionElement() : Object("IfcDistributionElement") {}
-
- };
-
- // C++ wrapper for IfcDistributionFlowElement
- struct IfcDistributionFlowElement : IfcDistributionElement, ObjectHelper<IfcDistributionFlowElement,0> { IfcDistributionFlowElement() : Object("IfcDistributionFlowElement") {}
-
- };
-
- // C++ wrapper for IfcDistributionChamberElement
- struct IfcDistributionChamberElement : IfcDistributionFlowElement, ObjectHelper<IfcDistributionChamberElement,0> { IfcDistributionChamberElement() : Object("IfcDistributionChamberElement") {}
-
- };
-
- // C++ wrapper for IfcDistributionChamberElementType
- struct IfcDistributionChamberElementType : IfcDistributionFlowElementType, ObjectHelper<IfcDistributionChamberElementType,1> { IfcDistributionChamberElementType() : Object("IfcDistributionChamberElementType") {}
- IfcDistributionChamberElementTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcDistributionControlElement
- struct IfcDistributionControlElement : IfcDistributionElement, ObjectHelper<IfcDistributionControlElement,1> { IfcDistributionControlElement() : Object("IfcDistributionControlElement") {}
- Maybe< IfcIdentifier::Out > ControlElementId;
- };
-
- // C++ wrapper for IfcPort
- struct IfcPort : IfcProduct, ObjectHelper<IfcPort,0> { IfcPort() : Object("IfcPort") {}
-
- };
-
- // C++ wrapper for IfcDistributionPort
- struct IfcDistributionPort : IfcPort, ObjectHelper<IfcDistributionPort,1> { IfcDistributionPort() : Object("IfcDistributionPort") {}
- Maybe< IfcFlowDirectionEnum::Out > FlowDirection;
- };
-
- // C++ wrapper for IfcDoor
- struct IfcDoor : IfcBuildingElement, ObjectHelper<IfcDoor,2> { IfcDoor() : Object("IfcDoor") {}
- Maybe< IfcPositiveLengthMeasure::Out > OverallHeight;
- Maybe< IfcPositiveLengthMeasure::Out > OverallWidth;
- };
-
- // C++ wrapper for IfcPropertyDefinition
- struct IfcPropertyDefinition : IfcRoot, ObjectHelper<IfcPropertyDefinition,0> { IfcPropertyDefinition() : Object("IfcPropertyDefinition") {}
-
- };
-
- // C++ wrapper for IfcPropertySetDefinition
- struct IfcPropertySetDefinition : IfcPropertyDefinition, ObjectHelper<IfcPropertySetDefinition,0> { IfcPropertySetDefinition() : Object("IfcPropertySetDefinition") {}
-
- };
-
- // 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 IfcDuctFittingType
- struct IfcDuctFittingType : IfcFlowFittingType, ObjectHelper<IfcDuctFittingType,1> { IfcDuctFittingType() : Object("IfcDuctFittingType") {}
- IfcDuctFittingTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcDuctSegmentType
- struct IfcDuctSegmentType : IfcFlowSegmentType, ObjectHelper<IfcDuctSegmentType,1> { IfcDuctSegmentType() : Object("IfcDuctSegmentType") {}
- IfcDuctSegmentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowTreatmentDeviceType
- struct IfcFlowTreatmentDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowTreatmentDeviceType,0> { IfcFlowTreatmentDeviceType() : Object("IfcFlowTreatmentDeviceType") {}
-
- };
-
- // C++ wrapper for IfcDuctSilencerType
- struct IfcDuctSilencerType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcDuctSilencerType,1> { IfcDuctSilencerType() : Object("IfcDuctSilencerType") {}
- IfcDuctSilencerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcEdge
- struct IfcEdge : IfcTopologicalRepresentationItem, ObjectHelper<IfcEdge,2> { IfcEdge() : Object("IfcEdge") {}
- Lazy< IfcVertex > EdgeStart;
- Lazy< IfcVertex > EdgeEnd;
- };
-
- // C++ wrapper for IfcEdgeCurve
- struct IfcEdgeCurve : IfcEdge, ObjectHelper<IfcEdgeCurve,2> { IfcEdgeCurve() : Object("IfcEdgeCurve") {}
- Lazy< IfcCurve > EdgeGeometry;
- BOOLEAN::Out SameSense;
- };
-
- // C++ wrapper for IfcLoop
- struct IfcLoop : IfcTopologicalRepresentationItem, ObjectHelper<IfcLoop,0> { IfcLoop() : Object("IfcLoop") {}
-
- };
-
- // C++ wrapper for IfcEdgeLoop
- struct IfcEdgeLoop : IfcLoop, ObjectHelper<IfcEdgeLoop,1> { IfcEdgeLoop() : Object("IfcEdgeLoop") {}
- ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList;
- };
-
- // C++ wrapper for IfcElectricApplianceType
- struct IfcElectricApplianceType : IfcFlowTerminalType, ObjectHelper<IfcElectricApplianceType,1> { IfcElectricApplianceType() : Object("IfcElectricApplianceType") {}
- IfcElectricApplianceTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowController
- struct IfcFlowController : IfcDistributionFlowElement, ObjectHelper<IfcFlowController,0> { IfcFlowController() : Object("IfcFlowController") {}
-
- };
-
- // C++ wrapper for IfcElectricDistributionPoint
- struct IfcElectricDistributionPoint : IfcFlowController, ObjectHelper<IfcElectricDistributionPoint,2> { IfcElectricDistributionPoint() : Object("IfcElectricDistributionPoint") {}
- IfcElectricDistributionPointFunctionEnum::Out DistributionPointFunction;
- Maybe< IfcLabel::Out > UserDefinedFunction;
- };
-
- // C++ wrapper for IfcFlowStorageDeviceType
- struct IfcFlowStorageDeviceType : IfcDistributionFlowElementType, ObjectHelper<IfcFlowStorageDeviceType,0> { IfcFlowStorageDeviceType() : Object("IfcFlowStorageDeviceType") {}
-
- };
-
- // C++ wrapper for IfcElectricFlowStorageDeviceType
- struct IfcElectricFlowStorageDeviceType : IfcFlowStorageDeviceType, ObjectHelper<IfcElectricFlowStorageDeviceType,1> { IfcElectricFlowStorageDeviceType() : Object("IfcElectricFlowStorageDeviceType") {}
- IfcElectricFlowStorageDeviceTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcElectricGeneratorType
- struct IfcElectricGeneratorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricGeneratorType,1> { IfcElectricGeneratorType() : Object("IfcElectricGeneratorType") {}
- IfcElectricGeneratorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcElectricHeaterType
- struct IfcElectricHeaterType : IfcFlowTerminalType, ObjectHelper<IfcElectricHeaterType,1> { IfcElectricHeaterType() : Object("IfcElectricHeaterType") {}
- IfcElectricHeaterTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcElectricMotorType
- struct IfcElectricMotorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcElectricMotorType,1> { IfcElectricMotorType() : Object("IfcElectricMotorType") {}
- IfcElectricMotorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcElectricTimeControlType
- struct IfcElectricTimeControlType : IfcFlowControllerType, ObjectHelper<IfcElectricTimeControlType,1> { IfcElectricTimeControlType() : Object("IfcElectricTimeControlType") {}
- IfcElectricTimeControlTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcSystem
- struct IfcSystem : IfcGroup, ObjectHelper<IfcSystem,0> { IfcSystem() : Object("IfcSystem") {}
-
- };
-
- // C++ wrapper for IfcElectricalCircuit
- struct IfcElectricalCircuit : IfcSystem, ObjectHelper<IfcElectricalCircuit,0> { IfcElectricalCircuit() : Object("IfcElectricalCircuit") {}
-
- };
-
- // C++ wrapper for IfcElectricalElement
- struct IfcElectricalElement : IfcElement, ObjectHelper<IfcElectricalElement,0> { IfcElectricalElement() : Object("IfcElectricalElement") {}
-
- };
-
- // C++ wrapper for IfcElementAssembly
- struct IfcElementAssembly : IfcElement, ObjectHelper<IfcElementAssembly,2> { IfcElementAssembly() : Object("IfcElementAssembly") {}
- Maybe< IfcAssemblyPlaceEnum::Out > AssemblyPlace;
- IfcElementAssemblyTypeEnum::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 IfcElementarySurface
- struct IfcElementarySurface : IfcSurface, ObjectHelper<IfcElementarySurface,1> { IfcElementarySurface() : Object("IfcElementarySurface") {}
- Lazy< IfcAxis2Placement3D > Position;
- };
-
- // C++ wrapper for IfcEllipse
- struct IfcEllipse : IfcConic, ObjectHelper<IfcEllipse,2> { IfcEllipse() : Object("IfcEllipse") {}
- IfcPositiveLengthMeasure::Out SemiAxis1;
- IfcPositiveLengthMeasure::Out SemiAxis2;
- };
-
- // C++ wrapper for IfcEllipseProfileDef
- struct IfcEllipseProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcEllipseProfileDef,2> { IfcEllipseProfileDef() : Object("IfcEllipseProfileDef") {}
- IfcPositiveLengthMeasure::Out SemiAxis1;
- IfcPositiveLengthMeasure::Out SemiAxis2;
- };
-
- // C++ wrapper for IfcEnergyConversionDevice
- struct IfcEnergyConversionDevice : IfcDistributionFlowElement, ObjectHelper<IfcEnergyConversionDevice,0> { IfcEnergyConversionDevice() : Object("IfcEnergyConversionDevice") {}
-
- };
-
- // C++ wrapper for IfcEquipmentElement
- struct IfcEquipmentElement : IfcElement, ObjectHelper<IfcEquipmentElement,0> { IfcEquipmentElement() : Object("IfcEquipmentElement") {}
-
- };
-
- // C++ wrapper for IfcEquipmentStandard
- struct IfcEquipmentStandard : IfcControl, ObjectHelper<IfcEquipmentStandard,0> { IfcEquipmentStandard() : Object("IfcEquipmentStandard") {}
-
- };
-
- // C++ wrapper for IfcEvaporativeCoolerType
- struct IfcEvaporativeCoolerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporativeCoolerType,1> { IfcEvaporativeCoolerType() : Object("IfcEvaporativeCoolerType") {}
- IfcEvaporativeCoolerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcEvaporatorType
- struct IfcEvaporatorType : IfcEnergyConversionDeviceType, ObjectHelper<IfcEvaporatorType,1> { IfcEvaporatorType() : Object("IfcEvaporatorType") {}
- IfcEvaporatorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcSweptAreaSolid
- struct IfcSweptAreaSolid : IfcSolidModel, ObjectHelper<IfcSweptAreaSolid,2> { IfcSweptAreaSolid() : Object("IfcSweptAreaSolid") {}
- Lazy< IfcProfileDef > SweptArea;
- Lazy< IfcAxis2Placement3D > Position;
- };
-
- // C++ wrapper for IfcExtrudedAreaSolid
- struct IfcExtrudedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcExtrudedAreaSolid,2> { IfcExtrudedAreaSolid() : Object("IfcExtrudedAreaSolid") {}
- Lazy< IfcDirection > ExtrudedDirection;
- IfcPositiveLengthMeasure::Out Depth;
- };
-
- // C++ wrapper for IfcFace
- struct IfcFace : IfcTopologicalRepresentationItem, ObjectHelper<IfcFace,1> { IfcFace() : Object("IfcFace") {}
- ListOf< Lazy< IfcFaceBound >, 1, 0 > Bounds;
- };
-
- // C++ wrapper for IfcFaceBasedSurfaceModel
- struct IfcFaceBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcFaceBasedSurfaceModel,1> { IfcFaceBasedSurfaceModel() : Object("IfcFaceBasedSurfaceModel") {}
- ListOf< Lazy< IfcConnectedFaceSet >, 1, 0 > FbsmFaces;
- };
-
- // C++ wrapper for IfcFaceBound
- struct IfcFaceBound : IfcTopologicalRepresentationItem, ObjectHelper<IfcFaceBound,2> { IfcFaceBound() : Object("IfcFaceBound") {}
- Lazy< IfcLoop > Bound;
- BOOLEAN::Out Orientation;
- };
-
- // C++ wrapper for IfcFaceOuterBound
- struct IfcFaceOuterBound : IfcFaceBound, ObjectHelper<IfcFaceOuterBound,0> { IfcFaceOuterBound() : Object("IfcFaceOuterBound") {}
-
- };
-
- // C++ wrapper for IfcFaceSurface
- struct IfcFaceSurface : IfcFace, ObjectHelper<IfcFaceSurface,2> { IfcFaceSurface() : Object("IfcFaceSurface") {}
- Lazy< IfcSurface > FaceSurface;
- BOOLEAN::Out SameSense;
- };
-
- // C++ wrapper for IfcManifoldSolidBrep
- struct IfcManifoldSolidBrep : IfcSolidModel, ObjectHelper<IfcManifoldSolidBrep,1> { IfcManifoldSolidBrep() : Object("IfcManifoldSolidBrep") {}
- Lazy< IfcClosedShell > Outer;
- };
-
- // C++ wrapper for IfcFacetedBrep
- struct IfcFacetedBrep : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrep,0> { IfcFacetedBrep() : Object("IfcFacetedBrep") {}
-
- };
-
- // C++ wrapper for IfcFacetedBrepWithVoids
- struct IfcFacetedBrepWithVoids : IfcManifoldSolidBrep, ObjectHelper<IfcFacetedBrepWithVoids,1> { IfcFacetedBrepWithVoids() : Object("IfcFacetedBrepWithVoids") {}
- ListOf< Lazy< IfcClosedShell >, 1, 0 > Voids;
- };
-
- // C++ wrapper for IfcFanType
- struct IfcFanType : IfcFlowMovingDeviceType, ObjectHelper<IfcFanType,1> { IfcFanType() : Object("IfcFanType") {}
- IfcFanTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFastener
- struct IfcFastener : IfcElementComponent, ObjectHelper<IfcFastener,0> { IfcFastener() : Object("IfcFastener") {}
-
- };
-
- // C++ wrapper for IfcFastenerType
- struct IfcFastenerType : IfcElementComponentType, ObjectHelper<IfcFastenerType,0> { IfcFastenerType() : Object("IfcFastenerType") {}
-
- };
-
- // C++ wrapper for IfcFeatureElementAddition
- struct IfcFeatureElementAddition : IfcFeatureElement, ObjectHelper<IfcFeatureElementAddition,0> { IfcFeatureElementAddition() : Object("IfcFeatureElementAddition") {}
-
- };
-
- // 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 IfcFillAreaStyleTileSymbolWithStyle
- struct IfcFillAreaStyleTileSymbolWithStyle : IfcGeometricRepresentationItem, ObjectHelper<IfcFillAreaStyleTileSymbolWithStyle,1> { IfcFillAreaStyleTileSymbolWithStyle() : Object("IfcFillAreaStyleTileSymbolWithStyle") {}
- Lazy< IfcAnnotationSymbolOccurrence > Symbol;
- };
-
- // 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 IfcFilterType
- struct IfcFilterType : IfcFlowTreatmentDeviceType, ObjectHelper<IfcFilterType,1> { IfcFilterType() : Object("IfcFilterType") {}
- IfcFilterTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFireSuppressionTerminalType
- struct IfcFireSuppressionTerminalType : IfcFlowTerminalType, ObjectHelper<IfcFireSuppressionTerminalType,1> { IfcFireSuppressionTerminalType() : Object("IfcFireSuppressionTerminalType") {}
- IfcFireSuppressionTerminalTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowFitting
- struct IfcFlowFitting : IfcDistributionFlowElement, ObjectHelper<IfcFlowFitting,0> { IfcFlowFitting() : Object("IfcFlowFitting") {}
-
- };
-
- // C++ wrapper for IfcFlowInstrumentType
- struct IfcFlowInstrumentType : IfcDistributionControlElementType, ObjectHelper<IfcFlowInstrumentType,1> { IfcFlowInstrumentType() : Object("IfcFlowInstrumentType") {}
- IfcFlowInstrumentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowMeterType
- struct IfcFlowMeterType : IfcFlowControllerType, ObjectHelper<IfcFlowMeterType,1> { IfcFlowMeterType() : Object("IfcFlowMeterType") {}
- IfcFlowMeterTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFlowMovingDevice
- struct IfcFlowMovingDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowMovingDevice,0> { IfcFlowMovingDevice() : Object("IfcFlowMovingDevice") {}
-
- };
-
- // C++ wrapper for IfcFlowSegment
- struct IfcFlowSegment : IfcDistributionFlowElement, ObjectHelper<IfcFlowSegment,0> { IfcFlowSegment() : Object("IfcFlowSegment") {}
-
- };
-
- // C++ wrapper for IfcFlowStorageDevice
- struct IfcFlowStorageDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowStorageDevice,0> { IfcFlowStorageDevice() : Object("IfcFlowStorageDevice") {}
-
- };
-
- // C++ wrapper for IfcFlowTerminal
- struct IfcFlowTerminal : IfcDistributionFlowElement, ObjectHelper<IfcFlowTerminal,0> { IfcFlowTerminal() : Object("IfcFlowTerminal") {}
-
- };
-
- // C++ wrapper for IfcFlowTreatmentDevice
- struct IfcFlowTreatmentDevice : IfcDistributionFlowElement, ObjectHelper<IfcFlowTreatmentDevice,0> { IfcFlowTreatmentDevice() : Object("IfcFlowTreatmentDevice") {}
-
- };
-
- // C++ wrapper for IfcFooting
- struct IfcFooting : IfcBuildingElement, ObjectHelper<IfcFooting,1> { IfcFooting() : Object("IfcFooting") {}
- IfcFootingTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcFurnishingElement
- struct IfcFurnishingElement : IfcElement, ObjectHelper<IfcFurnishingElement,0> { IfcFurnishingElement() : Object("IfcFurnishingElement") {}
-
- };
-
- // C++ wrapper for IfcFurnishingElementType
- struct IfcFurnishingElementType : IfcElementType, ObjectHelper<IfcFurnishingElementType,0> { IfcFurnishingElementType() : Object("IfcFurnishingElementType") {}
-
- };
-
- // C++ wrapper for IfcFurnitureStandard
- struct IfcFurnitureStandard : IfcControl, ObjectHelper<IfcFurnitureStandard,0> { IfcFurnitureStandard() : Object("IfcFurnitureStandard") {}
-
- };
-
- // C++ wrapper for IfcFurnitureType
- struct IfcFurnitureType : IfcFurnishingElementType, ObjectHelper<IfcFurnitureType,1> { IfcFurnitureType() : Object("IfcFurnitureType") {}
- IfcAssemblyPlaceEnum::Out AssemblyPlace;
- };
-
- // C++ wrapper for IfcGasTerminalType
- struct IfcGasTerminalType : IfcFlowTerminalType, ObjectHelper<IfcGasTerminalType,1> { IfcGasTerminalType() : Object("IfcGasTerminalType") {}
- IfcGasTerminalTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcGeometricSet
- struct IfcGeometricSet : IfcGeometricRepresentationItem, ObjectHelper<IfcGeometricSet,1> { IfcGeometricSet() : Object("IfcGeometricSet") {}
- ListOf< IfcGeometricSetSelect, 1, 0 >::Out Elements;
- };
-
- // C++ wrapper for IfcGeometricCurveSet
- struct IfcGeometricCurveSet : IfcGeometricSet, ObjectHelper<IfcGeometricCurveSet,0> { IfcGeometricCurveSet() : Object("IfcGeometricCurveSet") {}
-
- };
-
- // C++ wrapper for IfcRepresentationContext
- struct IfcRepresentationContext : ObjectHelper<IfcRepresentationContext,2> { IfcRepresentationContext() : Object("IfcRepresentationContext") {}
- Maybe< IfcLabel::Out > ContextIdentifier;
- Maybe< IfcLabel::Out > ContextType;
- };
-
- // 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 IfcGeometricRepresentationSubContext
- struct IfcGeometricRepresentationSubContext : IfcGeometricRepresentationContext, ObjectHelper<IfcGeometricRepresentationSubContext,4> { IfcGeometricRepresentationSubContext() : Object("IfcGeometricRepresentationSubContext") {}
- Lazy< IfcGeometricRepresentationContext > ParentContext;
- Maybe< IfcPositiveRatioMeasure::Out > TargetScale;
- IfcGeometricProjectionEnum::Out TargetView;
- Maybe< IfcLabel::Out > UserDefinedTargetView;
- };
-
- // 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 IfcObjectPlacement
- struct IfcObjectPlacement : ObjectHelper<IfcObjectPlacement,0> { IfcObjectPlacement() : Object("IfcObjectPlacement") {}
-
- };
-
- // C++ wrapper for IfcGridPlacement
- struct IfcGridPlacement : IfcObjectPlacement, ObjectHelper<IfcGridPlacement,2> { IfcGridPlacement() : Object("IfcGridPlacement") {}
- Lazy< NotImplemented > PlacementLocation;
- Maybe< Lazy< NotImplemented > > PlacementRefDirection;
- };
-
- // C++ wrapper for IfcHeatExchangerType
- struct IfcHeatExchangerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHeatExchangerType,1> { IfcHeatExchangerType() : Object("IfcHeatExchangerType") {}
- IfcHeatExchangerTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcHumidifierType
- struct IfcHumidifierType : IfcEnergyConversionDeviceType, ObjectHelper<IfcHumidifierType,1> { IfcHumidifierType() : Object("IfcHumidifierType") {}
- IfcHumidifierTypeEnum::Out PredefinedType;
- };
-
- // 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 IfcJunctionBoxType
- struct IfcJunctionBoxType : IfcFlowFittingType, ObjectHelper<IfcJunctionBoxType,1> { IfcJunctionBoxType() : Object("IfcJunctionBoxType") {}
- IfcJunctionBoxTypeEnum::Out PredefinedType;
- };
-
- // 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 IfcLaborResource
- struct IfcLaborResource : IfcConstructionResource, ObjectHelper<IfcLaborResource,1> { IfcLaborResource() : Object("IfcLaborResource") {}
- Maybe< IfcText::Out > SkillSet;
- };
-
- // C++ wrapper for IfcLampType
- struct IfcLampType : IfcFlowTerminalType, ObjectHelper<IfcLampType,1> { IfcLampType() : Object("IfcLampType") {}
- IfcLampTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcLightFixtureType
- struct IfcLightFixtureType : IfcFlowTerminalType, ObjectHelper<IfcLightFixtureType,1> { IfcLightFixtureType() : Object("IfcLightFixtureType") {}
- IfcLightFixtureTypeEnum::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 IfcLightSourceAmbient
- struct IfcLightSourceAmbient : IfcLightSource, ObjectHelper<IfcLightSourceAmbient,0> { IfcLightSourceAmbient() : Object("IfcLightSourceAmbient") {}
-
- };
-
- // C++ wrapper for IfcLightSourceDirectional
- struct IfcLightSourceDirectional : IfcLightSource, ObjectHelper<IfcLightSourceDirectional,1> { IfcLightSourceDirectional() : Object("IfcLightSourceDirectional") {}
- Lazy< IfcDirection > Orientation;
- };
-
- // 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 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 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 IfcLine
- struct IfcLine : IfcCurve, ObjectHelper<IfcLine,2> { IfcLine() : Object("IfcLine") {}
- Lazy< IfcCartesianPoint > Pnt;
- Lazy< IfcVector > Dir;
- };
-
- // C++ wrapper for IfcLinearDimension
- struct IfcLinearDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcLinearDimension,0> { IfcLinearDimension() : Object("IfcLinearDimension") {}
-
- };
-
- // C++ wrapper for IfcLocalPlacement
- struct IfcLocalPlacement : IfcObjectPlacement, ObjectHelper<IfcLocalPlacement,2> { IfcLocalPlacement() : Object("IfcLocalPlacement") {}
- Maybe< Lazy< IfcObjectPlacement > > PlacementRelTo;
- IfcAxis2Placement::Out RelativePlacement;
- };
-
- // C++ wrapper for IfcMappedItem
- struct IfcMappedItem : IfcRepresentationItem, ObjectHelper<IfcMappedItem,2> { IfcMappedItem() : Object("IfcMappedItem") {}
- Lazy< IfcRepresentationMap > MappingSource;
- Lazy< IfcCartesianTransformationOperator > MappingTarget;
- };
-
- // 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 IfcMaterialDefinitionRepresentation
- struct IfcMaterialDefinitionRepresentation : IfcProductRepresentation, ObjectHelper<IfcMaterialDefinitionRepresentation,1> { IfcMaterialDefinitionRepresentation() : Object("IfcMaterialDefinitionRepresentation") {}
- Lazy< NotImplemented > RepresentedMaterial;
- };
-
- // C++ wrapper for IfcMeasureWithUnit
- struct IfcMeasureWithUnit : ObjectHelper<IfcMeasureWithUnit,2> { IfcMeasureWithUnit() : Object("IfcMeasureWithUnit") {}
- IfcValue::Out ValueComponent;
- IfcUnit::Out UnitComponent;
- };
-
- // C++ wrapper for IfcMechanicalFastener
- struct IfcMechanicalFastener : IfcFastener, ObjectHelper<IfcMechanicalFastener,2> { IfcMechanicalFastener() : Object("IfcMechanicalFastener") {}
- Maybe< IfcPositiveLengthMeasure::Out > NominalDiameter;
- Maybe< IfcPositiveLengthMeasure::Out > NominalLength;
- };
-
- // C++ wrapper for IfcMechanicalFastenerType
- struct IfcMechanicalFastenerType : IfcFastenerType, ObjectHelper<IfcMechanicalFastenerType,0> { IfcMechanicalFastenerType() : Object("IfcMechanicalFastenerType") {}
-
- };
-
- // C++ wrapper for IfcMember
- struct IfcMember : IfcBuildingElement, ObjectHelper<IfcMember,0> { IfcMember() : Object("IfcMember") {}
-
- };
-
- // C++ wrapper for IfcMemberType
- struct IfcMemberType : IfcBuildingElementType, ObjectHelper<IfcMemberType,1> { IfcMemberType() : Object("IfcMemberType") {}
- IfcMemberTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcMotorConnectionType
- struct IfcMotorConnectionType : IfcEnergyConversionDeviceType, ObjectHelper<IfcMotorConnectionType,1> { IfcMotorConnectionType() : Object("IfcMotorConnectionType") {}
- IfcMotorConnectionTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcProcess
- struct IfcProcess : IfcObject, ObjectHelper<IfcProcess,0> { IfcProcess() : Object("IfcProcess") {}
-
- };
-
- // 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 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 IfcOccupant
- struct IfcOccupant : IfcActor, ObjectHelper<IfcOccupant,1> { IfcOccupant() : Object("IfcOccupant") {}
- IfcOccupantTypeEnum::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 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 IfcOneDirectionRepeatFactor
- struct IfcOneDirectionRepeatFactor : IfcGeometricRepresentationItem, ObjectHelper<IfcOneDirectionRepeatFactor,1> { IfcOneDirectionRepeatFactor() : Object("IfcOneDirectionRepeatFactor") {}
- Lazy< IfcVector > RepeatFactor;
- };
-
- // C++ wrapper for IfcOpenShell
- struct IfcOpenShell : IfcConnectedFaceSet, ObjectHelper<IfcOpenShell,0> { IfcOpenShell() : Object("IfcOpenShell") {}
-
- };
-
- // C++ wrapper for IfcOpeningElement
- struct IfcOpeningElement : IfcFeatureElementSubtraction, ObjectHelper<IfcOpeningElement,0> { IfcOpeningElement() : Object("IfcOpeningElement") {}
-
- };
-
- // C++ wrapper for IfcOrderAction
- struct IfcOrderAction : IfcTask, ObjectHelper<IfcOrderAction,1> { IfcOrderAction() : Object("IfcOrderAction") {}
- IfcIdentifier::Out ActionID;
- };
-
- // C++ wrapper for IfcOrientedEdge
- struct IfcOrientedEdge : IfcEdge, ObjectHelper<IfcOrientedEdge,2> { IfcOrientedEdge() : Object("IfcOrientedEdge") {}
- Lazy< IfcEdge > EdgeElement;
- BOOLEAN::Out Orientation;
- };
-
- // C++ wrapper for IfcOutletType
- struct IfcOutletType : IfcFlowTerminalType, ObjectHelper<IfcOutletType,1> { IfcOutletType() : Object("IfcOutletType") {}
- IfcOutletTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcPath
- struct IfcPath : IfcTopologicalRepresentationItem, ObjectHelper<IfcPath,1> { IfcPath() : Object("IfcPath") {}
- ListOf< Lazy< IfcOrientedEdge >, 1, 0 > EdgeList;
- };
-
- // C++ wrapper for IfcPerformanceHistory
- struct IfcPerformanceHistory : IfcControl, ObjectHelper<IfcPerformanceHistory,1> { IfcPerformanceHistory() : Object("IfcPerformanceHistory") {}
- IfcLabel::Out LifeCyclePhase;
- };
-
- // C++ wrapper for IfcPermit
- struct IfcPermit : IfcControl, ObjectHelper<IfcPermit,1> { IfcPermit() : Object("IfcPermit") {}
- IfcIdentifier::Out PermitID;
- };
-
- // C++ wrapper for IfcPile
- struct IfcPile : IfcBuildingElement, ObjectHelper<IfcPile,2> { IfcPile() : Object("IfcPile") {}
- IfcPileTypeEnum::Out PredefinedType;
- Maybe< IfcPileConstructionEnum::Out > ConstructionType;
- };
-
- // C++ wrapper for IfcPipeFittingType
- struct IfcPipeFittingType : IfcFlowFittingType, ObjectHelper<IfcPipeFittingType,1> { IfcPipeFittingType() : Object("IfcPipeFittingType") {}
- IfcPipeFittingTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcPipeSegmentType
- struct IfcPipeSegmentType : IfcFlowSegmentType, ObjectHelper<IfcPipeSegmentType,1> { IfcPipeSegmentType() : Object("IfcPipeSegmentType") {}
- IfcPipeSegmentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcPlanarExtent
- struct IfcPlanarExtent : IfcGeometricRepresentationItem, ObjectHelper<IfcPlanarExtent,2> { IfcPlanarExtent() : Object("IfcPlanarExtent") {}
- IfcLengthMeasure::Out SizeInX;
- IfcLengthMeasure::Out SizeInY;
- };
-
- // C++ wrapper for IfcPlanarBox
- struct IfcPlanarBox : IfcPlanarExtent, ObjectHelper<IfcPlanarBox,1> { IfcPlanarBox() : Object("IfcPlanarBox") {}
- IfcAxis2Placement::Out Placement;
- };
-
- // C++ wrapper for IfcPlane
- struct IfcPlane : IfcElementarySurface, ObjectHelper<IfcPlane,0> { IfcPlane() : Object("IfcPlane") {}
-
- };
-
- // C++ wrapper for IfcPlate
- struct IfcPlate : IfcBuildingElement, ObjectHelper<IfcPlate,0> { IfcPlate() : Object("IfcPlate") {}
-
- };
-
- // C++ wrapper for IfcPlateType
- struct IfcPlateType : IfcBuildingElementType, ObjectHelper<IfcPlateType,1> { IfcPlateType() : Object("IfcPlateType") {}
- IfcPlateTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcPointOnCurve
- struct IfcPointOnCurve : IfcPoint, ObjectHelper<IfcPointOnCurve,2> { IfcPointOnCurve() : Object("IfcPointOnCurve") {}
- Lazy< IfcCurve > BasisCurve;
- IfcParameterValue::Out PointParameter;
- };
-
- // 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 IfcPolyLoop
- struct IfcPolyLoop : IfcLoop, ObjectHelper<IfcPolyLoop,1> { IfcPolyLoop() : Object("IfcPolyLoop") {}
- ListOf< Lazy< IfcCartesianPoint >, 3, 0 > Polygon;
- };
-
- // C++ wrapper for IfcPolygonalBoundedHalfSpace
- struct IfcPolygonalBoundedHalfSpace : IfcHalfSpaceSolid, ObjectHelper<IfcPolygonalBoundedHalfSpace,2> { IfcPolygonalBoundedHalfSpace() : Object("IfcPolygonalBoundedHalfSpace") {}
- Lazy< IfcAxis2Placement3D > Position;
- Lazy< IfcBoundedCurve > PolygonalBoundary;
- };
-
- // C++ wrapper for IfcPolyline
- struct IfcPolyline : IfcBoundedCurve, ObjectHelper<IfcPolyline,1> { IfcPolyline() : Object("IfcPolyline") {}
- ListOf< Lazy< IfcCartesianPoint >, 2, 0 > Points;
- };
-
- // C++ wrapper for IfcPresentationStyleAssignment
- struct IfcPresentationStyleAssignment : ObjectHelper<IfcPresentationStyleAssignment,1> { IfcPresentationStyleAssignment() : Object("IfcPresentationStyleAssignment") {}
- ListOf< IfcPresentationStyleSelect, 1, 0 >::Out Styles;
- };
-
- // 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 IfcProductDefinitionShape
- struct IfcProductDefinitionShape : IfcProductRepresentation, ObjectHelper<IfcProductDefinitionShape,0> { IfcProductDefinitionShape() : Object("IfcProductDefinitionShape") {}
-
- };
-
- // 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 IfcProjectOrder
- struct IfcProjectOrder : IfcControl, ObjectHelper<IfcProjectOrder,3> { IfcProjectOrder() : Object("IfcProjectOrder") {}
- IfcIdentifier::Out ID;
- IfcProjectOrderTypeEnum::Out PredefinedType;
- Maybe< IfcLabel::Out > Status;
- };
-
- // 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 IfcProjectionCurve
- struct IfcProjectionCurve : IfcAnnotationCurveOccurrence, ObjectHelper<IfcProjectionCurve,0> { IfcProjectionCurve() : Object("IfcProjectionCurve") {}
-
- };
-
- // C++ wrapper for IfcProjectionElement
- struct IfcProjectionElement : IfcFeatureElementAddition, ObjectHelper<IfcProjectionElement,0> { IfcProjectionElement() : Object("IfcProjectionElement") {}
-
- };
-
- // C++ wrapper for IfcSimpleProperty
- struct IfcSimpleProperty : IfcProperty, ObjectHelper<IfcSimpleProperty,0> { IfcSimpleProperty() : Object("IfcSimpleProperty") {}
-
- };
-
- // 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 IfcPropertyEnumeratedValue
- struct IfcPropertyEnumeratedValue : IfcSimpleProperty, ObjectHelper<IfcPropertyEnumeratedValue,2> { IfcPropertyEnumeratedValue() : Object("IfcPropertyEnumeratedValue") {}
- ListOf< IfcValue, 1, 0 >::Out EnumerationValues;
- Maybe< Lazy< NotImplemented > > EnumerationReference;
- };
-
- // 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 IfcPropertyReferenceValue
- struct IfcPropertyReferenceValue : IfcSimpleProperty, ObjectHelper<IfcPropertyReferenceValue,2> { IfcPropertyReferenceValue() : Object("IfcPropertyReferenceValue") {}
- Maybe< IfcLabel::Out > UsageName;
- IfcObjectReferenceSelect::Out PropertyReference;
- };
-
- // C++ wrapper for IfcPropertySet
- struct IfcPropertySet : IfcPropertySetDefinition, ObjectHelper<IfcPropertySet,1> { IfcPropertySet() : Object("IfcPropertySet") {}
- ListOf< Lazy< IfcProperty >, 1, 0 > HasProperties;
- };
-
- // C++ wrapper for IfcPropertySingleValue
- struct IfcPropertySingleValue : IfcSimpleProperty, ObjectHelper<IfcPropertySingleValue,2> { IfcPropertySingleValue() : Object("IfcPropertySingleValue") {}
- Maybe< IfcValue::Out > NominalValue;
- Maybe< IfcUnit::Out > Unit;
- };
-
- // 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 IfcProtectiveDeviceType
- struct IfcProtectiveDeviceType : IfcFlowControllerType, ObjectHelper<IfcProtectiveDeviceType,1> { IfcProtectiveDeviceType() : Object("IfcProtectiveDeviceType") {}
- IfcProtectiveDeviceTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcProxy
- struct IfcProxy : IfcProduct, ObjectHelper<IfcProxy,2> { IfcProxy() : Object("IfcProxy") {}
- IfcObjectTypeEnum::Out ProxyType;
- Maybe< IfcLabel::Out > Tag;
- };
-
- // C++ wrapper for IfcPumpType
- struct IfcPumpType : IfcFlowMovingDeviceType, ObjectHelper<IfcPumpType,1> { IfcPumpType() : Object("IfcPumpType") {}
- IfcPumpTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcRadiusDimension
- struct IfcRadiusDimension : IfcDimensionCurveDirectedCallout, ObjectHelper<IfcRadiusDimension,0> { IfcRadiusDimension() : Object("IfcRadiusDimension") {}
-
- };
-
- // C++ wrapper for IfcRailing
- struct IfcRailing : IfcBuildingElement, ObjectHelper<IfcRailing,1> { IfcRailing() : Object("IfcRailing") {}
- Maybe< IfcRailingTypeEnum::Out > PredefinedType;
- };
-
- // C++ wrapper for IfcRailingType
- struct IfcRailingType : IfcBuildingElementType, ObjectHelper<IfcRailingType,1> { IfcRailingType() : Object("IfcRailingType") {}
- IfcRailingTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcRamp
- struct IfcRamp : IfcBuildingElement, ObjectHelper<IfcRamp,1> { IfcRamp() : Object("IfcRamp") {}
- IfcRampTypeEnum::Out ShapeType;
- };
-
- // C++ wrapper for IfcRampFlight
- struct IfcRampFlight : IfcBuildingElement, ObjectHelper<IfcRampFlight,0> { IfcRampFlight() : Object("IfcRampFlight") {}
-
- };
-
- // C++ wrapper for IfcRampFlightType
- struct IfcRampFlightType : IfcBuildingElementType, ObjectHelper<IfcRampFlightType,1> { IfcRampFlightType() : Object("IfcRampFlightType") {}
- IfcRampFlightTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcRationalBezierCurve
- struct IfcRationalBezierCurve : IfcBezierCurve, ObjectHelper<IfcRationalBezierCurve,1> { IfcRationalBezierCurve() : Object("IfcRationalBezierCurve") {}
- ListOf< REAL, 2, 0 >::Out WeightsData;
- };
-
- // C++ wrapper for IfcRectangleProfileDef
- struct IfcRectangleProfileDef : IfcParameterizedProfileDef, ObjectHelper<IfcRectangleProfileDef,2> { IfcRectangleProfileDef() : Object("IfcRectangleProfileDef") {}
- IfcPositiveLengthMeasure::Out XDim;
- IfcPositiveLengthMeasure::Out YDim;
- };
-
- // 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 IfcRectangularPyramid
- struct IfcRectangularPyramid : IfcCsgPrimitive3D, ObjectHelper<IfcRectangularPyramid,3> { IfcRectangularPyramid() : Object("IfcRectangularPyramid") {}
- IfcPositiveLengthMeasure::Out XLength;
- IfcPositiveLengthMeasure::Out YLength;
- IfcPositiveLengthMeasure::Out Height;
- };
-
- // 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 IfcReinforcingElement
- struct IfcReinforcingElement : IfcBuildingElementComponent, ObjectHelper<IfcReinforcingElement,1> { IfcReinforcingElement() : Object("IfcReinforcingElement") {}
- Maybe< IfcLabel::Out > SteelGrade;
- };
-
- // 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 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 IfcRelationship
- struct IfcRelationship : IfcRoot, ObjectHelper<IfcRelationship,0> { IfcRelationship() : Object("IfcRelationship") {}
-
- };
-
- // 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 IfcRelAggregates
- struct IfcRelAggregates : IfcRelDecomposes, ObjectHelper<IfcRelAggregates,0> { IfcRelAggregates() : Object("IfcRelAggregates") {}
-
- };
-
- // C++ wrapper for IfcRelConnects
- struct IfcRelConnects : IfcRelationship, ObjectHelper<IfcRelConnects,0> { IfcRelConnects() : Object("IfcRelConnects") {}
-
- };
-
- // 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 IfcRelDefines
- struct IfcRelDefines : IfcRelationship, ObjectHelper<IfcRelDefines,1> { IfcRelDefines() : Object("IfcRelDefines") {}
- ListOf< Lazy< IfcObject >, 1, 0 > RelatedObjects;
- };
-
- // C++ wrapper for IfcRelDefinesByProperties
- struct IfcRelDefinesByProperties : IfcRelDefines, ObjectHelper<IfcRelDefinesByProperties,1> { IfcRelDefinesByProperties() : Object("IfcRelDefinesByProperties") {}
- Lazy< IfcPropertySetDefinition > RelatingPropertyDefinition;
- };
-
- // C++ wrapper for IfcRelFillsElement
- struct IfcRelFillsElement : IfcRelConnects, ObjectHelper<IfcRelFillsElement,2> { IfcRelFillsElement() : Object("IfcRelFillsElement") {}
- Lazy< IfcOpeningElement > RelatingOpeningElement;
- Lazy< IfcElement > RelatedBuildingElement;
- };
-
- // C++ wrapper for IfcRelOverridesProperties
- struct IfcRelOverridesProperties : IfcRelDefinesByProperties, ObjectHelper<IfcRelOverridesProperties,1> { IfcRelOverridesProperties() : Object("IfcRelOverridesProperties") {}
- ListOf< Lazy< IfcProperty >, 1, 0 > OverridingProperties;
- };
-
- // C++ wrapper for IfcRelVoidsElement
- struct IfcRelVoidsElement : IfcRelConnects, ObjectHelper<IfcRelVoidsElement,2> { IfcRelVoidsElement() : Object("IfcRelVoidsElement") {}
- Lazy< IfcElement > RelatingBuildingElement;
- Lazy< IfcFeatureElementSubtraction > RelatedOpeningElement;
- };
-
- // 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 IfcRepresentationMap
- struct IfcRepresentationMap : ObjectHelper<IfcRepresentationMap,2> { IfcRepresentationMap() : Object("IfcRepresentationMap") {}
- IfcAxis2Placement::Out MappingOrigin;
- Lazy< IfcRepresentation > MappedRepresentation;
- };
-
- // C++ wrapper for IfcRevolvedAreaSolid
- struct IfcRevolvedAreaSolid : IfcSweptAreaSolid, ObjectHelper<IfcRevolvedAreaSolid,2> { IfcRevolvedAreaSolid() : Object("IfcRevolvedAreaSolid") {}
- Lazy< IfcAxis1Placement > Axis;
- IfcPlaneAngleMeasure::Out Angle;
- };
-
- // C++ wrapper for IfcRightCircularCone
- struct IfcRightCircularCone : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCone,2> { IfcRightCircularCone() : Object("IfcRightCircularCone") {}
- IfcPositiveLengthMeasure::Out Height;
- IfcPositiveLengthMeasure::Out BottomRadius;
- };
-
- // C++ wrapper for IfcRightCircularCylinder
- struct IfcRightCircularCylinder : IfcCsgPrimitive3D, ObjectHelper<IfcRightCircularCylinder,2> { IfcRightCircularCylinder() : Object("IfcRightCircularCylinder") {}
- IfcPositiveLengthMeasure::Out Height;
- IfcPositiveLengthMeasure::Out Radius;
- };
-
- // C++ wrapper for IfcRoof
- struct IfcRoof : IfcBuildingElement, ObjectHelper<IfcRoof,1> { IfcRoof() : Object("IfcRoof") {}
- IfcRoofTypeEnum::Out ShapeType;
- };
-
- // C++ wrapper for IfcRoundedEdgeFeature
- struct IfcRoundedEdgeFeature : IfcEdgeFeature, ObjectHelper<IfcRoundedEdgeFeature,1> { IfcRoundedEdgeFeature() : Object("IfcRoundedEdgeFeature") {}
- Maybe< IfcPositiveLengthMeasure::Out > Radius;
- };
-
- // C++ wrapper for IfcRoundedRectangleProfileDef
- struct IfcRoundedRectangleProfileDef : IfcRectangleProfileDef, ObjectHelper<IfcRoundedRectangleProfileDef,1> { IfcRoundedRectangleProfileDef() : Object("IfcRoundedRectangleProfileDef") {}
- IfcPositiveLengthMeasure::Out RoundingRadius;
- };
-
- // C++ wrapper for IfcSIUnit
- struct IfcSIUnit : IfcNamedUnit, ObjectHelper<IfcSIUnit,2> { IfcSIUnit() : Object("IfcSIUnit") {}
- Maybe< IfcSIPrefix::Out > Prefix;
- IfcSIUnitName::Out Name;
- };
-
- // C++ wrapper for IfcSanitaryTerminalType
- struct IfcSanitaryTerminalType : IfcFlowTerminalType, ObjectHelper<IfcSanitaryTerminalType,1> { IfcSanitaryTerminalType() : Object("IfcSanitaryTerminalType") {}
- IfcSanitaryTerminalTypeEnum::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 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 IfcSensorType
- struct IfcSensorType : IfcDistributionControlElementType, ObjectHelper<IfcSensorType,1> { IfcSensorType() : Object("IfcSensorType") {}
- IfcSensorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcServiceLife
- struct IfcServiceLife : IfcControl, ObjectHelper<IfcServiceLife,2> { IfcServiceLife() : Object("IfcServiceLife") {}
- IfcServiceLifeTypeEnum::Out ServiceLifeType;
- IfcTimeMeasure::Out ServiceLifeDuration;
- };
-
- // C++ wrapper for IfcShapeModel
- struct IfcShapeModel : IfcRepresentation, ObjectHelper<IfcShapeModel,0> { IfcShapeModel() : Object("IfcShapeModel") {}
-
- };
-
- // C++ wrapper for IfcShapeRepresentation
- struct IfcShapeRepresentation : IfcShapeModel, ObjectHelper<IfcShapeRepresentation,0> { IfcShapeRepresentation() : Object("IfcShapeRepresentation") {}
-
- };
-
- // C++ wrapper for IfcShellBasedSurfaceModel
- struct IfcShellBasedSurfaceModel : IfcGeometricRepresentationItem, ObjectHelper<IfcShellBasedSurfaceModel,1> { IfcShellBasedSurfaceModel() : Object("IfcShellBasedSurfaceModel") {}
- ListOf< IfcShell, 1, 0 >::Out SbsmBoundary;
- };
-
- // 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 IfcSlab
- struct IfcSlab : IfcBuildingElement, ObjectHelper<IfcSlab,1> { IfcSlab() : Object("IfcSlab") {}
- Maybe< IfcSlabTypeEnum::Out > PredefinedType;
- };
-
- // C++ wrapper for IfcSlabType
- struct IfcSlabType : IfcBuildingElementType, ObjectHelper<IfcSlabType,1> { IfcSlabType() : Object("IfcSlabType") {}
- IfcSlabTypeEnum::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 IfcSpaceHeaterType
- struct IfcSpaceHeaterType : IfcEnergyConversionDeviceType, ObjectHelper<IfcSpaceHeaterType,1> { IfcSpaceHeaterType() : Object("IfcSpaceHeaterType") {}
- IfcSpaceHeaterTypeEnum::Out PredefinedType;
- };
-
- // 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 IfcSpatialStructureElementType
- struct IfcSpatialStructureElementType : IfcElementType, ObjectHelper<IfcSpatialStructureElementType,0> { IfcSpatialStructureElementType() : Object("IfcSpatialStructureElementType") {}
-
- };
-
- // C++ wrapper for IfcSpaceType
- struct IfcSpaceType : IfcSpatialStructureElementType, ObjectHelper<IfcSpaceType,1> { IfcSpaceType() : Object("IfcSpaceType") {}
- IfcSpaceTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcSphere
- struct IfcSphere : IfcCsgPrimitive3D, ObjectHelper<IfcSphere,1> { IfcSphere() : Object("IfcSphere") {}
- IfcPositiveLengthMeasure::Out Radius;
- };
-
- // C++ wrapper for IfcStackTerminalType
- struct IfcStackTerminalType : IfcFlowTerminalType, ObjectHelper<IfcStackTerminalType,1> { IfcStackTerminalType() : Object("IfcStackTerminalType") {}
- IfcStackTerminalTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcStair
- struct IfcStair : IfcBuildingElement, ObjectHelper<IfcStair,1> { IfcStair() : Object("IfcStair") {}
- IfcStairTypeEnum::Out ShapeType;
- };
-
- // 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 IfcStairFlightType
- struct IfcStairFlightType : IfcBuildingElementType, ObjectHelper<IfcStairFlightType,1> { IfcStairFlightType() : Object("IfcStairFlightType") {}
- IfcStairFlightTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcStructuralActivity
- struct IfcStructuralActivity : IfcProduct, ObjectHelper<IfcStructuralActivity,2> { IfcStructuralActivity() : Object("IfcStructuralActivity") {}
- Lazy< NotImplemented > AppliedLoad;
- IfcGlobalOrLocalEnum::Out GlobalOrLocal;
- };
-
- // C++ wrapper for IfcStructuralAction
- struct IfcStructuralAction : IfcStructuralActivity, ObjectHelper<IfcStructuralAction,2> { IfcStructuralAction() : Object("IfcStructuralAction") {}
- BOOLEAN::Out DestabilizingLoad;
- Maybe< Lazy< IfcStructuralReaction > > CausedBy;
- };
-
- // 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 IfcStructuralItem
- struct IfcStructuralItem : IfcProduct, ObjectHelper<IfcStructuralItem,0> { IfcStructuralItem() : Object("IfcStructuralItem") {}
-
- };
-
- // C++ wrapper for IfcStructuralConnection
- struct IfcStructuralConnection : IfcStructuralItem, ObjectHelper<IfcStructuralConnection,1> { IfcStructuralConnection() : Object("IfcStructuralConnection") {}
- Maybe< Lazy< NotImplemented > > AppliedCondition;
- };
-
- // C++ wrapper for IfcStructuralCurveConnection
- struct IfcStructuralCurveConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralCurveConnection,0> { IfcStructuralCurveConnection() : Object("IfcStructuralCurveConnection") {}
-
- };
-
- // C++ wrapper for IfcStructuralMember
- struct IfcStructuralMember : IfcStructuralItem, ObjectHelper<IfcStructuralMember,0> { IfcStructuralMember() : Object("IfcStructuralMember") {}
-
- };
-
- // C++ wrapper for IfcStructuralCurveMember
- struct IfcStructuralCurveMember : IfcStructuralMember, ObjectHelper<IfcStructuralCurveMember,1> { IfcStructuralCurveMember() : Object("IfcStructuralCurveMember") {}
- IfcStructuralCurveTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcStructuralCurveMemberVarying
- struct IfcStructuralCurveMemberVarying : IfcStructuralCurveMember, ObjectHelper<IfcStructuralCurveMemberVarying,0> { IfcStructuralCurveMemberVarying() : Object("IfcStructuralCurveMemberVarying") {}
-
- };
-
- // C++ wrapper for IfcStructuralLinearAction
- struct IfcStructuralLinearAction : IfcStructuralAction, ObjectHelper<IfcStructuralLinearAction,1> { IfcStructuralLinearAction() : Object("IfcStructuralLinearAction") {}
- IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue;
- };
-
- // 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 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 IfcStructuralPlanarAction
- struct IfcStructuralPlanarAction : IfcStructuralAction, ObjectHelper<IfcStructuralPlanarAction,1> { IfcStructuralPlanarAction() : Object("IfcStructuralPlanarAction") {}
- IfcProjectedOrTrueLengthEnum::Out ProjectedOrTrue;
- };
-
- // 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 IfcStructuralPointAction
- struct IfcStructuralPointAction : IfcStructuralAction, ObjectHelper<IfcStructuralPointAction,0> { IfcStructuralPointAction() : Object("IfcStructuralPointAction") {}
-
- };
-
- // C++ wrapper for IfcStructuralPointConnection
- struct IfcStructuralPointConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralPointConnection,0> { IfcStructuralPointConnection() : Object("IfcStructuralPointConnection") {}
-
- };
-
- // C++ wrapper for IfcStructuralReaction
- struct IfcStructuralReaction : IfcStructuralActivity, ObjectHelper<IfcStructuralReaction,0> { IfcStructuralReaction() : Object("IfcStructuralReaction") {}
-
- };
-
- // C++ wrapper for IfcStructuralPointReaction
- struct IfcStructuralPointReaction : IfcStructuralReaction, ObjectHelper<IfcStructuralPointReaction,0> { IfcStructuralPointReaction() : Object("IfcStructuralPointReaction") {}
-
- };
-
- // 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 IfcStructuralSurfaceConnection
- struct IfcStructuralSurfaceConnection : IfcStructuralConnection, ObjectHelper<IfcStructuralSurfaceConnection,0> { IfcStructuralSurfaceConnection() : Object("IfcStructuralSurfaceConnection") {}
-
- };
-
- // C++ wrapper for IfcStructuralSurfaceMember
- struct IfcStructuralSurfaceMember : IfcStructuralMember, ObjectHelper<IfcStructuralSurfaceMember,2> { IfcStructuralSurfaceMember() : Object("IfcStructuralSurfaceMember") {}
- IfcStructuralSurfaceTypeEnum::Out PredefinedType;
- Maybe< IfcPositiveLengthMeasure::Out > Thickness;
- };
-
- // 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 IfcStructuredDimensionCallout
- struct IfcStructuredDimensionCallout : IfcDraughtingCallout, ObjectHelper<IfcStructuredDimensionCallout,0> { IfcStructuredDimensionCallout() : Object("IfcStructuredDimensionCallout") {}
-
- };
-
- // C++ wrapper for IfcStyleModel
- struct IfcStyleModel : IfcRepresentation, ObjectHelper<IfcStyleModel,0> { IfcStyleModel() : Object("IfcStyleModel") {}
-
- };
-
- // C++ wrapper for IfcStyledRepresentation
- struct IfcStyledRepresentation : IfcStyleModel, ObjectHelper<IfcStyledRepresentation,0> { IfcStyledRepresentation() : Object("IfcStyledRepresentation") {}
-
- };
-
- // C++ wrapper for IfcSubContractResource
- struct IfcSubContractResource : IfcConstructionResource, ObjectHelper<IfcSubContractResource,2> { IfcSubContractResource() : Object("IfcSubContractResource") {}
- Maybe< IfcActorSelect::Out > SubContractor;
- Maybe< IfcText::Out > JobDescription;
- };
-
- // C++ wrapper for IfcSubedge
- struct IfcSubedge : IfcEdge, ObjectHelper<IfcSubedge,1> { IfcSubedge() : Object("IfcSubedge") {}
- Lazy< IfcEdge > ParentEdge;
- };
-
- // 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 IfcSweptSurface
- struct IfcSweptSurface : IfcSurface, ObjectHelper<IfcSweptSurface,2> { IfcSweptSurface() : Object("IfcSweptSurface") {}
- Lazy< IfcProfileDef > SweptCurve;
- 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 IfcSurfaceStyle
- struct IfcSurfaceStyle : IfcPresentationStyle, ObjectHelper<IfcSurfaceStyle,2> { IfcSurfaceStyle() : Object("IfcSurfaceStyle") {}
- IfcSurfaceSide::Out Side;
- ListOf< IfcSurfaceStyleElementSelect, 1, 5 >::Out Styles;
- };
-
- // C++ wrapper for IfcSurfaceStyleShading
- struct IfcSurfaceStyleShading : ObjectHelper<IfcSurfaceStyleShading,1> { IfcSurfaceStyleShading() : Object("IfcSurfaceStyleShading") {}
- Lazy< IfcColourRgb > SurfaceColour;
- };
-
- // 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 IfcSurfaceStyleWithTextures
- struct IfcSurfaceStyleWithTextures : ObjectHelper<IfcSurfaceStyleWithTextures,1> { IfcSurfaceStyleWithTextures() : Object("IfcSurfaceStyleWithTextures") {}
- ListOf< Lazy< NotImplemented >, 1, 0 > Textures;
- };
-
- // 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 IfcSwitchingDeviceType
- struct IfcSwitchingDeviceType : IfcFlowControllerType, ObjectHelper<IfcSwitchingDeviceType,1> { IfcSwitchingDeviceType() : Object("IfcSwitchingDeviceType") {}
- IfcSwitchingDeviceTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcSystemFurnitureElementType
- struct IfcSystemFurnitureElementType : IfcFurnishingElementType, ObjectHelper<IfcSystemFurnitureElementType,0> { IfcSystemFurnitureElementType() : Object("IfcSystemFurnitureElementType") {}
-
- };
-
- // 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 IfcTankType
- struct IfcTankType : IfcFlowStorageDeviceType, ObjectHelper<IfcTankType,1> { IfcTankType() : Object("IfcTankType") {}
- IfcTankTypeEnum::Out PredefinedType;
- };
-
- // 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 IfcTendonAnchor
- struct IfcTendonAnchor : IfcReinforcingElement, ObjectHelper<IfcTendonAnchor,0> { IfcTendonAnchor() : Object("IfcTendonAnchor") {}
-
- };
-
- // 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 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 IfcTopologyRepresentation
- struct IfcTopologyRepresentation : IfcShapeModel, ObjectHelper<IfcTopologyRepresentation,0> { IfcTopologyRepresentation() : Object("IfcTopologyRepresentation") {}
-
- };
-
- // C++ wrapper for IfcTransformerType
- struct IfcTransformerType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTransformerType,1> { IfcTransformerType() : Object("IfcTransformerType") {}
- IfcTransformerTypeEnum::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 IfcTransportElementType
- struct IfcTransportElementType : IfcElementType, ObjectHelper<IfcTransportElementType,1> { IfcTransportElementType() : Object("IfcTransportElementType") {}
- IfcTransportElementTypeEnum::Out PredefinedType;
- };
-
- // 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 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 IfcTubeBundleType
- struct IfcTubeBundleType : IfcEnergyConversionDeviceType, ObjectHelper<IfcTubeBundleType,1> { IfcTubeBundleType() : Object("IfcTubeBundleType") {}
- IfcTubeBundleTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcTwoDirectionRepeatFactor
- struct IfcTwoDirectionRepeatFactor : IfcOneDirectionRepeatFactor, ObjectHelper<IfcTwoDirectionRepeatFactor,1> { IfcTwoDirectionRepeatFactor() : Object("IfcTwoDirectionRepeatFactor") {}
- Lazy< IfcVector > SecondRepeatFactor;
- };
-
- // 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 IfcUnitAssignment
- struct IfcUnitAssignment : ObjectHelper<IfcUnitAssignment,1> { IfcUnitAssignment() : Object("IfcUnitAssignment") {}
- ListOf< IfcUnit, 1, 0 >::Out Units;
- };
-
- // C++ wrapper for IfcUnitaryEquipmentType
- struct IfcUnitaryEquipmentType : IfcEnergyConversionDeviceType, ObjectHelper<IfcUnitaryEquipmentType,1> { IfcUnitaryEquipmentType() : Object("IfcUnitaryEquipmentType") {}
- IfcUnitaryEquipmentTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcValveType
- struct IfcValveType : IfcFlowControllerType, ObjectHelper<IfcValveType,1> { IfcValveType() : Object("IfcValveType") {}
- IfcValveTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcVector
- struct IfcVector : IfcGeometricRepresentationItem, ObjectHelper<IfcVector,2> { IfcVector() : Object("IfcVector") {}
- Lazy< IfcDirection > Orientation;
- IfcLengthMeasure::Out Magnitude;
- };
-
- // C++ wrapper for IfcVertex
- struct IfcVertex : IfcTopologicalRepresentationItem, ObjectHelper<IfcVertex,0> { IfcVertex() : Object("IfcVertex") {}
-
- };
-
- // C++ wrapper for IfcVertexLoop
- struct IfcVertexLoop : IfcLoop, ObjectHelper<IfcVertexLoop,1> { IfcVertexLoop() : Object("IfcVertexLoop") {}
- Lazy< IfcVertex > LoopVertex;
- };
-
- // C++ wrapper for IfcVertexPoint
- struct IfcVertexPoint : IfcVertex, ObjectHelper<IfcVertexPoint,1> { IfcVertexPoint() : Object("IfcVertexPoint") {}
- Lazy< IfcPoint > VertexGeometry;
- };
-
- // C++ wrapper for IfcVibrationIsolatorType
- struct IfcVibrationIsolatorType : IfcDiscreteAccessoryType, ObjectHelper<IfcVibrationIsolatorType,1> { IfcVibrationIsolatorType() : Object("IfcVibrationIsolatorType") {}
- IfcVibrationIsolatorTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcVirtualElement
- struct IfcVirtualElement : IfcElement, ObjectHelper<IfcVirtualElement,0> { IfcVirtualElement() : Object("IfcVirtualElement") {}
-
- };
-
- // C++ wrapper for IfcWall
- struct IfcWall : IfcBuildingElement, ObjectHelper<IfcWall,0> { IfcWall() : Object("IfcWall") {}
-
- };
-
- // C++ wrapper for IfcWallStandardCase
- struct IfcWallStandardCase : IfcWall, ObjectHelper<IfcWallStandardCase,0> { IfcWallStandardCase() : Object("IfcWallStandardCase") {}
-
- };
-
- // C++ wrapper for IfcWallType
- struct IfcWallType : IfcBuildingElementType, ObjectHelper<IfcWallType,1> { IfcWallType() : Object("IfcWallType") {}
- IfcWallTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcWasteTerminalType
- struct IfcWasteTerminalType : IfcFlowTerminalType, ObjectHelper<IfcWasteTerminalType,1> { IfcWasteTerminalType() : Object("IfcWasteTerminalType") {}
- IfcWasteTerminalTypeEnum::Out PredefinedType;
- };
-
- // C++ wrapper for IfcWindow
- struct IfcWindow : IfcBuildingElement, ObjectHelper<IfcWindow,2> { IfcWindow() : Object("IfcWindow") {}
- Maybe< IfcPositiveLengthMeasure::Out > OverallHeight;
- Maybe< IfcPositiveLengthMeasure::Out > OverallWidth;
- };
-
- // 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 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 IfcWorkPlan
- struct IfcWorkPlan : IfcWorkControl, ObjectHelper<IfcWorkPlan,0> { IfcWorkPlan() : Object("IfcWorkPlan") {}
-
- };
-
- // C++ wrapper for IfcWorkSchedule
- struct IfcWorkSchedule : IfcWorkControl, ObjectHelper<IfcWorkSchedule,0> { IfcWorkSchedule() : Object("IfcWorkSchedule") {}
-
- };
-
- // 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 IfcZone
- struct IfcZone : IfcGroup, ObjectHelper<IfcZone,0> { IfcZone() : Object("IfcZone") {}
-
- };
-
- void GetSchema(EXPRESS::ConversionSchema& out);
-
-} //! IFC
-namespace STEP {
-
- // ******************************************************************************
- // Converter stubs
- // ******************************************************************************
-
-#define DECL_CONV_STUB(type) template <> size_t GenericFill<IFC::type>(const STEP::DB& db, const EXPRESS::LIST& params, IFC::type* in)
-
- DECL_CONV_STUB(IfcRepresentationItem);
- DECL_CONV_STUB(IfcGeometricRepresentationItem);
- DECL_CONV_STUB(IfcCurve);
- DECL_CONV_STUB(IfcBoundedCurve);
- DECL_CONV_STUB(IfcCompositeCurve);
- DECL_CONV_STUB(Ifc2DCompositeCurve);
- DECL_CONV_STUB(IfcRoot);
- DECL_CONV_STUB(IfcObjectDefinition);
- DECL_CONV_STUB(IfcObject);
- DECL_CONV_STUB(IfcControl);
- DECL_CONV_STUB(IfcActionRequest);
- DECL_CONV_STUB(IfcActor);
- DECL_CONV_STUB(IfcTypeObject);
- DECL_CONV_STUB(IfcTypeProduct);
- DECL_CONV_STUB(IfcElementType);
- DECL_CONV_STUB(IfcDistributionElementType);
- DECL_CONV_STUB(IfcDistributionControlElementType);
- DECL_CONV_STUB(IfcActuatorType);
- DECL_CONV_STUB(IfcDistributionFlowElementType);
- DECL_CONV_STUB(IfcFlowControllerType);
- DECL_CONV_STUB(IfcAirTerminalBoxType);
- DECL_CONV_STUB(IfcFlowTerminalType);
- DECL_CONV_STUB(IfcAirTerminalType);
- DECL_CONV_STUB(IfcEnergyConversionDeviceType);
- DECL_CONV_STUB(IfcAirToAirHeatRecoveryType);
- DECL_CONV_STUB(IfcAlarmType);
- DECL_CONV_STUB(IfcDraughtingCallout);
- DECL_CONV_STUB(IfcDimensionCurveDirectedCallout);
- DECL_CONV_STUB(IfcAngularDimension);
- DECL_CONV_STUB(IfcProduct);
- DECL_CONV_STUB(IfcAnnotation);
- DECL_CONV_STUB(IfcStyledItem);
- DECL_CONV_STUB(IfcAnnotationOccurrence);
- DECL_CONV_STUB(IfcAnnotationCurveOccurrence);
- DECL_CONV_STUB(IfcAnnotationFillArea);
- DECL_CONV_STUB(IfcAnnotationFillAreaOccurrence);
- DECL_CONV_STUB(IfcAnnotationSurface);
- DECL_CONV_STUB(IfcAnnotationSurfaceOccurrence);
- DECL_CONV_STUB(IfcAnnotationSymbolOccurrence);
- DECL_CONV_STUB(IfcAnnotationTextOccurrence);
- DECL_CONV_STUB(IfcProfileDef);
- DECL_CONV_STUB(IfcArbitraryClosedProfileDef);
- DECL_CONV_STUB(IfcArbitraryOpenProfileDef);
- DECL_CONV_STUB(IfcArbitraryProfileDefWithVoids);
- DECL_CONV_STUB(IfcGroup);
- DECL_CONV_STUB(IfcAsset);
- DECL_CONV_STUB(IfcParameterizedProfileDef);
- DECL_CONV_STUB(IfcIShapeProfileDef);
- DECL_CONV_STUB(IfcAsymmetricIShapeProfileDef);
- DECL_CONV_STUB(IfcPlacement);
- DECL_CONV_STUB(IfcAxis1Placement);
- DECL_CONV_STUB(IfcAxis2Placement2D);
- DECL_CONV_STUB(IfcAxis2Placement3D);
- DECL_CONV_STUB(IfcBSplineCurve);
- DECL_CONV_STUB(IfcElement);
- DECL_CONV_STUB(IfcBuildingElement);
- DECL_CONV_STUB(IfcBeam);
- DECL_CONV_STUB(IfcBuildingElementType);
- DECL_CONV_STUB(IfcBeamType);
- DECL_CONV_STUB(IfcBezierCurve);
- DECL_CONV_STUB(IfcCsgPrimitive3D);
- DECL_CONV_STUB(IfcBlock);
- DECL_CONV_STUB(IfcBoilerType);
- DECL_CONV_STUB(IfcBooleanResult);
- DECL_CONV_STUB(IfcBooleanClippingResult);
- DECL_CONV_STUB(IfcSurface);
- DECL_CONV_STUB(IfcBoundedSurface);
- DECL_CONV_STUB(IfcBoundingBox);
- DECL_CONV_STUB(IfcHalfSpaceSolid);
- DECL_CONV_STUB(IfcBoxedHalfSpace);
- DECL_CONV_STUB(IfcSpatialStructureElement);
- DECL_CONV_STUB(IfcBuilding);
- DECL_CONV_STUB(IfcBuildingElementComponent);
- DECL_CONV_STUB(IfcBuildingElementPart);
- DECL_CONV_STUB(IfcBuildingElementProxy);
- DECL_CONV_STUB(IfcBuildingElementProxyType);
- DECL_CONV_STUB(IfcBuildingStorey);
- DECL_CONV_STUB(IfcCShapeProfileDef);
- DECL_CONV_STUB(IfcFlowFittingType);
- DECL_CONV_STUB(IfcCableCarrierFittingType);
- DECL_CONV_STUB(IfcFlowSegmentType);
- DECL_CONV_STUB(IfcCableCarrierSegmentType);
- DECL_CONV_STUB(IfcCableSegmentType);
- DECL_CONV_STUB(IfcPoint);
- DECL_CONV_STUB(IfcCartesianPoint);
- DECL_CONV_STUB(IfcCartesianTransformationOperator);
- DECL_CONV_STUB(IfcCartesianTransformationOperator2D);
- DECL_CONV_STUB(IfcCartesianTransformationOperator2DnonUniform);
- DECL_CONV_STUB(IfcCartesianTransformationOperator3D);
- DECL_CONV_STUB(IfcCartesianTransformationOperator3DnonUniform);
- DECL_CONV_STUB(IfcCenterLineProfileDef);
- DECL_CONV_STUB(IfcFeatureElement);
- DECL_CONV_STUB(IfcFeatureElementSubtraction);
- DECL_CONV_STUB(IfcEdgeFeature);
- DECL_CONV_STUB(IfcChamferEdgeFeature);
- DECL_CONV_STUB(IfcChillerType);
- DECL_CONV_STUB(IfcConic);
- DECL_CONV_STUB(IfcCircle);
- DECL_CONV_STUB(IfcCircleProfileDef);
- DECL_CONV_STUB(IfcCircleHollowProfileDef);
- DECL_CONV_STUB(IfcTopologicalRepresentationItem);
- DECL_CONV_STUB(IfcConnectedFaceSet);
- DECL_CONV_STUB(IfcClosedShell);
- DECL_CONV_STUB(IfcCoilType);
- DECL_CONV_STUB(IfcColourSpecification);
- DECL_CONV_STUB(IfcColourRgb);
- DECL_CONV_STUB(IfcColumn);
- DECL_CONV_STUB(IfcColumnType);
- DECL_CONV_STUB(IfcProperty);
- DECL_CONV_STUB(IfcComplexProperty);
- DECL_CONV_STUB(IfcCompositeCurveSegment);
- DECL_CONV_STUB(IfcCompositeProfileDef);
- DECL_CONV_STUB(IfcFlowMovingDeviceType);
- DECL_CONV_STUB(IfcCompressorType);
- DECL_CONV_STUB(IfcCondenserType);
- DECL_CONV_STUB(IfcCondition);
- DECL_CONV_STUB(IfcConditionCriterion);
- DECL_CONV_STUB(IfcResource);
- DECL_CONV_STUB(IfcConstructionResource);
- DECL_CONV_STUB(IfcConstructionEquipmentResource);
- DECL_CONV_STUB(IfcConstructionMaterialResource);
- DECL_CONV_STUB(IfcConstructionProductResource);
- DECL_CONV_STUB(IfcNamedUnit);
- DECL_CONV_STUB(IfcContextDependentUnit);
- DECL_CONV_STUB(IfcControllerType);
- DECL_CONV_STUB(IfcConversionBasedUnit);
- DECL_CONV_STUB(IfcCooledBeamType);
- DECL_CONV_STUB(IfcCoolingTowerType);
- DECL_CONV_STUB(IfcCostItem);
- DECL_CONV_STUB(IfcCostSchedule);
- DECL_CONV_STUB(IfcCovering);
- DECL_CONV_STUB(IfcCoveringType);
- DECL_CONV_STUB(IfcCraneRailAShapeProfileDef);
- DECL_CONV_STUB(IfcCraneRailFShapeProfileDef);
- DECL_CONV_STUB(IfcCrewResource);
- DECL_CONV_STUB(IfcSolidModel);
- DECL_CONV_STUB(IfcCsgSolid);
- DECL_CONV_STUB(IfcCurtainWall);
- DECL_CONV_STUB(IfcCurtainWallType);
- DECL_CONV_STUB(IfcCurveBoundedPlane);
- DECL_CONV_STUB(IfcPresentationStyle);
- DECL_CONV_STUB(IfcDamperType);
- DECL_CONV_STUB(IfcDefinedSymbol);
- DECL_CONV_STUB(IfcDerivedProfileDef);
- DECL_CONV_STUB(IfcDiameterDimension);
- DECL_CONV_STUB(IfcDimensionCurve);
- DECL_CONV_STUB(IfcTerminatorSymbol);
- DECL_CONV_STUB(IfcDimensionCurveTerminator);
- DECL_CONV_STUB(IfcDirection);
- DECL_CONV_STUB(IfcElementComponent);
- DECL_CONV_STUB(IfcDiscreteAccessory);
- DECL_CONV_STUB(IfcElementComponentType);
- DECL_CONV_STUB(IfcDiscreteAccessoryType);
- DECL_CONV_STUB(IfcDistributionElement);
- DECL_CONV_STUB(IfcDistributionFlowElement);
- DECL_CONV_STUB(IfcDistributionChamberElement);
- DECL_CONV_STUB(IfcDistributionChamberElementType);
- DECL_CONV_STUB(IfcDistributionControlElement);
- DECL_CONV_STUB(IfcPort);
- DECL_CONV_STUB(IfcDistributionPort);
- DECL_CONV_STUB(IfcDoor);
- DECL_CONV_STUB(IfcPropertyDefinition);
- DECL_CONV_STUB(IfcPropertySetDefinition);
- DECL_CONV_STUB(IfcDoorStyle);
- DECL_CONV_STUB(IfcDuctFittingType);
- DECL_CONV_STUB(IfcDuctSegmentType);
- DECL_CONV_STUB(IfcFlowTreatmentDeviceType);
- DECL_CONV_STUB(IfcDuctSilencerType);
- DECL_CONV_STUB(IfcEdge);
- DECL_CONV_STUB(IfcEdgeCurve);
- DECL_CONV_STUB(IfcLoop);
- DECL_CONV_STUB(IfcEdgeLoop);
- DECL_CONV_STUB(IfcElectricApplianceType);
- DECL_CONV_STUB(IfcFlowController);
- DECL_CONV_STUB(IfcElectricDistributionPoint);
- DECL_CONV_STUB(IfcFlowStorageDeviceType);
- DECL_CONV_STUB(IfcElectricFlowStorageDeviceType);
- DECL_CONV_STUB(IfcElectricGeneratorType);
- DECL_CONV_STUB(IfcElectricHeaterType);
- DECL_CONV_STUB(IfcElectricMotorType);
- DECL_CONV_STUB(IfcElectricTimeControlType);
- DECL_CONV_STUB(IfcSystem);
- DECL_CONV_STUB(IfcElectricalCircuit);
- DECL_CONV_STUB(IfcElectricalElement);
- DECL_CONV_STUB(IfcElementAssembly);
- DECL_CONV_STUB(IfcElementQuantity);
- DECL_CONV_STUB(IfcElementarySurface);
- DECL_CONV_STUB(IfcEllipse);
- DECL_CONV_STUB(IfcEllipseProfileDef);
- DECL_CONV_STUB(IfcEnergyConversionDevice);
- DECL_CONV_STUB(IfcEquipmentElement);
- DECL_CONV_STUB(IfcEquipmentStandard);
- DECL_CONV_STUB(IfcEvaporativeCoolerType);
- DECL_CONV_STUB(IfcEvaporatorType);
- DECL_CONV_STUB(IfcSweptAreaSolid);
- DECL_CONV_STUB(IfcExtrudedAreaSolid);
- DECL_CONV_STUB(IfcFace);
- DECL_CONV_STUB(IfcFaceBasedSurfaceModel);
- DECL_CONV_STUB(IfcFaceBound);
- DECL_CONV_STUB(IfcFaceOuterBound);
- DECL_CONV_STUB(IfcFaceSurface);
- DECL_CONV_STUB(IfcManifoldSolidBrep);
- DECL_CONV_STUB(IfcFacetedBrep);
- DECL_CONV_STUB(IfcFacetedBrepWithVoids);
- DECL_CONV_STUB(IfcFanType);
- DECL_CONV_STUB(IfcFastener);
- DECL_CONV_STUB(IfcFastenerType);
- DECL_CONV_STUB(IfcFeatureElementAddition);
- DECL_CONV_STUB(IfcFillAreaStyleHatching);
- DECL_CONV_STUB(IfcFillAreaStyleTileSymbolWithStyle);
- DECL_CONV_STUB(IfcFillAreaStyleTiles);
- DECL_CONV_STUB(IfcFilterType);
- DECL_CONV_STUB(IfcFireSuppressionTerminalType);
- DECL_CONV_STUB(IfcFlowFitting);
- DECL_CONV_STUB(IfcFlowInstrumentType);
- DECL_CONV_STUB(IfcFlowMeterType);
- DECL_CONV_STUB(IfcFlowMovingDevice);
- DECL_CONV_STUB(IfcFlowSegment);
- DECL_CONV_STUB(IfcFlowStorageDevice);
- DECL_CONV_STUB(IfcFlowTerminal);
- DECL_CONV_STUB(IfcFlowTreatmentDevice);
- DECL_CONV_STUB(IfcFooting);
- DECL_CONV_STUB(IfcFurnishingElement);
- DECL_CONV_STUB(IfcFurnishingElementType);
- DECL_CONV_STUB(IfcFurnitureStandard);
- DECL_CONV_STUB(IfcFurnitureType);
- DECL_CONV_STUB(IfcGasTerminalType);
- DECL_CONV_STUB(IfcGeometricSet);
- DECL_CONV_STUB(IfcGeometricCurveSet);
- DECL_CONV_STUB(IfcRepresentationContext);
- DECL_CONV_STUB(IfcGeometricRepresentationContext);
- DECL_CONV_STUB(IfcGeometricRepresentationSubContext);
- DECL_CONV_STUB(IfcGrid);
- DECL_CONV_STUB(IfcObjectPlacement);
- DECL_CONV_STUB(IfcGridPlacement);
- DECL_CONV_STUB(IfcHeatExchangerType);
- DECL_CONV_STUB(IfcHumidifierType);
- DECL_CONV_STUB(IfcInventory);
- DECL_CONV_STUB(IfcJunctionBoxType);
- DECL_CONV_STUB(IfcLShapeProfileDef);
- DECL_CONV_STUB(IfcLaborResource);
- DECL_CONV_STUB(IfcLampType);
- DECL_CONV_STUB(IfcLightFixtureType);
- DECL_CONV_STUB(IfcLightSource);
- DECL_CONV_STUB(IfcLightSourceAmbient);
- DECL_CONV_STUB(IfcLightSourceDirectional);
- DECL_CONV_STUB(IfcLightSourceGoniometric);
- DECL_CONV_STUB(IfcLightSourcePositional);
- DECL_CONV_STUB(IfcLightSourceSpot);
- DECL_CONV_STUB(IfcLine);
- DECL_CONV_STUB(IfcLinearDimension);
- DECL_CONV_STUB(IfcLocalPlacement);
- DECL_CONV_STUB(IfcMappedItem);
- DECL_CONV_STUB(IfcProductRepresentation);
- DECL_CONV_STUB(IfcMaterialDefinitionRepresentation);
- DECL_CONV_STUB(IfcMeasureWithUnit);
- DECL_CONV_STUB(IfcMechanicalFastener);
- DECL_CONV_STUB(IfcMechanicalFastenerType);
- DECL_CONV_STUB(IfcMember);
- DECL_CONV_STUB(IfcMemberType);
- DECL_CONV_STUB(IfcMotorConnectionType);
- DECL_CONV_STUB(IfcProcess);
- DECL_CONV_STUB(IfcTask);
- DECL_CONV_STUB(IfcMove);
- DECL_CONV_STUB(IfcOccupant);
- DECL_CONV_STUB(IfcOffsetCurve2D);
- DECL_CONV_STUB(IfcOffsetCurve3D);
- DECL_CONV_STUB(IfcOneDirectionRepeatFactor);
- DECL_CONV_STUB(IfcOpenShell);
- DECL_CONV_STUB(IfcOpeningElement);
- DECL_CONV_STUB(IfcOrderAction);
- DECL_CONV_STUB(IfcOrientedEdge);
- DECL_CONV_STUB(IfcOutletType);
- DECL_CONV_STUB(IfcPath);
- DECL_CONV_STUB(IfcPerformanceHistory);
- DECL_CONV_STUB(IfcPermit);
- DECL_CONV_STUB(IfcPile);
- DECL_CONV_STUB(IfcPipeFittingType);
- DECL_CONV_STUB(IfcPipeSegmentType);
- DECL_CONV_STUB(IfcPlanarExtent);
- DECL_CONV_STUB(IfcPlanarBox);
- DECL_CONV_STUB(IfcPlane);
- DECL_CONV_STUB(IfcPlate);
- DECL_CONV_STUB(IfcPlateType);
- DECL_CONV_STUB(IfcPointOnCurve);
- DECL_CONV_STUB(IfcPointOnSurface);
- DECL_CONV_STUB(IfcPolyLoop);
- DECL_CONV_STUB(IfcPolygonalBoundedHalfSpace);
- DECL_CONV_STUB(IfcPolyline);
- DECL_CONV_STUB(IfcPresentationStyleAssignment);
- DECL_CONV_STUB(IfcProcedure);
- DECL_CONV_STUB(IfcProductDefinitionShape);
- DECL_CONV_STUB(IfcProject);
- DECL_CONV_STUB(IfcProjectOrder);
- DECL_CONV_STUB(IfcProjectOrderRecord);
- DECL_CONV_STUB(IfcProjectionCurve);
- DECL_CONV_STUB(IfcProjectionElement);
- DECL_CONV_STUB(IfcSimpleProperty);
- DECL_CONV_STUB(IfcPropertyBoundedValue);
- DECL_CONV_STUB(IfcPropertyEnumeratedValue);
- DECL_CONV_STUB(IfcPropertyListValue);
- DECL_CONV_STUB(IfcPropertyReferenceValue);
- DECL_CONV_STUB(IfcPropertySet);
- DECL_CONV_STUB(IfcPropertySingleValue);
- DECL_CONV_STUB(IfcPropertyTableValue);
- DECL_CONV_STUB(IfcProtectiveDeviceType);
- DECL_CONV_STUB(IfcProxy);
- DECL_CONV_STUB(IfcPumpType);
- DECL_CONV_STUB(IfcRadiusDimension);
- DECL_CONV_STUB(IfcRailing);
- DECL_CONV_STUB(IfcRailingType);
- DECL_CONV_STUB(IfcRamp);
- DECL_CONV_STUB(IfcRampFlight);
- DECL_CONV_STUB(IfcRampFlightType);
- DECL_CONV_STUB(IfcRationalBezierCurve);
- DECL_CONV_STUB(IfcRectangleProfileDef);
- DECL_CONV_STUB(IfcRectangleHollowProfileDef);
- DECL_CONV_STUB(IfcRectangularPyramid);
- DECL_CONV_STUB(IfcRectangularTrimmedSurface);
- DECL_CONV_STUB(IfcReinforcingElement);
- DECL_CONV_STUB(IfcReinforcingBar);
- DECL_CONV_STUB(IfcReinforcingMesh);
- DECL_CONV_STUB(IfcRelationship);
- DECL_CONV_STUB(IfcRelDecomposes);
- DECL_CONV_STUB(IfcRelAggregates);
- DECL_CONV_STUB(IfcRelConnects);
- DECL_CONV_STUB(IfcRelContainedInSpatialStructure);
- DECL_CONV_STUB(IfcRelDefines);
- DECL_CONV_STUB(IfcRelDefinesByProperties);
- DECL_CONV_STUB(IfcRelFillsElement);
- DECL_CONV_STUB(IfcRelOverridesProperties);
- DECL_CONV_STUB(IfcRelVoidsElement);
- DECL_CONV_STUB(IfcRepresentation);
- DECL_CONV_STUB(IfcRepresentationMap);
- DECL_CONV_STUB(IfcRevolvedAreaSolid);
- DECL_CONV_STUB(IfcRightCircularCone);
- DECL_CONV_STUB(IfcRightCircularCylinder);
- DECL_CONV_STUB(IfcRoof);
- DECL_CONV_STUB(IfcRoundedEdgeFeature);
- DECL_CONV_STUB(IfcRoundedRectangleProfileDef);
- DECL_CONV_STUB(IfcSIUnit);
- DECL_CONV_STUB(IfcSanitaryTerminalType);
- DECL_CONV_STUB(IfcScheduleTimeControl);
- DECL_CONV_STUB(IfcSectionedSpine);
- DECL_CONV_STUB(IfcSensorType);
- DECL_CONV_STUB(IfcServiceLife);
- DECL_CONV_STUB(IfcShapeModel);
- DECL_CONV_STUB(IfcShapeRepresentation);
- DECL_CONV_STUB(IfcShellBasedSurfaceModel);
- DECL_CONV_STUB(IfcSite);
- DECL_CONV_STUB(IfcSlab);
- DECL_CONV_STUB(IfcSlabType);
- DECL_CONV_STUB(IfcSpace);
- DECL_CONV_STUB(IfcSpaceHeaterType);
- DECL_CONV_STUB(IfcSpaceProgram);
- DECL_CONV_STUB(IfcSpatialStructureElementType);
- DECL_CONV_STUB(IfcSpaceType);
- DECL_CONV_STUB(IfcSphere);
- DECL_CONV_STUB(IfcStackTerminalType);
- DECL_CONV_STUB(IfcStair);
- DECL_CONV_STUB(IfcStairFlight);
- DECL_CONV_STUB(IfcStairFlightType);
- DECL_CONV_STUB(IfcStructuralActivity);
- DECL_CONV_STUB(IfcStructuralAction);
- DECL_CONV_STUB(IfcStructuralAnalysisModel);
- DECL_CONV_STUB(IfcStructuralItem);
- DECL_CONV_STUB(IfcStructuralConnection);
- DECL_CONV_STUB(IfcStructuralCurveConnection);
- DECL_CONV_STUB(IfcStructuralMember);
- DECL_CONV_STUB(IfcStructuralCurveMember);
- DECL_CONV_STUB(IfcStructuralCurveMemberVarying);
- DECL_CONV_STUB(IfcStructuralLinearAction);
- DECL_CONV_STUB(IfcStructuralLinearActionVarying);
- DECL_CONV_STUB(IfcStructuralLoadGroup);
- DECL_CONV_STUB(IfcStructuralPlanarAction);
- DECL_CONV_STUB(IfcStructuralPlanarActionVarying);
- DECL_CONV_STUB(IfcStructuralPointAction);
- DECL_CONV_STUB(IfcStructuralPointConnection);
- DECL_CONV_STUB(IfcStructuralReaction);
- DECL_CONV_STUB(IfcStructuralPointReaction);
- DECL_CONV_STUB(IfcStructuralResultGroup);
- DECL_CONV_STUB(IfcStructuralSurfaceConnection);
- DECL_CONV_STUB(IfcStructuralSurfaceMember);
- DECL_CONV_STUB(IfcStructuralSurfaceMemberVarying);
- DECL_CONV_STUB(IfcStructuredDimensionCallout);
- DECL_CONV_STUB(IfcStyleModel);
- DECL_CONV_STUB(IfcStyledRepresentation);
- DECL_CONV_STUB(IfcSubContractResource);
- DECL_CONV_STUB(IfcSubedge);
- DECL_CONV_STUB(IfcSurfaceCurveSweptAreaSolid);
- DECL_CONV_STUB(IfcSweptSurface);
- DECL_CONV_STUB(IfcSurfaceOfLinearExtrusion);
- DECL_CONV_STUB(IfcSurfaceOfRevolution);
- DECL_CONV_STUB(IfcSurfaceStyle);
- DECL_CONV_STUB(IfcSurfaceStyleShading);
- DECL_CONV_STUB(IfcSurfaceStyleRendering);
- DECL_CONV_STUB(IfcSurfaceStyleWithTextures);
- DECL_CONV_STUB(IfcSweptDiskSolid);
- DECL_CONV_STUB(IfcSwitchingDeviceType);
- DECL_CONV_STUB(IfcSystemFurnitureElementType);
- DECL_CONV_STUB(IfcTShapeProfileDef);
- DECL_CONV_STUB(IfcTankType);
- DECL_CONV_STUB(IfcTendon);
- DECL_CONV_STUB(IfcTendonAnchor);
- DECL_CONV_STUB(IfcTextLiteral);
- DECL_CONV_STUB(IfcTextLiteralWithExtent);
- DECL_CONV_STUB(IfcTimeSeriesSchedule);
- DECL_CONV_STUB(IfcTopologyRepresentation);
- DECL_CONV_STUB(IfcTransformerType);
- DECL_CONV_STUB(IfcTransportElement);
- DECL_CONV_STUB(IfcTransportElementType);
- DECL_CONV_STUB(IfcTrapeziumProfileDef);
- DECL_CONV_STUB(IfcTrimmedCurve);
- DECL_CONV_STUB(IfcTubeBundleType);
- DECL_CONV_STUB(IfcTwoDirectionRepeatFactor);
- DECL_CONV_STUB(IfcUShapeProfileDef);
- DECL_CONV_STUB(IfcUnitAssignment);
- DECL_CONV_STUB(IfcUnitaryEquipmentType);
- DECL_CONV_STUB(IfcValveType);
- DECL_CONV_STUB(IfcVector);
- DECL_CONV_STUB(IfcVertex);
- DECL_CONV_STUB(IfcVertexLoop);
- DECL_CONV_STUB(IfcVertexPoint);
- DECL_CONV_STUB(IfcVibrationIsolatorType);
- DECL_CONV_STUB(IfcVirtualElement);
- DECL_CONV_STUB(IfcWall);
- DECL_CONV_STUB(IfcWallStandardCase);
- DECL_CONV_STUB(IfcWallType);
- DECL_CONV_STUB(IfcWasteTerminalType);
- DECL_CONV_STUB(IfcWindow);
- DECL_CONV_STUB(IfcWindowStyle);
- DECL_CONV_STUB(IfcWorkControl);
- DECL_CONV_STUB(IfcWorkPlan);
- DECL_CONV_STUB(IfcWorkSchedule);
- DECL_CONV_STUB(IfcZShapeProfileDef);
- DECL_CONV_STUB(IfcZone);
-
-
-#undef DECL_CONV_STUB
-
-} //! STEP
-} //! Assimp
-
-#endif // INCLUDED_IFC_READER_GEN_H
diff --git a/src/3rdparty/assimp/code/IFCReaderGen1.cpp b/src/3rdparty/assimp/code/IFCReaderGen1.cpp
deleted file mode 100644
index bd526d454..000000000
--- a/src/3rdparty/assimp/code/IFCReaderGen1.cpp
+++ /dev/null
@@ -1,3168 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development 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 Development 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.
-
-----------------------------------------------------------------------
-*/
-
-/** MACHINE-GENERATED by scripts/ICFImporter/CppGenerator.py */
-
-//#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-
-#include "IFCReaderGen.h"
-
-namespace Assimp {
-using namespace IFC;
-
-namespace {
-
- typedef EXPRESS::ConversionSchema::SchemaEntry SchemaEntry;
- const SchemaEntry schema_raw[] = {
- SchemaEntry("ifcstairtypeenum",NULL )
-, SchemaEntry("ifcspacetypeenum",NULL )
-, SchemaEntry("ifcwalltypeenum",NULL )
-, SchemaEntry("ifcmonthinyearnumber",NULL )
-, SchemaEntry("ifcheatfluxdensitymeasure",NULL )
-, SchemaEntry("ifckinematicviscositymeasure",NULL )
-, SchemaEntry("ifcsequenceenum",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("ifcsensortypeenum",NULL )
-, SchemaEntry("ifcderivedunitenum",NULL )
-, SchemaEntry("ifcsizeselect",NULL )
-, SchemaEntry("ifctransportelementtypeenum",NULL )
-, SchemaEntry("ifcinventorytypeenum",NULL )
-, SchemaEntry("ifctextdecoration",NULL )
-, SchemaEntry("ifcdirectionsenseenum",NULL )
-, SchemaEntry("ifcductfittingtypeenum",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("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("ifcminuteinhour",NULL )
-, SchemaEntry("ifcinternalorexternalenum",NULL )
-, SchemaEntry("ifcrotationalfrequencymeasure",NULL )
-, SchemaEntry("ifcsanitaryterminaltypeenum",NULL )
-, SchemaEntry("ifcsymbolstyleselect",NULL )
-, SchemaEntry("ifcelementcompositionenum",NULL )
-, SchemaEntry("ifctextpath",NULL )
-, SchemaEntry("ifcpowermeasure",NULL )
-, SchemaEntry("ifcsurfacestyleelementselect",NULL )
-, SchemaEntry("ifcresourceconsumptionenum",NULL )
-, SchemaEntry("ifcelectriccapacitancemeasure",NULL )
-, SchemaEntry("ifclayersetdirectionenum",NULL )
-, SchemaEntry("ifcrailingtypeenum",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("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("ifctimestamp",NULL )
-, SchemaEntry("ifcmaterialselect",NULL )
-, SchemaEntry("ifcgloballyuniqueid",NULL )
-, SchemaEntry("ifcreflectancemethodenum",NULL )
-, SchemaEntry("ifcvaporpermeabilitymeasure",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("ifctorquemeasure",NULL )
-, SchemaEntry("ifctemperaturegradientmeasure",NULL )
-, SchemaEntry("ifcfillstyleselect",NULL )
-, SchemaEntry("ifcelectricchargemeasure",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("ifcmassmeasure",NULL )
-, SchemaEntry("ifcpileconstructionenum",NULL )
-, SchemaEntry("ifcdoorstyleoperationenum",NULL )
-, SchemaEntry("ifcflowdirectionenum",NULL )
-, SchemaEntry("ifcthermalloadsourceenum",NULL )
-, SchemaEntry("ifclengthmeasure",NULL )
-, SchemaEntry("ifcconstraintenum",NULL )
-, SchemaEntry("ifcaxis2placement",NULL )
-, SchemaEntry("ifcloadgrouptypeenum",NULL )
-, SchemaEntry("ifcvalue",NULL )
-, SchemaEntry("ifcreinforcingbarsurfaceenum",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("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("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("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("ifcrotationalmassmeasure",NULL )
-, SchemaEntry("ifcsecondinminute",NULL )
-, SchemaEntry("ifcdayinmonthnumber",NULL )
-, SchemaEntry("ifcdimensioncount",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("ifcwindowstyleconstructionenum",NULL )
-, SchemaEntry("ifcairterminalboxtypeenum",NULL )
-, SchemaEntry("ifcstairflighttypeenum",NULL )
-, SchemaEntry("ifcluminousintensitymeasure",NULL )
-, SchemaEntry("ifcmotorconnectiontypeenum",NULL )
-, SchemaEntry("ifcplaneanglemeasure",NULL )
-, SchemaEntry("ifcactuatortypeenum",NULL )
-, SchemaEntry("ifccolumntypeenum",NULL )
-, SchemaEntry("ifctextfontselect",NULL )
-, SchemaEntry("ifcdoorpanelpositionenum",NULL )
-, SchemaEntry("ifccoiltypeenum",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("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("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("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("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("ifcelementarysurface",&STEP::ObjectHelper<IfcElementarySurface,1>::Construct )
-, SchemaEntry("ifcplane",&STEP::ObjectHelper<IfcPlane,0>::Construct )
-, SchemaEntry("ifcbooleanresult",&STEP::ObjectHelper<IfcBooleanResult,3>::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("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("ifcrelfillselement",&STEP::ObjectHelper<IfcRelFillsElement,2>::Construct )
-, SchemaEntry("ifcprocedure",&STEP::ObjectHelper<IfcProcedure,3>::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("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("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("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("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("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("ifcdraughtingcallout",&STEP::ObjectHelper<IfcDraughtingCallout,1>::Construct )
-, SchemaEntry("ifcdimensioncurvedirectedcallout",&STEP::ObjectHelper<IfcDimensionCurveDirectedCallout,0>::Construct )
-, SchemaEntry("ifclineardimension",&STEP::ObjectHelper<IfcLinearDimension,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("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("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("ifcrightcircularcylinder",&STEP::ObjectHelper<IfcRightCircularCylinder,2>::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("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("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("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("ifcpermeablecoveringproperties",&STEP::ObjectHelper<NotImplemented,0>::Construct )
-, SchemaEntry("ifcflowfitting",&STEP::ObjectHelper<IfcFlowFitting,0>::Construct )
-, SchemaEntry("ifcapproval",&STEP::ObjectHelper<NotImplemented,0>::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("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("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("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("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("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("ifcflowstoragedevicetype",&STEP::ObjectHelper<IfcFlowStorageDeviceType,0>::Construct )
-, SchemaEntry("ifcvirtualgridintersection",&STEP::ObjectHelper<NotImplemented,0>::Construct )
-, SchemaEntry("ifcdiameterdimension",&STEP::ObjectHelper<IfcDiameterDimension,0>::Construct )
-, SchemaEntry("ifcswitchingdevicetype",&STEP::ObjectHelper<IfcSwitchingDeviceType,1>::Construct )
-, SchemaEntry("ifcaddress",&STEP::ObjectHelper<NotImplemented,0>::Construct )
-, SchemaEntry("ifctelecomaddress",&STEP::ObjectHelper<NotImplemented,0>::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("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("ifcfurnishingelement",&STEP::ObjectHelper<IfcFurnishingElement,0>::Construct )
-, SchemaEntry("ifcprotectivedevicetype",&STEP::ObjectHelper<IfcProtectiveDeviceType,1>::Construct )
-, SchemaEntry("ifczshapeprofiledef",&STEP::ObjectHelper<IfcZShapeProfileDef,6>::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("ifcblock",&STEP::ObjectHelper<IfcBlock,3>::Construct )
-, SchemaEntry("ifclightfixturetype",&STEP::ObjectHelper<IfcLightFixtureType,1>::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("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("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("ifcenergyconversiondevice",&STEP::ObjectHelper<IfcEnergyConversionDevice,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("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("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("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("ifcbeamtype",&STEP::ObjectHelper<IfcBeamType,1>::Construct )
-, SchemaEntry("ifcannotationfillarea",&STEP::ObjectHelper<IfcAnnotationFillArea,2>::Construct )
-, SchemaEntry("ifcrelaxation",&STEP::ObjectHelper<NotImplemented,0>::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 )
-
- };
-}
-
-// -----------------------------------------------------------------------------------------------------------
-void IFC::GetSchema(EXPRESS::ConversionSchema& out)
-{
- out = EXPRESS::ConversionSchema(schema_raw);
-}
-
-namespace STEP {
-
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<NotImplemented>(const STEP::DB& /*db*/, const LIST& /*params*/, NotImplemented* /*in*/)
-{
- return 0;
-}
-
-
-
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcRoot>(const DB& db, const LIST& params, IfcRoot* in)
-{
- size_t base = 0;
- if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRoot"); } do { // convert the 'GlobalId' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[0]=true; break; }
- try { GenericConvert( in->GlobalId, arg, db ); break; }
- catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcRoot to be a `IfcGloballyUniqueId`")); }
- } while(0);
- do { // convert the 'OwnerHistory' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[1]=true; break; }
- try { GenericConvert( in->OwnerHistory, arg, db ); break; }
- catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcRoot to be a `IfcOwnerHistory`")); }
- } while(0);
- do { // convert the 'Name' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::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 IfcRoot to be a `IfcLabel`")); }
- } while(0);
- do { // convert the 'Description' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcRoot,4>::aux_is_derived[3]=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 3 to IfcRoot to be a `IfcText`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcObjectDefinition>(const DB& db, const LIST& params, IfcObjectDefinition* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcRoot*>(in));
- if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcObjectDefinition"); } return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcTypeObject>(const DB& db, const LIST& params, IfcTypeObject* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcObjectDefinition*>(in));
-// this data structure is not used yet, so there is no code generated to fill its members
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcTypeProduct>(const DB& db, const LIST& params, IfcTypeProduct* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcTypeObject*>(in));
-// this data structure is not used yet, so there is no code generated to fill its members
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcElementType>(const DB& db, const LIST& params, IfcElementType* 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<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<IfcDistributionFlowElementType>(const DB& db, const LIST& params, IfcDistributionFlowElementType* 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<IfcFlowControllerType>(const DB& db, const LIST& params, IfcFlowControllerType* 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<IfcElectricTimeControlType>(const DB& db, const LIST& params, IfcElectricTimeControlType* 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<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
- std::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
- std::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
- std::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
- std::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<IfcShapeModel>(const DB& db, const LIST& params, IfcShapeModel* 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<IfcTopologyRepresentation>(const DB& db, const LIST& params, IfcTopologyRepresentation* 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<IfcRelationship>(const DB& db, const LIST& params, IfcRelationship* 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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcRelConnects>(const DB& db, const LIST& params, IfcRelConnects* 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<IfcCableCarrierFittingType>(const DB& db, const LIST& params, IfcCableCarrierFittingType* 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<IfcEnergyConversionDeviceType>(const DB& db, const LIST& params, IfcEnergyConversionDeviceType* 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<IfcCoilType>(const DB& db, const LIST& params, IfcCoilType* 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<IfcObject>(const DB& db, const LIST& params, IfcObject* 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
- std::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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcControl>(const DB& db, const LIST& params, IfcControl* 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<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<IfcRepresentationItem>(const DB& /*db*/, const LIST& /*params*/, IfcRepresentationItem* /*in*/)
-{
- size_t base = 0;
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcGeometricRepresentationItem>(const DB& db, const LIST& params, IfcGeometricRepresentationItem* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcTextLiteral>(const DB& db, const LIST& params, IfcTextLiteral* 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<IfcTextLiteralWithExtent>(const DB& db, const LIST& params, IfcTextLiteralWithExtent* 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<IfcProductRepresentation>(const DB& db, const LIST& params, IfcProductRepresentation* in)
-{
- size_t base = 0;
- if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcProductRepresentation"); } do { // convert the 'Name' argument
- std::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
- std::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
- std::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<IfcProduct>(const DB& db, const LIST& params, IfcProduct* 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
- std::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
- std::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<IfcElement>(const DB& db, const LIST& params, IfcElement* 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
- std::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<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<IfcDistributionFlowElement>(const DB& db, const LIST& params, IfcDistributionFlowElement* 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<IfcCurve>(const DB& db, const LIST& params, IfcCurve* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcBoundedCurve>(const DB& db, const LIST& params, IfcBoundedCurve* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcCurve*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-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
- std::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
- std::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() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCartesianTransformationOperator"); } do { // convert the 'Axis1' argument
- std::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
- std::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
- std::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
- std::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<IfcCartesianTransformationOperator3D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3D* 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
- std::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);
- 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
- std::shared_ptr<const DataType> arg = params[base++];
- 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
- std::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<IfcSimpleProperty>(const DB& db, const LIST& params, IfcSimpleProperty* 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<IfcBuildingElementType>(const DB& db, const LIST& params, IfcBuildingElementType* 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<IfcStairFlightType>(const DB& db, const LIST& params, IfcStairFlightType* 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<IfcSurface>(const DB& db, const LIST& params, IfcSurface* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcElementarySurface>(const DB& db, const LIST& params, IfcElementarySurface* 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
- std::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<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<IfcBooleanResult>(const DB& db, const LIST& params, IfcBooleanResult* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
- if (params.GetSize() < 3) { throw STEP::TypeError("expected 3 arguments to IfcBooleanResult"); } do { // convert the 'Operator' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[0]=true; break; }
- try { GenericConvert( in->Operator, arg, db ); break; }
- catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcBooleanResult to be a `IfcBooleanOperator`")); }
- } while(0);
- do { // convert the 'FirstOperand' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[1]=true; break; }
- try { GenericConvert( in->FirstOperand, arg, db ); break; }
- catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
- } while(0);
- do { // convert the 'SecondOperand' argument
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const ISDERIVED*>(&*arg)) { in->ObjectHelper<Assimp::IFC::IfcBooleanResult,3>::aux_is_derived[2]=true; break; }
- try { GenericConvert( in->SecondOperand, arg, db ); break; }
- catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcBooleanResult to be a `IfcBooleanOperand`")); }
- } while(0);
- 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<IfcSolidModel>(const DB& db, const LIST& params, IfcSolidModel* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcManifoldSolidBrep>(const DB& db, const LIST& params, IfcManifoldSolidBrep* 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
- std::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<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<IfcStackTerminalType>(const DB& db, const LIST& params, IfcStackTerminalType* 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<IfcStructuralItem>(const DB& db, const LIST& params, IfcStructuralItem* 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<IfcStructuralConnection>(const DB& db, const LIST& params, IfcStructuralConnection* 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<IfcStructuralCurveConnection>(const DB& db, const LIST& params, IfcStructuralCurveConnection* 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<IfcJunctionBoxType>(const DB& db, const LIST& params, IfcJunctionBoxType* 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<IfcPropertyDefinition>(const DB& db, const LIST& params, IfcPropertyDefinition* in)
-{
- 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<IfcPropertySetDefinition>(const DB& db, const LIST& params, IfcPropertySetDefinition* in)
-{
- 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<IfcProcess>(const DB& db, const LIST& params, IfcProcess* 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<IfcTask>(const DB& db, const LIST& params, IfcTask* 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<IfcRelFillsElement>(const DB& db, const LIST& params, IfcRelFillsElement* 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
- std::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`")); }
- } while(0);
- do { // convert the 'RelatedBuildingElement' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcProcedure>(const DB& db, const LIST& params, IfcProcedure* 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<IfcProxy>(const DB& db, const LIST& params, IfcProxy* 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<IfcResource>(const DB& db, const LIST& params, IfcResource* 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<IfcConstructionResource>(const DB& db, const LIST& params, IfcConstructionResource* 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<IfcSubContractResource>(const DB& db, const LIST& params, IfcSubContractResource* 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<IfcRelContainedInSpatialStructure>(const DB& db, const LIST& params, IfcRelContainedInSpatialStructure* 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
- std::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
- std::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<IfcTopologicalRepresentationItem>(const DB& db, const LIST& params, IfcTopologicalRepresentationItem* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcEdge>(const DB& db, const LIST& params, IfcEdge* 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<IfcEdgeCurve>(const DB& db, const LIST& params, IfcEdgeCurve* 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<IfcPlateType>(const DB& db, const LIST& params, IfcPlateType* 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<IfcObjectPlacement>(const DB& /*db*/, const LIST& /*params*/, IfcObjectPlacement* /*in*/)
-{
- size_t base = 0;
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcGridPlacement>(const DB& db, const LIST& params, IfcGridPlacement* 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
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcFireSuppressionTerminalType>(const DB& db, const LIST& params, IfcFireSuppressionTerminalType* 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<IfcFlowStorageDevice>(const DB& db, const LIST& params, IfcFlowStorageDevice* 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<IfcSweptSurface>(const DB& db, const LIST& params, IfcSweptSurface* 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<IfcSurfaceOfRevolution>(const DB& db, const LIST& params, IfcSurfaceOfRevolution* 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<IfcOrientedEdge>(const DB& db, const LIST& params, IfcOrientedEdge* 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<IfcDirection>(const DB& db, const LIST& params, IfcDirection* 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
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcProfileDef>(const DB& db, const LIST& params, IfcProfileDef* in)
-{
- size_t base = 0;
- if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcProfileDef"); } do { // convert the 'ProfileType' argument
- std::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
- std::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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcParameterizedProfileDef>(const DB& db, const LIST& params, IfcParameterizedProfileDef* 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
- std::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<IfcCShapeProfileDef>(const DB& db, const LIST& params, IfcCShapeProfileDef* 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<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<IfcEdgeFeature>(const DB& db, const LIST& params, IfcEdgeFeature* 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<IfcChamferEdgeFeature>(const DB& db, const LIST& params, IfcChamferEdgeFeature* 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<IfcBuildingElement>(const DB& db, const LIST& params, IfcBuildingElement* 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<IfcPropertyReferenceValue>(const DB& db, const LIST& params, IfcPropertyReferenceValue* 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<IfcElectricMotorType>(const DB& db, const LIST& params, IfcElectricMotorType* 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)
-{
- 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<IfcSpaceType>(const DB& db, const LIST& params, IfcSpaceType* 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<IfcColumnType>(const DB& db, const LIST& params, IfcColumnType* 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<IfcCraneRailAShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailAShapeProfileDef* 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<IfcCondenserType>(const DB& db, const LIST& params, IfcCondenserType* 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<IfcCircleProfileDef>(const DB& db, const LIST& params, IfcCircleProfileDef* 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
- std::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`")); }
- } while(0);
- 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
- std::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);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcPlacement>(const DB& db, const LIST& params, IfcPlacement* 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
- std::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<IfcAxis2Placement3D>(const DB& db, const LIST& params, IfcAxis2Placement3D* 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
- std::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
- std::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<IfcPresentationStyle>(const DB& db, const LIST& params, IfcPresentationStyle* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyle"); } do { // convert the 'Name' argument
- std::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<IfcEquipmentElement>(const DB& db, const LIST& params, IfcEquipmentElement* 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<IfcCompositeCurveSegment>(const DB& db, const LIST& params, IfcCompositeCurveSegment* 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
- std::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
- std::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
- std::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<IfcRectangleProfileDef>(const DB& db, const LIST& params, IfcRectangleProfileDef* 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
- std::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
- std::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<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<IfcDistributionControlElementType>(const DB& db, const LIST& params, IfcDistributionControlElementType* 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<IfcFlowInstrumentType>(const DB& db, const LIST& params, IfcFlowInstrumentType* 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<IfcDraughtingCallout>(const DB& db, const LIST& params, IfcDraughtingCallout* 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<IfcDimensionCurveDirectedCallout>(const DB& db, const LIST& params, IfcDimensionCurveDirectedCallout* 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<IfcLinearDimension>(const DB& db, const LIST& params, IfcLinearDimension* 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<IfcElementAssembly>(const DB& db, const LIST& params, IfcElementAssembly* 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<IfcCsgPrimitive3D>(const DB& db, const LIST& params, 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<IfcRightCircularCone>(const DB& db, const LIST& params, IfcRightCircularCone* 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<IfcProjectOrder>(const DB& db, const LIST& params, IfcProjectOrder* 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<IfcLShapeProfileDef>(const DB& db, const LIST& params, IfcLShapeProfileDef* 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<IfcAngularDimension>(const DB& db, const LIST& params, IfcAngularDimension* 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<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
- std::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`")); }
- } while(0);
- do { // convert the 'RelativePlacement' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcSweptAreaSolid>(const DB& db, const LIST& params, IfcSweptAreaSolid* 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
- std::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
- std::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<IfcRevolvedAreaSolid>(const DB& db, const LIST& params, IfcRevolvedAreaSolid* 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
- std::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
- std::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<IfcStructuralSurfaceConnection>(const DB& db, const LIST& params, IfcStructuralSurfaceConnection* 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<IfcRadiusDimension>(const DB& db, const LIST& params, IfcRadiusDimension* 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<IfcSweptDiskSolid>(const DB& db, const LIST& params, IfcSweptDiskSolid* in)
-{
- 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
- std::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
- std::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
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const UNSET*>(&*arg)) break;
- 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
- std::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
- std::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<IfcHalfSpaceSolid>(const DB& db, const LIST& params, IfcHalfSpaceSolid* 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
- std::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`")); }
- } while(0);
- do { // convert the 'AgreementFlag' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcPolygonalBoundedHalfSpace>(const DB& db, const LIST& params, IfcPolygonalBoundedHalfSpace* 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
- std::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`")); }
- } while(0);
- do { // convert the 'PolygonalBoundary' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcTimeSeriesSchedule>(const DB& db, const LIST& params, IfcTimeSeriesSchedule* 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<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<IfcProject>(const DB& db, const LIST& params, IfcProject* 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
- std::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
- std::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
- std::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
- std::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<IfcEvaporatorType>(const DB& db, const LIST& params, IfcEvaporatorType* 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<IfcLaborResource>(const DB& db, const LIST& params, IfcLaborResource* 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<IfcPropertyBoundedValue>(const DB& db, const LIST& params, IfcPropertyBoundedValue* 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<IfcRampFlightType>(const DB& db, const LIST& params, IfcRampFlightType* 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<IfcMember>(const DB& db, const LIST& params, IfcMember* 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<IfcTubeBundleType>(const DB& db, const LIST& params, IfcTubeBundleType* 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<IfcValveType>(const DB& db, const LIST& params, IfcValveType* 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<IfcTrimmedCurve>(const DB& db, const LIST& params, IfcTrimmedCurve* 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
- std::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
- std::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
- std::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
- std::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
- std::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<IfcRelDefines>(const DB& db, const LIST& params, IfcRelDefines* in)
-{
- 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
- std::shared_ptr<const DataType> arg = params[base++];
- 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<IfcRelDefinesByProperties>(const DB& db, const LIST& params, IfcRelDefinesByProperties* 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
- std::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<IfcOccupant>(const DB& db, const LIST& params, IfcOccupant* 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<IfcHumidifierType>(const DB& db, const LIST& params, IfcHumidifierType* 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<IfcArbitraryOpenProfileDef>(const DB& db, const LIST& params, IfcArbitraryOpenProfileDef* 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
- std::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<IfcOffsetCurve3D>(const DB& db, const LIST& params, IfcOffsetCurve3D* 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<IfcLightSource>(const DB& db, const LIST& params, IfcLightSource* 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<IfcLightSourcePositional>(const DB& db, const LIST& params, IfcLightSourcePositional* 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<IfcCompositeProfileDef>(const DB& db, const LIST& params, IfcCompositeProfileDef* 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<IfcRamp>(const DB& db, const LIST& params, IfcRamp* 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)
-{
- 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<IfcSpaceHeaterType>(const DB& db, const LIST& params, IfcSpaceHeaterType* 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<IfcLampType>(const DB& db, const LIST& params, IfcLampType* 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<IfcBuildingElementComponent>(const DB& db, const LIST& params, IfcBuildingElementComponent* 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<IfcReinforcingElement>(const DB& db, const LIST& params, IfcReinforcingElement* 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<IfcReinforcingBar>(const DB& db, const LIST& params, IfcReinforcingBar* 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<IfcElectricHeaterType>(const DB& db, const LIST& params, IfcElectricHeaterType* 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<IfcTShapeProfileDef>(const DB& db, const LIST& params, IfcTShapeProfileDef* 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<IfcStructuralActivity>(const DB& db, const LIST& params, IfcStructuralActivity* 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<IfcStructuralAction>(const DB& db, const LIST& params, IfcStructuralAction* 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<IfcDuctFittingType>(const DB& db, const LIST& params, IfcDuctFittingType* 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<IfcCartesianTransformationOperator2D>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2D* 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<IfcCartesianTransformationOperator2DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator2DnonUniform* 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<IfcVirtualElement>(const DB& db, const LIST& params, IfcVirtualElement* 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<IfcRightCircularCylinder>(const DB& db, const LIST& params, IfcRightCircularCylinder* 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<IfcOutletType>(const DB& db, const LIST& params, IfcOutletType* 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<IfcRelDecomposes>(const DB& db, const LIST& params, IfcRelDecomposes* 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
- std::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
- std::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);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcCovering>(const DB& db, const LIST& params, IfcCovering* 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<IfcPolyline>(const DB& db, const LIST& params, IfcPolyline* 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
- std::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<IfcPath>(const DB& db, const LIST& params, IfcPath* 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<IfcElementComponent>(const DB& db, const LIST& params, IfcElementComponent* 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<IfcFastener>(const DB& db, const LIST& params, IfcFastener* 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<IfcMappedItem>(const DB& db, const LIST& params, IfcMappedItem* 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
- std::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
- std::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<IfcRectangularPyramid>(const DB& db, const LIST& params, IfcRectangularPyramid* 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<IfcCrewResource>(const DB& db, const LIST& params, IfcCrewResource* 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<IfcNamedUnit>(const DB& db, const LIST& params, IfcNamedUnit* in)
-{
- size_t base = 0;
- if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcNamedUnit"); } do { // convert the 'Dimensions' argument
- std::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
- std::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<IfcContextDependentUnit>(const DB& db, const LIST& params, IfcContextDependentUnit* 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<IfcUnitaryEquipmentType>(const DB& db, const LIST& params, IfcUnitaryEquipmentType* 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<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<IfcStructuralMember>(const DB& db, const LIST& params, IfcStructuralMember* 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<IfcStyleModel>(const DB& db, const LIST& params, IfcStyleModel* 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<IfcStyledRepresentation>(const DB& db, const LIST& params, IfcStyledRepresentation* 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<IfcSpatialStructureElement>(const DB& db, const LIST& params, IfcSpatialStructureElement* 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
- std::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`")); }
- } while(0);
- do { // convert the 'CompositionType' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcBuilding>(const DB& db, const LIST& params, IfcBuilding* 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
- std::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
- std::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`")); }
- } while(0);
- do { // convert the 'BuildingAddress' argument
- std::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<IfcConnectedFaceSet>(const DB& db, const LIST& params, IfcConnectedFaceSet* 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
- std::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<IfcOpenShell>(const DB& db, const LIST& params, IfcOpenShell* 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<IfcFacetedBrep>(const DB& db, const LIST& params, IfcFacetedBrep* 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<IfcConic>(const DB& db, const LIST& params, IfcConic* 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
- std::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<IfcCoveringType>(const DB& db, const LIST& params, IfcCoveringType* 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<IfcRoundedRectangleProfileDef>(const DB& db, const LIST& params, IfcRoundedRectangleProfileDef* 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<IfcAirTerminalType>(const DB& db, const LIST& params, IfcAirTerminalType* 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<IfcFlowMovingDeviceType>(const DB& db, const LIST& params, IfcFlowMovingDeviceType* 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<IfcCompressorType>(const DB& db, const LIST& params, IfcCompressorType* 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<IfcIShapeProfileDef>(const DB& db, const LIST& params, IfcIShapeProfileDef* in)
-{
- 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
- std::shared_ptr<const DataType> arg = params[base++];
- 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 'OverallDepth' argument
- std::shared_ptr<const DataType> arg = params[base++];
- 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
- std::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
- std::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
- std::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<IfcAsymmetricIShapeProfileDef>(const DB& db, const LIST& params, IfcAsymmetricIShapeProfileDef* 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<IfcControllerType>(const DB& db, const LIST& params, IfcControllerType* 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<IfcRailing>(const DB& db, const LIST& params, IfcRailing* 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<IfcGroup>(const DB& db, const LIST& params, IfcGroup* 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<IfcAsset>(const DB& db, const LIST& params, IfcAsset* 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<IfcMaterialDefinitionRepresentation>(const DB& db, const LIST& params, IfcMaterialDefinitionRepresentation* 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<IfcRailingType>(const DB& db, const LIST& params, IfcRailingType* 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<IfcWall>(const DB& db, const LIST& params, IfcWall* 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<IfcStructuralPointConnection>(const DB& db, const LIST& params, IfcStructuralPointConnection* 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<IfcPropertyListValue>(const DB& db, const LIST& params, IfcPropertyListValue* in)
-{
- 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
- std::shared_ptr<const DataType> arg = params[base++];
- 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
- std::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<IfcFurnitureStandard>(const DB& db, const LIST& params, IfcFurnitureStandard* 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<IfcElectricGeneratorType>(const DB& db, const LIST& params, IfcElectricGeneratorType* 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<IfcDoor>(const DB& db, const LIST& params, IfcDoor* 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
- std::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
- std::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);
- 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
- std::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
- std::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`")); }
- } while(0);
- do { // convert the 'Name' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcAnnotationOccurrence>(const DB& db, const LIST& params, IfcAnnotationOccurrence* 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<IfcAnnotationSymbolOccurrence>(const DB& db, const LIST& params, IfcAnnotationSymbolOccurrence* 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<IfcArbitraryClosedProfileDef>(const DB& db, const LIST& params, IfcArbitraryClosedProfileDef* 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
- std::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<IfcArbitraryProfileDefWithVoids>(const DB& db, const LIST& params, IfcArbitraryProfileDefWithVoids* 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<IfcLine>(const DB& db, const LIST& params, IfcLine* 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
- std::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`")); }
- } while(0);
- do { // convert the 'Dir' argument
- std::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`")); }
- } while(0);
- 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
- std::shared_ptr<const DataType> arg = params[base++];
- if (dynamic_cast<const UNSET*>(&*arg)) break;
- 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 'Unit' argument
- std::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 IfcPropertySingleValue to be a `IfcUnit`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcAlarmType>(const DB& db, const LIST& params, IfcAlarmType* 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<IfcEllipseProfileDef>(const DB& db, const LIST& params, IfcEllipseProfileDef* 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<IfcStair>(const DB& db, const LIST& params, IfcStair* 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<IfcSurfaceStyleShading>(const DB& db, const LIST& params, IfcSurfaceStyleShading* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleShading"); } do { // convert the 'SurfaceColour' argument
- std::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<IfcDefinedSymbol>(const DB& db, const LIST& params, IfcDefinedSymbol* 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<IfcElementComponentType>(const DB& db, const LIST& params, IfcElementComponentType* 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<IfcFastenerType>(const DB& db, const LIST& params, IfcFastenerType* 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<IfcMechanicalFastenerType>(const DB& db, const LIST& params, IfcMechanicalFastenerType* 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<IfcFlowFitting>(const DB& db, const LIST& params, IfcFlowFitting* 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<IfcLightSourceDirectional>(const DB& db, const LIST& params, IfcLightSourceDirectional* 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;
-}
-// -----------------------------------------------------------------------------------------------------------
-
-} // ! STEP
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCReaderGen2.cpp b/src/3rdparty/assimp/code/IFCReaderGen2.cpp
deleted file mode 100644
index 52979260c..000000000
--- a/src/3rdparty/assimp/code/IFCReaderGen2.cpp
+++ /dev/null
@@ -1,1917 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development 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 Development 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.
-
-----------------------------------------------------------------------
-*/
-
-//#include "AssimpPCH.h"
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-
-#include "IFCReaderGen.h"
-
-namespace Assimp {
-using namespace IFC;
-
-namespace STEP {
-
-template <> size_t GenericFill<IfcSurfaceStyle>(const DB& db, const LIST& params, IfcSurfaceStyle* 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
- std::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
- std::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);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcAnnotationSurface>(const DB& db, const LIST& params, IfcAnnotationSurface* 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<IfcFlowController>(const DB& db, const LIST& params, IfcFlowController* 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<IfcBuildingStorey>(const DB& db, const LIST& params, IfcBuildingStorey* 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<IfcWorkControl>(const DB& db, const LIST& params, IfcWorkControl* 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<IfcWorkSchedule>(const DB& db, const LIST& params, IfcWorkSchedule* 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<IfcDuctSegmentType>(const DB& db, const LIST& params, IfcDuctSegmentType* 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<IfcFace>(const DB& db, const LIST& params, IfcFace* 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
- std::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<IfcStructuralSurfaceMember>(const DB& db, const LIST& params, IfcStructuralSurfaceMember* 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<IfcStructuralSurfaceMemberVarying>(const DB& db, const LIST& params, IfcStructuralSurfaceMemberVarying* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcStructuralSurfaceMember*>(in));
-// this data structure is not used yet, so there is no code generated to fill its members
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcFaceSurface>(const DB& db, const LIST& params, IfcFaceSurface* 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<IfcCostSchedule>(const DB& db, const LIST& params, IfcCostSchedule* 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<IfcPlanarExtent>(const DB& db, const LIST& params, IfcPlanarExtent* 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<IfcPlanarBox>(const DB& db, const LIST& params, IfcPlanarBox* 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<IfcColourSpecification>(const DB& db, const LIST& params, IfcColourSpecification* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcColourSpecification"); } do { // convert the 'Name' argument
- std::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);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcVector>(const DB& db, const LIST& params, IfcVector* 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
- std::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
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcBeam>(const DB& db, const LIST& params, IfcBeam* 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<IfcColourRgb>(const DB& db, const LIST& params, IfcColourRgb* 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
- std::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
- std::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
- std::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<IfcStructuralPlanarAction>(const DB& db, const LIST& params, IfcStructuralPlanarAction* 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<IfcStructuralPlanarActionVarying>(const DB& db, const LIST& params, IfcStructuralPlanarActionVarying* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcStructuralPlanarAction*>(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)
-{
- 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
- std::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
- std::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`")); }
- } while(0);
- do { // convert the 'RefElevation' argument
- std::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`")); }
- } while(0);
- do { // convert the 'LandTitleNumber' argument
- std::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
- std::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<IfcDiscreteAccessoryType>(const DB& db, const LIST& params, IfcDiscreteAccessoryType* 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<IfcVibrationIsolatorType>(const DB& db, const LIST& params, IfcVibrationIsolatorType* 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<IfcEvaporativeCoolerType>(const DB& db, const LIST& params, IfcEvaporativeCoolerType* 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<IfcDistributionChamberElementType>(const DB& db, const LIST& params, IfcDistributionChamberElementType* 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<IfcFeatureElementAddition>(const DB& db, const LIST& params, IfcFeatureElementAddition* 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<IfcStructuredDimensionCallout>(const DB& db, const LIST& params, IfcStructuredDimensionCallout* 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<IfcCoolingTowerType>(const DB& db, const LIST& params, IfcCoolingTowerType* 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<IfcCenterLineProfileDef>(const DB& db, const LIST& params, IfcCenterLineProfileDef* 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<IfcWindowStyle>(const DB& db, const LIST& params, IfcWindowStyle* 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<IfcLightSourceGoniometric>(const DB& db, const LIST& params, IfcLightSourceGoniometric* 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<IfcTransformerType>(const DB& db, const LIST& params, IfcTransformerType* 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<IfcMemberType>(const DB& db, const LIST& params, IfcMemberType* 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<IfcSurfaceOfLinearExtrusion>(const DB& db, const LIST& params, IfcSurfaceOfLinearExtrusion* 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<IfcMotorConnectionType>(const DB& db, const LIST& params, IfcMotorConnectionType* 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<IfcFlowTreatmentDeviceType>(const DB& db, const LIST& params, IfcFlowTreatmentDeviceType* 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<IfcDuctSilencerType>(const DB& db, const LIST& params, IfcDuctSilencerType* 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<IfcFurnishingElementType>(const DB& db, const LIST& params, IfcFurnishingElementType* 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<IfcSystemFurnitureElementType>(const DB& db, const LIST& params, IfcSystemFurnitureElementType* 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<IfcWasteTerminalType>(const DB& db, const LIST& params, IfcWasteTerminalType* 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<IfcBSplineCurve>(const DB& db, const LIST& params, IfcBSplineCurve* 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
- std::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
- std::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
- std::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
- std::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
- std::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<IfcBezierCurve>(const DB& db, const LIST& params, IfcBezierCurve* in)
-{
- 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<IfcActuatorType>(const DB& db, const LIST& params, IfcActuatorType* 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<IfcDistributionControlElement>(const DB& db, const LIST& params, IfcDistributionControlElement* 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<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
- std::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<IfcExtrudedAreaSolid>(const DB& db, const LIST& params, IfcExtrudedAreaSolid* 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
- std::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
- std::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<IfcFillAreaStyleHatching>(const DB& db, const LIST& params, IfcFillAreaStyleHatching* 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<IfcRelVoidsElement>(const DB& db, const LIST& params, IfcRelVoidsElement* 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
- std::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`")); }
- } while(0);
- do { // convert the 'RelatedOpeningElement' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcSurfaceCurveSweptAreaSolid>(const DB& db, const LIST& params, IfcSurfaceCurveSweptAreaSolid* 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<IfcCartesianTransformationOperator3DnonUniform>(const DB& db, const LIST& params, IfcCartesianTransformationOperator3DnonUniform* 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
- std::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
- std::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<IfcCurtainWallType>(const DB& db, const LIST& params, IfcCurtainWallType* 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<IfcEquipmentStandard>(const DB& db, const LIST& params, IfcEquipmentStandard* 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<IfcFlowStorageDeviceType>(const DB& db, const LIST& params, IfcFlowStorageDeviceType* 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<IfcDiameterDimension>(const DB& db, const LIST& params, IfcDiameterDimension* 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<IfcSwitchingDeviceType>(const DB& db, const LIST& params, IfcSwitchingDeviceType* 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<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<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<IfcChillerType>(const DB& db, const LIST& params, IfcChillerType* 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<IfcRectangleHollowProfileDef>(const DB& db, const LIST& params, IfcRectangleHollowProfileDef* 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<IfcBoxedHalfSpace>(const DB& db, const LIST& params, IfcBoxedHalfSpace* 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<IfcAxis2Placement2D>(const DB& db, const LIST& params, IfcAxis2Placement2D* 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
- std::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);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcSpaceProgram>(const DB& db, const LIST& params, IfcSpaceProgram* 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<IfcPoint>(const DB& db, const LIST& params, IfcPoint* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcGeometricRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcCartesianPoint>(const DB& db, const LIST& params, IfcCartesianPoint* 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
- std::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<IfcBoundedSurface>(const DB& db, const LIST& params, IfcBoundedSurface* 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<IfcLoop>(const DB& db, const LIST& params, IfcLoop* in)
-{
- size_t base = GenericFill(db,params,static_cast<IfcTopologicalRepresentationItem*>(in));
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcPolyLoop>(const DB& db, const LIST& params, IfcPolyLoop* 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
- std::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<IfcTerminatorSymbol>(const DB& db, const LIST& params, IfcTerminatorSymbol* 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<IfcDimensionCurveTerminator>(const DB& db, const LIST& params, IfcDimensionCurveTerminator* 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<IfcTrapeziumProfileDef>(const DB& db, const LIST& params, IfcTrapeziumProfileDef* 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<IfcRepresentationContext>(const DB& db, const LIST& params, IfcRepresentationContext* in)
-{
- size_t base = 0;
- if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationContext"); } do { // convert the 'ContextIdentifier' argument
- std::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
- std::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
- std::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
- std::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
- std::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
- std::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<IfcSIUnit>(const DB& db, const LIST& params, IfcSIUnit* 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
- std::shared_ptr<const DataType> arg = params[base++];
- 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 'Name' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcStructuralReaction>(const DB& db, const LIST& params, IfcStructuralReaction* 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<IfcStructuralPointReaction>(const DB& db, const LIST& params, IfcStructuralPointReaction* 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<IfcAxis1Placement>(const DB& db, const LIST& params, IfcAxis1Placement* 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
- std::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<IfcSensorType>(const DB& db, const LIST& params, IfcSensorType* 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<IfcFurnishingElement>(const DB& db, const LIST& params, IfcFurnishingElement* 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<IfcProtectiveDeviceType>(const DB& db, const LIST& params, IfcProtectiveDeviceType* 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<IfcZShapeProfileDef>(const DB& db, const LIST& params, IfcZShapeProfileDef* 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<IfcScheduleTimeControl>(const DB& db, const LIST& params, IfcScheduleTimeControl* 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<IfcRepresentationMap>(const DB& db, const LIST& params, IfcRepresentationMap* in)
-{
- size_t base = 0;
- if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcRepresentationMap"); } do { // convert the 'MappingOrigin' argument
- std::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
- std::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<IfcBlock>(const DB& db, const LIST& params, IfcBlock* 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<IfcLightFixtureType>(const DB& db, const LIST& params, IfcLightFixtureType* 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<IfcOpeningElement>(const DB& db, const LIST& params, IfcOpeningElement* 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<IfcTendonAnchor>(const DB& db, const LIST& params, IfcTendonAnchor* 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<IfcElectricFlowStorageDeviceType>(const DB& db, const LIST& params, IfcElectricFlowStorageDeviceType* 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<IfcSphere>(const DB& db, const LIST& params, IfcSphere* 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<IfcDamperType>(const DB& db, const LIST& params, IfcDamperType* 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<IfcProjectOrderRecord>(const DB& db, const LIST& params, IfcProjectOrderRecord* 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<IfcDistributionChamberElement>(const DB& db, const LIST& params, IfcDistributionChamberElement* 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<IfcMechanicalFastener>(const DB& db, const LIST& params, IfcMechanicalFastener* in)
-{
- 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<IfcRectangularTrimmedSurface>(const DB& db, const LIST& params, IfcRectangularTrimmedSurface* 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<IfcZone>(const DB& db, const LIST& params, IfcZone* 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<IfcFanType>(const DB& db, const LIST& params, IfcFanType* 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<IfcGeometricSet>(const DB& db, const LIST& params, IfcGeometricSet* 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<IfcFillAreaStyleTiles>(const DB& db, const LIST& params, IfcFillAreaStyleTiles* 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<IfcCableSegmentType>(const DB& db, const LIST& params, IfcCableSegmentType* 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<IfcRelOverridesProperties>(const DB& db, const LIST& params, IfcRelOverridesProperties* in)
-{
- 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<IfcMeasureWithUnit>(const DB& db, const LIST& params, IfcMeasureWithUnit* in)
-{
- size_t base = 0;
- if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); } do { // convert the 'ValueComponent' argument
- std::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`")); }
- } while(0);
- do { // convert the 'UnitComponent' argument
- std::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<IfcSlabType>(const DB& db, const LIST& params, IfcSlabType* 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<IfcServiceLife>(const DB& db, const LIST& params, IfcServiceLife* 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<IfcFurnitureType>(const DB& db, const LIST& params, IfcFurnitureType* 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<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<IfcReinforcingMesh>(const DB& db, const LIST& params, IfcReinforcingMesh* 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<IfcFacetedBrepWithVoids>(const DB& db, const LIST& params, IfcFacetedBrepWithVoids* 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<IfcGasTerminalType>(const DB& db, const LIST& params, IfcGasTerminalType* 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<IfcPile>(const DB& db, const LIST& params, IfcPile* 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<IfcFillAreaStyleTileSymbolWithStyle>(const DB& db, const LIST& params, IfcFillAreaStyleTileSymbolWithStyle* 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<IfcConstructionMaterialResource>(const DB& db, const LIST& params, IfcConstructionMaterialResource* 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<IfcAnnotationCurveOccurrence>(const DB& db, const LIST& params, IfcAnnotationCurveOccurrence* 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<IfcDimensionCurve>(const DB& db, const LIST& params, IfcDimensionCurve* 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<IfcGeometricCurveSet>(const DB& db, const LIST& params, IfcGeometricCurveSet* 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<IfcRelAggregates>(const DB& db, const LIST& params, IfcRelAggregates* 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;
-}
-// -----------------------------------------------------------------------------------------------------------
-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
- std::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<IfcEnergyConversionDevice>(const DB& db, const LIST& params, IfcEnergyConversionDevice* 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<IfcRampFlight>(const DB& db, const LIST& params, IfcRampFlight* 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<IfcVertexLoop>(const DB& db, const LIST& params, IfcVertexLoop* 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<IfcPlate>(const DB& db, const LIST& params, IfcPlate* 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<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<IfcFaceBound>(const DB& db, const LIST& params, IfcFaceBound* 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
- std::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
- std::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<IfcFaceOuterBound>(const DB& db, const LIST& params, IfcFaceOuterBound* 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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcOneDirectionRepeatFactor>(const DB& db, const LIST& params, IfcOneDirectionRepeatFactor* 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<IfcBoilerType>(const DB& db, const LIST& params, IfcBoilerType* 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<IfcConstructionEquipmentResource>(const DB& db, const LIST& params, IfcConstructionEquipmentResource* 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<IfcComplexProperty>(const DB& db, const LIST& params, IfcComplexProperty* in)
-{
- 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
- std::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
- std::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<IfcFooting>(const DB& db, const LIST& params, IfcFooting* 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<IfcConstructionProductResource>(const DB& db, const LIST& params, IfcConstructionProductResource* 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<IfcDerivedProfileDef>(const DB& db, const LIST& params, IfcDerivedProfileDef* 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<IfcPropertyTableValue>(const DB& db, const LIST& params, IfcPropertyTableValue* 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<IfcFlowMeterType>(const DB& db, const LIST& params, IfcFlowMeterType* 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<IfcDoorStyle>(const DB& db, const LIST& params, IfcDoorStyle* 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<IfcUnitAssignment>(const DB& db, const LIST& params, IfcUnitAssignment* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcUnitAssignment"); } do { // convert the 'Units' argument
- std::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<IfcFlowTerminal>(const DB& db, const LIST& params, IfcFlowTerminal* 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<IfcCraneRailFShapeProfileDef>(const DB& db, const LIST& params, IfcCraneRailFShapeProfileDef* 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<IfcFlowSegment>(const DB& db, const LIST& params, IfcFlowSegment* 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<IfcElementQuantity>(const DB& db, const LIST& params, IfcElementQuantity* in)
-{
- 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
- std::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
- std::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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcCurtainWall>(const DB& db, const LIST& params, IfcCurtainWall* 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<IfcDiscreteAccessory>(const DB& db, const LIST& params, IfcDiscreteAccessory* 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<IfcGrid>(const DB& db, const LIST& params, IfcGrid* 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<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<IfcSubedge>(const DB& db, const LIST& params, IfcSubedge* 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<IfcFilterType>(const DB& db, const LIST& params, IfcFilterType* 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<IfcTendon>(const DB& db, const LIST& params, IfcTendon* 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)
-{
- 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<IfcPresentationStyleAssignment>(const DB& db, const LIST& params, IfcPresentationStyleAssignment* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcPresentationStyleAssignment"); } do { // convert the 'Styles' argument
- std::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<IfcStructuralCurveMember>(const DB& db, const LIST& params, IfcStructuralCurveMember* 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<IfcLightSourceAmbient>(const DB& db, const LIST& params, IfcLightSourceAmbient* 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<IfcCondition>(const DB& db, const LIST& params, IfcCondition* 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<IfcPort>(const DB& db, const LIST& params, IfcPort* 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<IfcSpace>(const DB& db, const LIST& params, IfcSpace* 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
- std::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
- std::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<IfcHeatExchangerType>(const DB& db, const LIST& params, IfcHeatExchangerType* 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<IfcTankType>(const DB& db, const LIST& params, IfcTankType* 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<IfcInventory>(const DB& db, const LIST& params, IfcInventory* 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<IfcTransportElementType>(const DB& db, const LIST& params, IfcTransportElementType* 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<IfcAirToAirHeatRecoveryType>(const DB& db, const LIST& params, IfcAirToAirHeatRecoveryType* 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<IfcStairFlight>(const DB& db, const LIST& params, IfcStairFlight* 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<IfcElectricalElement>(const DB& db, const LIST& params, IfcElectricalElement* 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<IfcSurfaceStyleWithTextures>(const DB& db, const LIST& params, IfcSurfaceStyleWithTextures* in)
-{
- size_t base = 0;
- if (params.GetSize() < 1) { throw STEP::TypeError("expected 1 arguments to IfcSurfaceStyleWithTextures"); } do { // convert the 'Textures' argument
- std::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`")); }
- } while(0);
- return base;
-}
-// -----------------------------------------------------------------------------------------------------------
-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() < 4) { throw STEP::TypeError("expected 4 arguments to IfcBoundingBox"); } do { // convert the 'Corner' argument
- std::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
- std::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
- std::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
- std::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<IfcWallType>(const DB& db, const LIST& params, IfcWallType* 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<IfcMove>(const DB& db, const LIST& params, IfcMove* 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<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
- std::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<IfcOffsetCurve2D>(const DB& db, const LIST& params, IfcOffsetCurve2D* 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<IfcPointOnCurve>(const DB& db, const LIST& params, IfcPointOnCurve* 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<IfcStructuralResultGroup>(const DB& db, const LIST& params, IfcStructuralResultGroup* 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<IfcSectionedSpine>(const DB& db, const LIST& params, IfcSectionedSpine* 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<IfcSlab>(const DB& db, const LIST& params, IfcSlab* 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<IfcVertex>(const DB& db, const LIST& params, IfcVertex* 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<IfcVertexPoint>(const DB& db, const LIST& params, IfcVertexPoint* 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<IfcStructuralLinearAction>(const DB& db, const LIST& params, IfcStructuralLinearAction* 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<IfcStructuralLinearActionVarying>(const DB& db, const LIST& params, IfcStructuralLinearActionVarying* 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<IfcBuildingElementProxyType>(const DB& db, const LIST& params, IfcBuildingElementProxyType* 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<IfcProjectionElement>(const DB& db, const LIST& params, IfcProjectionElement* in)
-{
- 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<IfcConversionBasedUnit>(const DB& db, const LIST& params, IfcConversionBasedUnit* 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
- std::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
- std::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;
-}
-// -----------------------------------------------------------------------------------------------------------
-template <> size_t GenericFill<IfcGeometricRepresentationSubContext>(const DB& db, const LIST& params, IfcGeometricRepresentationSubContext* 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<IfcAnnotationSurfaceOccurrence>(const DB& db, const LIST& params, IfcAnnotationSurfaceOccurrence* 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<IfcRoundedEdgeFeature>(const DB& db, const LIST& params, IfcRoundedEdgeFeature* 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<IfcElectricDistributionPoint>(const DB& db, const LIST& params, IfcElectricDistributionPoint* 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<IfcCableCarrierSegmentType>(const DB& db, const LIST& params, IfcCableCarrierSegmentType* 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<IfcWallStandardCase>(const DB& db, const LIST& params, IfcWallStandardCase* 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<IfcCsgSolid>(const DB& db, const LIST& params, IfcCsgSolid* 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<IfcBeamType>(const DB& db, const LIST& params, IfcBeamType* 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<IfcAnnotationFillArea>(const DB& db, const LIST& params, IfcAnnotationFillArea* 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<IfcStructuralCurveMemberVarying>(const DB& db, const LIST& params, IfcStructuralCurveMemberVarying* 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<IfcPointOnSurface>(const DB& db, const LIST& params, IfcPointOnSurface* 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<IfcOrderAction>(const DB& db, const LIST& params, IfcOrderAction* 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<IfcEdgeLoop>(const DB& db, const LIST& params, IfcEdgeLoop* 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<IfcAnnotationFillAreaOccurrence>(const DB& db, const LIST& params, IfcAnnotationFillAreaOccurrence* 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<IfcWorkPlan>(const DB& db, const LIST& params, IfcWorkPlan* 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<IfcEllipse>(const DB& db, const LIST& params, IfcEllipse* 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
- std::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
- std::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<IfcProductDefinitionShape>(const DB& db, const LIST& params, IfcProductDefinitionShape* 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<IfcProjectionCurve>(const DB& db, const LIST& params, IfcProjectionCurve* 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<IfcElectricalCircuit>(const DB& db, const LIST& params, IfcElectricalCircuit* 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<IfcRationalBezierCurve>(const DB& db, const LIST& params, IfcRationalBezierCurve* 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
- 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<IfcPipeSegmentType>(const DB& db, const LIST& params, IfcPipeSegmentType* 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<IfcTwoDirectionRepeatFactor>(const DB& db, const LIST& params, IfcTwoDirectionRepeatFactor* 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<IfcShapeRepresentation>(const DB& db, const LIST& params, IfcShapeRepresentation* 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<IfcPropertySet>(const DB& db, const LIST& params, IfcPropertySet* in)
-{
- 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
- std::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<IfcSurfaceStyleRendering>(const DB& db, const LIST& params, IfcSurfaceStyleRendering* 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
- std::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
- std::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
- std::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
- std::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
- std::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
- std::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
- std::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
- std::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<IfcDistributionPort>(const DB& db, const LIST& params, IfcDistributionPort* 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<IfcPipeFittingType>(const DB& db, const LIST& params, IfcPipeFittingType* 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<IfcTransportElement>(const DB& db, const LIST& params, IfcTransportElement* 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<IfcAnnotationTextOccurrence>(const DB& db, const LIST& params, IfcAnnotationTextOccurrence* 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<IfcStructuralAnalysisModel>(const DB& db, const LIST& params, IfcStructuralAnalysisModel* 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<IfcConditionCriterion>(const DB& db, const LIST& params, IfcConditionCriterion* 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;
-}
-
-} // ! STEP
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCUtil.cpp b/src/3rdparty/assimp/code/IFCUtil.cpp
deleted file mode 100644
index f5bd56a00..000000000
--- a/src/3rdparty/assimp/code/IFCUtil.cpp
+++ /dev/null
@@ -1,707 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFCUtil.cpp
- * @brief Implementation of conversion routines for some common Ifc helper entities.
- */
-
-
-
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-
-#include "IFCUtil.h"
-#include "PolyTools.h"
-#include "ProcessHelper.h"
-#include <assimp/Defines.h>
-
-namespace Assimp {
- namespace IFC {
-
-// ------------------------------------------------------------------------------------------------
-void TempOpening::Transform(const IfcMatrix4& mat)
-{
- if(profileMesh) {
- profileMesh->Transform(mat);
- }
- if(profileMesh2D) {
- profileMesh2D->Transform(mat);
- }
- extrusionDir *= IfcMatrix3(mat);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh* TempMesh::ToMesh()
-{
- ai_assert(verts.size() == std::accumulate(vertcnt.begin(),vertcnt.end(),size_t(0)));
-
- if (verts.empty()) {
- return NULL;
- }
-
- std::unique_ptr<aiMesh> mesh(new aiMesh());
-
- // copy vertices
- mesh->mNumVertices = static_cast<unsigned int>(verts.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- std::copy(verts.begin(),verts.end(),mesh->mVertices);
-
- // and build up faces
- mesh->mNumFaces = static_cast<unsigned int>(vertcnt.size());
- mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- for(unsigned int i = 0,n=0, acc = 0; i < mesh->mNumFaces; ++n) {
- aiFace& f = mesh->mFaces[i];
- if (!vertcnt[n]) {
- --mesh->mNumFaces;
- continue;
- }
-
- f.mNumIndices = vertcnt[n];
- f.mIndices = new unsigned int[f.mNumIndices];
- for(unsigned int a = 0; a < f.mNumIndices; ++a) {
- f.mIndices[a] = acc++;
- }
-
- ++i;
- }
-
- return mesh.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-void TempMesh::Clear()
-{
- verts.clear();
- vertcnt.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-void TempMesh::Transform(const IfcMatrix4& mat)
-{
- for(IfcVector3& v : verts) {
- v *= mat;
- }
-}
-
-// ------------------------------------------------------------------------------
-IfcVector3 TempMesh::Center() const
-{
- return (verts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(verts.begin(),verts.end(),IfcVector3()) / static_cast<IfcFloat>(verts.size()));
-}
-
-// ------------------------------------------------------------------------------------------------
-void TempMesh::Append(const TempMesh& other)
-{
- verts.insert(verts.end(),other.verts.begin(),other.verts.end());
- vertcnt.insert(vertcnt.end(),other.vertcnt.begin(),other.vertcnt.end());
-}
-
-// ------------------------------------------------------------------------------------------------
-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-10f) {
- it = vertcnt.erase(it);
- vit = verts.erase(vit, vit + pcount);
-
- drop = true;
- continue;
- }
-
- vit += pcount;
- ++it;
- }
-
- if(drop) {
- IFCImporter::LogDebug("removing degenerate faces");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize)
-{
- std::vector<IfcFloat> temp((cnt+2)*3);
- for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs )
- {
- const IfcVector3& v = vtcs[vofs];
- temp[i++] = v.x;
- temp[i++] = v.y;
- temp[i++] = v.z;
- }
-
- IfcVector3 nor;
- NewellNormal<3, 3, 3>(nor, static_cast<int>(cnt), &temp[0], &temp[1], &temp[2]);
- return normalize ? nor.Normalize() : nor;
-}
-
-// ------------------------------------------------------------------------------------------------
-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) {
- for(IfcVector3& n : normals) {
- n.Normalize();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compute the normal of the last polygon in the given mesh
-IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
-{
- return ComputePolygonNormal(&verts[verts.size() - vertcnt.back()], vertcnt.back(), normalize);
-}
-
-struct CompareVector
-{
- bool operator () (const IfcVector3& a, const IfcVector3& b) const
- {
- IfcVector3 d = a - b;
- IfcFloat eps = 1e-6;
- return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
- }
-};
-struct FindVector
-{
- IfcVector3 v;
- FindVector(const IfcVector3& p) : v(p) { }
- bool operator () (const IfcVector3& p) { return FuzzyVectorCompare(1e-6)(p, v); }
-};
-
-// ------------------------------------------------------------------------------------------------
-void TempMesh::FixupFaceOrientation()
-{
- const IfcVector3 vavg = Center();
-
- // create a list of start indices for all faces to allow random access to faces
- std::vector<size_t> faceStartIndices(vertcnt.size());
- for( size_t i = 0, a = 0; a < vertcnt.size(); i += vertcnt[a], ++a )
- faceStartIndices[a] = i;
-
- // list all faces on a vertex
- std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
- for( size_t a = 0; a < vertcnt.size(); ++a )
- {
- for( size_t b = 0; b < vertcnt[a]; ++b )
- facesByVertex[verts[faceStartIndices[a] + b]].push_back(a);
- }
- // determine neighbourhood for all polys
- std::vector<size_t> neighbour(verts.size(), SIZE_MAX);
- std::vector<size_t> tempIntersect(10);
- for( size_t a = 0; a < vertcnt.size(); ++a )
- {
- for( size_t b = 0; b < vertcnt[a]; ++b )
- {
- size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % vertcnt[a];
- const std::vector<size_t>& facesOnB = facesByVertex[verts[ib]];
- const std::vector<size_t>& facesOnNB = facesByVertex[verts[nib]];
- // there should be exactly one or two faces which appear in both lists. Our face and the other side
- std::vector<size_t>::iterator sectstart = tempIntersect.begin();
- std::vector<size_t>::iterator sectend = std::set_intersection(
- facesOnB.begin(), facesOnB.end(), facesOnNB.begin(), facesOnNB.end(), sectstart);
-
- if( std::distance(sectstart, sectend) != 2 )
- continue;
- if( *sectstart == a )
- ++sectstart;
- neighbour[ib] = *sectstart;
- }
- }
-
- // now we're getting started. We take the face which is the farthest away from the center. This face is most probably
- // facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring
- // faces to have the same winding until all faces have been tested.
- std::vector<bool> faceDone(vertcnt.size(), false);
- while( std::count(faceDone.begin(), faceDone.end(), false) != 0 )
- {
- // find the farthest of the remaining faces
- size_t farthestIndex = SIZE_MAX;
- IfcFloat farthestDistance = -1.0;
- for( size_t a = 0; a < vertcnt.size(); ++a )
- {
- if( faceDone[a] )
- continue;
- IfcVector3 faceCenter = std::accumulate(verts.begin() + faceStartIndices[a],
- verts.begin() + faceStartIndices[a] + vertcnt[a], IfcVector3(0.0)) / IfcFloat(vertcnt[a]);
- IfcFloat dst = (faceCenter - vavg).SquareLength();
- if( dst > farthestDistance ) { farthestDistance = dst; farthestIndex = a; }
- }
-
- // calculate its normal and reverse the poly if its facing towards the mesh center
- IfcVector3 farthestNormal = ComputePolygonNormal(verts.data() + faceStartIndices[farthestIndex], vertcnt[farthestIndex]);
- IfcVector3 farthestCenter = std::accumulate(verts.begin() + faceStartIndices[farthestIndex],
- verts.begin() + faceStartIndices[farthestIndex] + vertcnt[farthestIndex], IfcVector3(0.0))
- / IfcFloat(vertcnt[farthestIndex]);
- // We accapt a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
- // the file.
- if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
- {
- size_t fsi = faceStartIndices[farthestIndex], fvc = vertcnt[farthestIndex];
- std::reverse(verts.begin() + fsi, verts.begin() + fsi + fvc);
- std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
- // because of the neighbour index belonging to the edge starting with the point at the same index, we need to
- // cycle the neighbours through to match the edges again.
- // Before: points A - B - C - D with edge neighbour p - q - r - s
- // After: points D - C - B - A, reversed neighbours are s - r - q - p, but the should be
- // r q p s
- for( size_t a = 0; a < fvc - 1; ++a )
- std::swap(neighbour[fsi + a], neighbour[fsi + a + 1]);
- }
- faceDone[farthestIndex] = true;
- std::vector<size_t> todo;
- todo.push_back(farthestIndex);
-
- // go over its neighbour faces recursively and adapt their winding order to match the farthest face
- while( !todo.empty() )
- {
- size_t tdf = todo.back();
- size_t vsi = faceStartIndices[tdf], vc = vertcnt[tdf];
- todo.pop_back();
-
- // check its neighbours
- for( size_t a = 0; a < vc; ++a )
- {
- // ignore neighbours if we already checked them
- size_t nbi = neighbour[vsi + a];
- if( nbi == SIZE_MAX || faceDone[nbi] )
- continue;
-
- const IfcVector3& vp = verts[vsi + a];
- size_t nbvsi = faceStartIndices[nbi], nbvc = vertcnt[nbi];
- std::vector<IfcVector3>::iterator it = std::find_if(verts.begin() + nbvsi, verts.begin() + nbvsi + nbvc, FindVector(vp));
- ai_assert(it != verts.begin() + nbvsi + nbvc);
- size_t nb_vidx = std::distance(verts.begin() + nbvsi, it);
- // two faces winded in the same direction should have a crossed edge, where one face has p0->p1 and the other
- // has p1'->p0'. If the next point on the neighbouring face is also the next on the current face, we need
- // to reverse the neighbour
- nb_vidx = (nb_vidx + 1) % nbvc;
- size_t oursideidx = (a + 1) % vc;
- if( FuzzyVectorCompare(1e-6)(verts[vsi + oursideidx], verts[nbvsi + nb_vidx]) )
- {
- std::reverse(verts.begin() + nbvsi, verts.begin() + nbvsi + nbvc);
- std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
- for( size_t a = 0; a < nbvc - 1; ++a )
- std::swap(neighbour[nbvsi + a], neighbour[nbvsi + a + 1]);
- }
-
- // either way we're done with the neighbour. Mark it as done and continue checking from there recursively
- faceDone[nbi] = true;
- todo.push_back(nbi);
- }
- }
-
- // no more faces reachable from this part of the surface, start over with a disjunct part and its farthest face
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void TempMesh::RemoveAdjacentDuplicates()
-{
-
- bool drop = false;
- std::vector<IfcVector3>::iterator base = verts.begin();
- for(unsigned int& cnt : vertcnt) {
- if (cnt < 2){
- base += cnt;
- continue;
- }
-
- IfcVector3 vmin,vmax;
- ArrayBounds(&*base, cnt ,vmin,vmax);
-
-
- const IfcFloat epsilon = (vmax-vmin).SquareLength() / static_cast<IfcFloat>(1e9);
- //const IfcFloat dotepsilon = 1e-9;
-
- //// look for vertices that lie directly on the line between their predecessor and their
- //// successor and replace them with either of them.
-
- //for(size_t i = 0; i < cnt; ++i) {
- // IfcVector3& v1 = *(base+i), &v0 = *(base+(i?i-1:cnt-1)), &v2 = *(base+(i+1)%cnt);
- // const IfcVector3& d0 = (v1-v0), &d1 = (v2-v1);
- // const IfcFloat l0 = d0.SquareLength(), l1 = d1.SquareLength();
- // if (!l0 || !l1) {
- // continue;
- // }
-
- // const IfcFloat d = (d0/std::sqrt(l0))*(d1/std::sqrt(l1));
-
- // if ( d >= 1.f-dotepsilon ) {
- // v1 = v0;
- // }
- // else if ( d < -1.f+dotepsilon ) {
- // v2 = v1;
- // continue;
- // }
- //}
-
- // drop any identical, adjacent vertices. this pass will collect the dropouts
- // of the previous pass as a side-effect.
- FuzzyVectorCompare fz(epsilon);
- std::vector<IfcVector3>::iterator end = base+cnt, e = std::unique( base, end, fz );
- if (e != end) {
- cnt -= static_cast<unsigned int>(std::distance(e, end));
- verts.erase(e,end);
- drop = true;
- }
-
- // check front and back vertices for this polygon
- if (cnt > 1 && fz(*base,*(base+cnt-1))) {
- verts.erase(base+ --cnt);
- drop = true;
- }
-
- // removing adjacent duplicates shouldn't erase everything :-)
- ai_assert(cnt>0);
- base += cnt;
- }
- if(drop) {
- 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";
-}
-
-// ------------------------------------------------------------------------------------------------
-IfcFloat ConvertSIPrefix(const std::string& prefix)
-{
- if (prefix == "EXA") {
- return 1e18f;
- }
- else if (prefix == "PETA") {
- return 1e15f;
- }
- else if (prefix == "TERA") {
- return 1e12f;
- }
- else if (prefix == "GIGA") {
- return 1e9f;
- }
- else if (prefix == "MEGA") {
- return 1e6f;
- }
- else if (prefix == "KILO") {
- return 1e3f;
- }
- else if (prefix == "HECTO") {
- return 1e2f;
- }
- else if (prefix == "DECA") {
- return 1e-0f;
- }
- else if (prefix == "DECI") {
- return 1e-1f;
- }
- else if (prefix == "CENTI") {
- return 1e-2f;
- }
- else if (prefix == "MILLI") {
- return 1e-3f;
- }
- else if (prefix == "MICRO") {
- return 1e-6f;
- }
- else if (prefix == "NANO") {
- return 1e-9f;
- }
- else if (prefix == "PICO") {
- return 1e-12f;
- }
- else if (prefix == "FEMTO") {
- return 1e-15f;
- }
- else if (prefix == "ATTO") {
- return 1e-18f;
- }
- else {
- IFCImporter::LogError("Unrecognized SI prefix: " + prefix);
- return 1;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertColor(aiColor4D& out, const IfcColourRgb& in)
-{
- out.r = static_cast<float>( in.Red );
- out.g = static_cast<float>( in.Green );
- out.b = static_cast<float>( in.Blue );
- out.a = static_cast<float>( 1.f );
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertColor(aiColor4D& out, const IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
-{
- if (const EXPRESS::REAL* const r = in.ToPtr<EXPRESS::REAL>()) {
- out.r = out.g = out.b = static_cast<float>(*r);
- if(base) {
- out.r *= static_cast<float>( base->r );
- out.g *= static_cast<float>( base->g );
- out.b *= static_cast<float>( base->b );
- out.a = static_cast<float>( base->a );
- }
- else out.a = 1.0;
- }
- else if (const IfcColourRgb* const rgb = in.ResolveSelectPtr<IfcColourRgb>(conv.db)) {
- ConvertColor(out,*rgb);
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in)
-{
- out = IfcVector3();
- for(size_t i = 0; i < in.Coordinates.size(); ++i) {
- out[static_cast<unsigned int>(i)] = in.Coordinates[i];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertVector(IfcVector3& out, const IfcVector& in)
-{
- ConvertDirection(out,in.Orientation);
- out *= in.Magnitude;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertDirection(IfcVector3& out, const IfcDirection& in)
-{
- out = IfcVector3();
- for(size_t i = 0; i < in.DirectionRatios.size(); ++i) {
- out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
- }
- const IfcFloat len = out.Length();
- if (len<1e-6) {
- IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero");
- return;
- }
- out /= len;
-}
-
-// ------------------------------------------------------------------------------------------------
-void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z)
-{
- out.a1 = x.x;
- out.b1 = x.y;
- out.c1 = x.z;
-
- out.a2 = y.x;
- out.b2 = y.y;
- out.c2 = y.z;
-
- out.a3 = z.x;
- out.b3 = z.y;
- out.c3 = z.z;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in)
-{
- IfcVector3 loc;
- ConvertCartesianPoint(loc,in.Location);
-
- IfcVector3 z(0.f,0.f,1.f),r(1.f,0.f,0.f),x;
-
- if (in.Axis) {
- ConvertDirection(z,*in.Axis.Get());
- }
- if (in.RefDirection) {
- ConvertDirection(r,*in.RefDirection.Get());
- }
-
- IfcVector3 v = r.Normalize();
- IfcVector3 tmpx = z * (v*z);
-
- x = (v-tmpx).Normalize();
- IfcVector3 y = (z^x);
-
- IfcMatrix4::Translation(loc,out);
- AssignMatrixAxes(out,x,y,z);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in)
-{
- IfcVector3 loc;
- ConvertCartesianPoint(loc,in.Location);
-
- IfcVector3 x(1.f,0.f,0.f);
- if (in.RefDirection) {
- ConvertDirection(x,*in.RefDirection.Get());
- }
-
- const IfcVector3 y = IfcVector3(x.y,-x.x,0.f);
-
- IfcMatrix4::Translation(loc,out);
- AssignMatrixAxes(out,x,y,IfcVector3(0.f,0.f,1.f));
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IfcAxis1Placement& in)
-{
- ConvertCartesianPoint(pos,in.Location);
- if (in.Axis) {
- ConvertDirection(axis,in.Axis.Get());
- }
- else {
- axis = IfcVector3(0.f,0.f,1.f);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv)
-{
- if(const IfcAxis2Placement3D* pl3 = in.ResolveSelectPtr<IfcAxis2Placement3D>(conv.db)) {
- ConvertAxisPlacement(out,*pl3);
- }
- else if(const IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<IfcAxis2Placement2D>(conv.db)) {
- ConvertAxisPlacement(out,*pl2);
- }
- else {
- IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op)
-{
- IfcVector3 loc;
- ConvertCartesianPoint(loc,op.LocalOrigin);
-
- IfcVector3 x(1.f,0.f,0.f),y(0.f,1.f,0.f),z(0.f,0.f,1.f);
- if (op.Axis1) {
- ConvertDirection(x,*op.Axis1.Get());
- }
- if (op.Axis2) {
- ConvertDirection(y,*op.Axis2.Get());
- }
- if (const IfcCartesianTransformationOperator3D* op2 = op.ToPtr<IfcCartesianTransformationOperator3D>()) {
- if(op2->Axis3) {
- ConvertDirection(z,*op2->Axis3.Get());
- }
- }
-
- IfcMatrix4 locm;
- IfcMatrix4::Translation(loc,locm);
- AssignMatrixAxes(out,x,y,z);
-
-
- IfcVector3 vscale;
- if (const IfcCartesianTransformationOperator3DnonUniform* nuni = op.ToPtr<IfcCartesianTransformationOperator3DnonUniform>()) {
- vscale.x = nuni->Scale?op.Scale.Get():1.f;
- vscale.y = nuni->Scale2?nuni->Scale2.Get():1.f;
- vscale.z = nuni->Scale3?nuni->Scale3.Get():1.f;
- }
- else {
- const IfcFloat sc = op.Scale?op.Scale.Get():1.f;
- vscale = IfcVector3(sc,sc,sc);
- }
-
- IfcMatrix4 s;
- IfcMatrix4::Scaling(vscale,s);
-
- out = locm * out * s;
-}
-
-
-} // ! IFC
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFCUtil.h b/src/3rdparty/assimp/code/IFCUtil.h
deleted file mode 100644
index f90f421d6..000000000
--- a/src/3rdparty/assimp/code/IFCUtil.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IFC.cpp
- * @brief Implementation of the Industry Foundation Classes loader.
- */
-
-#ifndef INCLUDED_IFCUTIL_H
-#define INCLUDED_IFCUTIL_H
-
-#include "IFCReaderGen.h"
-#include "IFCLoader.h"
-#include "STEPFile.h"
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-
-struct aiNode;
-
-namespace Assimp {
-namespace IFC {
-
- typedef double IfcFloat;
-
- // IfcFloat-precision math data types
- typedef aiVector2t<IfcFloat> IfcVector2;
- typedef aiVector3t<IfcFloat> IfcVector3;
- typedef aiMatrix4x4t<IfcFloat> IfcMatrix4;
- typedef aiMatrix3x3t<IfcFloat> IfcMatrix3;
- typedef aiColor4t<IfcFloat> IfcColor4;
-
-
-// ------------------------------------------------------------------------------------------------
-// Helper for std::for_each to delete all heap-allocated items in a container
-// ------------------------------------------------------------------------------------------------
-template<typename T>
-struct delete_fun
-{
- void operator()(T* del) {
- delete del;
- }
-};
-
-
-
-// ------------------------------------------------------------------------------------------------
-// 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();
-
- static IfcVector3 ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize = true);
- 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 TempOpening
-{
- const IFC::IfcSolidModel* solid;
- IfcVector3 extrusionDir;
-
- std::shared_ptr<TempMesh> profileMesh;
- std::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::IfcSolidModel* solid,IfcVector3 extrusionDir,
- std::shared_ptr<TempMesh> profileMesh,
- std::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;
- };
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Intermediate data storage during conversion. Keeps everything and a bit more.
-// ------------------------------------------------------------------------------------------------
-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)
- , db(db)
- , proj(proj)
- , out(out)
- , settings(settings)
- , apply_openings()
- , collect_openings()
- {}
-
- ~ConversionData() {
- std::for_each(meshes.begin(),meshes.end(),delete_fun<aiMesh>());
- std::for_each(materials.begin(),materials.end(),delete_fun<aiMaterial>());
- }
-
- IfcFloat len_scale, angle_scale;
- bool plane_angle_in_radians;
-
- const STEP::DB& db;
- const IFC::IfcProject& proj;
- aiScene* out;
-
- IfcMatrix4 wcs;
- std::vector<aiMesh*> meshes;
- std::vector<aiMaterial*> materials;
-
- struct MeshCacheIndex {
- const IFC::IfcRepresentationItem* item; unsigned int matindex;
- MeshCacheIndex() : item(NULL), matindex(0) { }
- MeshCacheIndex(const IFC::IfcRepresentationItem* i, unsigned int mi) : item(i), matindex(mi) { }
- bool operator == (const MeshCacheIndex& o) const { return item == o.item && matindex == o.matindex; }
- bool operator < (const MeshCacheIndex& o) const { return item < o.item || (item == o.item && matindex < o.matindex); }
- };
- typedef std::map<MeshCacheIndex, std::vector<unsigned int> > MeshCache;
- MeshCache cached_meshes;
-
- typedef std::map<const IFC::IfcSurfaceStyle*, unsigned int> MaterialCache;
- MaterialCache cached_materials;
-
- const IFCImporter::Settings& settings;
-
- // Intermediate arrays used to resolve openings in walls: only one of them
- // can be given at a time. apply_openings if present if the current element
- // is a wall and needs its openings to be poured into its geometry while
- // collect_openings is present only if the current element is an
- // IfcOpeningElement, for which all the geometry needs to be preserved
- // 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.
-// ------------------------------------------------------------------------------------------------
-struct FuzzyVectorCompare {
-
- FuzzyVectorCompare(IfcFloat epsilon) : epsilon(epsilon) {}
- bool operator()(const IfcVector3& a, const IfcVector3& b) {
- return std::abs((a-b).SquareLength()) < epsilon;
- }
-
- const IfcFloat epsilon;
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Ordering predicate to totally order R^2 vectors first by x and then by y
-// ------------------------------------------------------------------------------------------------
-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);
-void ConvertCartesianPoint(IfcVector3& out, const IfcCartesianPoint& in);
-void ConvertDirection(IfcVector3& out, const IfcDirection& in);
-void ConvertVector(IfcVector3& out, const IfcVector& in);
-void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z);
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement3D& in);
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement2D& in);
-void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const IFC::IfcAxis1Placement& in);
-void ConvertAxisPlacement(IfcMatrix4& out, const IfcAxis2Placement& in, ConversionData& conv);
-void ConvertTransformOperator(IfcMatrix4& out, const IfcCartesianTransformationOperator& op);
-bool IsTrue(const EXPRESS::BOOLEAN& in);
-IfcFloat ConvertSIPrefix(const std::string& prefix);
-
-
-// IFCProfile.cpp
-bool ProcessProfile(const IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv);
-bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
-
-// IFCMaterial.cpp
-unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionData& conv, bool forceDefaultMat);
-
-// IFCGeometry.cpp
-IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVector3& norOut);
-bool ProcessRepresentationItem(const IfcRepresentationItem& item, unsigned int matid, 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
-
-// ------------------------------------------------------------------------------------------------
-// Custom exception for use by members of the Curve class
-// ------------------------------------------------------------------------------------------------
-class CurveError
-{
-public:
- CurveError(const std::string& s)
- : s(s)
- {
- }
-
- std::string s;
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Temporary representation for an arbitrary sub-class of IfcCurve. Used to sample the curves
-// to obtain a list of line segments.
-// ------------------------------------------------------------------------------------------------
-class Curve
-{
-protected:
-
- Curve(const IfcCurve& base_entity, ConversionData& conv)
- : base_entity(base_entity)
- , conv(conv)
- {}
-
-public:
-
- typedef std::pair<IfcFloat, IfcFloat> ParamRange;
-
-public:
-
-
- virtual ~Curve() {}
-
-
- // check if a curve is closed
- virtual bool IsClosed() const = 0;
-
- // evaluate the curve at the given parametric position
- virtual IfcVector3 Eval(IfcFloat p) const = 0;
-
- // try to match a point on the curve to a given parameter
- // for self-intersecting curves, the result is not ambiguous and
- // it is undefined which parameter is returned.
- virtual bool ReverseEval(const IfcVector3& val, IfcFloat& paramOut) const;
-
- // get the range of the curve (both inclusive).
- // +inf and -inf are valid return values, the curve is not bounded in such a case.
- virtual std::pair<IfcFloat,IfcFloat> GetParametricRange() const = 0;
- IfcFloat GetParametricRangeDelta() const;
-
- // estimate the number of sample points that this curve will require
- virtual size_t EstimateSampleCount(IfcFloat start,IfcFloat end) const;
-
- // intelligently sample the curve based on the current settings
- // and append the result to the mesh
- virtual void SampleDiscrete(TempMesh& out,IfcFloat start,IfcFloat end) const;
-
-#ifdef ASSIMP_BUILD_DEBUG
- // check if a particular parameter value lies within the well-defined range
- bool InRange(IfcFloat) const;
-#endif
-
-public:
-
- static Curve* Convert(const IFC::IfcCurve&,ConversionData& conv);
-
-protected:
-
- const IfcCurve& base_entity;
- ConversionData& conv;
-};
-
-
-// --------------------------------------------------------------------------------
-// A BoundedCurve always holds the invariant that GetParametricRange()
-// never returns infinite values.
-// --------------------------------------------------------------------------------
-class BoundedCurve : public Curve
-{
-public:
-
- BoundedCurve(const IfcBoundedCurve& entity, ConversionData& conv)
- : Curve(entity,conv)
- {}
-
-public:
-
- bool IsClosed() const;
-
-public:
-
- // sample the entire curve
- void SampleDiscrete(TempMesh& out) const;
- using Curve::SampleDiscrete;
-};
-
-// IfcProfile.cpp
-bool ProcessCurve(const IfcCurve& curve, TempMesh& meshout, ConversionData& conv);
-}
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/IFF.h b/src/3rdparty/assimp/code/IFF.h
deleted file mode 100644
index 2b42b554b..000000000
--- a/src/3rdparty/assimp/code/IFF.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Definitions for the Interchange File Format (IFF)
-// Alexander Gessler, 2006
-// Adapted to Assimp August 2008
-
-#ifndef AI_IFF_H_INCLUDED
-#define AI_IFF_H_INCLUDED
-
-#include "ByteSwapper.h"
-
-namespace Assimp {
-namespace IFF {
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Describes an IFF chunk header
-/////////////////////////////////////////////////////////////////////////////////
-struct ChunkHeader
-{
- //! Type of the chunk header - FourCC
- uint32_t type;
-
- //! Length of the chunk data, in bytes
- uint32_t length;
-};
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Describes an IFF sub chunk header
-/////////////////////////////////////////////////////////////////////////////////
-struct SubChunkHeader
-{
- //! Type of the chunk header - FourCC
- uint32_t type;
-
- //! Length of the chunk data, in bytes
- uint16_t length;
-};
-
-
-#define AI_IFF_FOURCC(a,b,c,d) ((uint32_t) (((uint8_t)a << 24u) | \
- ((uint8_t)b << 16u) | ((uint8_t)c << 8u) | ((uint8_t)d)))
-
-
-#define AI_IFF_FOURCC_FORM AI_IFF_FOURCC('F','O','R','M')
-
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Load a chunk header
-//! @param outFile Pointer to the file data - points to the chunk data afterwards
-//! @return Copy of the chunk header
-/////////////////////////////////////////////////////////////////////////////////
-inline ChunkHeader LoadChunk(uint8_t*& outFile)
-{
- ChunkHeader head;
- ::memcpy(&head.type, outFile, 4);
- outFile += 4;
- ::memcpy(&head.length, outFile, 4);
- outFile += 4;
- AI_LSWAP4(head.length);
- AI_LSWAP4(head.type);
- return head;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Load a sub chunk header
-//! @param outFile Pointer to the file data - points to the chunk data afterwards
-//! @return Copy of the sub chunk header
-/////////////////////////////////////////////////////////////////////////////////
-inline SubChunkHeader LoadSubChunk(uint8_t*& outFile)
-{
- SubChunkHeader head;
- ::memcpy(&head.type, outFile, 4);
- outFile += 4;
- ::memcpy(&head.length, outFile, 2);
- outFile += 2;
- AI_LSWAP2(head.length);
- AI_LSWAP4(head.type);
- return head;
-}
-
-/////////////////////////////////////////////////////////////////////////////////
-//! Read the file header and return the type of the file and its size
-//! @param outFile Pointer to the file data. The buffer must at
-//! least be 12 bytes large.
-//! @param fileType Receives the type of the file
-//! @return 0 if everything was OK, otherwise an error message
-/////////////////////////////////////////////////////////////////////////////////
-inline const char* ReadHeader(uint8_t* outFile, uint32_t& fileType)
-{
- ChunkHeader head = LoadChunk(outFile);
- if(AI_IFF_FOURCC_FORM != head.type)
- {
- return "The file is not an IFF file: FORM chunk is missing";
- }
- ::memcpy(&fileType, outFile, 4);
- AI_LSWAP4(fileType);
- return 0;
-}
-
-
-}}
-
-#endif // !! AI_IFF_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/IOStreamBuffer.h b/src/3rdparty/assimp/code/IOStreamBuffer.h
deleted file mode 100644
index d7528de7e..000000000
--- a/src/3rdparty/assimp/code/IOStreamBuffer.h
+++ /dev/null
@@ -1,350 +0,0 @@
-#pragma once
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include <assimp/types.h>
-#include <assimp/IOStream.hpp>
-#include "ParsingUtils.h"
-
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/**
- * Implementation of a cached stream buffer.
- */
-template<class T>
-class IOStreamBuffer {
-public:
- /// @brief The class constructor.
- IOStreamBuffer( size_t cache = 4096 * 4096 );
-
- /// @brief The class destructor.
- ~IOStreamBuffer();
-
- /// @brief Will open the cached access for a given stream.
- /// @param stream The stream to cache.
- /// @return true if successful.
- bool open( IOStream *stream );
-
- /// @brief Will close the cached access.
- /// @return true if successful.
- bool close();
-
- /// @brief Returns the file-size.
- /// @return The file-size.
- size_t size() const;
-
- /// @brief Returns the cache size.
- /// @return The cache size.
- size_t cacheSize() const;
-
- /// @brief Will read the next block.
- /// @return true if successful.
- bool readNextBlock();
-
- /// @brief Returns the number of blocks to read.
- /// @return The number of blocks.
- size_t getNumBlocks() const;
-
- /// @brief Returns the current block index.
- /// @return The current block index.
- size_t getCurrentBlockIndex() const;
-
- /// @brief Returns the current file pos.
- /// @return The current file pos.
- size_t getFilePos() const;
-
- /// @brief Will read the next line.
- /// @param buffer The buffer for the next line.
- /// @return true if successful.
- bool getNextDataLine( std::vector<T> &buffer, T continuationToken );
-
- /// @brief Will read the next line ascii or binary end line char.
- /// @param buffer The buffer for the next line.
- /// @return true if successful.
- bool getNextLine(std::vector<T> &buffer);
-
- /// @brief Will read the next block.
- /// @param buffer The buffer for the next block.
- /// @return true if successful.
- bool getNextBlock( std::vector<T> &buffer );
-
-private:
- IOStream *m_stream;
- size_t m_filesize;
- size_t m_cacheSize;
- size_t m_numBlocks;
- size_t m_blockIdx;
- std::vector<T> m_cache;
- size_t m_cachePos;
- size_t m_filePos;
-};
-
-template<class T>
-inline
-IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
-: m_stream( nullptr )
-, m_filesize( 0 )
-, m_cacheSize( cache )
-, m_numBlocks( 0 )
-, m_blockIdx( 0 )
-, m_cachePos( 0 )
-, m_filePos( 0 ) {
- m_cache.resize( cache );
- std::fill( m_cache.begin(), m_cache.end(), '\n' );
-}
-
-template<class T>
-inline
-IOStreamBuffer<T>::~IOStreamBuffer() {
- // empty
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::open( IOStream *stream ) {
- // file still opened!
- if ( nullptr != m_stream ) {
- return false;
- }
-
- // Invalid stream pointer
- if ( nullptr == stream ) {
- return false;
- }
-
- m_stream = stream;
- m_filesize = m_stream->FileSize();
- if ( m_filesize == 0 ) {
- return false;
- }
- if ( m_filesize < m_cacheSize ) {
- m_cacheSize = m_filesize;
- }
-
- m_numBlocks = m_filesize / m_cacheSize;
- if ( ( m_filesize % m_cacheSize ) > 0 ) {
- m_numBlocks++;
- }
-
- return true;
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::close() {
- if ( nullptr == m_stream ) {
- return false;
- }
-
- // init counters and state vars
- m_stream = nullptr;
- m_filesize = 0;
- m_numBlocks = 0;
- m_blockIdx = 0;
- m_cachePos = 0;
- m_filePos = 0;
-
- return true;
-}
-
-template<class T>
-inline
-size_t IOStreamBuffer<T>::size() const {
- return m_filesize;
-}
-
-template<class T>
-inline
-size_t IOStreamBuffer<T>::cacheSize() const {
- return m_cacheSize;
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::readNextBlock() {
- m_stream->Seek( m_filePos, aiOrigin_SET );
- size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
- if ( readLen == 0 ) {
- return false;
- }
- if ( readLen < m_cacheSize ) {
- m_cacheSize = readLen;
- }
- m_filePos += m_cacheSize;
- m_cachePos = 0;
- m_blockIdx++;
-
- return true;
-}
-
-template<class T>
-inline
-size_t IOStreamBuffer<T>::getNumBlocks() const {
- return m_numBlocks;
-}
-
-template<class T>
-inline
-size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
- return m_blockIdx;
-}
-
-template<class T>
-inline
-size_t IOStreamBuffer<T>::getFilePos() const {
- return m_filePos;
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
- buffer.resize( m_cacheSize );
- if ( m_cachePos == m_cacheSize || 0 == m_filePos ) {
- if ( !readNextBlock() ) {
- return false;
- }
- }
-
- bool continuationFound( false ), endOfDataLine( false );
- size_t i = 0;
- while ( !endOfDataLine ) {
- if ( continuationToken == m_cache[ m_cachePos ] ) {
- continuationFound = true;
- ++m_cachePos;
- }
- if ( IsLineEnd( m_cache[ m_cachePos ] ) ) {
- if ( !continuationFound ) {
- // the end of the data line
- break;
- } else {
- // skip line end
- while ( m_cache[m_cachePos] != '\n') {
- ++m_cachePos;
- }
- ++m_cachePos;
- continuationFound = false;
- }
- }
-
- buffer[ i ] = m_cache[ m_cachePos ];
- m_cachePos++;
- i++;
- if ( m_cachePos >= m_cacheSize ) {
- if ( !readNextBlock() ) {
- return false;
- }
- }
- }
-
- buffer[ i ] = '\n';
- m_cachePos++;
-
- return true;
-}
-
-static
-inline
-bool isEndOfCache( size_t pos, size_t cacheSize ) {
- return ( pos == cacheSize );
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
- buffer.resize(m_cacheSize);
- if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
- if (!readNextBlock()) {
- return false;
- }
- }
-
- if (IsLineEnd(m_cache[m_cachePos])) {
- // skip line end
- while (m_cache[m_cachePos] != '\n') {
- ++m_cachePos;
- }
- ++m_cachePos;
- if ( isEndOfCache( m_cachePos, m_cacheSize ) ) {
- if ( !readNextBlock() ) {
- return false;
- }
- }
- }
-
- size_t i = 0;
- while (!IsLineEnd(m_cache[ m_cachePos ])) {
- buffer[i] = m_cache[ m_cachePos ];
- m_cachePos++;
- i++;
- if (m_cachePos >= m_cacheSize) {
- if (!readNextBlock()) {
- return false;
- }
- }
- }
- buffer[i] = '\n';
- m_cachePos++;
-
- return true;
-}
-
-template<class T>
-inline
-bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
- //just return the last blockvalue if getNextLine was used before
- if ( m_cachePos != 0) {
- buffer = std::vector<T>(m_cache.begin() + m_cachePos, m_cache.end());
- m_cachePos = 0;
- }
- else {
- if ( !readNextBlock() )
- return false;
-
- buffer = std::vector<T>(m_cache.begin(), m_cache.end());
- }
- return true;
-}
-
-} // !ns Assimp
diff --git a/src/3rdparty/assimp/code/IRRLoader.cpp b/src/3rdparty/assimp/code/IRRLoader.cpp
deleted file mode 100644
index c29d5b072..000000000
--- a/src/3rdparty/assimp/code/IRRLoader.cpp
+++ /dev/null
@@ -1,1488 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IRRLoader.cpp
- * @brief Implementation of the Irr importer class
- */
-
-
-
-#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
-
-#include "IRRLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "GenericProperty.h"
-
-#include <assimp/SceneCombiner.h>
-#include "StandardShapes.h"
-#include "Importer.h"
-
-// We need MathFunctions.h to compute the lcm/gcd of a number
-#include "MathFunctions.h"
-#include <memory>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/postprocess.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-static const aiImporterDesc desc = {
- "Irrlicht Scene Reader",
- "",
- "",
- "http://irrlicht.sourceforge.net/",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "irr xml"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IRRImporter::IRRImporter()
- : fps(),
- configSpeedFlag()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IRRImporter::~IRRImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- /* NOTE: A simple check for the file extension is not enough
- * here. Irrmesh and irr are easy, but xml is too generic
- * and could be collada, too. So we need to open the file and
- * search for typical tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "irr")return true;
- else if (extension == "xml" || checkSig)
- {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"irr_scene"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* IRRImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::SetupProperties(const Importer* pImp)
-{
- // read the output frame rate of all node animation channels
- fps = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_IRR_ANIM_FPS,100);
- if (fps < 10.) {
- DefaultLogger::get()->error("IRR: Invalid FPS configuration");
- fps = 100;
- }
-
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a mesh tha consists of a single squad (a side of a skybox)
-aiMesh* IRRImporter::BuildSingleQuadMesh(const SkyboxVertex& v1,
- const SkyboxVertex& v2,
- const SkyboxVertex& v3,
- const SkyboxVertex& v4)
-{
- // allocate and prepare the mesh
- aiMesh* out = new aiMesh();
-
- out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- out->mNumFaces = 1;
-
- // build the face
- out->mFaces = new aiFace[1];
- aiFace& face = out->mFaces[0];
-
- face.mNumIndices = 4;
- face.mIndices = new unsigned int[4];
- for (unsigned int i = 0; i < 4;++i)
- face.mIndices[i] = i;
-
- out->mNumVertices = 4;
-
- // copy vertex positions
- aiVector3D* vec = out->mVertices = new aiVector3D[4];
- *vec++ = v1.position;
- *vec++ = v2.position;
- *vec++ = v3.position;
- *vec = v4.position;
-
- // copy vertex normals
- vec = out->mNormals = new aiVector3D[4];
- *vec++ = v1.normal;
- *vec++ = v2.normal;
- *vec++ = v3.normal;
- *vec = v4.normal;
-
- // copy texture coordinates
- vec = out->mTextureCoords[0] = new aiVector3D[4];
- *vec++ = v1.uv;
- *vec++ = v2.uv;
- *vec++ = v3.uv;
- *vec = v4.uv;
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::BuildSkybox(std::vector<aiMesh*>& meshes, std::vector<aiMaterial*> materials)
-{
- // Update the material of the skybox - replace the name and disable shading for skyboxes.
- for (unsigned int i = 0; i < 6;++i) {
- aiMaterial* out = ( aiMaterial* ) (*(materials.end()-(6-i)));
-
- aiString s;
- s.length = ::ai_snprintf( s.data, MAXLEN, "SkyboxSide_%u",i );
- out->AddProperty(&s,AI_MATKEY_NAME);
-
- int shading = aiShadingMode_NoShading;
- out->AddProperty(&shading,1,AI_MATKEY_SHADING_MODEL);
- }
-
- // Skyboxes are much more difficult. They are represented
- // by six single planes with different textures, so we'll
- // need to build six meshes.
-
- const ai_real l = 10.0; // the size used by Irrlicht
-
- // FRONT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex(-l,-l,-l, 0, 0, 1, 1.0,1.0),
- SkyboxVertex( l,-l,-l, 0, 0, 1, 0.0,1.0),
- SkyboxVertex( l, l,-l, 0, 0, 1, 0.0,0.0),
- SkyboxVertex(-l, l,-l, 0, 0, 1, 1.0,0.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-6u);
-
- // LEFT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l,-l, -1, 0, 0, 1.0,1.0),
- SkyboxVertex( l,-l, l, -1, 0, 0, 0.0,1.0),
- SkyboxVertex( l, l, l, -1, 0, 0, 0.0,0.0),
- SkyboxVertex( l, l,-l, -1, 0, 0, 1.0,0.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-5u);
-
- // BACK SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l, l, 0, 0, -1, 1.0,1.0),
- SkyboxVertex(-l,-l, l, 0, 0, -1, 0.0,1.0),
- SkyboxVertex(-l, l, l, 0, 0, -1, 0.0,0.0),
- SkyboxVertex( l, l, l, 0, 0, -1, 1.0,0.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-4u);
-
- // RIGHT SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex(-l,-l, l, 1, 0, 0, 1.0,1.0),
- SkyboxVertex(-l,-l,-l, 1, 0, 0, 0.0,1.0),
- SkyboxVertex(-l, l,-l, 1, 0, 0, 0.0,0.0),
- SkyboxVertex(-l, l, l, 1, 0, 0, 1.0,0.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-3u);
-
- // TOP SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l, l,-l, 0, -1, 0, 1.0,1.0),
- SkyboxVertex( l, l, l, 0, -1, 0, 0.0,1.0),
- SkyboxVertex(-l, l, l, 0, -1, 0, 0.0,0.0),
- SkyboxVertex(-l, l,-l, 0, -1, 0, 1.0,0.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-2u);
-
- // BOTTOM SIDE
- meshes.push_back( BuildSingleQuadMesh(
- SkyboxVertex( l,-l, l, 0, 1, 0, 0.0,0.0),
- SkyboxVertex( l,-l,-l, 0, 1, 0, 1.0,0.0),
- SkyboxVertex(-l,-l,-l, 0, 1, 0, 1.0,1.0),
- SkyboxVertex(-l,-l, l, 0, 1, 0, 0.0,1.0)) );
- meshes.back()->mMaterialIndex = static_cast<unsigned int>(materials.size()-1u);
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::CopyMaterial(std::vector<aiMaterial*>& materials,
- std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
- unsigned int& defMatIdx,
- aiMesh* mesh)
-{
- if (inmaterials.empty()) {
- // Do we have a default material? If not we need to create one
- if (UINT_MAX == defMatIdx)
- {
- defMatIdx = (unsigned int)materials.size();
- //TODO: add this materials to someone?
- /*aiMaterial* mat = new aiMaterial();
-
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- aiColor3D c(0.6f,0.6f,0.6f);
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);*/
- }
- mesh->mMaterialIndex = defMatIdx;
- return;
- }
- else if (inmaterials.size() > 1) {
- DefaultLogger::get()->info("IRR: Skipping additional materials");
- }
-
- mesh->mMaterialIndex = (unsigned int)materials.size();
- materials.push_back(inmaterials[0].first);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-inline int ClampSpline(int idx, int size)
-{
- return ( idx<0 ? size+idx : ( idx>=size ? idx-size : idx ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void FindSuitableMultiple(int& angle)
-{
- if (angle < 3)angle = 3;
- else if (angle < 10) angle = 10;
- else if (angle < 20) angle = 20;
- else if (angle < 30) angle = 30;
- else
- {
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNodeAnim*>& anims)
-{
- ai_assert(NULL != root && NULL != real);
-
- // XXX totally WIP - doesn't produce proper results, need to evaluate
- // whether there's any use for Irrlicht's proprietary scene format
- // outside Irrlicht ...
-
- if (root->animators.empty()) {
- return;
- }
- unsigned int total = 0;
- for (std::list<Animator>::iterator it = root->animators.begin();it != root->animators.end(); ++it) {
- if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER) {
- DefaultLogger::get()->warn("IRR: Skipping unknown or unsupported animator");
- continue;
- }
- ++total;
- }
- if (!total)return;
- else if (1 == total) {
- DefaultLogger::get()->warn("IRR: Adding dummy nodes to simulate multiple animators");
- }
-
- // NOTE: 1 tick == i millisecond
-
- unsigned int cur = 0;
- for (std::list<Animator>::iterator it = root->animators.begin();
- it != root->animators.end(); ++it)
- {
- if ((*it).type == Animator::UNKNOWN || (*it).type == Animator::OTHER)continue;
-
- Animator& in = *it ;
- aiNodeAnim* anim = new aiNodeAnim();
-
- if (cur != total-1) {
- // Build a new name - a prefix instead of a suffix because it is
- // easier to check against
- anim->mNodeName.length = ::ai_snprintf(anim->mNodeName.data, MAXLEN,
- "$INST_DUMMY_%i_%s",total-1,
- (root->name.length() ? root->name.c_str() : ""));
-
- // we'll also need to insert a dummy in the node hierarchy.
- aiNode* dummy = new aiNode();
-
- for (unsigned int i = 0; i < real->mParent->mNumChildren;++i)
- if (real->mParent->mChildren[i] == real)
- real->mParent->mChildren[i] = dummy;
-
- dummy->mParent = real->mParent;
- dummy->mName = anim->mNodeName;
-
- dummy->mNumChildren = 1;
- dummy->mChildren = new aiNode*[dummy->mNumChildren];
- dummy->mChildren[0] = real;
-
- // the transformation matrix of the dummy node is the identity
-
- real->mParent = dummy;
- }
- else anim->mNodeName.Set(root->name);
- ++cur;
-
- switch (in.type) {
- case Animator::ROTATION:
- {
- // -----------------------------------------------------
- // find out how long a full rotation will take
- // This is the least common multiple of 360.f and all
- // three euler angles. Although we'll surely find a
- // possible multiple (haha) it could be somewhat large
- // for our purposes. So we need to modify the angles
- // here in order to get good results.
- // -----------------------------------------------------
- int angles[3];
- angles[0] = (int)(in.direction.x*100);
- angles[1] = (int)(in.direction.y*100);
- angles[2] = (int)(in.direction.z*100);
-
- angles[0] %= 360;
- angles[1] %= 360;
- angles[2] %= 360;
-
- if ( (angles[0]*angles[1]) != 0 && (angles[1]*angles[2]) != 0 )
- {
- FindSuitableMultiple(angles[0]);
- FindSuitableMultiple(angles[1]);
- FindSuitableMultiple(angles[2]);
- }
-
- int lcm = 360;
-
- if (angles[0])
- lcm = Math::lcm(lcm,angles[0]);
-
- if (angles[1])
- lcm = Math::lcm(lcm,angles[1]);
-
- if (angles[2])
- lcm = Math::lcm(lcm,angles[2]);
-
- if (360 == lcm)
- break;
-
-#if 0
- // This can be a division through zero, but we don't care
- float f1 = (float)lcm / angles[0];
- float f2 = (float)lcm / angles[1];
- float f3 = (float)lcm / angles[2];
-#endif
-
- // find out how many time units we'll need for the finest
- // track (in seconds) - this defines the number of output
- // keys (fps * seconds)
- float max = 0.f;
- if (angles[0])
- max = (float)lcm / angles[0];
- if (angles[1])
- max = std::max(max, (float)lcm / angles[1]);
- if (angles[2])
- max = std::max(max, (float)lcm / angles[2]);
-
- anim->mNumRotationKeys = (unsigned int)(max*fps);
- anim->mRotationKeys = new aiQuatKey[anim->mNumRotationKeys];
-
- // begin with a zero angle
- aiVector3D angle;
- for (unsigned int i = 0; i < anim->mNumRotationKeys;++i)
- {
- // build the quaternion for the given euler angles
- aiQuatKey& q = anim->mRotationKeys[i];
-
- q.mValue = aiQuaternion(angle.x, angle.y, angle.z);
- q.mTime = (double)i;
-
- // increase the angle
- angle += in.direction;
- }
-
- // This animation is repeated and repeated ...
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- }
- break;
-
- case Animator::FLY_CIRCLE:
- {
- // -----------------------------------------------------
- // Find out how much time we'll need to perform a
- // full circle.
- // -----------------------------------------------------
- const double seconds = (1. / in.speed) / 1000.;
- const double tdelta = 1000. / fps;
-
- anim->mNumPositionKeys = (unsigned int) (fps * seconds);
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- // from Irrlicht, what else should we do than copying it?
- aiVector3D vecU,vecV;
- if (in.direction.y) {
- vecV = aiVector3D(50,0,0) ^ in.direction;
- }
- else vecV = aiVector3D(0,50,00) ^ in.direction;
- vecV.Normalize();
- vecU = (vecV ^ in.direction).Normalize();
-
- // build the output keys
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
- aiVectorKey& key = anim->mPositionKeys[i];
- key.mTime = i * tdelta;
-
- const ai_real t = (ai_real) ( in.speed * key.mTime );
- key.mValue = in.circleCenter + in.circleRadius * ((vecU * std::cos(t)) + (vecV * std::sin(t)));
- }
-
- // This animation is repeated and repeated ...
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- }
- break;
-
- case Animator::FLY_STRAIGHT:
- {
- anim->mPostState = anim->mPreState = (in.loop ? aiAnimBehaviour_REPEAT : aiAnimBehaviour_CONSTANT);
- const double seconds = in.timeForWay / 1000.;
- const double tdelta = 1000. / fps;
-
- anim->mNumPositionKeys = (unsigned int) (fps * seconds);
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- aiVector3D diff = in.direction - in.circleCenter;
- const ai_real lengthOfWay = diff.Length();
- diff.Normalize();
-
- const double timeFactor = lengthOfWay / in.timeForWay;
-
- // build the output keys
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i) {
- aiVectorKey& key = anim->mPositionKeys[i];
- key.mTime = i * tdelta;
- key.mValue = in.circleCenter + diff * ai_real(timeFactor * key.mTime);
- }
- }
- break;
-
- case Animator::FOLLOW_SPLINE:
- {
- // repeat outside the defined time range
- anim->mPostState = anim->mPreState = aiAnimBehaviour_REPEAT;
- const int size = (int)in.splineKeys.size();
- if (!size) {
- // We have no point in the spline. That's bad. Really bad.
- DefaultLogger::get()->warn("IRR: Spline animators with no points defined");
-
- delete anim;anim = NULL;
- break;
- }
- else if (size == 1) {
- // We have just one point in the spline so we don't need the full calculation
- anim->mNumPositionKeys = 1;
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- anim->mPositionKeys[0].mValue = in.splineKeys[0].mValue;
- anim->mPositionKeys[0].mTime = 0.f;
- break;
- }
-
- unsigned int ticksPerFull = 15;
- anim->mNumPositionKeys = (unsigned int) ( ticksPerFull * fps );
- anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
-
- for (unsigned int i = 0; i < anim->mNumPositionKeys;++i)
- {
- aiVectorKey& key = anim->mPositionKeys[i];
-
- const ai_real dt = (i * in.speed * ai_real( 0.001 ) );
- const ai_real u = dt - std::floor(dt);
- const int idx = (int)std::floor(dt) % size;
-
- // get the 4 current points to evaluate the spline
- const aiVector3D& p0 = in.splineKeys[ ClampSpline( idx - 1, size ) ].mValue;
- const aiVector3D& p1 = in.splineKeys[ ClampSpline( idx + 0, size ) ].mValue;
- const aiVector3D& p2 = in.splineKeys[ ClampSpline( idx + 1, size ) ].mValue;
- const aiVector3D& p3 = in.splineKeys[ ClampSpline( idx + 2, size ) ].mValue;
-
- // compute polynomials
- const ai_real u2 = u*u;
- const ai_real u3 = u2*2;
-
- const ai_real h1 = ai_real( 2.0 ) * u3 - ai_real( 3.0 ) * u2 + ai_real( 1.0 );
- const ai_real h2 = ai_real( -2.0 ) * u3 + ai_real( 3.0 ) * u3;
- const ai_real h3 = u3 - ai_real( 2.0 ) * u3;
- const ai_real h4 = u3 - u2;
-
- // compute the spline tangents
- const aiVector3D t1 = ( p2 - p0 ) * in.tightness;
- aiVector3D t2 = ( p3 - p1 ) * in.tightness;
-
- // and use them to get the interpolated point
- t2 = (h1 * p1 + p2 * h2 + t1 * h3 + h4 * t2);
-
- // build a simple translation matrix from it
- key.mValue = t2;
- key.mTime = (double) i;
- }
- }
- break;
- default:
- // UNKNOWN , OTHER
- break;
- };
- if (anim) {
- anims.push_back(anim);
- ++total;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// This function is maybe more generic than we'd need it here
-void SetupMapping (aiMaterial* mat, aiTextureMapping mode, const aiVector3D& axis = aiVector3D(0.f,0.f,-1.f))
-{
- // Check whether there are texture properties defined - setup
- // the desired texture mapping mode for all of them and ignore
- // all UV settings we might encounter. WE HAVE NO UVS!
-
- std::vector<aiMaterialProperty*> p;
- p.reserve(mat->mNumProperties+1);
-
- for (unsigned int i = 0; i < mat->mNumProperties;++i)
- {
- aiMaterialProperty* prop = mat->mProperties[i];
- if (!::strcmp( prop->mKey.data, "$tex.file")) {
- // Setup the mapping key
- aiMaterialProperty* m = new aiMaterialProperty();
- m->mKey.Set("$tex.mapping");
- m->mIndex = prop->mIndex;
- m->mSemantic = prop->mSemantic;
- m->mType = aiPTI_Integer;
-
- m->mDataLength = 4;
- m->mData = new char[4];
- *((int*)m->mData) = mode;
-
- p.push_back(prop);
- p.push_back(m);
-
- // Setup the mapping axis
- if (mode == aiTextureMapping_CYLINDER || mode == aiTextureMapping_PLANE || mode == aiTextureMapping_SPHERE) {
- m = new aiMaterialProperty();
- m->mKey.Set("$tex.mapaxis");
- m->mIndex = prop->mIndex;
- m->mSemantic = prop->mSemantic;
- m->mType = aiPTI_Float;
-
- m->mDataLength = 12;
- m->mData = new char[12];
- *((aiVector3D*)m->mData) = axis;
- p.push_back(m);
- }
- }
- else if (! ::strcmp( prop->mKey.data, "$tex.uvwsrc")) {
- delete mat->mProperties[i];
- }
- else p.push_back(prop);
- }
-
- if (p.empty())return;
-
- // rebuild the output array
- if (p.size() > mat->mNumAllocated) {
- delete[] mat->mProperties;
- mat->mProperties = new aiMaterialProperty*[p.size()*2];
-
- mat->mNumAllocated = static_cast<unsigned int>(p.size()*2);
- }
- mat->mNumProperties = (unsigned int)p.size();
- ::memcpy(mat->mProperties,&p[0],sizeof(void*)*mat->mNumProperties);
-}
-
-// ------------------------------------------------------------------------------------------------
-void IRRImporter::GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
- BatchLoader& batch,
- std::vector<aiMesh*>& meshes,
- std::vector<aiNodeAnim*>& anims,
- std::vector<AttachmentInfo>& attach,
- std::vector<aiMaterial*>& materials,
- unsigned int& defMatIdx)
-{
- unsigned int oldMeshSize = (unsigned int)meshes.size();
- //unsigned int meshTrafoAssign = 0;
-
- // Now determine the type of the node
- switch (root->type)
- {
- case Node::ANIMMESH:
- case Node::MESH:
- {
- if (!root->meshPath.length())
- break;
-
- // Get the loaded mesh from the scene and add it to
- // the list of all scenes to be attached to the
- // graph we're currently building
- aiScene* scene = batch.GetImport(root->id);
- if (!scene) {
- DefaultLogger::get()->error("IRR: Unable to load external file: " + root->meshPath);
- break;
- }
- attach.push_back(AttachmentInfo(scene,rootOut));
-
- // Now combine the material we've loaded for this mesh
- // with the real materials we got from the file. As we
- // don't execute any pp-steps on the file, the numbers
- // should be equal. If they are not, we can impossibly
- // do this ...
- if (root->materials.size() != (unsigned int)scene->mNumMaterials) {
- DefaultLogger::get()->warn("IRR: Failed to match imported materials "
- "with the materials found in the IRR scene file");
-
- break;
- }
- for (unsigned int i = 0; i < scene->mNumMaterials;++i) {
- // Delete the old material, we don't need it anymore
- delete scene->mMaterials[i];
-
- std::pair<aiMaterial*, unsigned int>& src = root->materials[i];
- scene->mMaterials[i] = src.first;
- }
-
- // NOTE: Each mesh should have exactly one material assigned,
- // but we do it in a separate loop if this behaviour changes
- // in future.
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- // Process material flags
- aiMesh* mesh = scene->mMeshes[i];
-
-
- // If "trans_vertex_alpha" mode is enabled, search all vertex colors
- // and check whether they have a common alpha value. This is quite
- // often the case so we can simply extract it to a shared oacity
- // value.
- std::pair<aiMaterial*, unsigned int>& src = root->materials[mesh->mMaterialIndex];
- aiMaterial* mat = (aiMaterial*)src.first;
-
- if (mesh->HasVertexColors(0) && src.second & AI_IRRMESH_MAT_trans_vertex_alpha)
- {
- bool bdo = true;
- for (unsigned int a = 1; a < mesh->mNumVertices;++a) {
-
- if (mesh->mColors[0][a].a != mesh->mColors[0][a-1].a) {
- bdo = false;
- break;
- }
- }
- if (bdo) {
- DefaultLogger::get()->info("IRR: Replacing mesh vertex alpha with common opacity");
-
- for (unsigned int a = 0; a < mesh->mNumVertices;++a)
- mesh->mColors[0][a].a = 1.f;
-
- mat->AddProperty(& mesh->mColors[0][0].a, 1, AI_MATKEY_OPACITY);
- }
- }
-
- // If we have a second texture coordinate set and a second texture
- // (either lightmap, normalmap, 2layered material) we need to
- // setup the correct UV index for it. The texture can either
- // be diffuse (lightmap & 2layer) or a normal map (normal & parallax)
- if (mesh->HasTextureCoords(1)) {
-
- int idx = 1;
- if (src.second & (AI_IRRMESH_MAT_solid_2layer | AI_IRRMESH_MAT_lightmap)) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
- }
- else if (src.second & AI_IRRMESH_MAT_normalmap_solid) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0));
- }
- }
- }
- }
- break;
-
- case Node::LIGHT:
- case Node::CAMERA:
-
- // We're already finished with lights and cameras
- break;
-
-
- case Node::SPHERE:
- {
- // Generate the sphere model. Our input parameter to
- // the sphere generation algorithm is the number of
- // subdivisions of each triangle - but here we have
- // the number of poylgons on a specific axis. Just
- // use some hardcoded limits to approximate this ...
- unsigned int mul = root->spherePolyCountX*root->spherePolyCountY;
- if (mul < 100)mul = 2;
- else if (mul < 300)mul = 3;
- else mul = 4;
-
- meshes.push_back(StandardShapes::MakeMesh(mul,
- &StandardShapes::MakeSphere));
-
- // Adjust scaling
- root->scaling *= root->sphereRadius/2;
-
- // Copy one output material
- CopyMaterial(materials, root->materials, defMatIdx, meshes.back());
-
- // Now adjust this output material - if there is a first texture
- // set, setup spherical UV mapping around the Y axis.
- SetupMapping ( (aiMaterial*) materials.back(), aiTextureMapping_SPHERE);
- }
- break;
-
- case Node::CUBE:
- {
- // Generate an unit cube first
- meshes.push_back(StandardShapes::MakeMesh(
- &StandardShapes::MakeHexahedron));
-
- // Adjust scaling
- root->scaling *= root->sphereRadius;
-
- // Copy one output material
- CopyMaterial(materials, root->materials, defMatIdx, meshes.back());
-
- // Now adjust this output material - if there is a first texture
- // set, setup cubic UV mapping
- SetupMapping ( (aiMaterial*) materials.back(), aiTextureMapping_BOX );
- }
- break;
-
-
- case Node::SKYBOX:
- {
- // A skybox is defined by six materials
- if (root->materials.size() < 6) {
- DefaultLogger::get()->error("IRR: There should be six materials for a skybox");
- break;
- }
-
- // copy those materials and generate 6 meshes for our new skybox
- materials.reserve(materials.size() + 6);
- for (unsigned int i = 0; i < 6;++i)
- materials.insert(materials.end(),root->materials[i].first);
-
- BuildSkybox(meshes,materials);
-
- // *************************************************************
- // Skyboxes will require a different code path for rendering,
- // so there must be a way for the user to add special support
- // for IRR skyboxes. We add a 'IRR.SkyBox_' prefix to the node.
- // *************************************************************
- root->name = "IRR.SkyBox_" + root->name;
- DefaultLogger::get()->info("IRR: Loading skybox, this will "
- "require special handling to be displayed correctly");
- }
- break;
-
- case Node::TERRAIN:
- {
- // to support terrains, we'd need to have a texture decoder
- DefaultLogger::get()->error("IRR: Unsupported node - TERRAIN");
- }
- break;
- default:
- // DUMMY
- break;
- };
-
- // Check whether we added a mesh (or more than one ...). In this case
- // we'll also need to attach it to the node
- if (oldMeshSize != (unsigned int) meshes.size()) {
-
- rootOut->mNumMeshes = (unsigned int)meshes.size() - oldMeshSize;
- rootOut->mMeshes = new unsigned int[rootOut->mNumMeshes];
-
- for (unsigned int a = 0; a < rootOut->mNumMeshes;++a) {
- rootOut->mMeshes[a] = oldMeshSize+a;
- }
- }
-
- // Setup the name of this node
- rootOut->mName.Set(root->name);
-
- // Now compute the final local transformation matrix of the
- // node from the given translation, rotation and scaling values.
- // (the rotation is given in Euler angles, XYZ order)
- //std::swap((float&)root->rotation.z,(float&)root->rotation.y);
- rootOut->mTransformation.FromEulerAnglesXYZ(AI_DEG_TO_RAD(root->rotation) );
-
- // apply scaling
- aiMatrix4x4& mat = rootOut->mTransformation;
- mat.a1 *= root->scaling.x;
- mat.b1 *= root->scaling.x;
- mat.c1 *= root->scaling.x;
- mat.a2 *= root->scaling.y;
- mat.b2 *= root->scaling.y;
- mat.c2 *= root->scaling.y;
- mat.a3 *= root->scaling.z;
- mat.b3 *= root->scaling.z;
- mat.c3 *= root->scaling.z;
-
- // apply translation
- mat.a4 += root->position.x;
- mat.b4 += root->position.y;
- mat.c4 += root->position.z;
-
- // now compute animations for the node
- ComputeAnimations(root,rootOut, anims);
-
- // Add all children recursively. First allocate enough storage
- // for them, then call us again
- rootOut->mNumChildren = (unsigned int)root->children.size();
- if (rootOut->mNumChildren) {
-
- rootOut->mChildren = new aiNode*[rootOut->mNumChildren];
- for (unsigned int i = 0; i < rootOut->mNumChildren;++i) {
-
- aiNode* node = rootOut->mChildren[i] = new aiNode();
- node->mParent = rootOut;
- GenerateGraph(root->children[i],node,scene,batch,meshes,
- anims,attach,materials,defMatIdx);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void IRRImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open IRR file " + pFile + "");
-
- // Construct the irrXML parser
- CIrrXML_IOStreamReader st(file.get());
- reader = createIrrXMLReader((IFileReadCallBack*) &st);
-
- // The root node of the scene
- Node* root = new Node(Node::DUMMY);
- root->parent = NULL;
- root->name = "<IRRSceneRoot>";
-
- // Current node parent
- Node* curParent = root;
-
- // Scenegraph node we're currently working on
- Node* curNode = NULL;
-
- // List of output cameras
- std::vector<aiCamera*> cameras;
-
- // List of output lights
- std::vector<aiLight*> lights;
-
- // Batch loader used to load external models
- BatchLoader batch(pIOHandler);
-// batch.SetBasePath(pFile);
-
- cameras.reserve(5);
- lights.reserve(5);
-
- bool inMaterials = false, inAnimator = false;
- unsigned int guessedAnimCnt = 0, guessedMeshCnt = 0, guessedMatCnt = 0;
-
- // Parse the XML file
- while (reader->read()) {
- switch (reader->getNodeType()) {
- case EXN_ELEMENT:
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
- // ***********************************************************************
- /* What we're going to do with the node depends
- * on its type:
- *
- * "mesh" - Load a mesh from an external file
- * "cube" - Generate a cube
- * "skybox" - Generate a skybox
- * "light" - A light source
- * "sphere" - Generate a sphere mesh
- * "animatedMesh" - Load an animated mesh from an external file
- * and join its animation channels with ours.
- * "empty" - A dummy node
- * "camera" - A camera
- * "terrain" - a terrain node (data comes from a heightmap)
- * "billboard", ""
- *
- * Each of these nodes can be animated and all can have multiple
- * materials assigned (except lights, cameras and dummies, of course).
- */
- // ***********************************************************************
- const char* sz = reader->getAttributeValueSafe("type");
- Node* nd;
- if (!ASSIMP_stricmp(sz,"mesh") || !ASSIMP_stricmp(sz,"octTree")) {
- // OctTree's and meshes are treated equally
- nd = new Node(Node::MESH);
- }
- else if (!ASSIMP_stricmp(sz,"cube")) {
- nd = new Node(Node::CUBE);
- ++guessedMeshCnt;
- // meshes.push_back(StandardShapes::MakeMesh(&StandardShapes::MakeHexahedron));
- }
- else if (!ASSIMP_stricmp(sz,"skybox")) {
- nd = new Node(Node::SKYBOX);
- guessedMeshCnt += 6;
- }
- else if (!ASSIMP_stricmp(sz,"camera")) {
- nd = new Node(Node::CAMERA);
-
- // Setup a temporary name for the camera
- aiCamera* cam = new aiCamera();
- cam->mName.Set( nd->name );
- cameras.push_back(cam);
- }
- else if (!ASSIMP_stricmp(sz,"light")) {
- nd = new Node(Node::LIGHT);
-
- // Setup a temporary name for the light
- aiLight* cam = new aiLight();
- cam->mName.Set( nd->name );
- lights.push_back(cam);
- }
- else if (!ASSIMP_stricmp(sz,"sphere")) {
- nd = new Node(Node::SPHERE);
- ++guessedMeshCnt;
- }
- else if (!ASSIMP_stricmp(sz,"animatedMesh")) {
- nd = new Node(Node::ANIMMESH);
- }
- else if (!ASSIMP_stricmp(sz,"empty")) {
- nd = new Node(Node::DUMMY);
- }
- else if (!ASSIMP_stricmp(sz,"terrain")) {
- nd = new Node(Node::TERRAIN);
- }
- else if (!ASSIMP_stricmp(sz,"billBoard")) {
- // We don't support billboards, so ignore them
- DefaultLogger::get()->error("IRR: Billboards are not supported by Assimp");
- nd = new Node(Node::DUMMY);
- }
- else {
- DefaultLogger::get()->warn("IRR: Found unknown node: " + std::string(sz));
-
- /* We skip the contents of nodes we don't know.
- * We parse the transformation and all animators
- * and skip the rest.
- */
- nd = new Node(Node::DUMMY);
- }
-
- /* Attach the newly created node to the scenegraph
- */
- curNode = nd;
- nd->parent = curParent;
- curParent->children.push_back(nd);
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
- inMaterials = true;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
- inAnimator = true;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
- /* We should have a valid node here
- * FIX: no ... the scene root node is also contained in an attributes block
- */
- if (!curNode) {
-#if 0
- DefaultLogger::get()->error("IRR: Encountered <attributes> element, but "
- "there is no node active");
-#endif
- continue;
- }
-
- Animator* curAnim = NULL;
-
- // Materials can occur for nearly any type of node
- if (inMaterials && curNode->type != Node::DUMMY) {
- /* This is a material description - parse it!
- */
- curNode->materials.push_back(std::pair< aiMaterial*, unsigned int > () );
- std::pair< aiMaterial*, unsigned int >& p = curNode->materials.back();
-
- p.first = ParseMaterial(p.second);
-
- ++guessedMatCnt;
- continue;
- }
- else if (inAnimator) {
- /* This is an animation path - add a new animator
- * to the list.
- */
- curNode->animators.push_back(Animator());
- curAnim = & curNode->animators.back();
-
- ++guessedAnimCnt;
- }
-
- /* Parse all elements in the attributes block
- * and process them.
- */
- while (reader->read()) {
- if (reader->getNodeType() == EXN_ELEMENT) {
- if (!ASSIMP_stricmp(reader->getNodeName(),"vector3d")) {
- VectorProperty prop;
- ReadVectorProperty(prop);
-
- if (inAnimator) {
- if (curAnim->type == Animator::ROTATION && prop.name == "Rotation") {
- // We store the rotation euler angles in 'direction'
- curAnim->direction = prop.value;
- }
- else if (curAnim->type == Animator::FOLLOW_SPLINE) {
- // Check whether the vector follows the PointN naming scheme,
- // here N is the ONE-based index of the point
- if (prop.name.length() >= 6 && prop.name.substr(0,5) == "Point") {
- // Add a new key to the list
- curAnim->splineKeys.push_back(aiVectorKey());
- aiVectorKey& key = curAnim->splineKeys.back();
-
- // and parse its properties
- key.mValue = prop.value;
- key.mTime = strtoul10(&prop.name[5]);
- }
- }
- else if (curAnim->type == Animator::FLY_CIRCLE) {
- if (prop.name == "Center") {
- curAnim->circleCenter = prop.value;
- }
- else if (prop.name == "Direction") {
- curAnim->direction = prop.value;
-
- // From Irrlicht's source - a workaround for backward compatibility with Irrlicht 1.1
- if (curAnim->direction == aiVector3D()) {
- curAnim->direction = aiVector3D(0.f,1.f,0.f);
- }
- else curAnim->direction.Normalize();
- }
- }
- else if (curAnim->type == Animator::FLY_STRAIGHT) {
- if (prop.name == "Start") {
- // We reuse the field here
- curAnim->circleCenter = prop.value;
- }
- else if (prop.name == "End") {
- // We reuse the field here
- curAnim->direction = prop.value;
- }
- }
- }
- else {
- if (prop.name == "Position") {
- curNode->position = prop.value;
- }
- else if (prop.name == "Rotation") {
- curNode->rotation = prop.value;
- }
- else if (prop.name == "Scale") {
- curNode->scaling = prop.value;
- }
- else if (Node::CAMERA == curNode->type)
- {
- aiCamera* cam = cameras.back();
- if (prop.name == "Target") {
- cam->mLookAt = prop.value;
- }
- else if (prop.name == "UpVector") {
- cam->mUp = prop.value;
- }
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"bool")) {
- BoolProperty prop;
- ReadBoolProperty(prop);
-
- if (inAnimator && curAnim->type == Animator::FLY_CIRCLE && prop.name == "Loop") {
- curAnim->loop = prop.value;
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"float")) {
- FloatProperty prop;
- ReadFloatProperty(prop);
-
- if (inAnimator) {
- // The speed property exists for several animators
- if (prop.name == "Speed") {
- curAnim->speed = prop.value;
- }
- else if (curAnim->type == Animator::FLY_CIRCLE && prop.name == "Radius") {
- curAnim->circleRadius = prop.value;
- }
- else if (curAnim->type == Animator::FOLLOW_SPLINE && prop.name == "Tightness") {
- curAnim->tightness = prop.value;
- }
- }
- else {
- if (prop.name == "FramesPerSecond" && Node::ANIMMESH == curNode->type) {
- curNode->framesPerSecond = prop.value;
- }
- else if (Node::CAMERA == curNode->type) {
- /* This is the vertical, not the horizontal FOV.
- * We need to compute the right FOV from the
- * screen aspect which we don't know yet.
- */
- if (prop.name == "Fovy") {
- cameras.back()->mHorizontalFOV = prop.value;
- }
- else if (prop.name == "Aspect") {
- cameras.back()->mAspect = prop.value;
- }
- else if (prop.name == "ZNear") {
- cameras.back()->mClipPlaneNear = prop.value;
- }
- else if (prop.name == "ZFar") {
- cameras.back()->mClipPlaneFar = prop.value;
- }
- }
- else if (Node::LIGHT == curNode->type) {
- /* Additional light information
- */
- if (prop.name == "Attenuation") {
- lights.back()->mAttenuationLinear = prop.value;
- }
- else if (prop.name == "OuterCone") {
- lights.back()->mAngleOuterCone = AI_DEG_TO_RAD( prop.value );
- }
- else if (prop.name == "InnerCone") {
- lights.back()->mAngleInnerCone = AI_DEG_TO_RAD( prop.value );
- }
- }
- // radius of the sphere to be generated -
- // or alternatively, size of the cube
- else if ((Node::SPHERE == curNode->type && prop.name == "Radius")
- || (Node::CUBE == curNode->type && prop.name == "Size" )) {
-
- curNode->sphereRadius = prop.value;
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"int")) {
- IntProperty prop;
- ReadIntProperty(prop);
-
- if (inAnimator) {
- if (curAnim->type == Animator::FLY_STRAIGHT && prop.name == "TimeForWay") {
- curAnim->timeForWay = prop.value;
- }
- }
- else {
- // sphere polgon numbers in each direction
- if (Node::SPHERE == curNode->type) {
-
- if (prop.name == "PolyCountX") {
- curNode->spherePolyCountX = prop.value;
- }
- else if (prop.name == "PolyCountY") {
- curNode->spherePolyCountY = prop.value;
- }
- }
- }
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"string") ||!ASSIMP_stricmp(reader->getNodeName(),"enum")) {
- StringProperty prop;
- ReadStringProperty(prop);
- if (prop.value.length()) {
- if (prop.name == "Name") {
- curNode->name = prop.value;
-
- /* If we're either a camera or a light source
- * we need to update the name in the aiLight/
- * aiCamera structure, too.
- */
- if (Node::CAMERA == curNode->type) {
- cameras.back()->mName.Set(prop.value);
- }
- else if (Node::LIGHT == curNode->type) {
- lights.back()->mName.Set(prop.value);
- }
- }
- else if (Node::LIGHT == curNode->type && "LightType" == prop.name)
- {
- if (prop.value == "Spot")
- lights.back()->mType = aiLightSource_SPOT;
- else if (prop.value == "Point")
- lights.back()->mType = aiLightSource_POINT;
- else if (prop.value == "Directional")
- lights.back()->mType = aiLightSource_DIRECTIONAL;
- else
- {
- // We won't pass the validation with aiLightSourceType_UNDEFINED,
- // so we remove the light and replace it with a silly dummy node
- delete lights.back();
- lights.pop_back();
- curNode->type = Node::DUMMY;
-
- DefaultLogger::get()->error("Ignoring light of unknown type: " + prop.value);
- }
- }
- else if ((prop.name == "Mesh" && Node::MESH == curNode->type) ||
- Node::ANIMMESH == curNode->type)
- {
- /* This is the file name of the mesh - either
- * animated or not. We need to make sure we setup
- * the correct postprocessing settings here.
- */
- unsigned int pp = 0;
- BatchLoader::PropertyMap map;
-
- /* If the mesh is a static one remove all animations from the impor data
- */
- if (Node::ANIMMESH != curNode->type) {
- pp |= aiProcess_RemoveComponent;
- SetGenericProperty<int>(map.ints,AI_CONFIG_PP_RVC_FLAGS,
- aiComponent_ANIMATIONS | aiComponent_BONEWEIGHTS);
- }
-
- /* TODO: maybe implement the protection against recursive
- * loading calls directly in BatchLoader? The current
- * implementation is not absolutely safe. A LWS and an IRR
- * file referencing each other *could* cause the system to
- * recurse forever.
- */
-
- const std::string extension = GetExtension(prop.value);
- if ("irr" == extension) {
- DefaultLogger::get()->error("IRR: Can't load another IRR file recursively");
- }
- else
- {
- curNode->id = batch.AddLoadRequest(prop.value,pp,&map);
- curNode->meshPath = prop.value;
- }
- }
- else if (inAnimator && prop.name == "Type")
- {
- // type of the animator
- if (prop.value == "rotation") {
- curAnim->type = Animator::ROTATION;
- }
- else if (prop.value == "flyCircle") {
- curAnim->type = Animator::FLY_CIRCLE;
- }
- else if (prop.value == "flyStraight") {
- curAnim->type = Animator::FLY_CIRCLE;
- }
- else if (prop.value == "followSpline") {
- curAnim->type = Animator::FOLLOW_SPLINE;
- }
- else {
- DefaultLogger::get()->warn("IRR: Ignoring unknown animator: "
- + prop.value);
-
- curAnim->type = Animator::UNKNOWN;
- }
- }
- }
- }
- }
- else if (reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(reader->getNodeName(),"attributes")) {
- break;
- }
- }
- }
- break;
-
- case EXN_ELEMENT_END:
-
- // If we reached the end of a node, we need to continue processing its parent
- if (!ASSIMP_stricmp(reader->getNodeName(),"node")) {
- if (!curNode) {
- // currently is no node set. We need to go
- // back in the node hierarchy
- if (!curParent) {
- curParent = root;
- DefaultLogger::get()->error("IRR: Too many closing <node> elements");
- }
- else curParent = curParent->parent;
- }
- else curNode = NULL;
- }
- // clear all flags
- else if (!ASSIMP_stricmp(reader->getNodeName(),"materials")) {
- inMaterials = false;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"animators")) {
- inAnimator = false;
- }
- break;
-
- default:
- // GCC complains that not all enumeration values are handled
- break;
- }
- }
-
- /* Now iterate through all cameras and compute their final (horizontal) FOV
- */
- for (aiCamera *cam : cameras) {
-
- // screen aspect could be missing
- if (cam->mAspect) {
- cam->mHorizontalFOV *= cam->mAspect;
- }
- else DefaultLogger::get()->warn("IRR: Camera aspect is not given, can't compute horizontal FOV");
- }
-
- batch.LoadAll();
-
- /* Allocate a tempoary scene data structure
- */
- aiScene* tempScene = new aiScene();
- tempScene->mRootNode = new aiNode();
- tempScene->mRootNode->mName.Set("<IRRRoot>");
-
- /* Copy the cameras to the output array
- */
- if (!cameras.empty()) {
- tempScene->mNumCameras = (unsigned int)cameras.size();
- tempScene->mCameras = new aiCamera*[tempScene->mNumCameras];
- ::memcpy(tempScene->mCameras,&cameras[0],sizeof(void*)*tempScene->mNumCameras);
- }
-
- /* Copy the light sources to the output array
- */
- if (!lights.empty()) {
- tempScene->mNumLights = (unsigned int)lights.size();
- tempScene->mLights = new aiLight*[tempScene->mNumLights];
- ::memcpy(tempScene->mLights,&lights[0],sizeof(void*)*tempScene->mNumLights);
- }
-
- // temporary data
- std::vector< aiNodeAnim*> anims;
- std::vector< aiMaterial*> materials;
- std::vector< AttachmentInfo > attach;
- std::vector<aiMesh*> meshes;
-
- // try to guess how much storage we'll need
- anims.reserve (guessedAnimCnt + (guessedAnimCnt >> 2));
- meshes.reserve (guessedMeshCnt + (guessedMeshCnt >> 2));
- materials.reserve (guessedMatCnt + (guessedMatCnt >> 2));
-
- /* Now process our scenegraph recursively: generate final
- * meshes and generate animation channels for all nodes.
- */
- unsigned int defMatIdx = UINT_MAX;
- GenerateGraph(root,tempScene->mRootNode, tempScene,
- batch, meshes, anims, attach, materials, defMatIdx);
-
- if (!anims.empty())
- {
- tempScene->mNumAnimations = 1;
- tempScene->mAnimations = new aiAnimation*[tempScene->mNumAnimations];
- aiAnimation* an = tempScene->mAnimations[0] = new aiAnimation();
-
- // ***********************************************************
- // This is only the global animation channel of the scene.
- // If there are animated models, they will have separate
- // animation channels in the scene. To display IRR scenes
- // correctly, users will need to combine the global anim
- // channel with all the local animations they want to play
- // ***********************************************************
- an->mName.Set("Irr_GlobalAnimChannel");
-
- // copy all node animation channels to the global channel
- an->mNumChannels = (unsigned int)anims.size();
- an->mChannels = new aiNodeAnim*[an->mNumChannels];
- ::memcpy(an->mChannels, & anims [0], sizeof(void*)*an->mNumChannels);
- }
- if (!meshes.empty()) {
- // copy all meshes to the temporary scene
- tempScene->mNumMeshes = (unsigned int)meshes.size();
- tempScene->mMeshes = new aiMesh*[tempScene->mNumMeshes];
- ::memcpy(tempScene->mMeshes,&meshes[0],tempScene->mNumMeshes*
- sizeof(void*));
- }
-
- /* Copy all materials to the output array
- */
- if (!materials.empty()) {
- tempScene->mNumMaterials = (unsigned int)materials.size();
- tempScene->mMaterials = new aiMaterial*[tempScene->mNumMaterials];
- ::memcpy(tempScene->mMaterials,&materials[0],sizeof(void*)*
- tempScene->mNumMaterials);
- }
-
- /* Now merge all sub scenes and attach them to the correct
- * attachment points in the scenegraph.
- */
- SceneCombiner::MergeScenes(&pScene,tempScene,attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
-
-
- /* If we have no meshes | no materials now set the INCOMPLETE
- * scene flag. This is necessary if we failed to load all
- * models from external files
- */
- if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
- DefaultLogger::get()->warn("IRR: No meshes loaded, setting AI_SCENE_FLAGS_INCOMPLETE");
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- /* Finished ... everything destructs automatically and all
- * temporary scenes have already been deleted by MergeScenes()
- */
- return;
-}
-
-#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
diff --git a/src/3rdparty/assimp/code/IRRLoader.h b/src/3rdparty/assimp/code/IRRLoader.h
deleted file mode 100644
index d07199c0b..000000000
--- a/src/3rdparty/assimp/code/IRRLoader.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IRRLoader.h
- * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
- * importer class.
- */
-#ifndef AI_IRRLOADER_H_INCLUDED
-#define AI_IRRLOADER_H_INCLUDED
-
-#include "IRRShared.h"
-#include <assimp/SceneCombiner.h>
-#include "Importer.h"
-#include "StringUtils.h"
-#include <assimp/anim.h>
-
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** Irr importer class.
- *
- * Irr is the native scene file format of the Irrlight engine and its editor
- * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
- * it might be a good file format for data exchange.
- */
-class IRRImporter : public BaseImporter, public IrrlichtBase
-{
-public:
- IRRImporter();
- ~IRRImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /**
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /**
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /**
- */
- void SetupProperties(const Importer* pImp);
-
-private:
-
- /** Data structure for a scenegraph node animator
- */
- struct Animator
- {
- // Type of the animator
- enum AT
- {
- UNKNOWN = 0x0,
- ROTATION = 0x1,
- FLY_CIRCLE = 0x2,
- FLY_STRAIGHT = 0x3,
- FOLLOW_SPLINE = 0x4,
- OTHER = 0x5
-
- } type;
-
- explicit Animator(AT t = UNKNOWN)
- : type (t)
- , speed ( ai_real( 0.001 ) )
- , direction ( ai_real( 0.0 ), ai_real( 1.0 ), ai_real( 0.0 ) )
- , circleRadius ( ai_real( 1.0) )
- , tightness ( ai_real( 0.5 ) )
- , loop (true)
- , timeForWay (100)
- {
- }
-
-
- // common parameters
- ai_real speed;
- aiVector3D direction;
-
- // FLY_CIRCLE
- aiVector3D circleCenter;
- ai_real circleRadius;
-
- // FOLLOW_SPLINE
- ai_real tightness;
- std::vector<aiVectorKey> splineKeys;
-
- // ROTATION (angles given in direction)
-
- // FLY STRAIGHT
- // circleCenter = start, direction = end
- bool loop;
- int timeForWay;
- };
-
- /** Data structure for a scenegraph node in an IRR file
- */
- struct Node
- {
- // Type of the node
- enum ET
- {
- LIGHT,
- CUBE,
- MESH,
- SKYBOX,
- DUMMY,
- CAMERA,
- TERRAIN,
- SPHERE,
- ANIMMESH
- } type;
-
- explicit Node(ET t)
- : type (t)
- , scaling (1.0,1.0,1.0) // assume uniform scaling by default
- , parent()
- , framesPerSecond (0.0)
- , id()
- , sphereRadius (1.0)
- , spherePolyCountX (100)
- , spherePolyCountY (100)
- {
-
- // Generate a default name for the node
- char buffer[128];
- static int cnt;
- ai_snprintf(buffer, 128, "IrrNode_%i",cnt++);
- name = std::string(buffer);
-
- // reserve space for up to 5 materials
- materials.reserve(5);
-
- // reserve space for up to 5 children
- children.reserve(5);
- }
-
- // Transformation of the node
- aiVector3D position, rotation, scaling;
-
- // Name of the node
- std::string name;
-
- // List of all child nodes
- std::vector<Node*> children;
-
- // Parent node
- Node* parent;
-
- // Animated meshes: frames per second
- // 0.f if not specified
- ai_real framesPerSecond;
-
- // Meshes: path to the mesh to be loaded
- std::string meshPath;
- unsigned int id;
-
- // Meshes: List of materials to be assigned
- // along with their corresponding material flags
- std::vector< std::pair<aiMaterial*, unsigned int> > materials;
-
- // Spheres: radius of the sphere to be generates
- ai_real sphereRadius;
-
- // Spheres: Number of polygons in the x,y direction
- unsigned int spherePolyCountX,spherePolyCountY;
-
- // List of all animators assigned to the node
- std::list<Animator> animators;
- };
-
- /** Data structure for a vertex in an IRR skybox
- */
- struct SkyboxVertex
- {
- SkyboxVertex()
- {}
-
- //! Construction from single vertex components
- SkyboxVertex(ai_real px, ai_real py, ai_real pz,
- ai_real nx, ai_real ny, ai_real nz,
- ai_real uvx, ai_real uvy)
-
- : position (px,py,pz)
- , normal (nx,ny,nz)
- , uv (uvx,uvy,0.0)
- {}
-
- aiVector3D position, normal, uv;
- };
-
-
- // -------------------------------------------------------------------
- /** Fill the scenegraph recursively
- */
- void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
- BatchLoader& batch,
- std::vector<aiMesh*>& meshes,
- std::vector<aiNodeAnim*>& anims,
- std::vector<AttachmentInfo>& attach,
- std::vector<aiMaterial*>& materials,
- unsigned int& defaultMatIdx);
-
-
- // -------------------------------------------------------------------
- /** Generate a mesh that consists of just a single quad
- */
- aiMesh* BuildSingleQuadMesh(const SkyboxVertex& v1,
- const SkyboxVertex& v2,
- const SkyboxVertex& v3,
- const SkyboxVertex& v4);
-
-
- // -------------------------------------------------------------------
- /** Build a skybox
- *
- * @param meshes Receives 6 output meshes
- * @param materials The last 6 materials are assigned to the newly
- * created meshes. The names of the materials are adjusted.
- */
- void BuildSkybox(std::vector<aiMesh*>& meshes,
- std::vector<aiMaterial*> materials);
-
-
- // -------------------------------------------------------------------
- /** Copy a material for a mesh to the output material list
- *
- * @param materials Receives an output material
- * @param inmaterials List of input materials
- * @param defMatIdx Default material index - UINT_MAX if not present
- * @param mesh Mesh to work on
- */
- void CopyMaterial(std::vector<aiMaterial*>& materials,
- std::vector< std::pair<aiMaterial*, unsigned int> >& inmaterials,
- unsigned int& defMatIdx,
- aiMesh* mesh);
-
-
- // -------------------------------------------------------------------
- /** Compute animations for a specific node
- *
- * @param root Node to be processed
- * @param anims The list of output animations
- */
- void ComputeAnimations(Node* root, aiNode* real,
- std::vector<aiNodeAnim*>& anims);
-
-
-private:
-
- /** Configuration option: desired output FPS */
- double fps;
-
- /** Configuration option: speed flag was set? */
- bool configSpeedFlag;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IRRIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/IRRMeshLoader.cpp b/src/3rdparty/assimp/code/IRRMeshLoader.cpp
deleted file mode 100644
index a63a2a134..000000000
--- a/src/3rdparty/assimp/code/IRRMeshLoader.cpp
+++ /dev/null
@@ -1,535 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the IrrMesh importer class */
-
-
-
-#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-
-#include "IRRMeshLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/mesh.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include "Macros.h"
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-static const aiImporterDesc desc = {
- "Irrlicht Mesh Reader",
- "",
- "",
- "http://irrlicht.sourceforge.net/",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "xml irrmesh"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-IRRMeshImporter::IRRMeshImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-IRRMeshImporter::~IRRMeshImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool IRRMeshImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- /* NOTE: A simple check for the file extension is not enough
- * here. Irrmesh and irr are easy, but xml is too generic
- * and could be collada, too. So we need to open the file and
- * search for typical tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "irrmesh")return true;
- else if (extension == "xml" || checkSig)
- {
- /* If CanRead() is called to check whether the loader
- * supports a specific file extension in general we
- * must return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"irrmesh"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all file extensions which are handled by this class
-const aiImporterDesc* IRRMeshImporter::GetInfo () const
-{
- return &desc;
-}
-
-static void releaseMaterial( aiMaterial **mat ) {
- if(*mat!= nullptr) {
- delete *mat;
- *mat = nullptr;
- }
-}
-
-static void releaseMesh( aiMesh **mesh ) {
- if (*mesh != nullptr){
- delete *mesh;
- *mesh = nullptr;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void IRRMeshImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open IRRMESH file " + pFile + "");
-
- // Construct the irrXML parser
- CIrrXML_IOStreamReader st(file.get());
- reader = createIrrXMLReader((IFileReadCallBack*) &st);
-
- // final data
- std::vector<aiMaterial*> materials;
- std::vector<aiMesh*> meshes;
- materials.reserve (5);
- meshes.reserve(5);
-
- // temporary data - current mesh buffer
- aiMaterial* curMat = nullptr;
- aiMesh* curMesh = nullptr;
- unsigned int curMatFlags = 0;
-
- std::vector<aiVector3D> curVertices,curNormals,curTangents,curBitangents;
- std::vector<aiColor4D> curColors;
- std::vector<aiVector3D> curUVs,curUV2s;
-
- // some temporary variables
- int textMeaning = 0;
- int vertexFormat = 0; // 0 = normal; 1 = 2 tcoords, 2 = tangents
- bool useColors = false;
-
- // Parse the XML file
- while (reader->read()) {
- switch (reader->getNodeType()) {
- case EXN_ELEMENT:
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"buffer") && (curMat || curMesh)) {
- // end of previous buffer. A material and a mesh should be there
- if ( !curMat || !curMesh) {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- releaseMaterial( &curMat );
- releaseMesh( &curMesh );
- } else {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- curMat = nullptr;
- curMesh = nullptr;
-
- curVertices.clear();
- curColors.clear();
- curNormals.clear();
- curUV2s.clear();
- curUVs.clear();
- curTangents.clear();
- curBitangents.clear();
- }
-
-
- if (!ASSIMP_stricmp(reader->getNodeName(),"material")) {
- if (curMat) {
- DefaultLogger::get()->warn("IRRMESH: Only one material description per buffer, please");
- releaseMaterial( &curMat );
- }
- curMat = ParseMaterial(curMatFlags);
- }
- /* no else here! */ if (!ASSIMP_stricmp(reader->getNodeName(),"vertices"))
- {
- int num = reader->getAttributeValueAsInt("vertexCount");
-
- if (!num) {
- // This is possible ... remove the mesh from the list and skip further reading
- DefaultLogger::get()->warn("IRRMESH: Found mesh with zero vertices");
-
- releaseMaterial( &curMat );
- releaseMesh( &curMesh );
- textMeaning = 0;
- continue;
- }
-
- curVertices.reserve(num);
- curNormals.reserve(num);
- curColors.reserve(num);
- curUVs.reserve(num);
-
- // Determine the file format
- const char* t = reader->getAttributeValueSafe("type");
- if (!ASSIMP_stricmp("2tcoords", t)) {
- curUV2s.reserve (num);
- vertexFormat = 1;
-
- if (curMatFlags & AI_IRRMESH_EXTRA_2ND_TEXTURE) {
- // *********************************************************
- // We have a second texture! So use this UV channel
- // for it. The 2nd texture can be either a normal
- // texture (solid_2layer or lightmap_xxx) or a normal
- // map (normal_..., parallax_...)
- // *********************************************************
- int idx = 1;
- aiMaterial* mat = ( aiMaterial* ) curMat;
-
- if (curMatFlags & AI_IRRMESH_MAT_lightmap){
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_LIGHTMAP(0));
- }
- else if (curMatFlags & AI_IRRMESH_MAT_normalmap_solid){
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_NORMALS(0));
- }
- else if (curMatFlags & AI_IRRMESH_MAT_solid_2layer) {
- mat->AddProperty(&idx,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
- }
- }
- }
- else if (!ASSIMP_stricmp("tangents", t)) {
- curTangents.reserve (num);
- curBitangents.reserve (num);
- vertexFormat = 2;
- }
- else if (ASSIMP_stricmp("standard", t)) {
- releaseMaterial( &curMat );
- DefaultLogger::get()->warn("IRRMESH: Unknown vertex format");
- }
- else vertexFormat = 0;
- textMeaning = 1;
- }
- else if (!ASSIMP_stricmp(reader->getNodeName(),"indices")) {
- if (curVertices.empty() && curMat) {
- releaseMaterial( &curMat );
- throw DeadlyImportError("IRRMESH: indices must come after vertices");
- }
-
- textMeaning = 2;
-
- // start a new mesh
- curMesh = new aiMesh();
-
- // allocate storage for all faces
- curMesh->mNumVertices = reader->getAttributeValueAsInt("indexCount");
- if (!curMesh->mNumVertices) {
- // This is possible ... remove the mesh from the list and skip further reading
- DefaultLogger::get()->warn("IRRMESH: Found mesh with zero indices");
-
- // mesh - away
- releaseMesh( &curMesh );
-
- // material - away
- releaseMaterial( &curMat );
-
- textMeaning = 0;
- continue;
- }
-
- if (curMesh->mNumVertices % 3) {
- DefaultLogger::get()->warn("IRRMESH: Number if indices isn't divisible by 3");
- }
-
- curMesh->mNumFaces = curMesh->mNumVertices / 3;
- curMesh->mFaces = new aiFace[curMesh->mNumFaces];
-
- // setup some members
- curMesh->mMaterialIndex = (unsigned int)materials.size();
- curMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for all vertices
- curMesh->mVertices = new aiVector3D[curMesh->mNumVertices];
-
- if (curNormals.size() == curVertices.size()) {
- curMesh->mNormals = new aiVector3D[curMesh->mNumVertices];
- }
- if (curTangents.size() == curVertices.size()) {
- curMesh->mTangents = new aiVector3D[curMesh->mNumVertices];
- }
- if (curBitangents.size() == curVertices.size()) {
- curMesh->mBitangents = new aiVector3D[curMesh->mNumVertices];
- }
- if (curColors.size() == curVertices.size() && useColors) {
- curMesh->mColors[0] = new aiColor4D[curMesh->mNumVertices];
- }
- if (curUVs.size() == curVertices.size()) {
- curMesh->mTextureCoords[0] = new aiVector3D[curMesh->mNumVertices];
- }
- if (curUV2s.size() == curVertices.size()) {
- curMesh->mTextureCoords[1] = new aiVector3D[curMesh->mNumVertices];
- }
- }
- break;
-
- case EXN_TEXT:
- {
- const char* sz = reader->getNodeData();
- if (textMeaning == 1) {
- textMeaning = 0;
-
- // read vertices
- do {
- SkipSpacesAndLineEnd(&sz);
- aiVector3D temp;aiColor4D c;
-
- // Read the vertex position
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.z);
- SkipSpaces(&sz);
- curVertices.push_back(temp);
-
- // Read the vertex normals
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.z);
- SkipSpaces(&sz);
- curNormals.push_back(temp);
-
- // read the vertex colors
- uint32_t clr = strtoul16(sz,&sz);
- ColorFromARGBPacked(clr,c);
-
- if (!curColors.empty() && c != *(curColors.end()-1))
- useColors = true;
-
- curColors.push_back(c);
- SkipSpaces(&sz);
-
-
- // read the first UV coordinate set
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.z = 0.f;
- temp.y = 1.f - temp.y; // DX to OGL
- curUVs.push_back(temp);
-
- // read the (optional) second UV coordinate set
- if (vertexFormat == 1) {
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- temp.y = 1.f - temp.y; // DX to OGL
- curUV2s.push_back(temp);
- }
- // read optional tangent and bitangent vectors
- else if (vertexFormat == 2) {
- // tangents
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.z);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curTangents.push_back(temp);
-
- // bitangents
- sz = fast_atoreal_move<float>(sz,(float&)temp.x);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.z);
- SkipSpaces(&sz);
-
- sz = fast_atoreal_move<float>(sz,(float&)temp.y);
- SkipSpaces(&sz);
- temp.y *= -1.0f;
- curBitangents.push_back(temp);
- }
- }
-
- /* IMPORTANT: We assume that each vertex is specified in one
- line. So we can skip the rest of the line - unknown vertex
- elements are ignored.
- */
-
- while (SkipLine(&sz));
- }
- else if (textMeaning == 2) {
- textMeaning = 0;
-
- // read indices
- aiFace* curFace = curMesh->mFaces;
- aiFace* const faceEnd = curMesh->mFaces + curMesh->mNumFaces;
-
- aiVector3D* pcV = curMesh->mVertices;
- aiVector3D* pcN = curMesh->mNormals;
- aiVector3D* pcT = curMesh->mTangents;
- aiVector3D* pcB = curMesh->mBitangents;
- aiColor4D* pcC0 = curMesh->mColors[0];
- aiVector3D* pcT0 = curMesh->mTextureCoords[0];
- aiVector3D* pcT1 = curMesh->mTextureCoords[1];
-
- unsigned int curIdx = 0;
- unsigned int total = 0;
- while(SkipSpacesAndLineEnd(&sz)) {
- if (curFace >= faceEnd) {
- DefaultLogger::get()->error("IRRMESH: Too many indices");
- break;
- }
- if (!curIdx) {
- curFace->mNumIndices = 3;
- curFace->mIndices = new unsigned int[3];
- }
-
- unsigned int idx = strtoul10(sz,&sz);
- if (idx >= curVertices.size()) {
- DefaultLogger::get()->error("IRRMESH: Index out of range");
- idx = 0;
- }
-
- curFace->mIndices[curIdx] = total++;
-
- *pcV++ = curVertices[idx];
- if (pcN)*pcN++ = curNormals[idx];
- if (pcT)*pcT++ = curTangents[idx];
- if (pcB)*pcB++ = curBitangents[idx];
- if (pcC0)*pcC0++ = curColors[idx];
- if (pcT0)*pcT0++ = curUVs[idx];
- if (pcT1)*pcT1++ = curUV2s[idx];
-
- if (++curIdx == 3) {
- ++curFace;
- curIdx = 0;
- }
- }
-
- if (curFace != faceEnd)
- DefaultLogger::get()->error("IRRMESH: Not enough indices");
-
- // Finish processing the mesh - do some small material workarounds
- if (curMatFlags & AI_IRRMESH_MAT_trans_vertex_alpha && !useColors) {
- // Take the opacity value of the current material
- // from the common vertex color alpha
- aiMaterial* mat = (aiMaterial*)curMat;
- mat->AddProperty(&curColors[0].a,1,AI_MATKEY_OPACITY);
- }
- }}
- break;
-
- default:
- // GCC complains here ...
- break;
-
- };
- }
-
- // End of the last buffer. A material and a mesh should be there
- if (curMat || curMesh) {
- if ( !curMat || !curMesh) {
- DefaultLogger::get()->error("IRRMESH: A buffer must contain a mesh and a material");
- releaseMaterial( &curMat );
- releaseMesh( &curMesh );
- }
- else {
- materials.push_back(curMat);
- meshes.push_back(curMesh);
- }
- }
-
- if (materials.empty())
- throw DeadlyImportError("IRRMESH: Unable to read a mesh from this file");
-
-
- // now generate the output scene
- pScene->mNumMeshes = (unsigned int)meshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- pScene->mMeshes[i] = meshes[i];
-
- // clean this value ...
- pScene->mMeshes[i]->mNumUVComponents[3] = 0;
- }
-
- pScene->mNumMaterials = (unsigned int)materials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- ::memcpy(pScene->mMaterials,&materials[0],sizeof(void*)*pScene->mNumMaterials);
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<IRRMesh>");
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- // clean up and return
- delete reader;
- AI_DEBUG_INVALIDATE_PTR(reader);
-}
-
-#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
diff --git a/src/3rdparty/assimp/code/IRRMeshLoader.h b/src/3rdparty/assimp/code/IRRMeshLoader.h
deleted file mode 100644
index 312dbbfe0..000000000
--- a/src/3rdparty/assimp/code/IRRMeshLoader.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IRRMeshLoader.h
- * @brief Declaration of the .irrMesh (Irrlight Engine Mesh Format)
- * importer class.
- */
-#ifndef AI_IRRMESHLOADER_H_INCLUDED
-#define AI_IRRMESHLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "IRRShared.h"
-
-#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** IrrMesh importer class.
- *
- * IrrMesh is the native file format of the Irrlight engine and its editor
- * irrEdit. As IrrEdit itself is capable of importing quite many file formats,
- * it might be a good file format for data exchange.
- */
-class IRRMeshImporter : public BaseImporter, public IrrlichtBase
-{
-public:
- IRRMeshImporter();
- ~IRRMeshImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-};
-
-} // end of namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-
-#endif // AI_IRRMESHIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/IRRShared.cpp b/src/3rdparty/assimp/code/IRRShared.cpp
deleted file mode 100644
index bfe408629..000000000
--- a/src/3rdparty/assimp/code/IRRShared.cpp
+++ /dev/null
@@ -1,505 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IRRShared.cpp
- * @brief Shared utilities for the IRR and IRRMESH loaders
- */
-
-
-
-//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"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/material.h>
-
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-// Transformation matrix to convert from Assimp to IRR space
-const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
-
-// ------------------------------------------------------------------------------------------------
-// read a property in hexadecimal format (i.e. ffffffff)
-void IrrlichtBase::ReadHexProperty (HexProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the hexadecimal value
- out.value = strtoul16(reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a decimal property
-void IrrlichtBase::ReadIntProperty (IntProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // parse the ecimal value
- out.value = strtol10(reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a string property
-void IrrlichtBase::ReadStringProperty (StringProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // simple copy the string
- out.value = std::string (reader->getAttributeValue(i));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a boolean property
-void IrrlichtBase::ReadBoolProperty (BoolProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // true or false, case insensitive
- out.value = (ASSIMP_stricmp( reader->getAttributeValue(i),
- "true") ? false : true);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a float property
-void IrrlichtBase::ReadFloatProperty (FloatProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // just parse the float
- out.value = fast_atof( reader->getAttributeValue(i) );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read a vector property
-void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
-{
- for (int i = 0; i < reader->getAttributeCount();++i)
- {
- if (!ASSIMP_stricmp(reader->getAttributeName(i),"name"))
- {
- out.name = std::string( reader->getAttributeValue(i) );
- }
- else if (!ASSIMP_stricmp(reader->getAttributeName(i),"value"))
- {
- // three floats, separated with commas
- const char* ptr = reader->getAttributeValue(i);
-
- SkipSpaces(&ptr);
- ptr = fast_atoreal_move<float>( ptr,(float&)out.value.x );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y );
- SkipSpaces(&ptr);
- if (',' != *ptr)
- {
- DefaultLogger::get()->error("IRR(MESH): Expected comma in vector definition");
- }
- else SkipSpaces(ptr+1,&ptr);
- ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a string to a proper aiMappingMode
-int ConvertMappingMode(const std::string& mode)
-{
- if (mode == "texture_clamp_repeat")
- {
- return aiTextureMapMode_Wrap;
- }
- else if (mode == "texture_clamp_mirror")
- return aiTextureMapMode_Mirror;
-
- return aiTextureMapMode_Clamp;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a material from the XML file
-aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
-{
- aiMaterial* mat = new aiMaterial();
- aiColor4D clr;
- aiString s;
-
- matFlags = 0; // zero output flags
- int cnt = 0; // number of used texture channels
- unsigned int nd = 0;
-
- // Continue reading from the file
- while (reader->read())
- {
- switch (reader->getNodeType())
- {
- case EXN_ELEMENT:
-
- // Hex properties
- if (!ASSIMP_stricmp(reader->getNodeName(),"color"))
- {
- HexProperty prop;
- ReadHexProperty(prop);
- if (prop.name == "Diffuse")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- }
- else if (prop.name == "Ambient")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
- }
- else if (prop.name == "Specular")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
- }
-
- // NOTE: The 'emissive' property causes problems. It is
- // often != 0, even if there is obviously no light
- // emitted by the described surface. In fact I think
- // IRRLICHT ignores this property, too.
-#if 0
- else if (prop.name == "Emissive")
- {
- ColorFromARGBPacked(prop.value,clr);
- mat->AddProperty(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
- }
-#endif
- }
- // Float properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"float"))
- {
- FloatProperty prop;
- ReadFloatProperty(prop);
- if (prop.name == "Shininess")
- {
- mat->AddProperty(&prop.value,1,AI_MATKEY_SHININESS);
- }
- }
- // Bool properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"bool"))
- {
- BoolProperty prop;
- ReadBoolProperty(prop);
- if (prop.name == "Wireframe")
- {
- int val = (prop.value ? true : false);
- mat->AddProperty(&val,1,AI_MATKEY_ENABLE_WIREFRAME);
- }
- else if (prop.name == "GouraudShading")
- {
- int val = (prop.value ? aiShadingMode_Gouraud
- : aiShadingMode_NoShading);
- mat->AddProperty(&val,1,AI_MATKEY_SHADING_MODEL);
- }
- else if (prop.name == "BackfaceCulling")
- {
- int val = (!prop.value);
- mat->AddProperty(&val,1,AI_MATKEY_TWOSIDED);
- }
- }
- // String properties - textures and texture related properties
- else if (!ASSIMP_stricmp(reader->getNodeName(),"texture") ||
- !ASSIMP_stricmp(reader->getNodeName(),"enum"))
- {
- StringProperty prop;
- ReadStringProperty(prop);
- if (prop.value.length())
- {
- // material type (shader)
- if (prop.name == "Type")
- {
- if (prop.value == "solid")
- {
- // default material ...
- }
- else if (prop.value == "trans_vertex_alpha")
- {
- matFlags = AI_IRRMESH_MAT_trans_vertex_alpha;
- }
- else if (prop.value == "lightmap")
- {
- matFlags = AI_IRRMESH_MAT_lightmap;
- }
- else if (prop.value == "solid_2layer")
- {
- matFlags = AI_IRRMESH_MAT_solid_2layer;
- }
- else if (prop.value == "lightmap_m2")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m2;
- }
- else if (prop.value == "lightmap_m4")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_m4;
- }
- else if (prop.value == "lightmap_light")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light;
- }
- else if (prop.value == "lightmap_light_m2")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light_m2;
- }
- else if (prop.value == "lightmap_light_m4")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_light_m4;
- }
- else if (prop.value == "lightmap_add")
- {
- matFlags = AI_IRRMESH_MAT_lightmap_add;
- }
- // Normal and parallax maps are treated equally
- else if (prop.value == "normalmap_solid" ||
- prop.value == "parallaxmap_solid")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_solid;
- }
- else if (prop.value == "normalmap_trans_vertex_alpha" ||
- prop.value == "parallaxmap_trans_vertex_alpha")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_tva;
- }
- else if (prop.value == "normalmap_trans_add" ||
- prop.value == "parallaxmap_trans_add")
- {
- matFlags = AI_IRRMESH_MAT_normalmap_ta;
- }
- else {
- DefaultLogger::get()->warn("IRRMat: Unrecognized material type: " + prop.value);
- }
- }
-
- // Up to 4 texture channels are supported
- if (prop.name == "Texture1")
- {
- // Always accept the primary texture channel
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else if (prop.name == "Texture2" && cnt == 1)
- {
- // 2-layer material lightmapped?
- if (matFlags & AI_IRRMESH_MAT_lightmap) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_LIGHTMAP(0));
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- // alternatively: normal or parallax mapping
- else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_NORMALS(0));
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- // or just as second diffuse texture
- else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(1));
- ++nd;
-
- // set the corresponding material flag
- matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
- }
- else DefaultLogger::get()->warn("IRRmat: Skipping second texture");
- }
-
- else if (prop.name == "Texture3" && cnt == 2)
- {
- // Irrlicht does not seem to use these channels.
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+1));
- }
- else if (prop.name == "Texture4" && cnt == 3)
- {
- // Irrlicht does not seem to use these channels.
- ++cnt;
- s.Set(prop.value);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(nd+2));
- }
-
- // Texture mapping options
- if (prop.name == "TextureWrap1" && cnt >= 1)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
- }
- else if (prop.name == "TextureWrap2" && cnt >= 2)
- {
- int map = ConvertMappingMode(prop.value);
- if (matFlags & AI_IRRMESH_MAT_lightmap) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(0));
- }
- else if (matFlags & (AI_IRRMESH_MAT_normalmap_solid)) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_NORMALS(0));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_NORMALS(0));
- }
- else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(1));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(1));
- }
- }
- else if (prop.name == "TextureWrap3" && cnt >= 3)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd+1));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd+1));
- }
- else if (prop.name == "TextureWrap4" && cnt >= 4)
- {
- int map = ConvertMappingMode(prop.value);
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(nd+2));
- mat->AddProperty(&map,1,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(nd+2));
- }
- }
- }
- break;
- case EXN_ELEMENT_END:
-
- /* Assume there are no further nested nodes in <material> elements
- */
- if (/* IRRMESH */ !ASSIMP_stricmp(reader->getNodeName(),"material") ||
- /* IRR */ !ASSIMP_stricmp(reader->getNodeName(),"attributes"))
- {
- // Now process lightmapping flags
- // We should have at least one textur to do that ..
- if (cnt && matFlags & AI_IRRMESH_MAT_lightmap)
- {
- float f = 1.f;
- unsigned int unmasked = matFlags&~AI_IRRMESH_MAT_lightmap;
-
- // Additive lightmap?
- int op = (unmasked & AI_IRRMESH_MAT_lightmap_add
- ? aiTextureOp_Add : aiTextureOp_Multiply);
-
- // Handle Irrlicht's lightmapping scaling factor
- if (unmasked & AI_IRRMESH_MAT_lightmap_m2 ||
- unmasked & AI_IRRMESH_MAT_lightmap_light_m2)
- {
- f = 2.f;
- }
- else if (unmasked & AI_IRRMESH_MAT_lightmap_m4 ||
- unmasked & AI_IRRMESH_MAT_lightmap_light_m4)
- {
- f = 4.f;
- }
- mat->AddProperty( &f, 1, AI_MATKEY_TEXBLEND_LIGHTMAP(0));
- mat->AddProperty( &op,1, AI_MATKEY_TEXOP_LIGHTMAP(0));
- }
-
- return mat;
- }
- default:
-
- // GCC complains here ...
- break;
- }
- }
- 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/IRRShared.h b/src/3rdparty/assimp/code/IRRShared.h
deleted file mode 100644
index b5cd5d5ba..000000000
--- a/src/3rdparty/assimp/code/IRRShared.h
+++ /dev/null
@@ -1,118 +0,0 @@
-
-
-/** @file IRRShared.h
- * @brief Shared utilities for the IRR and IRRMESH loaders
- */
-
-#ifndef INCLUDED_AI_IRRSHARED_H
-#define INCLUDED_AI_IRRSHARED_H
-
-#include "irrXMLWrapper.h"
-#include "BaseImporter.h"
-#include <stdint.h>
-
-struct aiMaterial;
-
-namespace Assimp {
-
-
-/** @brief Matrix to convert from Assimp to IRR and backwards
- */
-extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
-
-
-// Default: 0 = solid, one texture
-#define AI_IRRMESH_MAT_solid_2layer 0x10000
-
-// Transparency flags
-#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1
-#define AI_IRRMESH_MAT_trans_add 0x2
-
-// Lightmapping flags
-#define AI_IRRMESH_MAT_lightmap 0x2
-#define AI_IRRMESH_MAT_lightmap_m2 (AI_IRRMESH_MAT_lightmap|0x4)
-#define AI_IRRMESH_MAT_lightmap_m4 (AI_IRRMESH_MAT_lightmap|0x8)
-#define AI_IRRMESH_MAT_lightmap_light (AI_IRRMESH_MAT_lightmap|0x10)
-#define AI_IRRMESH_MAT_lightmap_light_m2 (AI_IRRMESH_MAT_lightmap|0x20)
-#define AI_IRRMESH_MAT_lightmap_light_m4 (AI_IRRMESH_MAT_lightmap|0x40)
-#define AI_IRRMESH_MAT_lightmap_add (AI_IRRMESH_MAT_lightmap|0x80)
-
-// Standard NormalMap (or Parallax map, they're treated equally)
-#define AI_IRRMESH_MAT_normalmap_solid (0x100)
-
-// Normal map combined with vertex alpha
-#define AI_IRRMESH_MAT_normalmap_tva \
- (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_vertex_alpha)
-
-// Normal map combined with additive transparency
-#define AI_IRRMESH_MAT_normalmap_ta \
- (AI_IRRMESH_MAT_normalmap_solid | AI_IRRMESH_MAT_trans_add)
-
-// Special flag. It indicates a second texture has been found
-// Its type depends ... either a normal textue or a normal map
-#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000
-
-// ---------------------------------------------------------------------------
-/** Base class for the Irr and IrrMesh importers.
- *
- * Declares some irrlight-related xml parsing utilities and provides tools
- * to load materials from IRR and IRRMESH files.
- */
-class IrrlichtBase
-{
-protected:
-
- /** @brief Data structure for a simple name-value property
- */
- template <class T>
- struct Property
- {
- std::string name;
- T value;
- };
-
- typedef Property<uint32_t> HexProperty;
- typedef Property<std::string> StringProperty;
- typedef Property<bool> BoolProperty;
- typedef Property<float> FloatProperty;
- typedef Property<aiVector3D> VectorProperty;
- typedef Property<int> IntProperty;
-
- /** XML reader instance
- */
- irr::io::IrrXMLReader* reader;
-
- // -------------------------------------------------------------------
- /** Parse a material description from the XML
- * @return The created material
- * @param matFlags Receives AI_IRRMESH_MAT_XX flags
- */
- aiMaterial* ParseMaterial(unsigned int& matFlags);
-
- // -------------------------------------------------------------------
- /** Read a property of the specified type from the current XML element.
- * @param out Recives output data
- */
- void ReadHexProperty (HexProperty& out);
- void ReadStringProperty (StringProperty& out);
- void ReadBoolProperty (BoolProperty& out);
- void ReadFloatProperty (FloatProperty& out);
- void ReadVectorProperty (VectorProperty& out);
- void ReadIntProperty (IntProperty& out);
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Unpack a hex color, e.g. 0xdcdedfff
-inline void ColorFromARGBPacked(uint32_t in, aiColor4D& clr)
-{
- clr.a = ((in >> 24) & 0xff) / 255.f;
- clr.r = ((in >> 16) & 0xff) / 255.f;
- clr.g = ((in >> 8) & 0xff) / 255.f;
- clr.b = ((in ) & 0xff) / 255.f;
-}
-
-
-} // end namespace Assimp
-
-#endif // !! INCLUDED_AI_IRRSHARED_H
diff --git a/src/3rdparty/assimp/code/Importer.cpp b/src/3rdparty/assimp/code/Importer.cpp
deleted file mode 100644
index c6c6f0edd..000000000
--- a/src/3rdparty/assimp/code/Importer.cpp
+++ /dev/null
@@ -1,1195 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Importer.cpp
- * @brief Implementation of the CPP-API class #Importer
- */
-
-#include <assimp/version.h>
-#include <assimp/config.h>
-#include <assimp/importerdesc.h>
-
-// ------------------------------------------------------------------------------------------------
-/* Uncomment this line to prevent Assimp from catching unknown exceptions.
- *
- * Note that any Exception except DeadlyImportError may lead to
- * undefined behaviour -> loaders could remain in an unusable state and
- * further imports with the same Importer instance could fail/crash/burn ...
- */
-// ------------------------------------------------------------------------------------------------
-#ifndef ASSIMP_BUILD_DEBUG
-# define ASSIMP_CATCH_GLOBAL_EXCEPTIONS
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Internal headers
-// ------------------------------------------------------------------------------------------------
-#include "Importer.h"
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-
-#include "DefaultProgressHandler.h"
-#include "GenericProperty.h"
-#include "ProcessHelper.h"
-#include "ScenePreprocessor.h"
-#include "ScenePrivate.h"
-#include "MemoryIOWrapper.h"
-#include "Profiler.h"
-#include "TinyFormatter.h"
-#include "Exceptional.h"
-#include "Profiler.h"
-#include <set>
-#include <memory>
-#include <cctype>
-
-#include <assimp/DefaultIOStream.h>
-#include <assimp/DefaultIOSystem.h>
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
-#endif
-
-using namespace Assimp::Profiling;
-using namespace Assimp::Formatter;
-
-namespace Assimp {
- // ImporterRegistry.cpp
- void GetImporterInstanceList(std::vector< BaseImporter* >& out);
- void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
-
- // PostStepRegistry.cpp
- void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
-}
-
-using namespace Assimp;
-using namespace Assimp::Intern;
-
-// ------------------------------------------------------------------------------------------------
-// Intern::AllocateFromAssimpHeap serves as abstract base class. It overrides
-// new and delete (and their array counterparts) of public API classes (e.g. Logger) to
-// utilize our DLL heap.
-// See http://www.gotw.ca/publications/mill15.htm
-// ------------------------------------------------------------------------------------------------
-void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) {
- return ::operator new(num_bytes);
-}
-
-void* AllocateFromAssimpHeap::operator new ( size_t num_bytes, const std::nothrow_t& ) throw() {
- try {
- return AllocateFromAssimpHeap::operator new( num_bytes );
- }
- catch( ... ) {
- return NULL;
- }
-}
-
-void AllocateFromAssimpHeap::operator delete ( void* data) {
- return ::operator delete(data);
-}
-
-void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes) {
- return ::operator new[](num_bytes);
-}
-
-void* AllocateFromAssimpHeap::operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw() {
- try {
- return AllocateFromAssimpHeap::operator new[]( num_bytes );
- }
- catch( ... ) {
- return NULL;
- }
-}
-
-void AllocateFromAssimpHeap::operator delete[] ( void* data) {
- return ::operator delete[](data);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Importer constructor.
-Importer::Importer()
- : pimpl( NULL ) {
- // allocate the pimpl first
- pimpl = new ImporterPimpl();
-
- pimpl->mScene = NULL;
- pimpl->mErrorString = "";
-
- // Allocate a default IO handler
- pimpl->mIOHandler = new DefaultIOSystem;
- pimpl->mIsDefaultHandler = true;
- pimpl->bExtraVerbose = false; // disable extra verbose mode by default
-
- pimpl->mProgressHandler = new DefaultProgressHandler();
- pimpl->mIsDefaultProgressHandler = true;
-
- GetImporterInstanceList(pimpl->mImporter);
- GetPostProcessingStepInstanceList(pimpl->mPostProcessingSteps);
-
- // Allocate a SharedPostProcessInfo object and store pointers to it in all post-process steps in the list.
- pimpl->mPPShared = new SharedPostProcessInfo();
- for (std::vector<BaseProcess*>::iterator it = pimpl->mPostProcessingSteps.begin();
- it != pimpl->mPostProcessingSteps.end();
- ++it) {
-
- (*it)->SetSharedData(pimpl->mPPShared);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor of Importer
-Importer::~Importer()
-{
- // Delete all import plugins
- DeleteImporterInstanceList(pimpl->mImporter);
-
- // Delete all post-processing plug-ins
- for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++)
- delete pimpl->mPostProcessingSteps[a];
-
- // Delete the assigned IO and progress handler
- delete pimpl->mIOHandler;
- delete pimpl->mProgressHandler;
-
- // Kill imported scene. Destructors should do that recursivly
- delete pimpl->mScene;
-
- // Delete shared post-processing data
- delete pimpl->mPPShared;
-
- // and finally the pimpl itself
- delete pimpl;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy constructor - copies the config of another Importer, not the scene
-Importer::Importer(const Importer &other)
- : pimpl(NULL) {
- new(this) Importer();
-
- pimpl->mIntProperties = other.pimpl->mIntProperties;
- pimpl->mFloatProperties = other.pimpl->mFloatProperties;
- pimpl->mStringProperties = other.pimpl->mStringProperties;
- pimpl->mMatrixProperties = other.pimpl->mMatrixProperties;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Register a custom post-processing step
-aiReturn Importer::RegisterPPStep(BaseProcess* pImp)
-{
- ai_assert(NULL != pImp);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- pimpl->mPostProcessingSteps.push_back(pImp);
- DefaultLogger::get()->info("Registering custom post-processing step");
-
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Register a custom loader plugin
-aiReturn Importer::RegisterLoader(BaseImporter* pImp)
-{
- ai_assert(NULL != pImp);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // --------------------------------------------------------------------
- // Check whether we would have two loaders for the same file extension
- // This is absolutely OK, but we should warn the developer of the new
- // loader that his code will probably never be called if the first
- // loader is a bit too lazy in his file checking.
- // --------------------------------------------------------------------
- std::set<std::string> st;
- std::string baked;
- pImp->GetExtensionList(st);
-
- for(std::set<std::string>::const_iterator it = st.begin(); it != st.end(); ++it) {
-
-#ifdef ASSIMP_BUILD_DEBUG
- if (IsExtensionSupported(*it)) {
- DefaultLogger::get()->warn("The file extension " + *it + " is already in use");
- }
-#endif
- baked += *it;
- }
-
- // add the loader
- pimpl->mImporter.push_back(pImp);
- DefaultLogger::get()->info("Registering custom importer for these file extensions: " + baked);
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unregister a custom loader plugin
-aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
-{
- if(!pImp) {
- // unregistering a NULL importer is no problem for us ... really!
- return AI_SUCCESS;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::vector<BaseImporter*>::iterator it = std::find(pimpl->mImporter.begin(),
- pimpl->mImporter.end(),pImp);
-
- if (it != pimpl->mImporter.end()) {
- pimpl->mImporter.erase(it);
- DefaultLogger::get()->info("Unregistering custom importer: ");
- return AI_SUCCESS;
- }
- DefaultLogger::get()->warn("Unable to remove custom importer: I can't find you ...");
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unregister a custom loader plugin
-aiReturn Importer::UnregisterPPStep(BaseProcess* pImp)
-{
- if(!pImp) {
- // unregistering a NULL ppstep is no problem for us ... really!
- return AI_SUCCESS;
- }
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::vector<BaseProcess*>::iterator it = std::find(pimpl->mPostProcessingSteps.begin(),
- pimpl->mPostProcessingSteps.end(),pImp);
-
- if (it != pimpl->mPostProcessingSteps.end()) {
- pimpl->mPostProcessingSteps.erase(it);
- DefaultLogger::get()->info("Unregistering custom post-processing step");
- return AI_SUCCESS;
- }
- DefaultLogger::get()->warn("Unable to remove custom post-processing step: I can't find you ..");
- ASSIMP_END_EXCEPTION_REGION(aiReturn);
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Supplies a custom IO handler to the importer to open and access files.
-void Importer::SetIOHandler( IOSystem* pIOHandler)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // If the new handler is zero, allocate a default IO implementation.
- if (!pIOHandler)
- {
- // Release pointer in the possession of the caller
- pimpl->mIOHandler = new DefaultIOSystem();
- pimpl->mIsDefaultHandler = true;
- }
- // Otherwise register the custom handler
- else if (pimpl->mIOHandler != pIOHandler)
- {
- delete pimpl->mIOHandler;
- pimpl->mIOHandler = pIOHandler;
- pimpl->mIsDefaultHandler = false;
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the currently set IO handler
-IOSystem* Importer::GetIOHandler() const
-{
- return pimpl->mIOHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a custom IO handler is currently set
-bool Importer::IsDefaultIOHandler() const
-{
- return pimpl->mIsDefaultHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Supplies a custom progress handler to get regular callbacks during importing
-void Importer::SetProgressHandler ( ProgressHandler* pHandler )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // If the new handler is zero, allocate a default implementation.
- if (!pHandler)
- {
- // Release pointer in the possession of the caller
- pimpl->mProgressHandler = new DefaultProgressHandler();
- pimpl->mIsDefaultProgressHandler = true;
- }
- // Otherwise register the custom handler
- else if (pimpl->mProgressHandler != pHandler)
- {
- delete pimpl->mProgressHandler;
- pimpl->mProgressHandler = pHandler;
- pimpl->mIsDefaultProgressHandler = false;
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the currently set progress handler
-ProgressHandler* Importer::GetProgressHandler() const
-{
- return pimpl->mProgressHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether a custom progress handler is currently set
-bool Importer::IsDefaultProgressHandler() const
-{
- return pimpl->mIsDefaultProgressHandler;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate post process step flags
-bool _ValidateFlags(unsigned int pFlags)
-{
- if (pFlags & aiProcess_GenSmoothNormals && pFlags & aiProcess_GenNormals) {
- DefaultLogger::get()->error("#aiProcess_GenSmoothNormals and #aiProcess_GenNormals are incompatible");
- return false;
- }
- if (pFlags & aiProcess_OptimizeGraph && pFlags & aiProcess_PreTransformVertices) {
- DefaultLogger::get()->error("#aiProcess_OptimizeGraph and #aiProcess_PreTransformVertices are incompatible");
- return false;
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Free the current scene
-void Importer::FreeScene( )
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- delete pimpl->mScene;
- pimpl->mScene = NULL;
-
- pimpl->mErrorString = "";
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the current error string, if any
-const char* Importer::GetErrorString() const
-{
- /* Must remain valid as long as ReadFile() or FreeFile() are not called */
- return pimpl->mErrorString.c_str();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Enable extra-verbose mode
-void Importer::SetExtraVerbose(bool bDo)
-{
- pimpl->bExtraVerbose = bDo;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the current scene
-const aiScene* Importer::GetScene() const
-{
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Orphan the current scene and return it.
-aiScene* Importer::GetOrphanedScene()
-{
- aiScene* s = pimpl->mScene;
-
- ASSIMP_BEGIN_EXCEPTION_REGION();
- pimpl->mScene = NULL;
-
- pimpl->mErrorString = ""; /* reset error string */
- ASSIMP_END_EXCEPTION_REGION(aiScene*);
- return s;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate post-processing flags
-bool Importer::ValidateFlags(unsigned int pFlags) const
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // run basic checks for mutually exclusive flags
- if(!_ValidateFlags(pFlags)) {
- return false;
- }
-
- // ValidateDS does not anymore occur in the pp list, it plays an awesome extra role ...
-#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- if (pFlags & aiProcess_ValidateDataStructure) {
- return false;
- }
-#endif
- pFlags &= ~aiProcess_ValidateDataStructure;
-
- // Now iterate through all bits which are set in the flags and check whether we find at least
- // one pp plugin which handles it.
- for (unsigned int mask = 1; mask < (1u << (sizeof(unsigned int)*8-1));mask <<= 1) {
-
- if (pFlags & mask) {
-
- bool have = false;
- for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
- if (pimpl->mPostProcessingSteps[a]-> IsActive(mask) ) {
-
- have = true;
- break;
- }
- }
- if (!have) {
- return false;
- }
- }
- }
- ASSIMP_END_EXCEPTION_REGION(bool);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
- size_t pLength,
- unsigned int pFlags,
- const char* pHint /*= ""*/)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- if (!pHint) {
- pHint = "";
- }
-
- if (!pBuffer || !pLength || strlen(pHint) > MaxLenHint ) {
- pimpl->mErrorString = "Invalid parameters passed to ReadFileFromMemory()";
- return NULL;
- }
-
- // prevent deletion of the previous IOHandler
- IOSystem* io = pimpl->mIOHandler;
- pimpl->mIOHandler = NULL;
-
- SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
-
- // read the file and recover the previous IOSystem
- static const size_t BufferSize(Importer::MaxLenHint + 28);
- char fbuff[ BufferSize ];
- ai_snprintf(fbuff, BufferSize, "%s.%s",AI_MEMORYIO_MAGIC_FILENAME,pHint);
-
- ReadFile(fbuff,pFlags);
- SetIOHandler(io);
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-void WriteLogOpening(const std::string& file)
-{
- Logger* l = DefaultLogger::get();
- if (!l) {
- return;
- }
- l->info("Load " + file);
-
- // print a full version dump. This is nice because we don't
- // need to ask the authors of incoming bug reports for
- // the library version they're using - a log dump is
- // sufficient.
- const unsigned int flags = aiGetCompileFlags();
- l->debug(format()
- << "Assimp "
- << aiGetVersionMajor()
- << "."
- << aiGetVersionMinor()
- << "."
- << aiGetVersionRevision()
-
- << " "
-#if defined(ASSIMP_BUILD_ARCHITECTURE)
- << ASSIMP_BUILD_ARCHITECTURE
-#elif defined(_M_IX86) || defined(__x86_32__) || defined(__i386__)
- << "x86"
-#elif defined(_M_X64) || defined(__x86_64__)
- << "amd64"
-#elif defined(_M_IA64) || defined(__ia64__)
- << "itanium"
-#elif defined(__ppc__) || defined(__powerpc__)
- << "ppc32"
-#elif defined(__powerpc64__)
- << "ppc64"
-#elif defined(__arm__)
- << "arm"
-#else
- << "<unknown architecture>"
-#endif
-
- << " "
-#if defined(ASSIMP_BUILD_COMPILER)
- << ASSIMP_BUILD_COMPILER
-#elif defined(_MSC_VER)
- << "msvc"
-#elif defined(__GNUC__)
- << "gcc"
-#else
- << "<unknown compiler>"
-#endif
-
-#ifdef ASSIMP_BUILD_DEBUG
- << " debug"
-#endif
-
- << (flags & ASSIMP_CFLAGS_NOBOOST ? " noboost" : "")
- << (flags & ASSIMP_CFLAGS_SHARED ? " shared" : "")
- << (flags & ASSIMP_CFLAGS_SINGLETHREADED ? " singlethreaded" : "")
- );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reads the given file and returns its contents if successful.
-const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- const std::string pFile(_pFile);
-
- // ----------------------------------------------------------------------
- // Put a large try block around everything to catch all std::exception's
- // that might be thrown by STL containers or by new().
- // ImportErrorException's are throw by ourselves and caught elsewhere.
- //-----------------------------------------------------------------------
-
- WriteLogOpening(pFile);
-
-#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- try
-#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- {
- // Check whether this Importer instance has already loaded
- // a scene. In this case we need to delete the old one
- if (pimpl->mScene) {
-
- DefaultLogger::get()->debug("(Deleting previous scene)");
- FreeScene();
- }
-
- // First check if the file is accessible at all
- if( !pimpl->mIOHandler->Exists( pFile)) {
-
- pimpl->mErrorString = "Unable to open file \"" + pFile + "\".";
- DefaultLogger::get()->error(pimpl->mErrorString);
- return NULL;
- }
-
- std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
- if (profiler) {
- profiler->BeginRegion("total");
- }
-
- // Find an worker class which can handle the file
- BaseImporter* imp = NULL;
- for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
-
- if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, false)) {
- imp = pimpl->mImporter[a];
- break;
- }
- }
-
- if (!imp) {
- // not so bad yet ... try format auto detection.
- const std::string::size_type s = pFile.find_last_of('.');
- if (s != std::string::npos) {
- DefaultLogger::get()->info("File extension not known, trying signature-based detection");
- for( unsigned int a = 0; a < pimpl->mImporter.size(); a++) {
-
- if( pimpl->mImporter[a]->CanRead( pFile, pimpl->mIOHandler, true)) {
- imp = pimpl->mImporter[a];
- break;
- }
- }
- }
- // Put a proper error message if no suitable importer was found
- if( !imp) {
- pimpl->mErrorString = "No suitable reader found for the file format of file \"" + pFile + "\".";
- DefaultLogger::get()->error(pimpl->mErrorString);
- return NULL;
- }
- }
-
- // Get file size for progress handler
- IOStream * fileIO = pimpl->mIOHandler->Open( pFile );
- uint32_t fileSize = 0;
- if (fileIO)
- {
- fileSize = static_cast<uint32_t>(fileIO->FileSize());
- pimpl->mIOHandler->Close( fileIO );
- }
-
- // Dispatch the reading to the worker class for this format
- const aiImporterDesc *desc( imp->GetInfo() );
- std::string ext( "unknown" );
- if ( NULL != desc ) {
- ext = desc->mName;
- }
- DefaultLogger::get()->info("Found a matching importer for this file format: " + ext + "." );
- pimpl->mProgressHandler->UpdateFileRead( 0, fileSize );
-
- if (profiler) {
- profiler->BeginRegion("import");
- }
-
- pimpl->mScene = imp->ReadFile( this, pFile, pimpl->mIOHandler);
- pimpl->mProgressHandler->UpdateFileRead( fileSize, fileSize );
-
- if (profiler) {
- profiler->EndRegion("import");
- }
-
- // If successful, apply all active post processing steps to the imported data
- if( pimpl->mScene) {
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- // The ValidateDS process is an exception. It is executed first, even before ScenePreprocessor is called.
- if (pFlags & aiProcess_ValidateDataStructure)
- {
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if (!pimpl->mScene) {
- return NULL;
- }
- }
-#endif // no validation
-
- // Preprocess the scene and prepare it for post-processing
- if (profiler) {
- profiler->BeginRegion("preprocess");
- }
-
- ScenePreprocessor pre(pimpl->mScene);
- pre.ProcessScene();
-
- if (profiler) {
- profiler->EndRegion("preprocess");
- }
-
- // Ensure that the validation process won't be called twice
- ApplyPostProcessing(pFlags & (~aiProcess_ValidateDataStructure));
- }
- // if failed, extract the error string
- else if( !pimpl->mScene) {
- pimpl->mErrorString = imp->GetErrorText();
- }
-
- // clear any data allocated by post-process steps
- pimpl->mPPShared->Clean();
-
- if (profiler) {
- profiler->EndRegion("total");
- }
- }
-#ifdef ASSIMP_CATCH_GLOBAL_EXCEPTIONS
- catch (std::exception &e)
- {
-#if (defined _MSC_VER) && (defined _CPPRTTI)
- // if we have RTTI get the full name of the exception that occurred
- pimpl->mErrorString = std::string(typeid( e ).name()) + ": " + e.what();
-#else
- pimpl->mErrorString = std::string("std::exception: ") + e.what();
-#endif
-
- DefaultLogger::get()->error(pimpl->mErrorString);
- delete pimpl->mScene; pimpl->mScene = NULL;
- }
-#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
-
- // either successful or failure - the pointer expresses it anyways
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Apply post-processing to the currently bound scene
-const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags)
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- // Return immediately if no scene is active
- if (!pimpl->mScene) {
- return NULL;
- }
-
- // If no flags are given, return the current scene with no further action
- if (!pFlags) {
- return pimpl->mScene;
- }
-
- // In debug builds: run basic flag validation
- ai_assert(_ValidateFlags(pFlags));
- DefaultLogger::get()->info("Entering post processing pipeline");
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- // The ValidateDS process plays an exceptional role. It isn't contained in the global
- // list of post-processing steps, so we need to call it manually.
- if (pFlags & aiProcess_ValidateDataStructure)
- {
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if (!pimpl->mScene) {
- return NULL;
- }
- }
-#endif // no validation
-#ifdef ASSIMP_BUILD_DEBUG
- if (pimpl->bExtraVerbose)
- {
-#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- DefaultLogger::get()->error("Verbose Import is not available due to build settings");
-#endif // no validation
- pFlags |= aiProcess_ValidateDataStructure;
- }
-#else
- if (pimpl->bExtraVerbose) {
- DefaultLogger::get()->warn("Not a debug build, ignoring extra verbose setting");
- }
-#endif // ! DEBUG
-
- std::unique_ptr<Profiler> profiler(GetPropertyInteger(AI_CONFIG_GLOB_MEASURE_TIME,0)?new Profiler():NULL);
- for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
-
- BaseProcess* process = pimpl->mPostProcessingSteps[a];
- pimpl->mProgressHandler->UpdatePostProcess(static_cast<int>(a), static_cast<int>(pimpl->mPostProcessingSteps.size()) );
- if( process->IsActive( pFlags)) {
-
- if (profiler) {
- profiler->BeginRegion("postprocess");
- }
-
- process->ExecuteOnScene ( this );
-
- if (profiler) {
- profiler->EndRegion("postprocess");
- }
- }
- if( !pimpl->mScene) {
- break;
- }
-#ifdef ASSIMP_BUILD_DEBUG
-
-#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- continue;
-#endif // no validation
-
- // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
- if (pimpl->bExtraVerbose) {
- DefaultLogger::get()->debug("Verbose Import: revalidating data structures");
-
- ValidateDSProcess ds;
- ds.ExecuteOnScene (this);
- if( !pimpl->mScene) {
- DefaultLogger::get()->error("Verbose Import: failed to revalidate data structures");
- break;
- }
- }
-#endif // ! DEBUG
- }
- pimpl->mProgressHandler->UpdatePostProcess( static_cast<int>(pimpl->mPostProcessingSteps.size()), static_cast<int>(pimpl->mPostProcessingSteps.size()) );
-
- // update private scene flags
- if( pimpl->mScene )
- ScenePriv(pimpl->mScene)->mPPStepsApplied |= pFlags;
-
- // clear any data allocated by post-process steps
- pimpl->mPPShared->Clean();
- DefaultLogger::get()->info("Leaving post processing pipeline");
-
- ASSIMP_END_EXCEPTION_REGION(const aiScene*);
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation ) {
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // Return immediately if no scene is active
- if ( NULL == pimpl->mScene ) {
- return NULL;
- }
-
- // If no flags are given, return the current scene with no further action
- if ( NULL == rootProcess ) {
- return pimpl->mScene;
- }
-
- // In debug builds: run basic flag validation
- DefaultLogger::get()->info( "Entering customized post processing pipeline" );
-
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- // The ValidateDS process plays an exceptional role. It isn't contained in the global
- // list of post-processing steps, so we need to call it manually.
- if ( requestValidation )
- {
- ValidateDSProcess ds;
- ds.ExecuteOnScene( this );
- if ( !pimpl->mScene ) {
- return NULL;
- }
- }
-#endif // no validation
-#ifdef ASSIMP_BUILD_DEBUG
- if ( pimpl->bExtraVerbose )
- {
-#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
- DefaultLogger::get()->error( "Verbose Import is not available due to build settings" );
-#endif // no validation
- }
-#else
- if ( pimpl->bExtraVerbose ) {
- DefaultLogger::get()->warn( "Not a debug build, ignoring extra verbose setting" );
- }
-#endif // ! DEBUG
-
- std::unique_ptr<Profiler> profiler( GetPropertyInteger( AI_CONFIG_GLOB_MEASURE_TIME, 0 ) ? new Profiler() : NULL );
-
- if ( profiler ) {
- profiler->BeginRegion( "postprocess" );
- }
-
- rootProcess->ExecuteOnScene( this );
-
- if ( profiler ) {
- profiler->EndRegion( "postprocess" );
- }
-
- // If the extra verbose mode is active, execute the ValidateDataStructureStep again - after each step
- if ( pimpl->bExtraVerbose || requestValidation ) {
- DefaultLogger::get()->debug( "Verbose Import: revalidating data structures" );
-
- ValidateDSProcess ds;
- ds.ExecuteOnScene( this );
- if ( !pimpl->mScene ) {
- DefaultLogger::get()->error( "Verbose Import: failed to revalidate data structures" );
- }
- }
-
- // clear any data allocated by post-process steps
- pimpl->mPPShared->Clean();
- DefaultLogger::get()->info( "Leaving customized post processing pipeline" );
-
- ASSIMP_END_EXCEPTION_REGION( const aiScene* );
-
- return pimpl->mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to check whether an extension is supported by ASSIMP
-bool Importer::IsExtensionSupported(const char* szExtension) const
-{
- return NULL != GetImporter(szExtension);
-}
-
-// ------------------------------------------------------------------------------------------------
-size_t Importer::GetImporterCount() const
-{
- return pimpl->mImporter.size();
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* Importer::GetImporterInfo(size_t index) const
-{
- if (index >= pimpl->mImporter.size()) {
- return NULL;
- }
- return pimpl->mImporter[index]->GetInfo();
-}
-
-
-// ------------------------------------------------------------------------------------------------
-BaseImporter* Importer::GetImporter (size_t index) const
-{
- if (index >= pimpl->mImporter.size()) {
- return NULL;
- }
- return pimpl->mImporter[index];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a loader plugin for a given file extension
-BaseImporter* Importer::GetImporter (const char* szExtension) const
-{
- return GetImporter(GetImporterIndex(szExtension));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Find a loader plugin for a given file extension
-size_t Importer::GetImporterIndex (const char* szExtension) const
-{
- ai_assert(szExtension);
- ASSIMP_BEGIN_EXCEPTION_REGION();
-
- // skip over wildcard and dot characters at string head --
- for(;*szExtension == '*' || *szExtension == '.'; ++szExtension);
-
- std::string ext(szExtension);
- if (ext.empty()) {
- return static_cast<size_t>(-1);
- }
- std::transform(ext.begin(),ext.end(), ext.begin(), tolower);
-
- std::set<std::string> str;
- for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
- str.clear();
-
- (*i)->GetExtensionList(str);
- for (std::set<std::string>::const_iterator it = str.begin(); it != str.end(); ++it) {
- if (ext == *it) {
- return std::distance(static_cast< std::vector<BaseImporter*>::const_iterator >(pimpl->mImporter.begin()), i);
- }
- }
- }
- ASSIMP_END_EXCEPTION_REGION(size_t);
- return static_cast<size_t>(-1);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to build a list of all file extensions supported by ASSIMP
-void Importer::GetExtensionList(aiString& szOut) const
-{
- ASSIMP_BEGIN_EXCEPTION_REGION();
- std::set<std::string> str;
- for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
- (*i)->GetExtensionList(str);
- }
-
- for (std::set<std::string>::const_iterator it = str.begin();; ) {
- szOut.Append("*.");
- szOut.Append((*it).c_str());
-
- if (++it == str.end()) {
- break;
- }
- szOut.Append(";");
- }
- ASSIMP_END_EXCEPTION_REGION(void);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool Importer::SetPropertyInteger(const char* szName, int iValue)
-{
- bool existing;
- ASSIMP_BEGIN_EXCEPTION_REGION();
- existing = SetGenericProperty<int>(pimpl->mIntProperties, szName,iValue);
- ASSIMP_END_EXCEPTION_REGION(bool);
- return existing;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool Importer::SetPropertyFloat(const char* szName, ai_real iValue)
-{
- bool exising;
- ASSIMP_BEGIN_EXCEPTION_REGION();
- exising = SetGenericProperty<ai_real>(pimpl->mFloatProperties, szName,iValue);
- ASSIMP_END_EXCEPTION_REGION(bool);
- return exising;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool Importer::SetPropertyString(const char* szName, const std::string& value)
-{
- bool exising;
- ASSIMP_BEGIN_EXCEPTION_REGION();
- exising = SetGenericProperty<std::string>(pimpl->mStringProperties, szName,value);
- ASSIMP_END_EXCEPTION_REGION(bool);
- return exising;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Set a configuration property
-bool Importer::SetPropertyMatrix(const char* szName, const aiMatrix4x4& value)
-{
- bool exising;
- ASSIMP_BEGIN_EXCEPTION_REGION();
- exising = SetGenericProperty<aiMatrix4x4>(pimpl->mMatrixProperties, szName,value);
- ASSIMP_END_EXCEPTION_REGION(bool);
- return exising;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-int Importer::GetPropertyInteger(const char* szName,
- int iErrorReturn /*= 0xffffffff*/) const
-{
- return GetGenericProperty<int>(pimpl->mIntProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-ai_real Importer::GetPropertyFloat(const char* szName,
- ai_real iErrorReturn /*= 10e10*/) const
-{
- return GetGenericProperty<ai_real>(pimpl->mFloatProperties,szName,iErrorReturn);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a configuration property
-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)
-{
- iScene += sizeof(aiNode);
- iScene += sizeof(unsigned int) * pcNode->mNumMeshes;
- iScene += sizeof(void*) * pcNode->mNumChildren;
-
- for (unsigned int i = 0; i < pcNode->mNumChildren;++i) {
- AddNodeWeight(iScene,pcNode->mChildren[i]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the memory requirements of the scene
-void Importer::GetMemoryRequirements(aiMemoryInfo& in) const
-{
- in = aiMemoryInfo();
- aiScene* mScene = pimpl->mScene;
-
- // return if we have no scene loaded
- if (!pimpl->mScene)
- return;
-
-
- in.total = sizeof(aiScene);
-
- // add all meshes
- for (unsigned int i = 0; i < mScene->mNumMeshes;++i)
- {
- in.meshes += sizeof(aiMesh);
- if (mScene->mMeshes[i]->HasPositions()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
-
- if (mScene->mMeshes[i]->HasNormals()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
-
- if (mScene->mMeshes[i]->HasTangentsAndBitangents()) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices * 2;
- }
-
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a) {
- if (mScene->mMeshes[i]->HasVertexColors(a)) {
- in.meshes += sizeof(aiColor4D) * mScene->mMeshes[i]->mNumVertices;
- }
- else break;
- }
- for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a) {
- if (mScene->mMeshes[i]->HasTextureCoords(a)) {
- in.meshes += sizeof(aiVector3D) * mScene->mMeshes[i]->mNumVertices;
- }
- else break;
- }
- if (mScene->mMeshes[i]->HasBones()) {
- in.meshes += sizeof(void*) * mScene->mMeshes[i]->mNumBones;
- for (unsigned int p = 0; p < mScene->mMeshes[i]->mNumBones;++p) {
- in.meshes += sizeof(aiBone);
- in.meshes += mScene->mMeshes[i]->mBones[p]->mNumWeights * sizeof(aiVertexWeight);
- }
- }
- in.meshes += (sizeof(aiFace) + 3 * sizeof(unsigned int))*mScene->mMeshes[i]->mNumFaces;
- }
- in.total += in.meshes;
-
- // add all embedded textures
- for (unsigned int i = 0; i < mScene->mNumTextures;++i) {
- const aiTexture* pc = mScene->mTextures[i];
- in.textures += sizeof(aiTexture);
- if (pc->mHeight) {
- in.textures += 4 * pc->mHeight * pc->mWidth;
- }
- else in.textures += pc->mWidth;
- }
- in.total += in.textures;
-
- // add all animations
- for (unsigned int i = 0; i < mScene->mNumAnimations;++i) {
- const aiAnimation* pc = mScene->mAnimations[i];
- in.animations += sizeof(aiAnimation);
-
- // add all bone anims
- for (unsigned int a = 0; a < pc->mNumChannels; ++a) {
- const aiNodeAnim* pc2 = pc->mChannels[i];
- in.animations += sizeof(aiNodeAnim);
- in.animations += pc2->mNumPositionKeys * sizeof(aiVectorKey);
- in.animations += pc2->mNumScalingKeys * sizeof(aiVectorKey);
- in.animations += pc2->mNumRotationKeys * sizeof(aiQuatKey);
- }
- }
- in.total += in.animations;
-
- // add all cameras and all lights
- in.total += in.cameras = sizeof(aiCamera) * mScene->mNumCameras;
- in.total += in.lights = sizeof(aiLight) * mScene->mNumLights;
-
- // add all nodes
- AddNodeWeight(in.nodes,mScene->mRootNode);
- in.total += in.nodes;
-
- // add all materials
- for (unsigned int i = 0; i < mScene->mNumMaterials;++i) {
- const aiMaterial* pc = mScene->mMaterials[i];
- in.materials += sizeof(aiMaterial);
- in.materials += pc->mNumAllocated * sizeof(void*);
-
- for (unsigned int a = 0; a < pc->mNumProperties;++a) {
- in.materials += pc->mProperties[a]->mDataLength;
- }
- }
- in.total += in.materials;
-}
diff --git a/src/3rdparty/assimp/code/Importer.h b/src/3rdparty/assimp/code/Importer.h
deleted file mode 100644
index e0fb57f5b..000000000
--- a/src/3rdparty/assimp/code/Importer.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Importer.h mostly internal stuff for use by #Assimp::Importer */
-#pragma once
-#ifndef INCLUDED_AI_IMPORTER_H
-#define INCLUDED_AI_IMPORTER_H
-
-#include <map>
-#include <vector>
-#include <string>
-#include <assimp/matrix4x4.h>
-
-struct aiScene;
-
-namespace Assimp {
- class ProgressHandler;
- class IOSystem;
- class BaseImporter;
- class BaseProcess;
- class SharedPostProcessInfo;
-
-
-//! @cond never
-// ---------------------------------------------------------------------------
-/** @brief Internal PIMPL implementation for Assimp::Importer
- *
- * Using this idiom here allows us to drop the dependency from
- * std::vector and std::map in the public headers. Furthermore we are dropping
- * any STL interface problems caused by mismatching STL settings. All
- * size calculation are now done by us, not the app heap. */
-class ImporterPimpl
-{
-public:
-
- // Data type to store the key hash
- typedef unsigned int KeyType;
-
- // 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, ai_real> FloatPropertyMap;
- typedef std::map<KeyType, std::string> StringPropertyMap;
- typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
-
-public:
-
- /** IO handler to use for all file accesses. */
- IOSystem* mIOHandler;
- bool mIsDefaultHandler;
-
- /** Progress handler for feedback. */
- ProgressHandler* mProgressHandler;
- bool mIsDefaultProgressHandler;
-
- /** Format-specific importer worker objects - one for each format we can read.*/
- std::vector< BaseImporter* > mImporter;
-
- /** Post processing steps we can apply at the imported data. */
- std::vector< BaseProcess* > mPostProcessingSteps;
-
- /** The imported data, if ReadFile() was successful, NULL otherwise. */
- aiScene* mScene;
-
- /** The error description, if there was one. */
- std::string mErrorString;
-
- /** List of integer properties */
- IntPropertyMap mIntProperties;
-
- /** List of floating-point properties */
- FloatPropertyMap mFloatProperties;
-
- /** 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;
-
- /** Used by post-process steps to share data */
- SharedPostProcessInfo* mPPShared;
-};
-//! @endcond
-
-
-struct BatchData;
-
-// ---------------------------------------------------------------------------
-/** FOR IMPORTER PLUGINS ONLY: A helper class to the pleasure of importers
- * that need to load many external meshes recursively.
- *
- * The class uses several threads to load these meshes (or at least it
- * could, this has not yet been implemented at the moment).
- *
- * @note The class may not be used by more than one thread*/
-class ASSIMP_API BatchLoader
-{
- // friend of Importer
-
-public:
- //! @cond never
- // -------------------------------------------------------------------
- /** Wraps a full list of configuration properties for an importer.
- * Properties can be set using SetGenericProperty */
- struct PropertyMap
- {
- 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 && matrices == prop.matrices;
- }
-
- bool empty () const {
- return ints.empty() && floats.empty() && strings.empty() && matrices.empty();
- }
- };
- //! @endcond
-
-public:
- // -------------------------------------------------------------------
- /** Construct a batch loader from a given IO system to be used
- * to access external files
- */
- explicit BatchLoader(IOSystem* pIO, bool validate = false );
-
- // -------------------------------------------------------------------
- /** The class destructor.
- */
- ~BatchLoader();
-
- // -------------------------------------------------------------------
- /** Sets the validation step. True for enable validation during postprocess.
- * @param enable True for validation.
- */
- void setValidation( bool enabled );
-
- // -------------------------------------------------------------------
- /** Returns the current validation step.
- * @return The current validation step.
- */
- bool getValidation() const;
-
- // -------------------------------------------------------------------
- /** Add a new file to the list of files to be loaded.
- * @param file File to be loaded
- * @param steps Post-processing steps to be executed on the file
- * @param map Optional configuration properties
- * @return 'Load request channel' - an unique ID that can later
- * be used to access the imported file data.
- * @see GetImport */
- unsigned int AddLoadRequest (
- const std::string& file,
- unsigned int steps = 0,
- const PropertyMap* map = NULL
- );
-
- // -------------------------------------------------------------------
- /** Get an imported scene.
- * This polls the import from the internal request list.
- * If an import is requested several times, this function
- * can be called several times, too.
- *
- * @param which LRWC returned by AddLoadRequest().
- * @return NULL if there is no scene with this file name
- * in the queue of the scene hasn't been loaded yet. */
- aiScene* GetImport(
- unsigned int which
- );
-
- // -------------------------------------------------------------------
- /** Waits until all scenes have been loaded. This returns
- * immediately if no scenes are queued.*/
- void LoadAll();
-
-private:
- // No need to have that in the public API ...
- BatchData *m_data;
-};
-
-} // Namespace Assimp
-
-#endif // INCLUDED_AI_IMPORTER_H
diff --git a/src/3rdparty/assimp/code/ImporterRegistry.cpp b/src/3rdparty/assimp/code/ImporterRegistry.cpp
deleted file mode 100644
index b4d2c3dcf..000000000
--- a/src/3rdparty/assimp/code/ImporterRegistry.cpp
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ImporterRegistry.cpp
-
-Central registry for all importers available. Do not edit this file
-directly (unless you are adding new loaders), instead use the
-corresponding preprocessor flag to selectively disable formats.
-*/
-
-#include <vector>
-#include "BaseImporter.h"
-
-// ------------------------------------------------------------------------------------------------
-// Importers
-// (include_new_importers_here)
-// ------------------------------------------------------------------------------------------------
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-# include "XFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
-# include "AMFImporter.hpp"
-#endif
-#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
-# include "3DSLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-# include "MD3Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-# include "MDLLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD2_IMPORTER
-# include "MD2Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-# include "PlyLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-# include "ASELoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER
-# include "ObjFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_HMP_IMPORTER
-# include "HMPLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-# include "SMDLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-# include "MDCLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-# include "MD5Loader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-# include "STLLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-# include "LWOLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
-# include "DXFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-# include "NFFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-# include "RawLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
-# include "SIBImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-# include "OFFLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
-# include "ACLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
-# include "BVHLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
-# include "IRRMeshLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
-# include "IRRLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-# include "Q3DLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
-# include "B3DImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
-# include "ColladaLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-# include "TerragenLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
-# include "CSMLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-# include "UnrealLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
-# include "LWSLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-# include "OgreImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-# include "OpenGEXImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-# include "MS3DLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
-# include "COBLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
-# include "BlenderLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-# include "Q3BSPFileImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
-# include "NDOLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
-# include "IFCLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
-# include "XGLLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
-# include "FBXImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
-# include "AssbinLoader.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-# include "glTFImporter.h"
-# include "glTF2Importer.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
-# include "C4DImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
-# include "D3MFImporter.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-# include "X3DImporter.hpp"
-#endif
-#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-# include "MMDImporter.h"
-#endif
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-void GetImporterInstanceList(std::vector< BaseImporter* >& out)
-{
- // ----------------------------------------------------------------------------
- // Add an instance of each worker class here
- // (register_new_importers_here)
- // ----------------------------------------------------------------------------
- out.reserve(64);
-#if (!defined ASSIMP_BUILD_NO_X_IMPORTER)
- out.push_back( new XFileImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OBJ_IMPORTER)
- out.push_back( new ObjFileImporter());
-#endif
-#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
- out.push_back( new AMFImporter() );
-#endif
-#if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
- out.push_back( new Discreet3DSImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
- out.push_back( new MD3Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD2_IMPORTER)
- out.push_back( new MD2Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_PLY_IMPORTER)
- out.push_back( new PLYImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MDL_IMPORTER)
- out.push_back( new MDLImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_ASE_IMPORTER)
- #if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
- out.push_back( new ASEImporter());
-# endif
-#endif
-#if (!defined ASSIMP_BUILD_NO_HMP_IMPORTER)
- out.push_back( new HMPImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SMD_IMPORTER)
- out.push_back( new SMDImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MDC_IMPORTER)
- out.push_back( new MDCImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_MD5_IMPORTER)
- out.push_back( new MD5Importer());
-#endif
-#if (!defined ASSIMP_BUILD_NO_STL_IMPORTER)
- out.push_back( new STLImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER)
- out.push_back( new LWOImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_DXF_IMPORTER)
- out.push_back( new DXFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_NFF_IMPORTER)
- out.push_back( new NFFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_RAW_IMPORTER)
- out.push_back( new RAWImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SIB_IMPORTER)
- out.push_back( new SIBImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OFF_IMPORTER)
- out.push_back( new OFFImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_AC_IMPORTER)
- out.push_back( new AC3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_BVH_IMPORTER)
- out.push_back( new BVHLoader());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IRRMESH_IMPORTER)
- out.push_back( new IRRMeshImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IRR_IMPORTER)
- out.push_back( new IRRImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_Q3D_IMPORTER)
- out.push_back( new Q3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_B3D_IMPORTER)
- out.push_back( new B3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_COLLADA_IMPORTER)
- out.push_back( new ColladaLoader());
-#endif
-#if (!defined ASSIMP_BUILD_NO_TERRAGEN_IMPORTER)
- out.push_back( new TerragenImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_CSM_IMPORTER)
- out.push_back( new CSMImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_3D_IMPORTER)
- out.push_back( new UnrealImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
- out.push_back( new LWSImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OGRE_IMPORTER)
- out.push_back( new Ogre::OgreImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OPENGEX_IMPORTER )
- out.push_back( new OpenGEX::OpenGEXImporter() );
-#endif
-#if (!defined ASSIMP_BUILD_NO_MS3D_IMPORTER)
- out.push_back( new MS3DImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_COB_IMPORTER)
- out.push_back( new COBImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_BLEND_IMPORTER)
- out.push_back( new BlenderImporter());
-#endif
-#if (!defined ASSIMP_BUILD_NO_Q3BSP_IMPORTER)
- out.push_back( new Q3BSPFileImporter() );
-#endif
-#if (!defined ASSIMP_BUILD_NO_NDO_IMPORTER)
- out.push_back( new NDOImporter() );
-#endif
-#if (!defined ASSIMP_BUILD_NO_IFC_IMPORTER)
- out.push_back( new IFCImporter() );
-#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
-#if ( !defined ASSIMP_BUILD_NO_ASSBIN_IMPORTER )
- out.push_back( new AssbinImporter() );
-#endif
-#if ( !defined ASSIMP_BUILD_NO_GLTF_IMPORTER )
- out.push_back( new glTFImporter() );
- out.push_back( new glTF2Importer() );
-#endif
-#if ( !defined ASSIMP_BUILD_NO_C4D_IMPORTER )
- out.push_back( new C4DImporter() );
-#endif
-#if ( !defined ASSIMP_BUILD_NO_3MF_IMPORTER )
- out.push_back( new D3MFImporter() );
-#endif
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
- out.push_back( new X3DImporter() );
-#endif
-#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
- out.push_back( new MMDImporter() );
-#endif
-}
-
-/** will delete all registered importers. */
-void DeleteImporterInstanceList(std::vector< BaseImporter* >& deleteList){
- for(size_t i= 0; i<deleteList.size();++i){
- delete deleteList[i];
- deleteList[i]=NULL;
- }//for
-}
-
-} // namespace Assimp
diff --git a/src/3rdparty/assimp/code/ImproveCacheLocality.cpp b/src/3rdparty/assimp/code/ImproveCacheLocality.cpp
deleted file mode 100644
index 2ac32aa84..000000000
--- a/src/3rdparty/assimp/code/ImproveCacheLocality.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to improve the cache locality of a mesh.
- * <br>
- * The algorithm is roughly basing on this paper:
- * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf
- * .. although overdraw rduction isn't implemented yet ...
- */
-
-
-
-// internal headers
-#include "ImproveCacheLocality.h"
-#include "VertexTriangleAdjacency.h"
-#include "StringUtils.h"
-#include <assimp/postprocess.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <stdio.h>
-#include <stack>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() {
- configCacheDepth = PP_ICL_PTCACHE_SIZE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ImproveCacheLocalityProcess::~ImproveCacheLocalityProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ImproveCacheLocalityProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_ImproveCacheLocality) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration
-void ImproveCacheLocalityProcess::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_PP_ICL_PTCACHE_SIZE controls the target cache size for the optimizer
- configCacheDepth = pImp->GetPropertyInteger(AI_CONFIG_PP_ICL_PTCACHE_SIZE,PP_ICL_PTCACHE_SIZE);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
-{
- if (!pScene->mNumMeshes) {
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess skipped; there are no meshes");
- return;
- }
-
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess begin");
-
- float out = 0.f;
- unsigned int numf = 0, numm = 0;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++){
- const float res = ProcessMesh( pScene->mMeshes[a],a);
- if (res) {
- numf += pScene->mMeshes[a]->mNumFaces;
- out += res;
- ++numm;
- }
- }
- if (!DefaultLogger::isNullLogger()) {
- char szBuff[128]; // should be sufficiently large in every case
- ai_snprintf(szBuff,128,"Cache relevant are %u meshes (%u faces). Average output ACMR is %f",
- numm,numf,out/numf);
-
- DefaultLogger::get()->info(szBuff);
- DefaultLogger::get()->debug("ImproveCacheLocalityProcess finished. ");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Improves the cache coherency of a specific mesh
-float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshNum)
-{
- // TODO: rewrite this to use std::vector or boost::shared_array
- ai_assert(NULL != pMesh);
-
- // Check whether the input data is valid
- // - there must be vertices and faces
- // - all faces must be triangulated or we can't operate on them
- if (!pMesh->HasFaces() || !pMesh->HasPositions())
- return 0.f;
-
- if (pMesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
- DefaultLogger::get()->error("This algorithm works on triangle meshes only");
- return 0.f;
- }
-
- if(pMesh->mNumVertices <= configCacheDepth) {
- return 0.f;
- }
-
- float fACMR = 3.f;
- const aiFace* const pcEnd = pMesh->mFaces+pMesh->mNumFaces;
-
- // Input ACMR is for logging purposes only
- if (!DefaultLogger::isNullLogger()) {
-
- unsigned int* piFIFOStack = new unsigned int[configCacheDepth];
- memset(piFIFOStack,0xff,configCacheDepth*sizeof(unsigned int));
- unsigned int* piCur = piFIFOStack;
- const unsigned int* const piCurEnd = piFIFOStack + configCacheDepth;
-
- // count the number of cache misses
- unsigned int iCacheMisses = 0;
- for (const aiFace* pcFace = pMesh->mFaces;pcFace != pcEnd;++pcFace) {
-
- for (unsigned int qq = 0; qq < 3;++qq) {
- bool bInCache = false;
-
- for (unsigned int* pp = piFIFOStack;pp < piCurEnd;++pp) {
- if (*pp == pcFace->mIndices[qq]) {
- // the vertex is in cache
- bInCache = true;
- break;
- }
- }
- if (!bInCache) {
- ++iCacheMisses;
- if (piCurEnd == piCur) {
- piCur = piFIFOStack;
- }
- *piCur++ = pcFace->mIndices[qq];
- }
- }
- }
- delete[] piFIFOStack;
- fACMR = (float)iCacheMisses / pMesh->mNumFaces;
- if (3.0 == fACMR) {
- char szBuff[128]; // should be sufficiently large in every case
-
- // the JoinIdenticalVertices process has not been executed on this
- // mesh, otherwise this value would normally be at least minimally
- // smaller than 3.0 ...
- ai_snprintf(szBuff,128,"Mesh %u: Not suitable for vcache optimization",meshNum);
- DefaultLogger::get()->warn(szBuff);
- return 0.f;
- }
- }
-
- // first we need to build a vertex-triangle adjacency list
- VertexTriangleAdjacency adj(pMesh->mFaces,pMesh->mNumFaces, pMesh->mNumVertices,true);
-
- // build a list to store per-vertex caching time stamps
- unsigned int* const piCachingStamps = new unsigned int[pMesh->mNumVertices];
- memset(piCachingStamps,0x0,pMesh->mNumVertices*sizeof(unsigned int));
-
- // allocate an empty output index buffer. We store the output indices in one large array.
- // Since the number of triangles won't change the input faces can be reused. This is how
- // we save thousands of redundant mini allocations for aiFace::mIndices
- const unsigned int iIdxCnt = pMesh->mNumFaces*3;
- unsigned int* const piIBOutput = new unsigned int[iIdxCnt];
- unsigned int* piCSIter = piIBOutput;
-
- // allocate the flag array to hold the information
- // whether a face has already been emitted or not
- std::vector<bool> abEmitted(pMesh->mNumFaces,false);
-
- // dead-end vertex index stack
- std::stack<unsigned int, std::vector<unsigned int> > sDeadEndVStack;
-
- // create a copy of the piNumTriPtr buffer
- unsigned int* const piNumTriPtr = adj.mLiveTriangles;
- const std::vector<unsigned int> piNumTriPtrNoModify(piNumTriPtr, piNumTriPtr + pMesh->mNumVertices);
-
- // get the largest number of referenced triangles and allocate the "candidate buffer"
- unsigned int iMaxRefTris = 0; {
- const unsigned int* piCur = adj.mLiveTriangles;
- const unsigned int* const piCurEnd = adj.mLiveTriangles+pMesh->mNumVertices;
- for (;piCur != piCurEnd;++piCur) {
- iMaxRefTris = std::max(iMaxRefTris,*piCur);
- }
- }
- ai_assert(iMaxRefTris > 0);
- unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
- unsigned int iCacheMisses = 0;
-
- // ...................................................................................
- /** PSEUDOCODE for the algorithm
-
- A = Build-Adjacency(I) Vertex-triangle adjacency
- L = Get-Triangle-Counts(A) Per-vertex live triangle counts
- C = Zero(Vertex-Count(I)) Per-vertex caching time stamps
- D = Empty-Stack() Dead-end vertex stack
- E = False(Triangle-Count(I)) Per triangle emitted flag
- O = Empty-Index-Buffer() Empty output buffer
- f = 0 Arbitrary starting vertex
- s = k+1, i = 1 Time stamp and cursor
- while f >= 0 For all valid fanning vertices
- N = Empty-Set() 1-ring of next candidates
- for each Triangle t in Neighbors(A, f)
- if !Emitted(E,t)
- for each Vertex v in t
- Append(O,v) Output vertex
- Push(D,v) Add to dead-end stack
- Insert(N,v) Register as candidate
- L[v] = L[v]-1 Decrease live triangle count
- if s-C[v] > k If not in cache
- C[v] = s Set time stamp
- s = s+1 Increment time stamp
- E[t] = true Flag triangle as emitted
- Select next fanning vertex
- f = Get-Next-Vertex(I,i,k,N,C,s,L,D)
- return O
- */
- // ...................................................................................
-
- int ivdx = 0;
- int ics = 1;
- int iStampCnt = configCacheDepth+1;
- while (ivdx >= 0) {
-
- unsigned int icnt = piNumTriPtrNoModify[ivdx];
- unsigned int* piList = adj.GetAdjacentTriangles(ivdx);
- unsigned int* piCurCandidate = piCandidates;
-
- // get all triangles in the neighborhood
- for (unsigned int tri = 0; tri < icnt;++tri) {
-
- // if they have not yet been emitted, add them to the output IB
- const unsigned int fidx = *piList++;
- if (!abEmitted[fidx]) {
-
- // so iterate through all vertices of the current triangle
- const aiFace* pcFace = &pMesh->mFaces[ fidx ];
- for (unsigned int* p = pcFace->mIndices, *p2 = pcFace->mIndices+3;p != p2;++p) {
- const unsigned int dp = *p;
-
- // the current vertex won't have any free triangles after this step
- if (ivdx != (int)dp) {
- // append the vertex to the dead-end stack
- sDeadEndVStack.push(dp);
-
- // register as candidate for the next step
- *piCurCandidate++ = dp;
-
- // decrease the per-vertex triangle counts
- piNumTriPtr[dp]--;
- }
-
- // append the vertex to the output index buffer
- *piCSIter++ = dp;
-
- // if the vertex is not yet in cache, set its cache count
- if (iStampCnt-piCachingStamps[dp] > configCacheDepth) {
- piCachingStamps[dp] = iStampCnt++;
- ++iCacheMisses;
- }
- }
- // flag triangle as emitted
- abEmitted[fidx] = true;
- }
- }
-
- // the vertex has now no living adjacent triangles anymore
- piNumTriPtr[ivdx] = 0;
-
- // get next fanning vertex
- ivdx = -1;
- int max_priority = -1;
- for (unsigned int* piCur = piCandidates;piCur != piCurCandidate;++piCur) {
- const unsigned int dp = *piCur;
-
- // must have live triangles
- if (piNumTriPtr[dp] > 0) {
- int priority = 0;
-
- // will the vertex be in cache, even after fanning occurs?
- unsigned int tmp;
- if ((tmp = iStampCnt-piCachingStamps[dp]) + 2*piNumTriPtr[dp] <= configCacheDepth) {
- priority = tmp;
- }
-
- // keep best candidate
- if (priority > max_priority) {
- max_priority = priority;
- ivdx = dp;
- }
- }
- }
- // did we reach a dead end?
- if (-1 == ivdx) {
- // need to get a non-local vertex for which we have a good chance that it is still
- // in the cache ...
- while (!sDeadEndVStack.empty()) {
- unsigned int iCachedIdx = sDeadEndVStack.top();
- sDeadEndVStack.pop();
- if (piNumTriPtr[ iCachedIdx ] > 0) {
- ivdx = iCachedIdx;
- break;
- }
- }
-
- if (-1 == ivdx) {
- // well, there isn't such a vertex. Simply get the next vertex in input order and
- // hope it is not too bad ...
- while (ics < (int)pMesh->mNumVertices) {
- ++ics;
- if (piNumTriPtr[ics] > 0) {
- ivdx = ics;
- break;
- }
- }
- }
- }
- }
- float fACMR2 = 0.0f;
- if (!DefaultLogger::isNullLogger()) {
- fACMR2 = (float)iCacheMisses / pMesh->mNumFaces;
-
- // very intense verbose logging ... prepare for much text if there are many meshes
- if ( DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
- char szBuff[128]; // should be sufficiently large in every case
-
- ai_snprintf(szBuff,128,"Mesh %u | ACMR in: %f out: %f | ~%.1f%%",meshNum,fACMR,fACMR2,
- ((fACMR - fACMR2) / fACMR) * 100.f);
- DefaultLogger::get()->debug(szBuff);
- }
-
- fACMR2 *= pMesh->mNumFaces;
- }
- // sort the output index buffer back to the input array
- piCSIter = piIBOutput;
- for (aiFace* pcFace = pMesh->mFaces; pcFace != pcEnd;++pcFace) {
- pcFace->mIndices[0] = *piCSIter++;
- pcFace->mIndices[1] = *piCSIter++;
- pcFace->mIndices[2] = *piCSIter++;
- }
-
- // delete temporary storage
- delete[] piCachingStamps;
- delete[] piIBOutput;
- delete[] piCandidates;
-
- return fACMR2;
-}
diff --git a/src/3rdparty/assimp/code/ImproveCacheLocality.h b/src/3rdparty/assimp/code/ImproveCacheLocality.h
deleted file mode 100644
index d91388c41..000000000
--- a/src/3rdparty/assimp/code/ImproveCacheLocality.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to reorder faces for
- better cache locality*/
-#ifndef AI_IMPROVECACHELOCALITY_H_INC
-#define AI_IMPROVECACHELOCALITY_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/types.h>
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The ImproveCacheLocalityProcess reorders all faces for improved vertex
- * cache locality. It tries to arrange all faces to fans and to render
- * faces which share vertices directly one after the other.
- *
- * @note This step expects triagulated input data.
- */
-class ImproveCacheLocalityProcess : public BaseProcess
-{
-public:
-
- ImproveCacheLocalityProcess();
- ~ImproveCacheLocalityProcess();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether the pp step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Executes the pp step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Configures the pp step
- void SetupProperties(const Importer* pImp);
-
-protected:
- // -------------------------------------------------------------------
- /** Executes the postprocessing step on the given mesh
- * @param pMesh The mesh to process.
- * @param meshNum Index of the mesh to process
- */
- float ProcessMesh( aiMesh* pMesh, unsigned int meshNum);
-
-private:
- //! Configuration parameter: specifies the size of the cache to
- //! optimize the vertex data for.
- unsigned int configCacheDepth;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IMPROVECACHELOCALITY_H_INC
diff --git a/src/3rdparty/assimp/code/JoinVerticesProcess.cpp b/src/3rdparty/assimp/code/JoinVerticesProcess.cpp
deleted file mode 100644
index 17b0ab07f..000000000
--- a/src/3rdparty/assimp/code/JoinVerticesProcess.cpp
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to join identical vertices
- * for all imported meshes
- */
-
-
-#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-
-#include "JoinVerticesProcess.h"
-#include "ProcessHelper.h"
-#include "Vertex.h"
-#include "TinyFormatter.h"
-#include <stdio.h>
-
-using namespace Assimp;
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-JoinVerticesProcess::JoinVerticesProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-JoinVerticesProcess::~JoinVerticesProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool JoinVerticesProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_JoinIdenticalVertices) != 0;
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void JoinVerticesProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("JoinVerticesProcess begin");
-
- // get the total number of vertices BEFORE the step is executed
- int iNumOldVertices = 0;
- if (!DefaultLogger::isNullLogger()) {
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
- iNumOldVertices += pScene->mMeshes[a]->mNumVertices;
- }
- }
-
- // execute the step
- int iNumVertices = 0;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- iNumVertices += ProcessMesh( pScene->mMeshes[a],a);
-
- // if logging is active, print detailed statistics
- if (!DefaultLogger::isNullLogger())
- {
- if (iNumOldVertices == iNumVertices)
- {
- DefaultLogger::get()->debug("JoinVerticesProcess finished ");
- } else
- {
- char szBuff[128]; // should be sufficiently large in every case
- ::ai_snprintf(szBuff,128,"JoinVerticesProcess finished | Verts in: %i out: %i | ~%.1f%%",
- iNumOldVertices,
- iNumVertices,
- ((iNumOldVertices - iNumVertices) / (float)iNumOldVertices) * 100.f);
- DefaultLogger::get()->info(szBuff);
- }
- }
-
- pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unites identical vertices in the given mesh
-int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
-{
- static_assert( AI_MAX_NUMBER_OF_COLOR_SETS == 8, "AI_MAX_NUMBER_OF_COLOR_SETS == 8");
- static_assert( AI_MAX_NUMBER_OF_TEXTURECOORDS == 8, "AI_MAX_NUMBER_OF_TEXTURECOORDS == 8");
-
- // Return early if we don't have any positions
- if (!pMesh->HasPositions() || !pMesh->HasFaces()) {
- return 0;
- }
-
- // We'll never have more vertices afterwards.
- std::vector<Vertex> uniqueVertices;
- uniqueVertices.reserve( pMesh->mNumVertices);
-
- // For each vertex the index of the vertex it was replaced by.
- // Since the maximal number of vertices is 2^31-1, the most significand bit can be used to mark
- // whether a new vertex was created for the index (true) or if it was replaced by an existing
- // unique vertex (false). This saves an additional std::vector<bool> and greatly enhances
- // branching performance.
- static_assert(AI_MAX_VERTICES == 0x7fffffff, "AI_MAX_VERTICES == 0x7fffffff");
- std::vector<unsigned int> replaceIndex( pMesh->mNumVertices, 0xffffffff);
-
- // A little helper to find locally close vertices faster.
- // Try to reuse the lookup table from the last step.
- const static float epsilon = 1e-5f;
- // float posEpsilonSqr;
- SpatialSort* vertexFinder = NULL;
- SpatialSort _vertexFinder;
-
- typedef std::pair<SpatialSort,float> SpatPair;
- if (shared) {
- std::vector<SpatPair >* avf;
- shared->GetProperty(AI_SPP_SPATIAL_SORT,avf);
- if (avf) {
- SpatPair& blubb = (*avf)[meshIndex];
- vertexFinder = &blubb.first;
- // posEpsilonSqr = blubb.second;
- }
- }
- if (!vertexFinder) {
- // bad, need to compute it.
- _vertexFinder.Fill(pMesh->mVertices, pMesh->mNumVertices, sizeof( aiVector3D));
- vertexFinder = &_vertexFinder;
- // posEpsilonSqr = ComputePositionEpsilon(pMesh);
- }
-
- // Squared because we check against squared length of the vector difference
- static const float squareEpsilon = epsilon * epsilon;
-
- // Again, better waste some bytes than a realloc ...
- std::vector<unsigned int> verticesFound;
- verticesFound.reserve(10);
-
- // Run an optimized code path if we don't have multiple UVs or vertex colors.
- // This should yield false in more than 99% of all imports ...
- const bool complex = ( pMesh->GetNumColorChannels() > 0 || pMesh->GetNumUVChannels() > 1);
-
- // Now check each vertex if it brings something new to the table
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- // collect the vertex data
- Vertex v(pMesh,a);
-
- // collect all vertices that are close enough to the given position
- vertexFinder->FindIdenticalPositions( v.position, verticesFound);
- unsigned int matchIndex = 0xffffffff;
-
- // check all unique vertices close to the position if this vertex is already present among them
- for( unsigned int b = 0; b < verticesFound.size(); b++) {
-
- const unsigned int vidx = verticesFound[b];
- const unsigned int uidx = replaceIndex[ vidx];
- if( uidx & 0x80000000)
- continue;
-
- const Vertex& uv = uniqueVertices[ uidx];
- // Position mismatch is impossible - the vertex finder already discarded all non-matching positions
-
- // We just test the other attributes even if they're not present in the mesh.
- // In this case they're initialized to 0 so the comparison succeeds.
- // By this method the non-present attributes are effectively ignored in the comparison.
- if( (uv.normal - v.normal).SquareLength() > squareEpsilon)
- continue;
- if( (uv.texcoords[0] - v.texcoords[0]).SquareLength() > squareEpsilon)
- continue;
- if( (uv.tangent - v.tangent).SquareLength() > squareEpsilon)
- continue;
- if( (uv.bitangent - v.bitangent).SquareLength() > squareEpsilon)
- continue;
-
- // Usually we won't have vertex colors or multiple UVs, so we can skip from here
- // Actually this increases runtime performance slightly, at least if branch
- // prediction is on our side.
- if (complex){
- // manually unrolled because continue wouldn't work as desired in an inner loop,
- // also because some compilers seem to fail the task. Colors and UV coords
- // are interleaved since the higher entries are most likely to be
- // zero and thus useless. By interleaving the arrays, vertices are,
- // on average, rejected earlier.
-
- if( (uv.texcoords[1] - v.texcoords[1]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[0], v.colors[0]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[2] - v.texcoords[2]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[1], v.colors[1]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[3] - v.texcoords[3]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[2], v.colors[2]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[4] - v.texcoords[4]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[3], v.colors[3]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[5] - v.texcoords[5]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[4], v.colors[4]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[6] - v.texcoords[6]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[5], v.colors[5]) > squareEpsilon)
- continue;
-
- if( (uv.texcoords[7] - v.texcoords[7]).SquareLength() > squareEpsilon)
- continue;
- if( GetColorDifference( uv.colors[6], v.colors[6]) > squareEpsilon)
- continue;
-
- if( GetColorDifference( uv.colors[7], v.colors[7]) > squareEpsilon)
- continue;
- }
-
- // we're still here -> this vertex perfectly matches our given vertex
- matchIndex = uidx;
- break;
- }
-
- // found a replacement vertex among the uniques?
- if( matchIndex != 0xffffffff)
- {
- // store where to found the matching unique vertex
- replaceIndex[a] = matchIndex | 0x80000000;
- }
- else
- {
- // no unique vertex matches it up to now -> so add it
- replaceIndex[a] = (unsigned int)uniqueVertices.size();
- uniqueVertices.push_back( v);
- }
- }
-
- if (!DefaultLogger::isNullLogger() && DefaultLogger::get()->getLogSeverity() == Logger::VERBOSE) {
- DefaultLogger::get()->debug((Formatter::format(),
- "Mesh ",meshIndex,
- " (",
- (pMesh->mName.length ? pMesh->mName.data : "unnamed"),
- ") | Verts in: ",pMesh->mNumVertices,
- " out: ",
- uniqueVertices.size(),
- " | ~",
- ((pMesh->mNumVertices - uniqueVertices.size()) / (float)pMesh->mNumVertices) * 100.f,
- "%"
- ));
- }
-
- // replace vertex data with the unique data sets
- pMesh->mNumVertices = (unsigned int)uniqueVertices.size();
-
- // ----------------------------------------------------------------------------
- // NOTE - we're *not* calling Vertex::SortBack() because it would check for
- // presence of every single vertex component once PER VERTEX. And our CPU
- // dislikes branches, even if they're easily predictable.
- // ----------------------------------------------------------------------------
-
- // Position
- delete [] pMesh->mVertices;
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
- pMesh->mVertices[a] = uniqueVertices[a].position;
-
- // Normals, if present
- if( pMesh->mNormals)
- {
- delete [] pMesh->mNormals;
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mNormals[a] = uniqueVertices[a].normal;
- }
- }
- // Tangents, if present
- if( pMesh->mTangents)
- {
- delete [] pMesh->mTangents;
- pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mTangents[a] = uniqueVertices[a].tangent;
- }
- }
- // Bitangents as well
- if( pMesh->mBitangents)
- {
- delete [] pMesh->mBitangents;
- pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
- for( unsigned int a = 0; a < pMesh->mNumVertices; a++) {
- pMesh->mBitangents[a] = uniqueVertices[a].bitangent;
- }
- }
- // Vertex colors
- for( unsigned int a = 0; pMesh->HasVertexColors(a); a++)
- {
- delete [] pMesh->mColors[a];
- pMesh->mColors[a] = new aiColor4D[pMesh->mNumVertices];
- for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
- pMesh->mColors[a][b] = uniqueVertices[b].colors[a];
- }
- }
- // Texture coords
- for( unsigned int a = 0; pMesh->HasTextureCoords(a); a++)
- {
- delete [] pMesh->mTextureCoords[a];
- pMesh->mTextureCoords[a] = new aiVector3D[pMesh->mNumVertices];
- for( unsigned int b = 0; b < pMesh->mNumVertices; b++) {
- pMesh->mTextureCoords[a][b] = uniqueVertices[b].texcoords[a];
- }
- }
-
- // adjust the indices in all faces
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
- {
- aiFace& face = pMesh->mFaces[a];
- for( unsigned int b = 0; b < face.mNumIndices; b++) {
- face.mIndices[b] = replaceIndex[face.mIndices[b]] & ~0x80000000;
- }
- }
-
- // adjust bone vertex weights.
- for( int a = 0; a < (int)pMesh->mNumBones; a++) {
- aiBone* bone = pMesh->mBones[a];
- std::vector<aiVertexWeight> newWeights;
- newWeights.reserve( bone->mNumWeights);
-
- if ( NULL != bone->mWeights ) {
- for ( unsigned int b = 0; b < bone->mNumWeights; b++ ) {
- const aiVertexWeight& ow = bone->mWeights[ b ];
- // if the vertex is a unique one, translate it
- if ( !( replaceIndex[ ow.mVertexId ] & 0x80000000 ) ) {
- aiVertexWeight nw;
- nw.mVertexId = replaceIndex[ ow.mVertexId ];
- nw.mWeight = ow.mWeight;
- newWeights.push_back( nw );
- }
- }
- } else {
- DefaultLogger::get()->error( "X-Export: aiBone shall contain weights, but pointer to them is NULL." );
- }
-
- if (newWeights.size() > 0) {
- // kill the old and replace them with the translated weights
- delete [] bone->mWeights;
- bone->mNumWeights = (unsigned int)newWeights.size();
-
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
- }
- else {
-
- /* NOTE:
- *
- * In the algorithm above we're assuming that there are no vertices
- * with a different bone weight setup at the same position. That wouldn't
- * make sense, but it is not absolutely impossible. SkeletonMeshBuilder
- * for example generates such input data if two skeleton points
- * share the same position. Again this doesn't make sense but is
- * reality for some model formats (MD5 for example uses these special
- * nodes as attachment tags for its weapons).
- *
- * Then it is possible that a bone has no weights anymore .... as a quick
- * workaround, we're just removing these bones. If they're animated,
- * model geometry might be modified but at least there's no risk of a crash.
- */
- delete bone;
- --pMesh->mNumBones;
- for (unsigned int n = a; n < pMesh->mNumBones; ++n) {
- pMesh->mBones[n] = pMesh->mBones[n+1];
- }
-
- --a;
- DefaultLogger::get()->warn("Removing bone -> no weights remaining");
- }
- }
- return pMesh->mNumVertices;
-}
-
-#endif // !! ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
diff --git a/src/3rdparty/assimp/code/JoinVerticesProcess.h b/src/3rdparty/assimp/code/JoinVerticesProcess.h
deleted file mode 100644
index a3204782a..000000000
--- a/src/3rdparty/assimp/code/JoinVerticesProcess.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to join identical vertices
- on all imported meshes.*/
-#ifndef AI_JOINVERTICESPROCESS_H_INC
-#define AI_JOINVERTICESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/types.h>
-
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ---------------------------------------------------------------------------
-/** The JoinVerticesProcess unites identical vertices in all imported meshes.
- * By default the importer returns meshes where each face addressed its own
- * set of vertices even if that means that identical vertices are stored multiple
- * times. The JoinVerticesProcess finds these identical vertices and
- * erases all but one of the copies. This usually reduces the number of vertices
- * in a mesh by a serious amount and is the standard form to render a mesh.
- */
-class ASSIMP_API JoinVerticesProcess : public BaseProcess
-{
-public:
- JoinVerticesProcess();
- ~JoinVerticesProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-public:
- // -------------------------------------------------------------------
- /** Unites identical vertices in the given mesh.
- * @param pMesh The mesh to process.
- * @param meshIndex Index of the mesh to process
- */
- int ProcessMesh( aiMesh* pMesh, unsigned int meshIndex);
-
-private:
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/LWOAnimation.cpp b/src/3rdparty/assimp/code/LWOAnimation.cpp
deleted file mode 100644
index 4b5338f7a..000000000
--- a/src/3rdparty/assimp/code/LWOAnimation.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWOAnimation.cpp
- * @brief LWOAnimationResolver utility class
- *
- * It's a very generic implementation of LightWave's system of
- * componentwise-animated stuff. The one and only fully free
- * implementation of LightWave envelopes of which I know.
-*/
-
-
-#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)
-
-#include <functional>
-
-// internal headers
-#include "LWOFileData.h"
-#include <assimp/anim.h>
-
-using namespace Assimp;
-using namespace Assimp::LWO;
-
-// ------------------------------------------------------------------------------------------------
-// Construct an animation resolver from a given list of envelopes
-AnimResolver::AnimResolver(std::list<Envelope>& _envelopes,double tick)
- : envelopes (_envelopes)
- , sample_rate (0.)
- , envl_x(), envl_y(), envl_z()
- , end_x(), end_y(), end_z()
- , flags()
- , sample_delta()
-{
- trans_x = trans_y = trans_z = NULL;
- rotat_x = rotat_y = rotat_z = NULL;
- scale_x = scale_y = scale_z = NULL;
-
- first = last = 150392.;
-
- // find transformation envelopes
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).old_first = 0;
- (*it).old_last = (*it).keys.size()-1;
-
- if ((*it).keys.empty()) continue;
- switch ((*it).type) {
-
- // translation
- case LWO::EnvelopeType_Position_X:
- trans_x = &*it;break;
- case LWO::EnvelopeType_Position_Y:
- trans_y = &*it;break;
- case LWO::EnvelopeType_Position_Z:
- trans_z = &*it;break;
-
- // rotation
- case LWO::EnvelopeType_Rotation_Heading:
- rotat_x = &*it;break;
- case LWO::EnvelopeType_Rotation_Pitch:
- rotat_y = &*it;break;
- case LWO::EnvelopeType_Rotation_Bank:
- rotat_z = &*it;break;
-
- // scaling
- case LWO::EnvelopeType_Scaling_X:
- scale_x = &*it;break;
- case LWO::EnvelopeType_Scaling_Y:
- scale_y = &*it;break;
- case LWO::EnvelopeType_Scaling_Z:
- scale_z = &*it;break;
- default:
- continue;
- };
-
- // convert from seconds to ticks
- for (std::vector<LWO::Key>::iterator d = (*it).keys.begin(); d != (*it).keys.end(); ++d)
- (*d).time *= tick;
-
- // set default animation range (minimum and maximum time value for which we have a keyframe)
- first = std::min(first, (*it).keys.front().time );
- last = std::max(last, (*it).keys.back().time );
- }
-
- // deferred setup of animation range to increase performance.
- // typically the application will want to specify its own.
- need_to_setup = true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reset all envelopes to their original contents
-void AnimResolver::ClearAnimRangeSetup()
-{
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
-
- (*it).keys.erase((*it).keys.begin(),(*it).keys.begin()+(*it).old_first);
- (*it).keys.erase((*it).keys.begin()+(*it).old_last+1,(*it).keys.end());
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Insert additional keys to match LWO's pre& post behaviours.
-void AnimResolver::UpdateAnimRangeSetup()
-{
- // XXX doesn't work yet (hangs if more than one envelope channels needs to be interpolated)
-
- for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
- if ((*it).keys.empty()) continue;
-
- const double my_first = (*it).keys.front().time;
- const double my_last = (*it).keys.back().time;
-
- const double delta = my_last-my_first;
- const size_t old_size = (*it).keys.size();
-
- const float value_delta = (*it).keys.back().value - (*it).keys.front().value;
-
- // NOTE: We won't handle reset, linear and constant here.
- // See DoInterpolation() for their implementation.
-
- // process pre behaviour
- switch ((*it).pre) {
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate:
- {
- const double start_time = delta - std::fmod(my_first-first,delta);
- std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
- [start_time](double t) { return start_time > t; }),m;
-
- size_t ofs = 0;
- if (n != (*it).keys.end()) {
- // copy from here - don't use iterators, insert() would invalidate them
- ofs = (*it).keys.end()-n;
- (*it).keys.insert((*it).keys.begin(),ofs,LWO::Key());
-
- std::copy((*it).keys.end()-ofs,(*it).keys.end(),(*it).keys.begin());
- }
-
- // do full copies. again, no iterators
- const unsigned int num = (unsigned int)((my_first-first) / delta);
- (*it).keys.resize((*it).keys.size() + num*old_size);
-
- n = (*it).keys.begin()+ofs;
- bool reverse = false;
- for (unsigned int i = 0; i < num; ++i) {
- m = n+old_size*(i+1);
- std::copy(n,n+old_size,m);
-
- if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse))
- std::reverse(m,m+old_size-1);
- }
-
- // update time values
- n = (*it).keys.end() - (old_size+1);
- double cur_minus = delta;
- unsigned int tt = 1;
- for (const double tmp = delta*(num+1);cur_minus <= tmp;cur_minus += delta,++tt) {
- m = (delta == tmp ? (*it).keys.begin() : n - (old_size+1));
- for (;m != n; --n) {
- (*n).time -= cur_minus;
-
- // offset repeat? add delta offset to key value
- if ((*it).pre == LWO::PrePostBehaviour_OffsetRepeat) {
- (*n).value += tt * value_delta;
- }
- }
- }
- break;
- }
- default:
- // silence compiler warning
- break;
- }
-
- // process post behaviour
- switch ((*it).post) {
-
- case LWO::PrePostBehaviour_OffsetRepeat:
- case LWO::PrePostBehaviour_Repeat:
- case LWO::PrePostBehaviour_Oscillate:
-
- break;
-
- default:
- // silence compiler warning
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract bind pose matrix
-void AnimResolver::ExtractBindPose(aiMatrix4x4& out)
-{
- // If we have no envelopes, return identity
- if (envelopes.empty()) {
- out = aiMatrix4x4();
- return;
- }
- aiVector3D angles, scaling(1.f,1.f,1.f), translation;
-
- if (trans_x) translation.x = trans_x->keys[0].value;
- if (trans_y) translation.y = trans_y->keys[0].value;
- if (trans_z) translation.z = trans_z->keys[0].value;
-
- if (rotat_x) angles.x = rotat_x->keys[0].value;
- if (rotat_y) angles.y = rotat_y->keys[0].value;
- if (rotat_z) angles.z = rotat_z->keys[0].value;
-
- if (scale_x) scaling.x = scale_x->keys[0].value;
- if (scale_y) scaling.y = scale_y->keys[0].value;
- if (scale_z) scaling.z = scale_z->keys[0].value;
-
- // build the final matrix
- aiMatrix4x4 s,rx,ry,rz,t;
- aiMatrix4x4::RotationZ(angles.z, rz);
- aiMatrix4x4::RotationX(angles.y, rx);
- aiMatrix4x4::RotationY(angles.x, ry);
- aiMatrix4x4::Translation(translation,t);
- aiMatrix4x4::Scaling(scaling,s);
- out = t*ry*rx*rz*s;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Do a single interpolation on a channel
-void AnimResolver::DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope* envl,double time, float& fill)
-{
- if (envl->keys.size() == 1) {
- fill = envl->keys[0].value;
- return;
- }
-
- // check whether we're at the beginning of the animation track
- if (cur == envl->keys.begin()) {
-
- // ok ... this depends on pre behaviour now
- // we don't need to handle repeat&offset repeat&oszillate here, see UpdateAnimRangeSetup()
- switch (envl->pre)
- {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur,cur+1,time,fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default : //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
- // check whether we're at the end of the animation track
- else if (cur == envl->keys.end()-1 && time > envl->keys.rbegin()->time) {
- // ok ... this depends on post behaviour now
- switch (envl->post)
- {
- case LWO::PrePostBehaviour_Linear:
- DoInterpolation2(cur,cur-1,time,fill);
- return;
-
- case LWO::PrePostBehaviour_Reset:
- fill = 0.f;
- return;
-
- default : //case LWO::PrePostBehaviour_Constant:
- fill = (*cur).value;
- return;
- }
- }
-
- // Otherwise do a simple interpolation
- DoInterpolation2(cur-1,cur,time,fill);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Almost the same, except we won't handle pre/post conditions here
-void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end,double time, float& fill)
-{
- switch ((*end).inter) {
-
- case LWO::IT_STEP:
- // no interpolation at all - take the value of the last key
- fill = (*beg).value;
- return;
- default:
-
- // silence compiler warning
- break;
- }
- // linear interpolation - default
- double duration = (*end).time - (*beg).time;
- if (duration > 0.0) {
- fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / duration));
- } else {
- fill = (*beg).value;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Subsample animation track by given key values
-void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& /*out*/,
- double /*time*/ ,double /*sample_delta*/ )
-{
- //ai_assert(out.empty() && sample_delta);
-
- //const double time_start = out.back().mTime;
-// for ()
-}
-
-// ------------------------------------------------------------------------------------------------
-// Track interpolation
-void AnimResolver::InterpolateTrack(std::vector<aiVectorKey>& out,aiVectorKey& fill,double time)
-{
- // subsample animation track?
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- SubsampleAnimTrack(out,time, sample_delta);
- }
-
- fill.mTime = time;
-
- // get x
- if ((*cur_x).time == time) {
- fill.mValue.x = (*cur_x).value;
-
- if (cur_x != envl_x->keys.end()-1) /* increment x */
- ++cur_x;
- else end_x = true;
- }
- else DoInterpolation(cur_x,envl_x,time,(float&)fill.mValue.x);
-
- // get y
- if ((*cur_y).time == time) {
- fill.mValue.y = (*cur_y).value;
-
- if (cur_y != envl_y->keys.end()-1) /* increment y */
- ++cur_y;
- else end_y = true;
- }
- else DoInterpolation(cur_y,envl_y,time,(float&)fill.mValue.y);
-
- // get z
- if ((*cur_z).time == time) {
- fill.mValue.z = (*cur_z).value;
-
- if (cur_z != envl_z->keys.end()-1) /* increment z */
- ++cur_z;
- else end_x = true;
- }
- else DoInterpolation(cur_z,envl_z,time,(float&)fill.mValue.z);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build linearly subsampled keys from three single envelopes, one for each component (x,y,z)
-void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
- LWO::Envelope* _envl_x,
- LWO::Envelope* _envl_y,
- LWO::Envelope* _envl_z,
- unsigned int _flags)
-{
- envl_x = _envl_x;
- envl_y = _envl_y;
- envl_z = _envl_z;
- flags = _flags;
-
- // generate default channels if none are given
- LWO::Envelope def_x, def_y, def_z;
- LWO::Key key_dummy;
- key_dummy.time = 0.f;
- if ((envl_x && envl_x->type == LWO::EnvelopeType_Scaling_X) ||
- (envl_y && envl_y->type == LWO::EnvelopeType_Scaling_Y) ||
- (envl_z && envl_z->type == LWO::EnvelopeType_Scaling_Z)) {
- key_dummy.value = 1.f;
- }
- else key_dummy.value = 0.f;
-
- if (!envl_x) {
- envl_x = &def_x;
- envl_x->keys.push_back(key_dummy);
- }
- if (!envl_y) {
- envl_y = &def_y;
- envl_y->keys.push_back(key_dummy);
- }
- if (!envl_z) {
- envl_z = &def_z;
- envl_z->keys.push_back(key_dummy);
- }
-
- // guess how many keys we'll get
- size_t reserve;
- double sr = 1.;
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- if (!sample_rate)
- sr = 100.f;
- else sr = sample_rate;
- sample_delta = 1.f / sr;
-
- reserve = (size_t)(
- std::max( envl_x->keys.rbegin()->time,
- std::max( envl_y->keys.rbegin()->time, envl_z->keys.rbegin()->time )) * sr);
- }
- else reserve = std::max(envl_x->keys.size(),std::max(envl_x->keys.size(),envl_z->keys.size()));
- out.reserve(reserve+(reserve>>1));
-
- // Iterate through all three arrays at once - it's tricky, but
- // rather interesting to implement.
- cur_x = envl_x->keys.begin();
- cur_y = envl_y->keys.begin();
- cur_z = envl_z->keys.begin();
-
- end_x = end_y = end_z = false;
- while (1) {
-
- aiVectorKey fill;
-
- if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {
-
- // 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;
- fill.mValue.y = (*cur_y).value;
- fill.mValue.z = (*cur_z).value;
-
- // subsample animation track
- if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
- //SubsampleAnimTrack(out,cur_x, cur_y, cur_z, d, sample_delta);
- }
- }
-
- // Find key with lowest time value
- else if ((*cur_x).time <= (*cur_y).time && !end_x) {
-
- if ((*cur_z).time <= (*cur_x).time && !end_z) {
- InterpolateTrack(out,fill,(*cur_z).time);
- }
- else {
- InterpolateTrack(out,fill,(*cur_x).time);
- }
- }
- else if ((*cur_z).time <= (*cur_y).time && !end_y) {
- InterpolateTrack(out,fill,(*cur_y).time);
- }
- else if (!end_y) {
- // welcome on the server, y
- InterpolateTrack(out,fill,(*cur_y).time);
- }
- else {
- // we have reached the end of at least 2 channels,
- // only one is remaining. Extrapolate the 2.
- if (end_y) {
- InterpolateTrack(out,fill,(end_x ? (*cur_z) : (*cur_x)).time);
- }
- else if (end_x) {
- InterpolateTrack(out,fill,(end_z ? (*cur_y) : (*cur_z)).time);
- }
- else { // if (end_z)
- InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
- }
- }
- double lasttime = fill.mTime;
- out.push_back(fill);
-
- if (lasttime >= (*cur_x).time) {
- if (cur_x != envl_x->keys.end()-1)
- ++cur_x;
- else end_x = true;
- }
- if (lasttime >= (*cur_y).time) {
- if (cur_y != envl_y->keys.end()-1)
- ++cur_y;
- else end_y = true;
- }
- if (lasttime >= (*cur_z).time) {
- if (cur_z != envl_z->keys.end()-1)
- ++cur_z;
- else end_z = true;
- }
-
- if( end_x && end_y && end_z ) /* finished? */
- break;
- }
-
- if (flags & AI_LWO_ANIM_FLAG_START_AT_ZERO) {
- for (std::vector<aiVectorKey>::iterator it = out.begin(); it != out.end(); ++it)
- (*it).mTime -= first;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract animation channel
-void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0*/)
-{
- *out = NULL;
-
-
- //FIXME: crashes if more than one component is animated at different timings, to be resolved.
-
- // If we have no envelopes, return NULL
- if (envelopes.empty()) {
- return;
- }
-
- // We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
- const bool trans = ((trans_x && trans_x->keys.size() > 1) || (trans_y && trans_y->keys.size() > 1) || (trans_z && trans_z->keys.size() > 1));
- const bool rotat = ((rotat_x && rotat_x->keys.size() > 1) || (rotat_y && rotat_y->keys.size() > 1) || (rotat_z && rotat_z->keys.size() > 1));
- const bool scale = ((scale_x && scale_x->keys.size() > 1) || (scale_y && scale_y->keys.size() > 1) || (scale_z && scale_z->keys.size() > 1));
- if (!trans && !rotat && !scale)
- return;
-
- // Allocate the output animation
- aiNodeAnim* anim = *out = new aiNodeAnim();
-
- // Setup default animation setup if necessary
- if (need_to_setup) {
- UpdateAnimRangeSetup();
- need_to_setup = false;
- }
-
- // copy translation keys
- if (trans) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,trans_x,trans_y,trans_z,flags);
-
- anim->mPositionKeys = new aiVectorKey[ anim->mNumPositionKeys = static_cast<unsigned int>(keys.size()) ];
- std::copy(keys.begin(),keys.end(),anim->mPositionKeys);
- }
-
- // copy rotation keys
- if (rotat) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,rotat_x,rotat_y,rotat_z,flags);
-
- anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = static_cast<unsigned int>(keys.size()) ];
-
- // convert heading, pitch, bank to quaternion
- // mValue.x=Heading=Rot(Y), mValue.y=Pitch=Rot(X), mValue.z=Bank=Rot(Z)
- // Lightwave's rotation order is ZXY
- aiVector3D X(1.0,0.0,0.0);
- aiVector3D Y(0.0,1.0,0.0);
- aiVector3D Z(0.0,0.0,1.0);
- for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
- aiQuatKey& qk = anim->mRotationKeys[i];
- qk.mTime = keys[i].mTime;
- qk.mValue = aiQuaternion(Y,keys[i].mValue.x)*aiQuaternion(X,keys[i].mValue.y)*aiQuaternion(Z,keys[i].mValue.z);
- }
- }
-
- // copy scaling keys
- if (scale) {
- std::vector<aiVectorKey> keys;
- GetKeys(keys,scale_x,scale_y,scale_z,flags);
-
- anim->mScalingKeys = new aiVectorKey[ anim->mNumScalingKeys = static_cast<unsigned int>(keys.size()) ];
- std::copy(keys.begin(),keys.end(),anim->mScalingKeys);
- }
-}
-
-
-#endif // no lwo or no lws
diff --git a/src/3rdparty/assimp/code/LWOAnimation.h b/src/3rdparty/assimp/code/LWOAnimation.h
deleted file mode 100644
index f0c578ad9..000000000
--- a/src/3rdparty/assimp/code/LWOAnimation.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWOAnimation.h
- * @brief LWOAnimationResolver utility class
- *
- * This is for all lightwave-related file format, not only LWO.
- * LWS isthe main purpose.
-*/
-#ifndef AI_LWO_ANIMATION_INCLUDED
-#define AI_LWO_ANIMATION_INCLUDED
-
-//
-#include <vector>
-#include <list>
-
-struct aiNodeAnim;
-struct aiVectorKey;
-
-namespace Assimp {
-namespace LWO {
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO envelopes
- */
-enum EnvelopeType
-{
- EnvelopeType_Position_X = 0x1,
- EnvelopeType_Position_Y = 0x2,
- EnvelopeType_Position_Z = 0x3,
-
- EnvelopeType_Rotation_Heading = 0x4,
- EnvelopeType_Rotation_Pitch = 0x5,
- EnvelopeType_Rotation_Bank = 0x6,
-
- EnvelopeType_Scaling_X = 0x7,
- EnvelopeType_Scaling_Y = 0x8,
- EnvelopeType_Scaling_Z = 0x9,
-
- // -- currently not yet handled
- EnvelopeType_Color_R = 0xa,
- EnvelopeType_Color_G = 0xb,
- EnvelopeType_Color_B = 0xc,
-
- EnvelopeType_Falloff_X = 0xd,
- EnvelopeType_Falloff_Y = 0xe,
- EnvelopeType_Falloff_Z = 0xf,
-
- EnvelopeType_Unknown
-};
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO interpolation modes
- */
-enum InterpolationType
-{
- IT_STEP, IT_LINE, IT_TCB, IT_HERM, IT_BEZI, IT_BEZ2
-};
-
-
-// ---------------------------------------------------------------------------
-/** \brief List of recognized LWO pre or post range behaviours
- */
-enum PrePostBehaviour
-{
- PrePostBehaviour_Reset = 0x0,
- PrePostBehaviour_Constant = 0x1,
- PrePostBehaviour_Repeat = 0x2,
- PrePostBehaviour_Oscillate = 0x3,
- PrePostBehaviour_OffsetRepeat = 0x4,
- PrePostBehaviour_Linear = 0x5
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation keyframe
- */
-struct Key
-{
- Key()
- : time(),
- value(),
- inter (IT_LINE),
- params()
- {}
-
- //! Current time
- double time;
-
- //! Current value
- float value;
-
- //! How to interpolate this key with previous key?
- InterpolationType inter;
-
- //! Interpolation parameters
- float params[5];
-
-
- // for std::find()
- operator double () {
- return time;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO animation envelope
- */
-struct Envelope
-{
- Envelope()
- : index()
- , type (EnvelopeType_Unknown)
- , pre (PrePostBehaviour_Constant)
- , post (PrePostBehaviour_Constant)
-
- , old_first (0)
- , old_last (0)
- {}
-
- //! Index of this envelope
- unsigned int index;
-
- //! Type of envelope
- EnvelopeType type;
-
- //! Pre and post-behaviour
- PrePostBehaviour pre,post;
-
- //! Keyframes for this envelope
- std::vector<Key> keys;
-
- // temporary data for AnimResolver
- size_t old_first,old_last;
-};
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_SAMPLE_ANIMS
-//! Flag for AnimResolver, subsamples the input data with the rate specified
-//! by AnimResolver::SetSampleRate().
-#define AI_LWO_ANIM_FLAG_SAMPLE_ANIMS 0x1
-
-
-// ---------------------------------------------------------------------------
-//! @def AI_LWO_ANIM_FLAG_START_AT_ZERO
-//! Flag for AnimResolver, ensures that the animations starts at zero.
-#define AI_LWO_ANIM_FLAG_START_AT_ZERO 0x2
-
-// ---------------------------------------------------------------------------
-/** @brief Utility class to build Assimp animations from LWO envelopes.
- *
- * Used for both LWO and LWS (MOT also).
- */
-class AnimResolver
-{
-public:
-
- // ------------------------------------------------------------------
- /** @brief Construct an AnimResolver from a given list of envelopes
- * @param envelopes Input envelopes. May be empty.
- * @param Output tick rate, per second
- * @note The input envelopes are possibly modified.
- */
- AnimResolver(std::list<Envelope>& envelopes, double tick);
-
-public:
-
- // ------------------------------------------------------------------
- /** @brief Extract the bind-pose transformation matrix.
- * @param out Receives bind-pose transformation matrix
- */
- void ExtractBindPose(aiMatrix4x4& out);
-
- // ------------------------------------------------------------------
- /** @brief Extract a node animation channel
- * @param out Receives a pointer to a newly allocated node anim.
- * If there's just one keyframe defined, *out is set to NULL and
- * no animation channel is computed.
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- */
- void ExtractAnimChannel(aiNodeAnim** out, unsigned int flags = 0);
-
-
- // ------------------------------------------------------------------
- /** @brief Set the sampling rate for ExtractAnimChannel().
- *
- * Non-linear interpolations are subsampled with this rate (keys
- * per second). Closer sampling positions, if existent, are kept.
- * The sampling rate defaults to 0, if this value is not changed and
- * AI_LWO_ANIM_FLAG_SAMPLE_ANIMS is specified for ExtractAnimChannel(),
- * the class finds a suitable sample rate by itself.
- */
- void SetSampleRate(double sr) {
- sample_rate = sr;
- }
-
- // ------------------------------------------------------------------
- /** @brief Getter for SetSampleRate()
- */
- double GetSampleRate() const {
- return sample_rate;
- }
-
- // ------------------------------------------------------------------
- /** @brief Set the animation time range
- *
- * @param first Time where the animation starts, in ticks
- * @param last Time where the animation ends, in ticks
- */
- void SetAnimationRange(double _first, double _last) {
- first = _first;
- last = _last;
-
- ClearAnimRangeSetup();
- UpdateAnimRangeSetup();
- }
-
-protected:
-
- // ------------------------------------------------------------------
- /** @brief Build linearly subsampled keys from 3 single envelopes
- * @param out Receives output keys
- * @param envl_x X-component envelope
- * @param envl_y Y-component envelope
- * @param envl_z Z-component envelope
- * @param flags Any combination of the AI_LWO_ANIM_FLAG_XXX flags.
- * @note Up to two input envelopes may be NULL
- */
- void GetKeys(std::vector<aiVectorKey>& out,
- LWO::Envelope* envl_x,
- LWO::Envelope* envl_y,
- LWO::Envelope* envl_z,
- unsigned int flags);
-
- // ------------------------------------------------------------------
- /** @brief Resolve a single animation key by applying the right
- * interpolation to it.
- * @param cur Current key
- * @param envl Envelope working on
- * @param time time to be interpolated
- * @param fill Receives the interpolated output value.
- */
- void DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
- LWO::Envelope* envl,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Almost the same, except we won't handle pre/post
- * conditions here.
- * @see DoInterpolation
- */
- void DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
- std::vector<LWO::Key>::const_iterator end,double time, float& fill);
-
- // ------------------------------------------------------------------
- /** @brief Interpolate 2 tracks if one is given
- *
- * @param out Receives extra output keys
- * @param key_out Primary output key
- * @param time Time to interpolate for
- */
- void InterpolateTrack(std::vector<aiVectorKey>& out,
- aiVectorKey& key_out,double time);
-
- // ------------------------------------------------------------------
- /** @brief Subsample an animation track by a given sampling rate
- *
- * @param out Receives output keys. Last key at input defines the
- * time where subsampling starts.
- * @param time Time to end subsampling at
- * @param sample_delta Time delta between two samples
- */
- void SubsampleAnimTrack(std::vector<aiVectorKey>& out,
- double time,double sample_delta);
-
- // ------------------------------------------------------------------
- /** @brief Delete all keys which we inserted to match anim setup
- */
- void ClearAnimRangeSetup();
-
- // ------------------------------------------------------------------
- /** @brief Insert extra keys to match LWO's pre and post behaviours
- * in a given time range [first...last]
- */
- void UpdateAnimRangeSetup();
-
-private:
- std::list<Envelope>& envelopes;
- double sample_rate;
-
- LWO::Envelope* trans_x, *trans_y, *trans_z;
- LWO::Envelope* rotat_x, *rotat_y, *rotat_z;
- LWO::Envelope* scale_x, *scale_y, *scale_z;
-
- double first, last;
- bool need_to_setup;
-
- // temporary storage
- LWO::Envelope* envl_x, * envl_y, * envl_z;
- std::vector<LWO::Key>::const_iterator cur_x,cur_y,cur_z;
- bool end_x, end_y, end_z;
-
- unsigned int flags;
- double sample_delta;
-};
-
-} // end namespace LWO
-} // end namespace Assimp
-
-#endif // !! AI_LWO_ANIMATION_INCLUDED
diff --git a/src/3rdparty/assimp/code/LWOBLoader.cpp b/src/3rdparty/assimp/code/LWOBLoader.cpp
deleted file mode 100644
index 6a07f81a7..000000000
--- a/src/3rdparty/assimp/code/LWOBLoader.cpp
+++ /dev/null
@@ -1,423 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the LWO importer class for the older LWOB
- file formats, including materials */
-
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// Internal headers
-#include "LWOLoader.h"
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBFile()
-{
- LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
- bool running = true;
- while (running)
- {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
- const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- {
- throw DeadlyImportError("LWOB: Invalid chunk length");
- break;
- }
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // vertex list
- case AI_LWO_PNTS:
- {
- if (!mCurLayer->mTempPoints.empty())
- DefaultLogger::get()->warn("LWO: PNTS chunk encountered twice");
- else LoadLWOPoints(head.length);
- break;
- }
- // face list
- case AI_LWO_POLS:
- {
-
- if (!mCurLayer->mFaces.empty())
- DefaultLogger::get()->warn("LWO: POLS chunk encountered twice");
- else LoadLWOBPolygons(head.length);
- break;
- }
- // list of tags
- case AI_LWO_SRFS:
- {
- if (!mTags->empty())
- DefaultLogger::get()->warn("LWO: SRFS chunk encountered twice");
- else LoadLWOTags(head.length);
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF:
- {
- LoadLWOBSurface(head.length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBPolygons(unsigned int length)
-{
- // first find out how many faces and vertices we'll finally need
- LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
- LE_NCONST uint16_t* cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- // perform endianness conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- while (cursor < end)ByteSwap::Swap2(cursor++);
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-#endif
-
- unsigned int iNumFaces = 0,iNumVertices = 0;
- CountVertsAndFacesLWOB(iNumVertices,iNumFaces,cursor,end);
-
- // allocate the output array and copy face indices
- if (iNumFaces)
- {
- cursor = (LE_NCONST uint16_t*)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces);
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWOB(it,cursor,end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWOB(unsigned int& verts, unsigned int& faces,
- LE_NCONST uint16_t*& cursor, const uint16_t* const end, unsigned int max)
-{
- while (cursor < end && max--)
- {
- uint16_t numIndices;
- // must have 2 shorts left for numIndices and surface
- if (end - cursor < 2) {
- throw DeadlyImportError("LWOB: Unexpected end of file");
- }
- ::memcpy(&numIndices, cursor++, 2);
- // must have enough left for indices and surface
- if (end - cursor < (1 + numIndices)) {
- throw DeadlyImportError("LWOB: Unexpected end of file");
- }
- verts += numIndices;
- faces++;
- cursor += numIndices;
- int16_t surface;
- ::memcpy(&surface, cursor++, 2);
- if (surface < 0)
- {
- // there are detail polygons
- ::memcpy(&numIndices, cursor++, 2);
- CountVertsAndFacesLWOB(verts,faces,cursor,end,numIndices);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWOB(FaceList::iterator& it,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max)
-{
- while (cursor < end && max--)
- {
- LWO::Face& face = *it;++it;
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- face.mNumIndices = numIndices;
- if(face.mNumIndices)
- {
- if (cursor + face.mNumIndices >= end)
- {
- break;
- }
- face.mIndices = new unsigned int[face.mNumIndices];
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- unsigned int & mi = face.mIndices[i];
- uint16_t index;
- ::memcpy(&index, cursor++, 2);
- mi = index;
- if (mi > mCurLayer->mTempPoints.size())
- {
- DefaultLogger::get()->warn("LWOB: face index is out of range");
- mi = (unsigned int)mCurLayer->mTempPoints.size()-1;
- }
- }
- }
- else DefaultLogger::get()->warn("LWOB: Face has 0 indices");
- int16_t surface;
- ::memcpy(&surface, cursor++, 2);
- if (surface < 0)
- {
- surface = -surface;
-
- // there are detail polygons.
- uint16_t numPolygons;
- ::memcpy(&numPolygons, cursor++, 2);
- if (cursor < end)
- {
- CopyFaceIndicesLWOB(it,cursor,end,numPolygons);
- }
- }
- face.surfaceIndex = surface-1;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-LWO::Texture* LWOImporter::SetupNewTextureLWOB(LWO::TextureList& list,unsigned int size)
-{
- list.push_back(LWO::Texture());
- LWO::Texture* tex = &list.back();
-
- std::string type;
- GetS0(type,size);
- const char* s = type.c_str();
-
- if(strstr(s, "Image Map"))
- {
- // Determine mapping type
- if(strstr(s, "Planar"))
- tex->mapMode = LWO::Texture::Planar;
- else if(strstr(s, "Cylindrical"))
- tex->mapMode = LWO::Texture::Cylindrical;
- else if(strstr(s, "Spherical"))
- tex->mapMode = LWO::Texture::Spherical;
- else if(strstr(s, "Cubic"))
- tex->mapMode = LWO::Texture::Cubic;
- else if(strstr(s, "Front"))
- tex->mapMode = LWO::Texture::FrontProjection;
- }
- else
- {
- // procedural or gradient, not supported
- DefaultLogger::get()->error("LWOB: Unsupported legacy texture: " + type);
- }
-
- return tex;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOBSurface(unsigned int size)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- mSurfaces->push_back( LWO::Surface () );
- LWO::Surface& surf = mSurfaces->back();
- LWO::Texture* pTex = NULL;
-
- GetS0(surf.mName,size);
- bool running = true;
- while (running) {
- if (mFileBuffer + 6 >= end)
- break;
-
- IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- /* A single test file (sonycam.lwo) seems to have invalid surface chunks.
- * I'm assuming it's the fault of a single, unknown exporter so there are
- * probably THOUSANDS of them. Here's a dirty workaround:
- *
- * We don't break if the chunk limit is exceeded. Instead, we're computing
- * how much storage is actually left and work with this value from now on.
- */
- if (mFileBuffer + head.length > end) {
- DefaultLogger::get()->error("LWOB: Invalid surface chunk length. Trying to continue.");
- head.length = (uint16_t) (end - mFileBuffer);
- }
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // diffuse color
- case AI_LWO_COLR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,3);
- surf.mColor.r = GetU1() / 255.0f;
- surf.mColor.g = GetU1() / 255.0f;
- surf.mColor.b = GetU1() / 255.0f;
- break;
- }
- // diffuse strength ...
- case AI_LWO_DIFF:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,2);
- surf.mDiffuseValue = GetU2() / 255.0f;
- break;
- }
- // specular strength ...
- case AI_LWO_SPEC:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,2);
- surf.mSpecularValue = GetU2() / 255.0f;
- break;
- }
- // luminosity ...
- case AI_LWO_LUMI:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LUMI,2);
- surf.mLuminosity = GetU2() / 255.0f;
- break;
- }
- // transparency
- case AI_LWO_TRAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,2);
- surf.mTransparency = GetU2() / 255.0f;
- break;
- }
- // surface flags
- case AI_LWO_FLAG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,FLAG,2);
- uint16_t flag = GetU2();
- if (flag & 0x4 ) surf.mMaximumSmoothAngle = 1.56207f;
- if (flag & 0x8 ) surf.mColorHighlights = 1.f;
- if (flag & 0x100) surf.bDoubleSided = true;
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
- surf.mMaximumSmoothAngle = std::fabs( GetF4() );
- break;
- }
- // glossiness
- case AI_LWO_GLOS:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,2);
- surf.mGlossiness = (float)GetU2();
- break;
- }
- // color texture
- case AI_LWO_CTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mColorTextures,
- head.length);
- break;
- }
- // diffuse texture
- case AI_LWO_DTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mDiffuseTextures,
- head.length);
- break;
- }
- // specular texture
- case AI_LWO_STEX:
- {
- pTex = SetupNewTextureLWOB(surf.mSpecularTextures,
- head.length);
- break;
- }
- // bump texture
- case AI_LWO_BTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mBumpTextures,
- head.length);
- break;
- }
- // transparency texture
- case AI_LWO_TTEX:
- {
- pTex = SetupNewTextureLWOB(surf.mOpacityTextures,
- head.length);
- break;
- }
- // texture path
- case AI_LWO_TIMG:
- {
- if (pTex) {
- GetS0(pTex->mFileName,head.length);
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TIMG chunk");
- break;
- }
- // texture strength
- case AI_LWO_TVAL:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TVAL,1);
- if (pTex) {
- pTex->mStrength = (float)GetU1()/ 255.f;
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TVAL chunk");
- break;
- }
- // texture flags
- case AI_LWO_TFLG:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TFLG,2);
-
- if (pTex)
- {
- const uint16_t s = GetU2();
- if (s & 1)
- pTex->majorAxis = LWO::Texture::AXIS_X;
- else if (s & 2)
- pTex->majorAxis = LWO::Texture::AXIS_Y;
- else if (s & 4)
- pTex->majorAxis = LWO::Texture::AXIS_Z;
-
- if (s & 16)
- DefaultLogger::get()->warn("LWOB: Ignoring \'negate\' flag on texture");
- }
- else DefaultLogger::get()->warn("LWOB: Unexpected TFLG chunk");
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/src/3rdparty/assimp/code/LWOFileData.h b/src/3rdparty/assimp/code/LWOFileData.h
deleted file mode 100644
index 7fa9a216d..000000000
--- a/src/3rdparty/assimp/code/LWOFileData.h
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWOFileData.h
- * @brief Defines chunk constants used by the LWO file format
-
-The chunks are taken from the official LightWave SDK headers.
-
-*/
-#ifndef AI_LWO_FILEDATA_INCLUDED
-#define AI_LWO_FILEDATA_INCLUDED
-
-// STL headers
-#include <vector>
-#include <list>
-
-// public ASSIMP headers
-#include <assimp/mesh.h>
-
-// internal headers
-#include "IFF.h"
-#include "LWOAnimation.h"
-
-namespace Assimp {
-namespace LWO {
-
-#define AI_LWO_FOURCC_LWOB AI_IFF_FOURCC('L','W','O','B')
-#define AI_LWO_FOURCC_LWO2 AI_IFF_FOURCC('L','W','O','2')
-#define AI_LWO_FOURCC_LXOB AI_IFF_FOURCC('L','X','O','B')
-
-// chunks specific to the LWOB format
-#define AI_LWO_SRFS AI_IFF_FOURCC('S','R','F','S')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G')
-#define AI_LWO_VLUM AI_IFF_FOURCC('V','L','U','M')
-#define AI_LWO_VDIF AI_IFF_FOURCC('V','D','I','F')
-#define AI_LWO_VSPC AI_IFF_FOURCC('V','S','P','C')
-#define AI_LWO_RFLT AI_IFF_FOURCC('R','F','L','T')
-#define AI_LWO_BTEX AI_IFF_FOURCC('B','T','E','X')
-#define AI_LWO_CTEX AI_IFF_FOURCC('C','T','E','X')
-#define AI_LWO_DTEX AI_IFF_FOURCC('D','T','E','X')
-#define AI_LWO_LTEX AI_IFF_FOURCC('L','T','E','X')
-#define AI_LWO_RTEX AI_IFF_FOURCC('R','T','E','X')
-#define AI_LWO_STEX AI_IFF_FOURCC('S','T','E','X')
-#define AI_LWO_TTEX AI_IFF_FOURCC('T','T','E','X')
-#define AI_LWO_TFLG AI_IFF_FOURCC('T','F','L','G')
-#define AI_LWO_TSIZ AI_IFF_FOURCC('T','S','I','Z')
-#define AI_LWO_TCTR AI_IFF_FOURCC('T','C','T','R')
-#define AI_LWO_TFAL AI_IFF_FOURCC('T','F','A','L')
-#define AI_LWO_TVEL AI_IFF_FOURCC('T','V','E','L')
-#define AI_LWO_TCLR AI_IFF_FOURCC('T','C','L','R')
-#define AI_LWO_TVAL AI_IFF_FOURCC('T','V','A','L')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G')
-#define AI_LWO_TAAS AI_IFF_FOURCC('T','A','A','S')
-#define AI_LWO_TREF AI_IFF_FOURCC('T','R','E','F')
-#define AI_LWO_TOPC AI_IFF_FOURCC('T','O','P','C')
-#define AI_LWO_SDAT AI_IFF_FOURCC('S','D','A','T')
-#define AI_LWO_TFP0 AI_IFF_FOURCC('T','F','P','0')
-#define AI_LWO_TFP1 AI_IFF_FOURCC('T','F','P','1')
-
-
-/* top-level chunks */
-#define AI_LWO_LAYR AI_IFF_FOURCC('L','A','Y','R')
-#define AI_LWO_TAGS AI_IFF_FOURCC('T','A','G','S')
-#define AI_LWO_PNTS AI_IFF_FOURCC('P','N','T','S')
-#define AI_LWO_BBOX AI_IFF_FOURCC('B','B','O','X')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P')
-#define AI_LWO_VMAD AI_IFF_FOURCC('V','M','A','D')
-#define AI_LWO_POLS AI_IFF_FOURCC('P','O','L','S')
-#define AI_LWO_PTAG AI_IFF_FOURCC('P','T','A','G')
-#define AI_LWO_ENVL AI_IFF_FOURCC('E','N','V','L')
-#define AI_LWO_CLIP AI_IFF_FOURCC('C','L','I','P')
-#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F')
-#define AI_LWO_DESC AI_IFF_FOURCC('D','E','S','C')
-#define AI_LWO_TEXT AI_IFF_FOURCC('T','E','X','T')
-#define AI_LWO_ICON AI_IFF_FOURCC('I','C','O','N')
-
-/* polygon types */
-#define AI_LWO_FACE AI_IFF_FOURCC('F','A','C','E')
-#define AI_LWO_CURV AI_IFF_FOURCC('C','U','R','V')
-#define AI_LWO_PTCH AI_IFF_FOURCC('P','T','C','H')
-#define AI_LWO_MBAL AI_IFF_FOURCC('M','B','A','L')
-#define AI_LWO_BONE AI_IFF_FOURCC('B','O','N','E')
-#define AI_LWO_SUBD AI_IFF_FOURCC('S','U','B','D')
-
-/* polygon tags */
-#define AI_LWO_SURF AI_IFF_FOURCC('S','U','R','F')
-#define AI_LWO_PART AI_IFF_FOURCC('P','A','R','T')
-#define AI_LWO_SMGP AI_IFF_FOURCC('S','M','G','P')
-
-/* envelopes */
-#define AI_LWO_PRE AI_IFF_FOURCC('P','R','E',' ')
-#define AI_LWO_POST AI_IFF_FOURCC('P','O','S','T')
-#define AI_LWO_KEY AI_IFF_FOURCC('K','E','Y',' ')
-#define AI_LWO_SPAN AI_IFF_FOURCC('S','P','A','N')
-#define AI_LWO_TCB AI_IFF_FOURCC('T','C','B',' ')
-#define AI_LWO_HERM AI_IFF_FOURCC('H','E','R','M')
-#define AI_LWO_BEZI AI_IFF_FOURCC('B','E','Z','I')
-#define AI_LWO_BEZ2 AI_IFF_FOURCC('B','E','Z','2')
-#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E')
-#define AI_LWO_STEP AI_IFF_FOURCC('S','T','E','P')
-
-/* clips */
-#define AI_LWO_STIL AI_IFF_FOURCC('S','T','I','L')
-#define AI_LWO_ISEQ AI_IFF_FOURCC('I','S','E','Q')
-#define AI_LWO_ANIM AI_IFF_FOURCC('A','N','I','M')
-#define AI_LWO_XREF AI_IFF_FOURCC('X','R','E','F')
-#define AI_LWO_STCC AI_IFF_FOURCC('S','T','C','C')
-#define AI_LWO_TIME AI_IFF_FOURCC('T','I','M','E')
-#define AI_LWO_CONT AI_IFF_FOURCC('C','O','N','T')
-#define AI_LWO_BRIT AI_IFF_FOURCC('B','R','I','T')
-#define AI_LWO_SATR AI_IFF_FOURCC('S','A','T','R')
-#define AI_LWO_HUE AI_IFF_FOURCC('H','U','E',' ')
-#define AI_LWO_GAMM AI_IFF_FOURCC('G','A','M','M')
-#define AI_LWO_NEGA AI_IFF_FOURCC('N','E','G','A')
-#define AI_LWO_IFLT AI_IFF_FOURCC('I','F','L','T')
-#define AI_LWO_PFLT AI_IFF_FOURCC('P','F','L','T')
-
-/* surfaces */
-#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R')
-#define AI_LWO_LUMI AI_IFF_FOURCC('L','U','M','I')
-#define AI_LWO_DIFF AI_IFF_FOURCC('D','I','F','F')
-#define AI_LWO_SPEC AI_IFF_FOURCC('S','P','E','C')
-#define AI_LWO_GLOS AI_IFF_FOURCC('G','L','O','S')
-#define AI_LWO_REFL AI_IFF_FOURCC('R','E','F','L')
-#define AI_LWO_RFOP AI_IFF_FOURCC('R','F','O','P')
-#define AI_LWO_RIMG AI_IFF_FOURCC('R','I','M','G')
-#define AI_LWO_RSAN AI_IFF_FOURCC('R','S','A','N')
-#define AI_LWO_TRAN AI_IFF_FOURCC('T','R','A','N')
-#define AI_LWO_TROP AI_IFF_FOURCC('T','R','O','P')
-#define AI_LWO_TIMG AI_IFF_FOURCC('T','I','M','G')
-#define AI_LWO_RIND AI_IFF_FOURCC('R','I','N','D')
-#define AI_LWO_TRNL AI_IFF_FOURCC('T','R','N','L')
-#define AI_LWO_BUMP AI_IFF_FOURCC('B','U','M','P')
-#define AI_LWO_SMAN AI_IFF_FOURCC('S','M','A','N')
-#define AI_LWO_SIDE AI_IFF_FOURCC('S','I','D','E')
-#define AI_LWO_CLRH AI_IFF_FOURCC('C','L','R','H')
-#define AI_LWO_CLRF AI_IFF_FOURCC('C','L','R','F')
-#define AI_LWO_ADTR AI_IFF_FOURCC('A','D','T','R')
-#define AI_LWO_SHRP AI_IFF_FOURCC('S','H','R','P')
-#define AI_LWO_LINE AI_IFF_FOURCC('L','I','N','E')
-#define AI_LWO_LSIZ AI_IFF_FOURCC('L','S','I','Z')
-#define AI_LWO_ALPH AI_IFF_FOURCC('A','L','P','H')
-#define AI_LWO_AVAL AI_IFF_FOURCC('A','V','A','L')
-#define AI_LWO_GVAL AI_IFF_FOURCC('G','V','A','L')
-#define AI_LWO_BLOK AI_IFF_FOURCC('B','L','O','K')
-#define AI_LWO_VCOL AI_IFF_FOURCC('V','C','O','L')
-
-/* texture layer */
-#define AI_LWO_TYPE AI_IFF_FOURCC('T','Y','P','E')
-#define AI_LWO_CHAN AI_IFF_FOURCC('C','H','A','N')
-#define AI_LWO_NAME AI_IFF_FOURCC('N','A','M','E')
-#define AI_LWO_ENAB AI_IFF_FOURCC('E','N','A','B')
-#define AI_LWO_OPAC AI_IFF_FOURCC('O','P','A','C')
-#define AI_LWO_FLAG AI_IFF_FOURCC('F','L','A','G')
-#define AI_LWO_PROJ AI_IFF_FOURCC('P','R','O','J')
-#define AI_LWO_STCK AI_IFF_FOURCC('S','T','C','K')
-#define AI_LWO_TAMP AI_IFF_FOURCC('T','A','M','P')
-
-/* texture coordinates */
-#define AI_LWO_TMAP AI_IFF_FOURCC('T','M','A','P')
-#define AI_LWO_AXIS AI_IFF_FOURCC('A','X','I','S')
-#define AI_LWO_CNTR AI_IFF_FOURCC('C','N','T','R')
-#define AI_LWO_SIZE AI_IFF_FOURCC('S','I','Z','E')
-#define AI_LWO_ROTA AI_IFF_FOURCC('R','O','T','A')
-#define AI_LWO_OREF AI_IFF_FOURCC('O','R','E','F')
-#define AI_LWO_FALL AI_IFF_FOURCC('F','A','L','L')
-#define AI_LWO_CSYS AI_IFF_FOURCC('C','S','Y','S')
-
-/* image map */
-#define AI_LWO_IMAP AI_IFF_FOURCC('I','M','A','P')
-#define AI_LWO_IMAG AI_IFF_FOURCC('I','M','A','G')
-#define AI_LWO_WRAP AI_IFF_FOURCC('W','R','A','P')
-#define AI_LWO_WRPW AI_IFF_FOURCC('W','R','P','W')
-#define AI_LWO_WRPH AI_IFF_FOURCC('W','R','P','H')
-#define AI_LWO_VMAP AI_IFF_FOURCC('V','M','A','P')
-#define AI_LWO_AAST AI_IFF_FOURCC('A','A','S','T')
-#define AI_LWO_PIXB AI_IFF_FOURCC('P','I','X','B')
-
-/* procedural */
-#define AI_LWO_PROC AI_IFF_FOURCC('P','R','O','C')
-#define AI_LWO_COLR AI_IFF_FOURCC('C','O','L','R')
-#define AI_LWO_VALU AI_IFF_FOURCC('V','A','L','U')
-#define AI_LWO_FUNC AI_IFF_FOURCC('F','U','N','C')
-#define AI_LWO_FTPS AI_IFF_FOURCC('F','T','P','S')
-#define AI_LWO_ITPS AI_IFF_FOURCC('I','T','P','S')
-#define AI_LWO_ETPS AI_IFF_FOURCC('E','T','P','S')
-
-/* gradient */
-#define AI_LWO_GRAD AI_IFF_FOURCC('G','R','A','D')
-#define AI_LWO_GRST AI_IFF_FOURCC('G','R','S','T')
-#define AI_LWO_GREN AI_IFF_FOURCC('G','R','E','N')
-#define AI_LWO_PNAM AI_IFF_FOURCC('P','N','A','M')
-#define AI_LWO_INAM AI_IFF_FOURCC('I','N','A','M')
-#define AI_LWO_GRPT AI_IFF_FOURCC('G','R','P','T')
-#define AI_LWO_FKEY AI_IFF_FOURCC('F','K','E','Y')
-#define AI_LWO_IKEY AI_IFF_FOURCC('I','K','E','Y')
-
-/* shader */
-#define AI_LWO_SHDR AI_IFF_FOURCC('S','H','D','R')
-#define AI_LWO_DATA AI_IFF_FOURCC('D','A','T','A')
-
-
-/* VMAP types */
-#define AI_LWO_TXUV AI_IFF_FOURCC('T','X','U','V')
-#define AI_LWO_RGB AI_IFF_FOURCC('R','G','B',' ')
-#define AI_LWO_RGBA AI_IFF_FOURCC('R','G','B','A')
-#define AI_LWO_WGHT AI_IFF_FOURCC('W','G','H','T')
-
-#define AI_LWO_MNVW AI_IFF_FOURCC('M','N','V','W')
-#define AI_LWO_MORF AI_IFF_FOURCC('M','O','R','F')
-#define AI_LWO_SPOT AI_IFF_FOURCC('S','P','O','T')
-#define AI_LWO_PICK AI_IFF_FOURCC('P','I','C','K')
-
-// MODO extension - per-vertex normal vectors
-#define AI_LWO_MODO_NORM AI_IFF_FOURCC('N', 'O', 'R', 'M')
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a face in a LWO file
- *
- * \note We can't use the code in SmoothingGroups.inl here - the mesh
- * structures of 3DS/ASE and LWO are too different.
- */
-struct Face : public aiFace
-{
- //! Default construction
- Face()
- : surfaceIndex (0)
- , smoothGroup (0)
- , type (AI_LWO_FACE)
- {}
-
- //! Construction from given type
- explicit Face(uint32_t _type)
- : surfaceIndex (0)
- , smoothGroup (0)
- , type (_type)
- {}
-
- //! Copy construction
- Face(const Face& f) : aiFace() {
- *this = f;
- }
-
- //! Zero-based index into tags chunk
- unsigned int surfaceIndex;
-
- //! Smooth group this face is assigned to
- unsigned int smoothGroup;
-
- //! Type of face
- uint32_t type;
-
-
- //! Assignment operator
- Face& operator=(const LWO::Face& f) {
- aiFace::operator =(f);
- surfaceIndex = f.surfaceIndex;
- smoothGroup = f.smoothGroup;
- type = f.type;
- return *this;
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Base structure for all vertex map representations
- */
-struct VMapEntry
-{
- explicit VMapEntry(unsigned int _dims)
- : dims(_dims)
- {}
-
- virtual ~VMapEntry() {}
-
- //! allocates memory for the vertex map
- virtual void Allocate(unsigned int num)
- {
- if (!rawData.empty())
- return; // return if already allocated
-
- const unsigned int m = num*dims;
- rawData.reserve(m + (m>>2u)); // 25% as extra storage for VMADs
- rawData.resize(m,0.f);
- abAssigned.resize(num,false);
- }
-
- std::string name;
- unsigned int dims;
-
- std::vector<float> rawData;
- std::vector<bool> abAssigned;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex color channel
- */
-struct VColorChannel : public VMapEntry
-{
- VColorChannel()
- : VMapEntry(4)
- {}
-
- //! need to overwrite this function - the alpha channel must
- //! be initialized to 1.0 by default
- virtual void Allocate(unsigned int num)
- {
- if (!rawData.empty())
- return; // return if already allocated
-
- unsigned int m = num*dims;
- rawData.reserve(m + (m>>2u)); // 25% as extra storage for VMADs
- rawData.resize(m);
-
- for (aiColor4D* p = (aiColor4D*)&rawData[0]; p < (aiColor4D*)&rawData[m-1]; ++p)
- p->a = 1.f;
-
- abAssigned.resize(num,false);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents an extra vertex UV channel
- */
-struct UVChannel : public VMapEntry
-{
- UVChannel()
- : VMapEntry(2)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a weight map
- */
-struct WeightChannel : public VMapEntry
-{
- WeightChannel()
- : VMapEntry(1)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a vertex-normals channel (MODO extension)
- */
-struct NormalChannel : public VMapEntry
-{
- NormalChannel()
- : VMapEntry(3)
- {}
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file texture
- */
-struct Texture
-{
- // we write the enum values out here to make debugging easier ...
- enum BlendType
- {
- Normal = 0,
- Subtractive = 1,
- Difference = 2,
- Multiply = 3,
- Divide = 4,
- Alpha = 5,
- TextureDispl = 6,
- Additive = 7
- };
-
- enum MappingMode
- {
- Planar = 0,
- Cylindrical = 1,
- Spherical = 2,
- Cubic = 3,
- FrontProjection = 4,
- UV = 5
- };
-
- enum Axes
- {
- AXIS_X = 0,
- AXIS_Y = 1,
- AXIS_Z = 2
- };
-
- enum Wrap
- {
- RESET = 0,
- REPEAT = 1,
- MIRROR = 2,
- EDGE = 3
- };
-
- Texture()
- : mClipIdx(UINT_MAX)
- , mStrength (1.0f)
- , type()
- , mUVChannelIndex ("unknown")
- , mRealUVIndex (UINT_MAX)
- , enabled (true)
- , blendType (Additive)
- , bCanUse (true)
- , mapMode (UV)
- , majorAxis (AXIS_X)
- , wrapAmountH (1.0f)
- , wrapAmountW (1.0f)
- , wrapModeWidth (REPEAT)
- , wrapModeHeight (REPEAT)
- , ordinal ("\x00")
- {}
-
- //! File name of the texture
- std::string mFileName;
-
- //! Clip index
- unsigned int mClipIdx;
-
- //! Strength of the texture - blend factor
- float mStrength;
-
- uint32_t type; // type of the texture
-
- //! Name of the corresponding UV channel
- std::string mUVChannelIndex;
- unsigned int mRealUVIndex;
-
- //! is the texture enabled?
- bool enabled;
-
- //! blend type
- BlendType blendType;
-
- //! are we able to use the texture?
- bool bCanUse;
-
- //! mapping mode
- MappingMode mapMode;
-
- //! major axis for planar, cylindrical, spherical projections
- Axes majorAxis;
-
- //! wrap amount for cylindrical and spherical projections
- float wrapAmountH,wrapAmountW;
-
- //! wrapping mode for the texture
- Wrap wrapModeWidth,wrapModeHeight;
-
- //! ordinal string of the texture
- std::string ordinal;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file clip
- */
-struct Clip
-{
- enum Type
- {
- STILL, SEQ, REF, UNSUPPORTED
- } type;
-
- Clip()
- : type (UNSUPPORTED)
- , clipRef()
- , idx (0)
- , negate (false)
- {}
-
- //! path to the base texture -
- std::string path;
-
- //! reference to another CLIP
- unsigned int clipRef;
-
- //! index of the clip
- unsigned int idx;
-
- //! Negate the clip?
- bool negate;
-};
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file shader
- *
- * Later
- */
-struct Shader
-{
- Shader()
- : ordinal ("\x00")
- , functionName ("unknown")
- , enabled (true)
- {}
-
- std::string ordinal;
- std::string functionName;
- bool enabled;
-};
-
-typedef std::list < Texture > TextureList;
-typedef std::list < Shader > ShaderList;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a LWO file surface (= material)
- */
-struct Surface
-{
- Surface()
- : mColor (0.78431f,0.78431f,0.78431f)
- , bDoubleSided (false)
- , mDiffuseValue (1.f)
- , mSpecularValue (0.f)
- , mTransparency (0.f)
- , mGlossiness (0.4f)
- , mLuminosity (0.f)
- , mColorHighlights (0.f)
- , mMaximumSmoothAngle (0.f) // 0 == not specified, no smoothing
- , mVCMap ("")
- , mVCMapType (AI_LWO_RGBA)
- , mIOR (1.f) // vakuum
- , mBumpIntensity (1.f)
- , mWireframe (false)
- , mAdditiveTransparency (0.f)
- {}
-
- //! Name of the surface
- std::string mName;
-
- //! Color of the surface
- aiColor3D mColor;
-
- //! true for two-sided materials
- bool bDoubleSided;
-
- //! Various material parameters
- float mDiffuseValue,mSpecularValue,mTransparency,mGlossiness,mLuminosity,mColorHighlights;
-
- //! Maximum angle between two adjacent triangles
- //! that they can be smoothed - in degrees
- float mMaximumSmoothAngle;
-
- //! Vertex color map to be used to color the surface
- std::string mVCMap;
- uint32_t mVCMapType;
-
- //! Names of the special shaders to be applied to the surface
- ShaderList mShaders;
-
- //! Textures - the first entry in the list is evaluated first
- TextureList mColorTextures, // color textures are added to both diffuse and specular texture stacks
- mDiffuseTextures,
- mSpecularTextures,
- mOpacityTextures,
- mBumpTextures,
- mGlossinessTextures,
- mReflectionTextures;
-
- //! Index of refraction
- float mIOR;
-
- //! Bump intensity scaling
- float mBumpIntensity;
-
- //! Wireframe flag
- bool mWireframe;
-
- //! Intensity of additive blending
- float mAdditiveTransparency;
-};
-
-// ---------------------------------------------------------------------------
-#define AI_LWO_VALIDATE_CHUNK_LENGTH(length,name,size) \
- if (length < size) \
- { \
- throw DeadlyImportError("LWO: "#name" chunk is too small"); \
- } \
-
-
-// some typedefs ... to make life with loader monsters like this easier
-typedef std::vector < aiVector3D > PointList;
-typedef std::vector < LWO::Face > FaceList;
-typedef std::vector < LWO::Surface > SurfaceList;
-typedef std::vector < std::string > TagList;
-typedef std::vector < unsigned int > TagMappingTable;
-typedef std::vector < unsigned int > ReferrerList;
-typedef std::vector < WeightChannel > WeightChannelList;
-typedef std::vector < VColorChannel > VColorChannelList;
-typedef std::vector < UVChannel > UVChannelList;
-typedef std::vector < Clip > ClipList;
-typedef std::vector < Envelope > EnvelopeList;
-typedef std::vector < unsigned int > SortedRep;
-
-// ---------------------------------------------------------------------------
-/** \brief Represents a layer in the file
- */
-struct Layer
-{
- Layer()
- : mFaceIDXOfs (0)
- , mPointIDXOfs (0)
- , mParent (0x0)
- , mIndex (0xffff)
- , skip (false)
- {}
-
- /** Temporary point list from the file */
- PointList mTempPoints;
-
- /** Lists for every point the index of another point
- that has been copied from *this* point or UINT_MAX if
- no copy of the point has been made */
- ReferrerList mPointReferrers;
-
- /** Weight channel list from the file */
- WeightChannelList mWeightChannels;
-
- /** Subdivision weight channel list from the file */
- WeightChannelList mSWeightChannels;
-
- /** Vertex color list from the file */
- VColorChannelList mVColorChannels;
-
- /** UV channel list from the file */
- UVChannelList mUVChannels;
-
- /** Normal vector channel from the file */
- NormalChannel mNormals;
-
- /** Temporary face list from the file*/
- FaceList mFaces;
-
- /** Current face indexing offset from the beginning of the buffers*/
- unsigned int mFaceIDXOfs;
-
- /** Current point indexing offset from the beginning of the buffers*/
- unsigned int mPointIDXOfs;
-
- /** Parent index */
- uint16_t mParent;
-
- /** Index of the layer */
- uint16_t mIndex;
-
- /** Name of the layer */
- std::string mName;
-
- /** Pivot point of the layer */
- aiVector3D mPivot;
-
- /** Skip this layer? */
- bool skip;
-};
-
-typedef std::list<LWO::Layer> LayerList;
-
-
-}}
-
-
-#endif // !! AI_LWO_FILEDATA_INCLUDED
-
diff --git a/src/3rdparty/assimp/code/LWOLoader.cpp b/src/3rdparty/assimp/code/LWOLoader.cpp
deleted file mode 100644
index 5ec07800d..000000000
--- a/src/3rdparty/assimp/code/LWOLoader.cpp
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWOLoader.cpp
- * @brief Implementation of the LWO importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "LWOLoader.h"
-#include "StringComparison.h"
-#include "SGSpatialSort.h"
-#include "ByteSwapper.h"
-#include "ProcessHelper.h"
-#include "ConvertToLHProcess.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-#include <sstream>
-#include <iomanip>
-#include <map>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "LightWave/Modo Object Importer",
- "",
- "",
- "https://www.lightwave3d.com/lightwave_sdk/",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "lwo lxo"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LWOImporter::LWOImporter()
- : mIsLWO2(),
- mIsLXOB(),
- mLayers(),
- mCurLayer(),
- mTags(),
- mMapping(),
- mSurfaces(),
- mFileBuffer(),
- fileSize(),
- pScene(),
- configSpeedFlag(),
- configLayerIndex(),
- hasNamedLayer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LWOImporter::~LWOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool LWOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "lwo" || extension == "lxo") {
- return true;
- }
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[3];
- tokens[0] = AI_LWO_FOURCC_LWOB;
- tokens[1] = AI_LWO_FOURCC_LWO2;
- tokens[2] = AI_LWO_FOURCC_LXOB;
- return CheckMagicToken(pIOHandler,pFile,tokens,3,8);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void LWOImporter::SetupProperties(const Importer* pImp)
-{
- configSpeedFlag = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0) ? true : false);
- configLayerIndex = pImp->GetPropertyInteger (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,UINT_MAX);
- configLayerName = pImp->GetPropertyString (AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,"");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of file extensions
-const aiImporterDesc* LWOImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void LWOImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene,
- IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open LWO file " + pFile + ".");
-
- if((this->fileSize = (unsigned int)file->FileSize()) < 12)
- throw DeadlyImportError("LWO: The file is too small to contain the IFF header");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector< uint8_t > mBuffer(fileSize);
- file->Read( &mBuffer[0], 1, fileSize);
- this->pScene = pScene;
-
- // Determine the type of the file
- uint32_t fileType;
- const char* sz = IFF::ReadHeader(&mBuffer[0],fileType);
- if (sz)throw DeadlyImportError(sz);
-
- mFileBuffer = &mBuffer[0] + 12;
- fileSize -= 12;
-
- // Initialize some members with their default values
- hasNamedLayer = false;
-
- // Create temporary storage on the stack but store pointers to it in the class
- // instance. Therefore everything will be destructed properly if an exception
- // is thrown and we needn't take care of that.
- LayerList _mLayers;
- SurfaceList _mSurfaces;
- TagList _mTags;
- TagMappingTable _mMapping;
-
- mLayers = &_mLayers;
- mTags = &_mTags;
- mMapping = &_mMapping;
- mSurfaces = &_mSurfaces;
-
- // Allocate a default layer (layer indices are 1-based from now)
- mLayers->push_back(Layer());
- mCurLayer = &mLayers->back();
- mCurLayer->mName = "<LWODefault>";
- mCurLayer->mIndex = -1;
-
- // old lightwave file format (prior to v6)
- if (AI_LWO_FOURCC_LWOB == fileType) {
- DefaultLogger::get()->info("LWO file format: LWOB (<= LightWave 5.5)");
-
- mIsLWO2 = false;
- mIsLXOB = false;
- LoadLWOBFile();
- }
- // New lightwave format
- else if (AI_LWO_FOURCC_LWO2 == fileType) {
- mIsLXOB = false;
- DefaultLogger::get()->info("LWO file format: LWO2 (>= LightWave 6)");
- }
- // MODO file format
- else if (AI_LWO_FOURCC_LXOB == fileType) {
- mIsLXOB = true;
- DefaultLogger::get()->info("LWO file format: LXOB (Modo)");
- }
- // we don't know this format
- else
- {
- char szBuff[5];
- szBuff[0] = (char)(fileType >> 24u);
- szBuff[1] = (char)(fileType >> 16u);
- szBuff[2] = (char)(fileType >> 8u);
- szBuff[3] = (char)(fileType);
- szBuff[4] = '\0';
- throw DeadlyImportError(std::string("Unknown LWO sub format: ") + szBuff);
- }
-
- if (AI_LWO_FOURCC_LWOB != fileType) {
- mIsLWO2 = true;
- LoadLWO2File();
-
- // The newer lightwave format allows the user to configure the
- // loader that just one layer is used. If this is the case
- // we need to check now whether the requested layer has been found.
- if (UINT_MAX != configLayerIndex) {
- unsigned int layerCount = 0;
- for(std::list<LWO::Layer>::iterator itLayers=mLayers->begin(); itLayers!=mLayers->end(); ++itLayers)
- if (!itLayers->skip)
- layerCount++;
- if (layerCount!=2)
- throw DeadlyImportError("LWO2: The requested layer was not found");
- }
-
- if (configLayerName.length() && !hasNamedLayer) {
- throw DeadlyImportError("LWO2: Unable to find the requested layer: "
- + configLayerName);
- }
- }
-
- // now, as we have loaded all data, we can resolve cross-referenced tags and clips
- ResolveTags();
- ResolveClips();
-
- // now process all layers and build meshes and nodes
- std::vector<aiMesh*> apcMeshes;
- std::map<uint16_t, aiNode*> apcNodes;
-
- apcMeshes.reserve(mLayers->size()*std::min(((unsigned int)mSurfaces->size()/2u), 1u));
-
- unsigned int iDefaultSurface = UINT_MAX; // index of the default surface
- for (LWO::Layer &layer : *mLayers) {
- if (layer.skip)
- continue;
-
- // I don't know whether there could be dummy layers, but it would be possible
- const unsigned int meshStart = (unsigned int)apcMeshes.size();
- if (!layer.mFaces.empty() && !layer.mTempPoints.empty()) {
-
- // now sort all faces by the surfaces assigned to them
- std::vector<SortedRep> pSorted(mSurfaces->size()+1);
-
- unsigned int i = 0;
- for (FaceList::iterator it = layer.mFaces.begin(), end = layer.mFaces.end();it != end;++it,++i) {
- // Check whether we support this face's type
- if ((*it).type != AI_LWO_FACE && (*it).type != AI_LWO_PTCH &&
- (*it).type != AI_LWO_BONE && (*it).type != AI_LWO_SUBD) {
- continue;
- }
-
- unsigned int idx = (*it).surfaceIndex;
- if (idx >= mTags->size())
- {
- DefaultLogger::get()->warn("LWO: Invalid face surface index");
- idx = UINT_MAX;
- }
- if(UINT_MAX == idx || UINT_MAX == (idx = _mMapping[idx])) {
- if (UINT_MAX == iDefaultSurface) {
- iDefaultSurface = (unsigned int)mSurfaces->size();
- mSurfaces->push_back(LWO::Surface());
- LWO::Surface& surf = mSurfaces->back();
- surf.mColor.r = surf.mColor.g = surf.mColor.b = 0.6f;
- surf.mName = "LWODefaultSurface";
- }
- idx = iDefaultSurface;
- }
- pSorted[idx].push_back(i);
- }
- if (UINT_MAX == iDefaultSurface) {
- pSorted.erase(pSorted.end()-1);
- }
- for (unsigned int p = 0,i = 0;i < mSurfaces->size();++i) {
- SortedRep& sorted = pSorted[i];
- if (sorted.empty())
- continue;
-
- // generate the mesh
- aiMesh* mesh = new aiMesh();
- apcMeshes.push_back(mesh);
- mesh->mNumFaces = (unsigned int)sorted.size();
-
- // count the number of vertices
- SortedRep::const_iterator it = sorted.begin(), end = sorted.end();
- for (;it != end;++it) {
- mesh->mNumVertices += layer.mFaces[*it].mNumIndices;
- }
-
- aiVector3D *nrm = NULL, * pv = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiFace* pf = mesh->mFaces = new aiFace[mesh->mNumFaces];
- mesh->mMaterialIndex = i;
-
- // find out which vertex color channels and which texture coordinate
- // channels are really required by the material attached to this mesh
- unsigned int vUVChannelIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- unsigned int vVColorIndices[AI_MAX_NUMBER_OF_COLOR_SETS];
-
-#ifdef ASSIMP_BUILD_DEBUG
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
- vUVChannelIndices[mui] = UINT_MAX;
- }
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui ) {
- vVColorIndices[mui] = UINT_MAX;
- }
-#endif
-
- FindUVChannels(_mSurfaces[i],sorted,layer,vUVChannelIndices);
- FindVCChannels(_mSurfaces[i],sorted,layer,vVColorIndices);
-
- // allocate storage for UV and CV channels
- aiVector3D* pvUV[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_TEXTURECOORDS;++mui ) {
- if (UINT_MAX == vUVChannelIndices[mui]) {
- break;
- }
-
- pvUV[mui] = mesh->mTextureCoords[mui] = new aiVector3D[mesh->mNumVertices];
-
- // LightWave doesn't support more than 2 UV components (?)
- mesh->mNumUVComponents[0] = 2;
- }
-
- if (layer.mNormals.name.length())
- nrm = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- aiColor4D* pvVC[AI_MAX_NUMBER_OF_COLOR_SETS];
- for (unsigned int mui = 0; mui < AI_MAX_NUMBER_OF_COLOR_SETS;++mui) {
- if (UINT_MAX == vVColorIndices[mui]) {
- break;
- }
- pvVC[mui] = mesh->mColors[mui] = new aiColor4D[mesh->mNumVertices];
- }
-
- // we would not need this extra array, but the code is much cleaner if we use it
- std::vector<unsigned int>& smoothingGroups = layer.mPointReferrers;
- smoothingGroups.erase (smoothingGroups.begin(),smoothingGroups.end());
- smoothingGroups.resize(mesh->mNumFaces,0);
-
- // now convert all faces
- unsigned int vert = 0;
- std::vector<unsigned int>::iterator outIt = smoothingGroups.begin();
- for (it = sorted.begin(); it != end;++it,++outIt) {
- const LWO::Face& face = layer.mFaces[*it];
- *outIt = face.smoothGroup;
-
- // copy all vertices
- for (unsigned int q = 0; q < face.mNumIndices;++q,++vert) {
- unsigned int idx = face.mIndices[q];
- *pv++ = layer.mTempPoints[idx] /*- layer.mPivot*/;
-
- // process UV coordinates
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_TEXTURECOORDS;++w) {
- if (UINT_MAX == vUVChannelIndices[w]) {
- break;
- }
- aiVector3D*& pp = pvUV[w];
- const aiVector2D& src = ((aiVector2D*)&layer.mUVChannels[vUVChannelIndices[w]].rawData[0])[idx];
- pp->x = src.x;
- pp->y = src.y;
- pp++;
- }
-
- // process normals (MODO extension)
- if (nrm) {
- *nrm = ((aiVector3D*)&layer.mNormals.rawData[0])[idx];
- nrm->z *= -1.f;
- ++nrm;
- }
-
- // process vertex colors
- for (unsigned int w = 0; w < AI_MAX_NUMBER_OF_COLOR_SETS;++w) {
- if (UINT_MAX == vVColorIndices[w]) {
- break;
- }
- *pvVC[w] = ((aiColor4D*)&layer.mVColorChannels[vVColorIndices[w]].rawData[0])[idx];
-
- // If a RGB color map is explicitly requested delete the
- // alpha channel - it could theoretically be != 1.
- if(_mSurfaces[i].mVCMapType == AI_LWO_RGB)
- pvVC[w]->a = 1.f;
-
- pvVC[w]++;
- }
-
-#if 0
- // process vertex weights. We can't properly reconstruct the whole skeleton for now,
- // but we can create dummy bones for all weight channels which we have.
- for (unsigned int w = 0; w < layer.mWeightChannels.size();++w)
- {
- }
-#endif
-
- face.mIndices[q] = vert;
- }
- pf->mIndices = face.mIndices;
- pf->mNumIndices = face.mNumIndices;
- unsigned int** p = (unsigned int**)&face.mIndices;*p = NULL; // HACK: make sure it won't be deleted
- pf++;
- }
-
- if (!mesh->mNormals) {
- // Compute normal vectors for the mesh - we can't use our GenSmoothNormal-
- // Step here since it wouldn't handle smoothing groups correctly for LWO.
- // So we use a separate implementation.
- ComputeNormals(mesh,smoothingGroups,_mSurfaces[i]);
- }
- else DefaultLogger::get()->debug("LWO2: No need to compute normals, they're already there");
- ++p;
- }
- }
-
- // Generate nodes to render the mesh. Store the source layer in the mParent member of the nodes
- unsigned int num = static_cast<unsigned int>(apcMeshes.size() - meshStart);
- if (layer.mName != "<LWODefault>" || num > 0) {
- aiNode* pcNode = new aiNode();
- apcNodes[layer.mIndex] = pcNode;
- pcNode->mName.Set(layer.mName);
- pcNode->mParent = (aiNode*)&layer;
- pcNode->mNumMeshes = num;
-
- if (pcNode->mNumMeshes) {
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- for (unsigned int p = 0; p < pcNode->mNumMeshes;++p)
- pcNode->mMeshes[p] = p + meshStart;
- }
- }
- }
-
- if (apcNodes.empty() || apcMeshes.empty())
- throw DeadlyImportError("LWO: No meshes loaded");
-
- // The RemoveRedundantMaterials step will clean this up later
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = (unsigned int)mSurfaces->size()];
- for (unsigned int mat = 0; mat < pScene->mNumMaterials;++mat) {
- aiMaterial* pcMat = new aiMaterial();
- pScene->mMaterials[mat] = pcMat;
- ConvertMaterial((*mSurfaces)[mat],pcMat);
- }
-
- // copy the meshes to the output structure
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes = (unsigned int)apcMeshes.size() ];
- ::memcpy(pScene->mMeshes,&apcMeshes[0],pScene->mNumMeshes*sizeof(void*));
-
- // generate the final node graph
- GenerateNodeGraph(apcNodes);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
- const LWO::Surface& surface)
-{
- // Allocate output storage
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- // First generate per-face normals
- aiVector3D* out;
- std::vector<aiVector3D> faceNormals;
-
- // ... in some cases that's already enough
- if (!surface.mMaximumSmoothAngle)
- out = mesh->mNormals;
- else {
- faceNormals.resize(mesh->mNumVertices);
- out = &faceNormals[0];
- }
-
- aiFace* begin = mesh->mFaces, *const end = mesh->mFaces+mesh->mNumFaces;
- 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];
- aiVector3D* pV3 = mesh->mVertices + face.mIndices[face.mNumIndices-1];
-
- aiVector3D vNor = ((*pV2 - *pV1) ^(*pV3 - *pV1)).Normalize();
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- out[face.mIndices[i]] = vNor;
- }
- if (!surface.mMaximumSmoothAngle)return;
- const float posEpsilon = ComputePositionEpsilon(mesh);
-
- // Now generate the spatial sort tree
- SGSpatialSort sSort;
- std::vector<unsigned int>::const_iterator it = smoothingGroups.begin();
- for( begin = mesh->mFaces; begin != end; ++begin, ++it)
- {
- aiFace& face = *begin;
- for (unsigned int i = 0; i < face.mNumIndices;++i)
- {
- unsigned int tt = face.mIndices[i];
- sSort.Add(mesh->mVertices[tt],tt,*it);
- }
- }
- // Sort everything - this takes O(nlogn) time
- sSort.Prepare();
- std::vector<unsigned int> poResult;
- poResult.reserve(20);
-
- // Generate vertex normals. We have O(logn) for the binary lookup, which we need
- // for n elements, thus the EXPECTED complexity is O(nlogn)
- if (surface.mMaximumSmoothAngle < 3.f && !configSpeedFlag) {
- const float fLimit = std::cos(surface.mMaximumSmoothAngle);
-
- for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace& face = *begin;
- unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx)
- {
- unsigned int idx = *beginIdx;
- sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
- std::vector<unsigned int>::const_iterator a, end = poResult.end();
-
- aiVector3D vNormals;
- for (a = poResult.begin();a != end;++a) {
- const aiVector3D& v = faceNormals[*a];
- if (v * faceNormals[idx] < fLimit)
- continue;
- vNormals += v;
- }
- mesh->mNormals[idx] = vNormals.Normalize();
- }
- }
- }
- // faster code path in case there is no smooth angle
- else {
- std::vector<bool> vertexDone(mesh->mNumVertices,false);
- for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it) {
- const aiFace& face = *begin;
- unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
- for (; beginIdx != endIdx; ++beginIdx)
- {
- unsigned int idx = *beginIdx;
- if (vertexDone[idx])
- continue;
- sSort.FindPositions(mesh->mVertices[idx],*it,posEpsilon,poResult,true);
- std::vector<unsigned int>::const_iterator a, end = poResult.end();
-
- aiVector3D vNormals;
- for (a = poResult.begin();a != end;++a) {
- const aiVector3D& v = faceNormals[*a];
- vNormals += v;
- }
- vNormals.Normalize();
- for (a = poResult.begin();a != end;++a) {
- mesh->mNormals[*a] = vNormals;
- vertexDone[*a] = true;
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes)
-{
- // now generate the final nodegraph - generate a root node and attach children
- aiNode* root = pScene->mRootNode = new aiNode();
- root->mName.Set("<LWORoot>");
-
- //Set parent of all children, inserting pivots
- //std::cout << "Set parent of all children" << std::endl;
- std::map<uint16_t, aiNode*> mapPivot;
- for (std::map<uint16_t,aiNode*>::iterator itapcNodes = apcNodes.begin(); itapcNodes != apcNodes.end(); ++itapcNodes) {
-
- //Get the parent index
- LWO::Layer* nodeLayer = (LWO::Layer*)(itapcNodes->second->mParent);
- uint16_t parentIndex = nodeLayer->mParent;
-
- //Create pivot node, store it into the pivot map, and set the parent as the pivot
- aiNode* pivotNode = new aiNode();
- pivotNode->mName.Set("Pivot-"+std::string(itapcNodes->second->mName.data));
- mapPivot[-(itapcNodes->first+2)] = pivotNode;
- itapcNodes->second->mParent = pivotNode;
-
- //Look for the parent node to attach the pivot to
- if (apcNodes.find(parentIndex) != apcNodes.end()) {
- pivotNode->mParent = apcNodes[parentIndex];
- } else {
- //If not, attach to the root node
- pivotNode->mParent = root;
- }
-
- //Set the node and the pivot node transformation
- itapcNodes->second->mTransformation.a4 = -nodeLayer->mPivot.x;
- itapcNodes->second->mTransformation.b4 = -nodeLayer->mPivot.y;
- itapcNodes->second->mTransformation.c4 = -nodeLayer->mPivot.z;
- pivotNode->mTransformation.a4 = nodeLayer->mPivot.x;
- pivotNode->mTransformation.b4 = nodeLayer->mPivot.y;
- pivotNode->mTransformation.c4 = nodeLayer->mPivot.z;
- }
-
- //Merge pivot map into node map
- //std::cout << "Merge pivot map into node map" << std::endl;
- for (std::map<uint16_t, aiNode*>::iterator itMapPivot = mapPivot.begin(); itMapPivot != mapPivot.end(); ++itMapPivot) {
- apcNodes[itMapPivot->first] = itMapPivot->second;
- }
-
- //Set children of all parents
- apcNodes[-1] = root;
- for (std::map<uint16_t,aiNode*>::iterator itMapParentNodes = apcNodes.begin(); itMapParentNodes != apcNodes.end(); ++itMapParentNodes) {
- for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
- if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
- ++(itMapParentNodes->second->mNumChildren);
- }
- }
- if (itMapParentNodes->second->mNumChildren) {
- itMapParentNodes->second->mChildren = new aiNode* [ itMapParentNodes->second->mNumChildren ];
- uint16_t p = 0;
- for (std::map<uint16_t,aiNode*>::iterator itMapChildNodes = apcNodes.begin(); itMapChildNodes != apcNodes.end(); ++itMapChildNodes) {
- if ((itMapParentNodes->first != itMapChildNodes->first) && (itMapParentNodes->second == itMapChildNodes->second->mParent)) {
- itMapParentNodes->second->mChildren[p++] = itMapChildNodes->second;
- }
- }
- }
- }
-
- if (!pScene->mRootNode->mNumChildren)
- throw DeadlyImportError("LWO: Unable to build a valid node graph");
-
- // Remove a single root node with no meshes assigned to it ...
- if (1 == pScene->mRootNode->mNumChildren) {
- aiNode* pc = pScene->mRootNode->mChildren[0];
- pc->mParent = pScene->mRootNode->mChildren[0] = NULL;
- delete pScene->mRootNode;
- pScene->mRootNode = pc;
- }
-
- // convert the whole stuff to RH with CCW winding
- MakeLeftHandedProcess maker;
- maker.Execute(pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveTags()
-{
- // --- this function is used for both LWO2 and LWOB
- mMapping->resize(mTags->size(), UINT_MAX);
- for (unsigned int a = 0; a < mTags->size();++a) {
-
- const std::string& c = (*mTags)[a];
- for (unsigned int i = 0; i < mSurfaces->size();++i) {
-
- const std::string& d = (*mSurfaces)[i].mName;
- if (!ASSIMP_stricmp(c,d)) {
-
- (*mMapping)[a] = i;
- break;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ResolveClips()
-{
- for( unsigned int i = 0; i < mClips.size();++i) {
-
- Clip& clip = mClips[i];
- if (Clip::REF == clip.type) {
-
- if (clip.clipRef >= mClips.size()) {
- DefaultLogger::get()->error("LWO2: Clip referrer index is out of range");
- clip.clipRef = 0;
- }
-
- Clip& dest = mClips[clip.clipRef];
- if (Clip::REF == dest.type) {
- DefaultLogger::get()->error("LWO2: Clip references another clip reference");
- clip.type = Clip::UNSUPPORTED;
- }
-
- else {
- clip.path = dest.path;
- clip.type = dest.type;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::AdjustTexturePath(std::string& out)
-{
- // --- this function is used for both LWO2 and LWOB
- if (!mIsLWO2 && ::strstr(out.c_str(), "(sequence)")) {
-
- // remove the (sequence) and append 000
- DefaultLogger::get()->info("LWOB: Sequence of animated texture found. It will be ignored");
- out = out.substr(0,out.length()-10) + "000";
- }
-
- // format: drive:path/file - we just need to insert a slash after the drive
- std::string::size_type n = out.find_first_of(':');
- if (std::string::npos != n) {
- out.insert(n+1,"/");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOTags(unsigned int size)
-{
- // --- this function is used for both LWO2 and LWOB
-
- const char* szCur = (const char*)mFileBuffer, *szLast = szCur;
- const char* const szEnd = szLast+size;
- while (szCur < szEnd)
- {
- if (!(*szCur))
- {
- const size_t len = (size_t)(szCur-szLast);
- // FIX: skip empty-sized tags
- if (len)
- mTags->push_back(std::string(szLast,len));
- szCur += (len&0x1 ? 1 : 2);
- szLast = szCur;
- }
- szCur++;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWOPoints(unsigned int length)
-{
- // --- this function is used for both LWO2 and LWOB but for
- // LWO2 we need to allocate 25% more storage - it could be we'll
- // need to duplicate some points later.
- const size_t vertexLen = 12;
- if ((length % vertexLen) != 0)
- {
- throw DeadlyImportError( "LWO2: Points chunk length is not multiple of vertexLen (12)");
- }
- unsigned int regularSize = (unsigned int)mCurLayer->mTempPoints.size() + length / 12;
- if (mIsLWO2)
- {
- mCurLayer->mTempPoints.reserve ( regularSize + (regularSize>>2u) );
- mCurLayer->mTempPoints.resize ( regularSize );
-
- // initialize all point referrers with the default values
- mCurLayer->mPointReferrers.reserve ( regularSize + (regularSize>>2u) );
- mCurLayer->mPointReferrers.resize ( regularSize, UINT_MAX );
- }
- else mCurLayer->mTempPoints.resize( regularSize );
-
- // perform endianness conversions
-#ifndef AI_BUILD_BIG_ENDIAN
- for (unsigned int i = 0; i < length>>2;++i)
- ByteSwap::Swap4( mFileBuffer + (i << 2));
-#endif
- ::memcpy(&mCurLayer->mTempPoints[0],mFileBuffer,length);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Polygons(unsigned int length)
-{
- LE_NCONST uint16_t* const end = (LE_NCONST uint16_t*)(mFileBuffer+length);
- const uint32_t type = GetU4();
-
- // Determine the type of the polygons
- switch (type)
- {
- // read unsupported stuff too (although we won't process it)
- case AI_LWO_MBAL:
- DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (METABALL)");
- break;
- case AI_LWO_CURV:
- DefaultLogger::get()->warn("LWO2: Encountered unsupported primitive chunk (SPLINE)");;
- break;
-
- // These are ok with no restrictions
- case AI_LWO_PTCH:
- case AI_LWO_FACE:
- case AI_LWO_BONE:
- case AI_LWO_SUBD:
- break;
- default:
-
- // hm!? wtf is this? ok ...
- DefaultLogger::get()->error("LWO2: Ignoring unknown polygon type.");
- break;
- }
-
- // first find out how many faces and vertices we'll finally need
- uint16_t* cursor= (uint16_t*)mFileBuffer;
-
- unsigned int iNumFaces = 0,iNumVertices = 0;
- CountVertsAndFacesLWO2(iNumVertices,iNumFaces,cursor,end);
-
- // allocate the output array and copy face indices
- if (iNumFaces)
- {
- cursor = (uint16_t*)mFileBuffer;
-
- mCurLayer->mFaces.resize(iNumFaces,LWO::Face(type));
- FaceList::iterator it = mCurLayer->mFaces.begin();
- CopyFaceIndicesLWO2(it,cursor,end);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CountVertsAndFacesLWO2(unsigned int& verts, unsigned int& faces,
- uint16_t*& cursor, const uint16_t* const end, unsigned int max)
-{
- while (cursor < end && max--)
- {
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- AI_LSWAP2(numIndices);
- numIndices &= 0x03FF;
-
- verts += numIndices;
- ++faces;
-
- for(uint16_t i = 0; i < numIndices; i++)
- {
- ReadVSizedIntLWO2((uint8_t*&)cursor);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::CopyFaceIndicesLWO2(FaceList::iterator& it,
- uint16_t*& cursor,
- const uint16_t* const end)
-{
- while (cursor < end)
- {
- LWO::Face& face = *it++;
- uint16_t numIndices;
- ::memcpy(&numIndices, cursor++, 2);
- AI_LSWAP2(numIndices);
- face.mNumIndices = numIndices & 0x03FF;
-
- if(face.mNumIndices) /* byte swapping has already been done */
- {
- face.mIndices = new unsigned int[face.mNumIndices];
- for(unsigned int i = 0; i < face.mNumIndices; i++)
- {
- face.mIndices[i] = ReadVSizedIntLWO2((uint8_t*&)cursor) + mCurLayer->mPointIDXOfs;
- if(face.mIndices[i] > mCurLayer->mTempPoints.size())
- {
- DefaultLogger::get()->warn("LWO2: Failure evaluating face record, index is out of range");
- face.mIndices[i] = (unsigned int)mCurLayer->mTempPoints.size()-1;
- }
- }
- }
- else throw DeadlyImportError("LWO2: Encountered invalid face record with zero indices");
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2PolygonTags(unsigned int length)
-{
- LE_NCONST uint8_t* const end = mFileBuffer+length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,PTAG,4);
- uint32_t type = GetU4();
-
- if (type != AI_LWO_SURF && type != AI_LWO_SMGP)
- return;
-
- while (mFileBuffer < end)
- {
- unsigned int i = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- unsigned int j = GetU2();
-
- if (i >= mCurLayer->mFaces.size()) {
- DefaultLogger::get()->warn("LWO2: face index in PTAG is out of range");
- continue;
- }
-
- switch (type) {
-
- case AI_LWO_SURF:
- mCurLayer->mFaces[i].surfaceIndex = j;
- break;
- case AI_LWO_SMGP: /* is that really used? */
- mCurLayer->mFaces[i].smoothGroup = j;
- break;
- };
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-VMapEntry* FindEntry(std::vector< T >& list,const std::string& name, bool perPoly)
-{
- for (auto & elem : list) {
- if (elem.name == name) {
- if (!perPoly) {
- DefaultLogger::get()->warn("LWO2: Found two VMAP sections with equal names");
- }
- return &elem;
- }
- }
- list.push_back( T() );
- VMapEntry* p = &list.back();
- p->name = name;
- return p;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(T& chan, unsigned int srcIdx)
-{
- if (!chan.name.length())
- return;
-
- chan.abAssigned[srcIdx] = true;
- chan.abAssigned.resize(chan.abAssigned.size()+1,false);
-
- for (unsigned int a = 0; a < chan.dims;++a)
- chan.rawData.push_back(chan.rawData[srcIdx*chan.dims+a]);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline void CreateNewEntry(std::vector< T >& list, unsigned int srcIdx)
-{
- for (auto &elem : list) {
- CreateNewEntry( elem, srcIdx );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead,
- unsigned int idx, float* data)
-{
- ai_assert(NULL != data);
- LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
- unsigned int i;
-
- if (idx >= base->abAssigned.size()) {
- throw DeadlyImportError("Bad index");
- }
- base->abAssigned[idx] = true;
- for (i = 0; i < numRead;++i) {
- base->rawData[idx*base->dims+i]= data[i];
- }
-
- if (UINT_MAX != (i = refList[idx])) {
- DoRecursiveVMAPAssignment(base,numRead,i,data);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void AddToSingleLinkedList(ReferrerList& refList, unsigned int srcIdx, unsigned int destIdx)
-{
- if(UINT_MAX == refList[srcIdx]) {
- refList[srcIdx] = destIdx;
- return;
- }
- AddToSingleLinkedList(refList,refList[srcIdx],destIdx);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 vertex map
-void LWOImporter::LoadLWO2VertexMap(unsigned int length, bool perPoly)
-{
- LE_NCONST uint8_t* const end = mFileBuffer+length;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,VMAP,6);
- unsigned int type = GetU4();
- unsigned int dims = GetU2();
-
- VMapEntry* base;
-
- // read the name of the vertex map
- std::string name;
- GetS0(name,length);
-
- switch (type)
- {
- case AI_LWO_TXUV:
- if (dims != 2) {
- DefaultLogger::get()->warn("LWO2: Skipping UV channel \'"
- + name + "\' with !2 components");
- return;
- }
- base = FindEntry(mCurLayer->mUVChannels,name,perPoly);
- break;
- case AI_LWO_WGHT:
- case AI_LWO_MNVW:
- if (dims != 1) {
- DefaultLogger::get()->warn("LWO2: Skipping Weight Channel \'"
- + name + "\' with !1 components");
- return;
- }
- base = FindEntry((type == AI_LWO_WGHT ? mCurLayer->mWeightChannels
- : mCurLayer->mSWeightChannels),name,perPoly);
- break;
- case AI_LWO_RGB:
- case AI_LWO_RGBA:
- if (dims != 3 && dims != 4) {
- DefaultLogger::get()->warn("LWO2: Skipping Color Map \'"
- + name + "\' with a dimension > 4 or < 3");
- return;
- }
- base = FindEntry(mCurLayer->mVColorChannels,name,perPoly);
- break;
-
- case AI_LWO_MODO_NORM:
- /* This is a non-standard extension chunk used by Luxology's MODO.
- * It stores per-vertex normals. This VMAP exists just once, has
- * 3 dimensions and is btw extremely beautiful.
- */
- if (name != "vert_normals" || dims != 3 || mCurLayer->mNormals.name.length())
- return;
-
- DefaultLogger::get()->info("Processing non-standard extension: MODO VMAP.NORM.vert_normals");
-
- mCurLayer->mNormals.name = name;
- base = & mCurLayer->mNormals;
- break;
-
- case AI_LWO_PICK: /* these VMAPs are just silently dropped */
- case AI_LWO_MORF:
- case AI_LWO_SPOT:
- return;
-
- default:
- if (name == "APS.Level") {
- // XXX handle this (seems to be subdivision-related).
- }
- DefaultLogger::get()->warn("LWO2: Skipping unknown VMAP/VMAD channel \'" + name + "\'");
- return;
- };
- base->Allocate((unsigned int)mCurLayer->mTempPoints.size());
-
- // now read all entries in the map
- type = std::min(dims,base->dims);
- const unsigned int diff = (dims - type)<<2u;
-
- LWO::FaceList& list = mCurLayer->mFaces;
- LWO::PointList& pointList = mCurLayer->mTempPoints;
- LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
-
- const unsigned int numPoints = (unsigned int)pointList.size();
- const unsigned int numFaces = (unsigned int)list.size();
-
- while (mFileBuffer < end) {
-
- unsigned int idx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mPointIDXOfs;
- if (idx >= numPoints) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAP/VMAD entry \'" + name + "\', vertex index is out of range");
- mFileBuffer += base->dims<<2u;
- continue;
- }
- if (perPoly) {
- unsigned int polyIdx = ReadVSizedIntLWO2(mFileBuffer) + mCurLayer->mFaceIDXOfs;
- if (base->abAssigned[idx]) {
- // we have already a VMAP entry for this vertex - thus
- // we need to duplicate the corresponding polygon.
- if (polyIdx >= numFaces) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', polygon index is out of range");
- mFileBuffer += base->dims<<2u;
- continue;
- }
-
- LWO::Face& src = list[polyIdx];
-
- // generate a new unique vertex for the corresponding index - but only
- // if we can find the index in the face
- bool had = false;
- for (unsigned int i = 0; i < src.mNumIndices;++i) {
-
- unsigned int srcIdx = src.mIndices[i], tmp = idx;
- do {
- if (tmp == srcIdx)
- break;
- }
- while ((tmp = refList[tmp]) != UINT_MAX);
- if (tmp == UINT_MAX) {
- continue;
- }
-
- had = true;
- refList.resize(refList.size()+1, UINT_MAX);
-
- idx = (unsigned int)pointList.size();
- src.mIndices[i] = (unsigned int)pointList.size();
-
- // store the index of the new vertex in the old vertex
- // so we get a single linked list we can traverse in
- // only one direction
- AddToSingleLinkedList(refList,srcIdx,src.mIndices[i]);
- pointList.push_back(pointList[srcIdx]);
-
- CreateNewEntry(mCurLayer->mVColorChannels, srcIdx );
- CreateNewEntry(mCurLayer->mUVChannels, srcIdx );
- CreateNewEntry(mCurLayer->mWeightChannels, srcIdx );
- CreateNewEntry(mCurLayer->mSWeightChannels, srcIdx );
- CreateNewEntry(mCurLayer->mNormals, srcIdx );
- }
- if (!had) {
- DefaultLogger::get()->warn("LWO2: Failure evaluating VMAD entry \'" + name + "\', vertex index wasn't found in that polygon");
- ai_assert(had);
- }
- }
- }
-
- std::unique_ptr<float[]> temp(new float[type]);
- for (unsigned int l = 0; l < type;++l)
- temp[l] = GetF4();
-
- DoRecursiveVMAPAssignment(base,type,idx, temp.get());
- mFileBuffer += diff;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load LWO2 clip
-void LWOImporter::LoadLWO2Clip(unsigned int length)
-{
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,CLIP,10);
-
- mClips.push_back(LWO::Clip());
- LWO::Clip& clip = mClips.back();
-
- // first - get the index of the clip
- clip.idx = GetU4();
-
- IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
- switch (head.type)
- {
- case AI_LWO_STIL:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,STIL,1);
-
- // "Normal" texture
- GetS0(clip.path,head.length);
- clip.type = Clip::STILL;
- break;
-
- case AI_LWO_ISEQ:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,ISEQ,16);
- // Image sequence. We'll later take the first.
- {
- uint8_t digits = GetU1(); mFileBuffer++;
- int16_t offset = GetU2(); mFileBuffer+=4;
- int16_t start = GetU2(); mFileBuffer+=4;
-
- std::string s;
- std::ostringstream ss;
- GetS0(s,head.length);
-
- head.length -= (uint16_t)s.length()+1;
- ss << s;
- ss << std::setw(digits) << offset + start;
- GetS0(s,head.length);
- ss << s;
- clip.path = ss.str();
- clip.type = Clip::SEQ;
- }
- break;
-
- case AI_LWO_STCC:
- DefaultLogger::get()->warn("LWO2: Color shifted images are not supported");
- break;
-
- case AI_LWO_ANIM:
- DefaultLogger::get()->warn("LWO2: Animated textures are not supported");
- break;
-
- case AI_LWO_XREF:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,XREF,4);
-
- // Just a cross-reference to another CLIp
- clip.type = Clip::REF;
- clip.clipRef = GetU4();
- break;
-
- case AI_LWO_NEGA:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,NEGA,2);
- clip.negate = (0 != GetU2());
- break;
-
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown CLIP subchunk");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load envelope description
-void LWOImporter::LoadLWO2Envelope(unsigned int length)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + length;
- AI_LWO_VALIDATE_CHUNK_LENGTH(length,ENVL,4);
-
- mEnvelopes.push_back(LWO::Envelope());
- LWO::Envelope& envelope = mEnvelopes.back();
-
- // Get the index of the envelope
- envelope.index = ReadVSizedIntLWO2(mFileBuffer);
-
- // It looks like there might be an extra U4 right after the index,
- // at least in modo (LXOB) files: we'll ignore it if it's zero,
- // otherwise it represents the start of a subchunk, so we backtrack.
- if (mIsLXOB)
- {
- uint32_t extra = GetU4();
- if (extra)
- {
- mFileBuffer -= 4;
- }
- }
-
- // ... and read all subchunks
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid envelope chunk length");
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // Type & representation of the envelope
- case AI_LWO_TYPE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TYPE,2);
- mFileBuffer++; // skip user format
-
- // Determine type of envelope
- envelope.type = (LWO::EnvelopeType)*mFileBuffer;
- ++mFileBuffer;
- break;
-
- // precondition
- case AI_LWO_PRE:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,PRE,2);
- envelope.pre = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // postcondition
- case AI_LWO_POST:
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,POST,2);
- envelope.post = (LWO::PrePostBehaviour)GetU2();
- break;
-
- // keyframe
- case AI_LWO_KEY:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,KEY,8);
-
- envelope.keys.push_back(LWO::Key());
- LWO::Key& key = envelope.keys.back();
-
- key.time = GetF4();
- key.value = GetF4();
- break;
- }
-
- // interval interpolation
- case AI_LWO_SPAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPAN,4);
- if (envelope.keys.size()<2)
- DefaultLogger::get()->warn("LWO2: Unexpected SPAN chunk");
- else {
- LWO::Key& key = envelope.keys.back();
- switch (GetU4())
- {
- case AI_LWO_STEP:
- key.inter = LWO::IT_STEP;break;
- case AI_LWO_LINE:
- key.inter = LWO::IT_LINE;break;
- case AI_LWO_TCB:
- key.inter = LWO::IT_TCB;break;
- case AI_LWO_HERM:
- key.inter = LWO::IT_HERM;break;
- case AI_LWO_BEZI:
- key.inter = LWO::IT_BEZI;break;
- case AI_LWO_BEZ2:
- key.inter = LWO::IT_BEZ2;break;
- default:
- DefaultLogger::get()->warn("LWO2: Unknown interval interpolation mode");
- };
-
- // todo ... read params
- }
- break;
- }
-
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown ENVL subchunk");
- }
- // regardless how much we did actually read, go to the next chunk
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load file - master function
-void LWOImporter::LoadLWO2File()
-{
- bool skip = false;
-
- LE_NCONST uint8_t* const end = mFileBuffer + fileSize;
- while (true)
- {
- if (mFileBuffer + sizeof(IFF::ChunkHeader) > end)break;
- const IFF::ChunkHeader head = IFF::LoadChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- {
- throw DeadlyImportError("LWO2: Chunk length points behind the file");
- break;
- }
- uint8_t* const next = mFileBuffer+head.length;
- unsigned int iUnnamed = 0;
-
- if(!head.length) {
- mFileBuffer = next;
- continue;
- }
-
- switch (head.type)
- {
- // new layer
- case AI_LWO_LAYR:
- {
- // add a new layer to the list ....
- mLayers->push_back ( LWO::Layer() );
- LWO::Layer& layer = mLayers->back();
- mCurLayer = &layer;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LAYR,16);
-
- // layer index.
- layer.mIndex = GetU2();
-
- // Continue loading this layer or ignore it? Check the layer index property
- if (UINT_MAX != configLayerIndex && (configLayerIndex-1) != layer.mIndex) {
- skip = true;
- }
- else skip = false;
-
- // pivot point
- mFileBuffer += 2; /* unknown */
- mCurLayer->mPivot.x = GetF4();
- mCurLayer->mPivot.y = GetF4();
- mCurLayer->mPivot.z = GetF4();
- GetS0(layer.mName,head.length-16);
-
- // if the name is empty, generate a default name
- if (layer.mName.empty()) {
- char buffer[128]; // should be sufficiently large
- ::ai_snprintf(buffer, 128, "Layer_%i", iUnnamed++);
- layer.mName = buffer;
- }
-
- // load this layer or ignore it? Check the layer name property
- if (configLayerName.length() && configLayerName != layer.mName) {
- skip = true;
- }
- else hasNamedLayer = true;
-
- // optional: parent of this layer
- if (mFileBuffer + 2 <= next)
- layer.mParent = GetU2();
- else layer.mParent = -1;
-
- // Set layer skip parameter
- layer.skip = skip;
-
- break;
- }
-
- // vertex list
- case AI_LWO_PNTS:
- {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mTempPoints.size();
- LoadLWOPoints(head.length);
- mCurLayer->mPointIDXOfs = old;
- break;
- }
- // vertex tags
- case AI_LWO_VMAD:
- if (mCurLayer->mFaces.empty())
- {
- DefaultLogger::get()->warn("LWO2: Unexpected VMAD chunk");
- break;
- }
- // --- intentionally no break here
- case AI_LWO_VMAP:
- {
- if (skip)
- break;
-
- if (mCurLayer->mTempPoints.empty())
- DefaultLogger::get()->warn("LWO2: Unexpected VMAP chunk");
- else LoadLWO2VertexMap(head.length,head.type == AI_LWO_VMAD);
- break;
- }
- // face list
- case AI_LWO_POLS:
- {
- if (skip)
- break;
-
- unsigned int old = (unsigned int)mCurLayer->mFaces.size();
- LoadLWO2Polygons(head.length);
- mCurLayer->mFaceIDXOfs = old;
- break;
- }
- // polygon tags
- case AI_LWO_PTAG:
- {
- if (skip)
- break;
-
- if (mCurLayer->mFaces.empty())
- DefaultLogger::get()->warn("LWO2: Unexpected PTAG");
- else LoadLWO2PolygonTags(head.length);
- break;
- }
- // list of tags
- case AI_LWO_TAGS:
- {
- if (!mTags->empty())
- DefaultLogger::get()->warn("LWO2: SRFS chunk encountered twice");
- else LoadLWOTags(head.length);
- break;
- }
-
- // surface chunk
- case AI_LWO_SURF:
- {
- LoadLWO2Surface(head.length);
- break;
- }
-
- // clip chunk
- case AI_LWO_CLIP:
- {
- LoadLWO2Clip(head.length);
- break;
- }
-
- // envelope chunk
- case AI_LWO_ENVL:
- {
- LoadLWO2Envelope(head.length);
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_LWO_IMPORTER
diff --git a/src/3rdparty/assimp/code/LWOLoader.h b/src/3rdparty/assimp/code/LWOLoader.h
deleted file mode 100644
index b92e5aab4..000000000
--- a/src/3rdparty/assimp/code/LWOLoader.h
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Declaration of the LWO importer class. */
-#ifndef AI_LWOLOADER_H_INCLUDED
-#define AI_LWOLOADER_H_INCLUDED
-
-#include <assimp/types.h>
-#include <assimp/material.h>
-#include <assimp/DefaultLogger.hpp>
-
-#include "LWOFileData.h"
-#include "BaseImporter.h"
-
-#include <map>
-
-struct aiTexture;
-struct aiNode;
-struct aiMaterial;
-
-namespace Assimp {
-using namespace LWO;
-
-// ---------------------------------------------------------------------------
-/** Class to load LWO files.
- *
- * @note Methods named "xxxLWO2[xxx]" are used with the newer LWO2 format.
- * Methods named "xxxLWOB[xxx]" are used with the older LWOB format.
- * Methods named "xxxLWO[xxx]" are used with both formats.
- * Methods named "xxx" are used to preprocess the loaded data -
- * they aren't specific to one format version
-*/
-// ---------------------------------------------------------------------------
-class LWOImporter : public BaseImporter
-{
-public:
- LWOImporter();
- ~LWOImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- // Get list of supported extensions
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- // -------------------------------------------------------------------
- /** Loads a LWO file in the older LWOB format (LW < 6)
- */
- void LoadLWOBFile();
-
- // -------------------------------------------------------------------
- /** Loads a LWO file in the newer LWO2 format (LW >= 6)
- */
- void LoadLWO2File();
-
-
- // -------------------------------------------------------------------
- /** Parsing functions used for all file format versions
- */
- inline void GetS0(std::string& out,unsigned int max);
- inline float GetF4();
- inline uint32_t GetU4();
- inline uint16_t GetU2();
- inline uint8_t GetU1();
-
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWOB file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOBSurface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a surface chunk from an LWO2 file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWO2Surface(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Loads a texture block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head,
- unsigned int size );
-
- // -------------------------------------------------------------------
- /** Loads a shader block from a LWO2 file.
- * @param size Maximum size to be read, in bytes.
- * @param head Header of the SUF.BLOK header
- */
- void LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* head,
- unsigned int size );
-
- // -------------------------------------------------------------------
- /** Loads an image map from a LWO2 file
- * @param size Maximum size to be read, in bytes.
- * @param tex Texture object to be filled
- */
- void LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex );
- void LoadLWO2Gradient(unsigned int size, LWO::Texture& tex );
- void LoadLWO2Procedural(unsigned int size, LWO::Texture& tex );
-
- // loads the header - used by thethree functions above
- void LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex );
-
- // -------------------------------------------------------------------
- /** Loads the LWO tag list from the file
- * @param size Maximum size to be read, in bytes.
- */
- void LoadLWOTags(unsigned int size);
-
- // -------------------------------------------------------------------
- /** Load polygons from a POLS chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Polygons(unsigned int length);
- void LoadLWOBPolygons(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load polygon tags from a PTAG chunk
- * @param length Size of the chunk
- */
- void LoadLWO2PolygonTags(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a vertex map from a VMAP/VMAD chunk
- * @param length Size of the chunk
- * @param perPoly Operate on per-polygon base?
- */
- void LoadLWO2VertexMap(unsigned int length, bool perPoly);
-
- // -------------------------------------------------------------------
- /** Load polygons from a PNTS chunk
- * @param length Size of the chunk
- */
- void LoadLWOPoints(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load a clip from a CLIP chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Clip(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Load an envelope from an EVL chunk
- * @param length Size of the chunk
- */
- void LoadLWO2Envelope(unsigned int length);
-
- // -------------------------------------------------------------------
- /** Count vertices and faces in a LWOB/LWO2 file
- */
- void CountVertsAndFacesLWO2(unsigned int& verts,
- unsigned int& faces,
- uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = UINT_MAX);
-
- void CountVertsAndFacesLWOB(unsigned int& verts,
- unsigned int& faces,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = UINT_MAX);
-
- // -------------------------------------------------------------------
- /** Read vertices and faces in a LWOB/LWO2 file
- */
- void CopyFaceIndicesLWO2(LWO::FaceList::iterator& it,
- uint16_t*& cursor,
- const uint16_t* const end);
-
- // -------------------------------------------------------------------
- void CopyFaceIndicesLWOB(LWO::FaceList::iterator& it,
- LE_NCONST uint16_t*& cursor,
- const uint16_t* const end,
- unsigned int max = UINT_MAX);
-
- // -------------------------------------------------------------------
- /** Resolve the tag and surface lists that have been loaded.
- * Generates the mMapping table.
- */
- void ResolveTags();
-
- // -------------------------------------------------------------------
- /** Resolve the clip list that has been loaded.
- * Replaces clip references with real clips.
- */
- void ResolveClips();
-
- // -------------------------------------------------------------------
- /** Add a texture list to an output material description.
- *
- * @param pcMat Output material
- * @param in Input texture list
- * @param type Type identifier of the texture list
- */
- bool HandleTextures(aiMaterial* pcMat, const TextureList& in,
- aiTextureType type);
-
- // -------------------------------------------------------------------
- /** Adjust a texture path
- */
- void AdjustTexturePath(std::string& out);
-
- // -------------------------------------------------------------------
- /** Convert a LWO surface description to an ASSIMP material
- */
- void ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat);
-
-
- // -------------------------------------------------------------------
- /** Get a list of all UV/VC channels required by a specific surface.
- *
- * @param surf Working surface
- * @param layer Working layer
- * @param out Output list. The members are indices into the
- * UV/VC channel lists of the layer
- */
- void FindUVChannels(/*const*/ LWO::Surface& surf,
- LWO::SortedRep& sorted,
- /*const*/ LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS]);
-
- // -------------------------------------------------------------------
- char FindUVChannels(LWO::TextureList& list,
- LWO::Layer& layer,LWO::UVChannel& uv, unsigned int next);
-
- // -------------------------------------------------------------------
- void FindVCChannels(const LWO::Surface& surf,
- LWO::SortedRep& sorted,
- const LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS]);
-
- // -------------------------------------------------------------------
- /** Generate the final node graph
- * Unused nodes are deleted.
- * @param apcNodes Flat list of nodes
- */
- void GenerateNodeGraph(std::map<uint16_t,aiNode*>& apcNodes);
-
- // -------------------------------------------------------------------
- /** Add children to a node
- * @param node Node to become a father
- * @param parent Index of the node
- * @param apcNodes Flat list of nodes - used nodes are set to NULL.
- */
- void AddChildren(aiNode* node, uint16_t parent,
- std::vector<aiNode*>& apcNodes);
-
- // -------------------------------------------------------------------
- /** Read a variable sized integer
- * @param inout Input and output buffer
- */
- int ReadVSizedIntLWO2(uint8_t*& inout);
-
- // -------------------------------------------------------------------
- /** Assign a value from a VMAP to a vertex and all vertices
- * attached to it.
- * @param base VMAP destination data
- * @param numRead Number of float's to be read
- * @param idx Absolute index of the first vertex
- * @param data Value of the VMAP to be assigned - read numRead
- * floats from this array.
- */
- void DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int numRead,
- unsigned int idx, float* data);
-
- // -------------------------------------------------------------------
- /** Compute normal vectors for a mesh
- * @param mesh Input mesh
- * @param smoothingGroups Smoothing-groups-per-face array
- * @param surface Surface for the mesh
- */
- void ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>& smoothingGroups,
- const LWO::Surface& surface);
-
-
- // -------------------------------------------------------------------
- /** Setup a new texture after the corresponding chunk was
- * encountered in the file.
- * @param list Texture list
- * @param size Maximum number of bytes to be read
- * @return Pointer to new texture
- */
- LWO::Texture* SetupNewTextureLWOB(LWO::TextureList& list,
- unsigned int size);
-
-protected:
-
- /** true if the file is a LWO2 file*/
- bool mIsLWO2;
-
- /** true if the file is a LXOB file*/
- bool mIsLXOB;
-
- /** Temporary list of layers from the file */
- LayerList* mLayers;
-
- /** Pointer to the current layer */
- LWO::Layer* mCurLayer;
-
- /** Temporary tag list from the file */
- TagList* mTags;
-
- /** Mapping table to convert from tag to surface indices.
- UINT_MAX indicates that a no corresponding surface is available */
- TagMappingTable* mMapping;
-
- /** Temporary surface list from the file */
- SurfaceList* mSurfaces;
-
- /** Temporary clip list from the file */
- ClipList mClips;
-
- /** Temporary envelope list from the file */
- EnvelopeList mEnvelopes;
-
- /** file buffer */
- uint8_t* mFileBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Output scene */
- aiScene* pScene;
-
- /** Configuration option: speed flag set? */
- bool configSpeedFlag;
-
- /** Configuration option: index of layer to be loaded */
- unsigned int configLayerIndex;
-
- /** Configuration option: name of layer to be loaded */
- std::string configLayerName;
-
- /** True if we have a named layer */
- bool hasNamedLayer;
-};
-
-
-// ------------------------------------------------------------------------------------------------
-inline float LWOImporter::GetF4()
-{
- float f;
- ::memcpy(&f, mFileBuffer, 4);
- mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint32_t LWOImporter::GetU4()
-{
- uint32_t f;
- ::memcpy(&f, mFileBuffer, 4);
- mFileBuffer += 4;
- AI_LSWAP4(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint16_t LWOImporter::GetU2()
-{
- uint16_t f;
- ::memcpy(&f, mFileBuffer, 2);
- mFileBuffer += 2;
- AI_LSWAP2(f);
- return f;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline uint8_t LWOImporter::GetU1()
-{
- return *mFileBuffer++;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline int LWOImporter::ReadVSizedIntLWO2(uint8_t*& inout)
-{
- int i;
- int c = *inout;inout++;
- if(c != 0xFF)
- {
- i = c << 8;
- c = *inout;inout++;
- i |= c;
- }
- else
- {
- c = *inout;inout++;
- i = c << 16;
- c = *inout;inout++;
- i |= c << 8;
- c = *inout;inout++;
- i |= c;
- }
- return i;
-}
-
-// ------------------------------------------------------------------------------------------------
-inline void LWOImporter::GetS0(std::string& out,unsigned int max)
-{
- unsigned int iCursor = 0;
- const char*sz = (const char*)mFileBuffer;
- while (*mFileBuffer)
- {
- if (++iCursor > max)
- {
- DefaultLogger::get()->warn("LWO: Invalid file, string is is too long");
- break;
- }
- ++mFileBuffer;
- }
- size_t len = (size_t) ((const char*)mFileBuffer-sz);
- out = std::string(sz,len);
- mFileBuffer += (len&0x1 ? 1 : 2);
-}
-
-
-
-} // end of namespace Assimp
-
-#endif // AI_LWOIMPORTER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/LWOMaterial.cpp b/src/3rdparty/assimp/code/LWOMaterial.cpp
deleted file mode 100644
index 621a2edc6..000000000
--- a/src/3rdparty/assimp/code/LWOMaterial.cpp
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the material oart of the LWO importer class */
-
-
-
-#ifndef ASSIMP_BUILD_NO_LWO_IMPORTER
-
-// internal headers
-#include "LWOLoader.h"
-#include "ByteSwapper.h"
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-T lerp(const T& one, const T& two, float val)
-{
- return one + (two-one)*val;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a lightwave mapping mode to our's
-inline aiTextureMapMode GetMapMode(LWO::Texture::Wrap in)
-{
- switch (in)
- {
- case LWO::Texture::REPEAT:
- return aiTextureMapMode_Wrap;
-
- case LWO::Texture::MIRROR:
- return aiTextureMapMode_Mirror;
-
- case LWO::Texture::RESET:
- DefaultLogger::get()->warn("LWO2: Unsupported texture map mode: RESET");
-
- // fall though here
- case LWO::Texture::EDGE:
- return aiTextureMapMode_Clamp;
- }
- return (aiTextureMapMode)0;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type)
-{
- ai_assert(NULL != pcMat);
-
- unsigned int cur = 0, temp = 0;
- aiString s;
- bool ret = false;
-
- for (const auto &texture : in) {
- if (!texture.enabled || !texture.bCanUse)
- continue;
- ret = true;
-
- // Convert lightwave's mapping modes to ours. We let them
- // as they are, the GenUVcoords step will compute UV
- // channels if they're not there.
-
- aiTextureMapping mapping;
- switch (texture.mapMode)
- {
- case LWO::Texture::Planar:
- mapping = aiTextureMapping_PLANE;
- break;
- case LWO::Texture::Cylindrical:
- mapping = aiTextureMapping_CYLINDER;
- break;
- case LWO::Texture::Spherical:
- mapping = aiTextureMapping_SPHERE;
- break;
- case LWO::Texture::Cubic:
- mapping = aiTextureMapping_BOX;
- break;
- case LWO::Texture::FrontProjection:
- DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection");
- mapping = aiTextureMapping_OTHER;
- break;
- case LWO::Texture::UV:
- {
- if( UINT_MAX == texture.mRealUVIndex ) {
- // We have no UV index for this texture, so we can't display it
- continue;
- }
-
- // add the UV source index
- temp = texture.mRealUVIndex;
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur));
-
- mapping = aiTextureMapping_UV;
- }
- break;
- default:
- ai_assert(false);
- };
-
- if (mapping != aiTextureMapping_UV) {
- // Setup the main axis
- aiVector3D v;
- switch (texture.majorAxis) {
- case Texture::AXIS_X:
- v = aiVector3D(1.0,0.0,0.0);
- break;
- case Texture::AXIS_Y:
- v = aiVector3D(0.0,1.0,0.0);
- break;
- default: // case Texture::AXIS_Z:
- v = aiVector3D(0.0,0.0,1.0);
- break;
- }
-
- pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur));
-
- // Setup UV scalings for cylindric and spherical projections
- if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) {
- aiUVTransform trafo;
- trafo.mScaling.x = texture.wrapAmountW;
- trafo.mScaling.y = texture.wrapAmountH;
-
- static_assert(sizeof(aiUVTransform)/sizeof(ai_real) == 5, "sizeof(aiUVTransform)/sizeof(ai_real) == 5");
- pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur));
- }
- DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping");
- }
-
- // 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 (take the last one if multiple
- // share the same index)
- ClipList::iterator end = mClips.end(), candidate = end;
- temp = texture.mClipIdx;
- for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) {
- if ((*clip).idx == temp) {
- candidate = clip;
- }
-
- }
- if (candidate == end) {
- DefaultLogger::get()->error("LWO2: Clip index is out of bounds");
- temp = 0;
-
- // 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.
-
- s.Set("$texture.png");
-
- //continue;
- }
- else {
- if (Clip::UNSUPPORTED == (*candidate).type) {
- DefaultLogger::get()->error("LWO2: Clip type is not supported");
- continue;
- }
- AdjustTexturePath((*candidate).path);
- s.Set((*candidate).path);
-
- // Additional image settings
- int flags = 0;
- if ((*candidate).negate) {
- flags |= aiTextureFlags_Invert;
- }
- pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur));
- }
- }
- else
- {
- std::string ss = texture.mFileName;
- if (!ss.length()) {
- DefaultLogger::get()->error("LWOB: Empty file name");
- continue;
- }
- AdjustTexturePath(ss);
- s.Set(ss);
- }
- pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur));
-
- // add the blend factor
- pcMat->AddProperty<float>(&texture.mStrength,1,AI_MATKEY_TEXBLEND(type,cur));
-
- // add the blend operation
- switch (texture.blendType)
- {
- case LWO::Texture::Normal:
- case LWO::Texture::Multiply:
- temp = (unsigned int)aiTextureOp_Multiply;
- break;
-
- case LWO::Texture::Subtractive:
- case LWO::Texture::Difference:
- temp = (unsigned int)aiTextureOp_Subtract;
- break;
-
- case LWO::Texture::Divide:
- temp = (unsigned int)aiTextureOp_Divide;
- break;
-
- case LWO::Texture::Additive:
- temp = (unsigned int)aiTextureOp_Add;
- break;
-
- default:
- temp = (unsigned int)aiTextureOp_Multiply;
- DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement");
-
- }
- // Setup texture operation
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur));
-
- // setup the mapping mode
- pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur));
-
- // add the u-wrapping
- temp = (unsigned int)GetMapMode(texture.wrapModeWidth);
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur));
-
- // add the v-wrapping
- temp = (unsigned int)GetMapMode(texture.wrapModeHeight);
- pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur));
-
- ++cur;
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
-{
- // copy the name of the surface
- aiString st;
- st.Set(surf.mName);
- pcMat->AddProperty(&st,AI_MATKEY_NAME);
-
- const int i = surf.bDoubleSided ? 1 : 0;
- pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
-
- // add the refraction index and the bump intensity
- pcMat->AddProperty(&surf.mIOR,1,AI_MATKEY_REFRACTI);
- pcMat->AddProperty(&surf.mBumpIntensity,1,AI_MATKEY_BUMPSCALING);
-
- aiShadingMode m;
- if (surf.mSpecularValue && surf.mGlossiness)
- {
- float fGloss;
- if (mIsLWO2) {
- fGloss = std::pow( surf.mGlossiness*ai_real( 10.0 )+ ai_real( 2.0 ), ai_real( 2.0 ) );
- }
- else
- {
- if (16.0 >= surf.mGlossiness)
- fGloss = 6.0;
- else if (64.0 >= surf.mGlossiness)
- fGloss = 20.0;
- else if (256.0 >= surf.mGlossiness)
- fGloss = 50.0;
- else fGloss = 80.0;
- }
-
- pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
- pcMat->AddProperty(&fGloss,1,AI_MATKEY_SHININESS);
- m = aiShadingMode_Phong;
- }
- else m = aiShadingMode_Gouraud;
-
- // specular color
- aiColor3D clr = lerp( aiColor3D(1.0,1.0,1.0), surf.mColor, surf.mColorHighlights );
- pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_SPECULAR);
- pcMat->AddProperty(&surf.mSpecularValue,1,AI_MATKEY_SHININESS_STRENGTH);
-
- // emissive color
- // luminosity is not really the same but it affects the surface in a similar way. Some scaling looks good.
- clr.g = clr.b = clr.r = surf.mLuminosity*ai_real( 0.8 );
- pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_EMISSIVE);
-
- // opacity ... either additive or default-blended, please
- if (0.0 != surf.mAdditiveTransparency) {
-
- const int add = aiBlendMode_Additive;
- pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
- pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC);
- }
-
- else if (10e10f != surf.mTransparency) {
- const int def = aiBlendMode_Default;
- const float f = 1.0f-surf.mTransparency;
- pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY);
- pcMat->AddProperty(&def,1,AI_MATKEY_BLEND_FUNC);
- }
-
-
- // ADD TEXTURES to the material
- // TODO: find out how we can handle COLOR textures correctly...
- bool b = HandleTextures(pcMat,surf.mColorTextures,aiTextureType_DIFFUSE);
- b = (b || HandleTextures(pcMat,surf.mDiffuseTextures,aiTextureType_DIFFUSE));
- HandleTextures(pcMat,surf.mSpecularTextures,aiTextureType_SPECULAR);
- HandleTextures(pcMat,surf.mGlossinessTextures,aiTextureType_SHININESS);
- HandleTextures(pcMat,surf.mBumpTextures,aiTextureType_HEIGHT);
- HandleTextures(pcMat,surf.mOpacityTextures,aiTextureType_OPACITY);
- HandleTextures(pcMat,surf.mReflectionTextures,aiTextureType_REFLECTION);
-
- // Now we need to know which shader to use .. iterate through the shader list of
- // the surface and search for a name which we know ...
- for (const auto &shader : surf.mShaders) {
- if (shader.functionName == "LW_SuperCelShader" || shader.functionName == "AH_CelShader") {
- DefaultLogger::get()->info("LWO2: Mapping LW_SuperCelShader/AH_CelShader to aiShadingMode_Toon");
-
- m = aiShadingMode_Toon;
- break;
- }
- else if (shader.functionName == "LW_RealFresnel" || shader.functionName == "LW_FastFresnel") {
- DefaultLogger::get()->info("LWO2: Mapping LW_RealFresnel/LW_FastFresnel to aiShadingMode_Fresnel");
-
- m = aiShadingMode_Fresnel;
- break;
- }
- else
- {
- DefaultLogger::get()->warn("LWO2: Unknown surface shader: " + shader.functionName);
- }
- }
- if (surf.mMaximumSmoothAngle <= 0.0)
- m = aiShadingMode_Flat;
- pcMat->AddProperty((int*)&m,1,AI_MATKEY_SHADING_MODEL);
-
- // (the diffuse value is just a scaling factor)
- // If a diffuse texture is set, we set this value to 1.0
- clr = (b && false ? aiColor3D(1.0,1.0,1.0) : surf.mColor);
- clr.r *= surf.mDiffuseValue;
- clr.g *= surf.mDiffuseValue;
- clr.b *= surf.mDiffuseValue;
- pcMat->AddProperty<aiColor3D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-}
-
-// ------------------------------------------------------------------------------------------------
-char LWOImporter::FindUVChannels(LWO::TextureList& list,
- LWO::Layer& /*layer*/,LWO::UVChannel& uv, unsigned int next)
-{
- char ret = 0;
- for (auto &texture : list) {
-
- // Ignore textures with non-UV mappings for the moment.
- if (!texture.enabled || !texture.bCanUse || texture.mapMode != LWO::Texture::UV) {
- continue;
- }
-
- if (texture.mUVChannelIndex == uv.name) {
- ret = 1;
-
- // got it.
- if (texture.mRealUVIndex == UINT_MAX || texture.mRealUVIndex == next)
- {
- texture.mRealUVIndex = next;
- }
- else {
- // channel mismatch. need to duplicate the material.
- DefaultLogger::get()->warn("LWO: Channel mismatch, would need to duplicate surface [design bug]");
-
- // TODO
- }
- }
- }
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindUVChannels(LWO::Surface& surf,
- LWO::SortedRep& sorted,LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_TEXTURECOORDS])
-{
- unsigned int next = 0, extra = 0, num_extra = 0;
-
- // Check whether we have an UV entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mUVChannels.size();++i) {
- LWO::UVChannel& uv = layer.mUVChannels[i];
-
- for (LWO::SortedRep::const_iterator it = sorted.begin(); it != sorted.end(); ++it) {
-
- LWO::Face& face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (uv.abAssigned[idx] && ((aiVector2D*)&uv.rawData[0])[idx] != aiVector2D()) {
-
- if (extra >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-
- DefaultLogger::get()->error("LWO: Maximum number of UV channels for "
- "this mesh reached. Skipping channel \'" + uv.name + "\'");
-
- }
- else {
- // Search through all textures assigned to 'surf' and look for this UV channel
- char had = 0;
- had |= FindUVChannels(surf.mColorTextures,layer,uv,next);
- had |= FindUVChannels(surf.mDiffuseTextures,layer,uv,next);
- had |= FindUVChannels(surf.mSpecularTextures,layer,uv,next);
- had |= FindUVChannels(surf.mGlossinessTextures,layer,uv,next);
- had |= FindUVChannels(surf.mOpacityTextures,layer,uv,next);
- had |= FindUVChannels(surf.mBumpTextures,layer,uv,next);
- had |= FindUVChannels(surf.mReflectionTextures,layer,uv,next);
-
- // We have a texture referencing this UV channel so we have to take special care
- // and are willing to drop unreferenced channels in favour of it.
- if (had != 0) {
- if (num_extra) {
-
- for (unsigned int a = next; a < std::min( extra, AI_MAX_NUMBER_OF_TEXTURECOORDS-1u ); ++a) {
- out[a+1] = out[a];
- }
- }
- ++extra;
- out[next++] = i;
- }
- // Bah ... seems not to be used at all. Push to end if enough space is available.
- else {
- out[extra++] = i;
- ++num_extra;
- }
- }
- it = sorted.end()-1;
- break;
- }
- }
- }
- }
- if (extra < AI_MAX_NUMBER_OF_TEXTURECOORDS) {
- out[extra] = UINT_MAX;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorted, const LWO::Layer& layer,
- unsigned int out[AI_MAX_NUMBER_OF_COLOR_SETS])
-{
- unsigned int next = 0;
-
- // Check whether we have an vc entry != 0 for one of the faces in 'sorted'
- for (unsigned int i = 0; i < layer.mVColorChannels.size();++i) {
- const LWO::VColorChannel& vc = layer.mVColorChannels[i];
-
- if (surf.mVCMap == vc.name) {
- // The vertex color map is explicitly requested by the surface so we need to take special care of it
- for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
- out[a+1] = out[a];
- }
- out[0] = i;
- ++next;
- }
- else {
-
- for (LWO::SortedRep::iterator it = sorted.begin(); it != sorted.end(); ++it) {
- const LWO::Face& face = layer.mFaces[*it];
-
- for (unsigned int n = 0; n < face.mNumIndices; ++n) {
- unsigned int idx = face.mIndices[n];
-
- if (vc.abAssigned[idx] && ((aiColor4D*)&vc.rawData[0])[idx] != aiColor4D(0.0,0.0,0.0,1.0)) {
- if (next >= AI_MAX_NUMBER_OF_COLOR_SETS) {
-
- DefaultLogger::get()->error("LWO: Maximum number of vertex color channels for "
- "this mesh reached. Skipping channel \'" + vc.name + "\'");
-
- }
- else {
- out[next++] = i;
- }
- it = sorted.end()-1;
- break;
- }
- }
- }
- }
- }
- if (next != AI_MAX_NUMBER_OF_COLOR_SETS) {
- out[next] = UINT_MAX;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ImageMap(unsigned int size, LWO::Texture& tex )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- LE_NCONST IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid SURF.BLOCK chunk length");
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- case AI_LWO_PROJ:
- tex.mapMode = (Texture::MappingMode)GetU2();
- break;
- case AI_LWO_WRAP:
- tex.wrapModeWidth = (Texture::Wrap)GetU2();
- tex.wrapModeHeight = (Texture::Wrap)GetU2();
- break;
- case AI_LWO_AXIS:
- tex.majorAxis = (Texture::Axes)GetU2();
- break;
- case AI_LWO_IMAG:
- tex.mClipIdx = GetU2();
- break;
- case AI_LWO_VMAP:
- GetS0(tex.mUVChannelIndex,head.length);
- break;
- case AI_LWO_WRPH:
- tex.wrapAmountH = GetF4();
- break;
- case AI_LWO_WRPW:
- tex.wrapAmountW = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Procedural(unsigned int /*size*/, LWO::Texture& tex )
-{
- // --- not supported at the moment
- DefaultLogger::get()->error("LWO2: Found procedural texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Gradient(unsigned int /*size*/, LWO::Texture& tex )
-{
- // --- not supported at the moment
- DefaultLogger::get()->error("LWO2: Found gradient texture, this is not supported");
- tex.bCanUse = false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureHeader(unsigned int size, LWO::Texture& tex )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- // get the ordinal string
- GetS0( tex.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!tex.ordinal.length())
- {
- DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
- tex.ordinal = "\x00";
- }
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid texture header chunk length");
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- case AI_LWO_CHAN:
- tex.type = GetU4();
- break;
- case AI_LWO_ENAB:
- tex.enabled = GetU2() ? true : false;
- break;
- case AI_LWO_OPAC:
- tex.blendType = (Texture::BlendType)GetU2();
- tex.mStrength = GetF4();
- break;
- }
- mFileBuffer = next;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size )
-{
- ai_assert(!mSurfaces->empty());
- LWO::Surface& surf = mSurfaces->back();
- LWO::Texture tex;
-
- // load the texture header
- LoadLWO2TextureHeader(head->length,tex);
- size -= head->length + 6;
-
- // now get the exact type of the texture
- switch (head->type)
- {
- case AI_LWO_PROC:
- LoadLWO2Procedural(size,tex);
- break;
- case AI_LWO_GRAD:
- LoadLWO2Gradient(size,tex);
- break;
- case AI_LWO_IMAP:
- LoadLWO2ImageMap(size,tex);
- }
-
- // get the destination channel
- TextureList* listRef = NULL;
- switch (tex.type)
- {
- case AI_LWO_COLR:
- listRef = &surf.mColorTextures;break;
- case AI_LWO_DIFF:
- listRef = &surf.mDiffuseTextures;break;
- case AI_LWO_SPEC:
- listRef = &surf.mSpecularTextures;break;
- case AI_LWO_GLOS:
- listRef = &surf.mGlossinessTextures;break;
- case AI_LWO_BUMP:
- listRef = &surf.mBumpTextures;break;
- case AI_LWO_TRAN:
- listRef = &surf.mOpacityTextures;break;
- case AI_LWO_REFL:
- listRef = &surf.mReflectionTextures;break;
- default:
- DefaultLogger::get()->warn("LWO2: Encountered unknown texture type");
- return;
- }
-
- // now attach the texture to the parent surface - sort by ordinal string
- for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it) {
- if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
- listRef->insert(it,tex);
- return;
- }
- }
- listRef->push_back(tex);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2ShaderBlock(LE_NCONST IFF::SubChunkHeader* /*head*/, unsigned int size )
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- ai_assert(!mSurfaces->empty());
- LWO::Surface& surf = mSurfaces->back();
- LWO::Shader shader;
-
- // get the ordinal string
- GetS0( shader.ordinal, size);
-
- // we could crash later if this is an empty string ...
- if (!shader.ordinal.length())
- {
- DefaultLogger::get()->error("LWO2: Ill-formed SURF.BLOK ordinal string");
- shader.ordinal = "\x00";
- }
-
- // read the header
- while (true)
- {
- if (mFileBuffer + 6 >= end)break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid shader header chunk length");
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- case AI_LWO_ENAB:
- shader.enabled = GetU2() ? true : false;
- break;
-
- case AI_LWO_FUNC:
- GetS0( shader.functionName, head.length );
- }
- mFileBuffer = next;
- }
-
- // now attach the shader to the parent surface - sort by ordinal string
- for (ShaderList::iterator it = surf.mShaders.begin();it != surf.mShaders.end(); ++it) {
- if (::strcmp(shader.ordinal.c_str(),(*it).ordinal.c_str()) < 0) {
- surf.mShaders.insert(it,shader);
- return;
- }
- }
- surf.mShaders.push_back(shader);
-}
-
-// ------------------------------------------------------------------------------------------------
-void LWOImporter::LoadLWO2Surface(unsigned int size)
-{
- LE_NCONST uint8_t* const end = mFileBuffer + size;
-
- mSurfaces->push_back( LWO::Surface () );
- LWO::Surface& surf = mSurfaces->back();
-
- GetS0(surf.mName,size);
-
- // check whether this surface was derived from any other surface
- std::string derived;
- GetS0(derived,(unsigned int)(end - mFileBuffer));
- if (derived.length()) {
- // yes, find this surface
- for (SurfaceList::iterator it = mSurfaces->begin(), end = mSurfaces->end()-1; it != end; ++it) {
- if ((*it).mName == derived) {
- // we have it ...
- surf = *it;
- derived.clear();break;
- }
- }
- if (derived.size())
- DefaultLogger::get()->warn("LWO2: Unable to find source surface: " + derived);
- }
-
- while (true)
- {
- if (mFileBuffer + 6 >= end)
- break;
- const IFF::SubChunkHeader head = IFF::LoadSubChunk(mFileBuffer);
-
- if (mFileBuffer + head.length > end)
- throw DeadlyImportError("LWO2: Invalid surface chunk length");
-
- uint8_t* const next = mFileBuffer+head.length;
- switch (head.type)
- {
- // diffuse color
- case AI_LWO_COLR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,COLR,12);
- surf.mColor.r = GetF4();
- surf.mColor.g = GetF4();
- surf.mColor.b = GetF4();
- break;
- }
- // diffuse strength ... hopefully
- case AI_LWO_DIFF:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,DIFF,4);
- surf.mDiffuseValue = GetF4();
- break;
- }
- // specular strength ... hopefully
- case AI_LWO_SPEC:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SPEC,4);
- surf.mSpecularValue = GetF4();
- break;
- }
- // transparency
- case AI_LWO_TRAN:
- {
- // transparency explicitly disabled?
- if (surf.mTransparency == 10e10f)
- break;
-
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,TRAN,4);
- surf.mTransparency = GetF4();
- break;
- }
- // additive transparency
- case AI_LWO_ADTR:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,ADTR,4);
- surf.mAdditiveTransparency = GetF4();
- break;
- }
- // wireframe mode
- case AI_LWO_LINE:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,LINE,2);
- if (GetU2() & 0x1)
- surf.mWireframe = true;
- break;
- }
- // glossiness
- case AI_LWO_GLOS:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,GLOS,4);
- surf.mGlossiness = GetF4();
- break;
- }
- // bump intensity
- case AI_LWO_BUMP:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,BUMP,4);
- surf.mBumpIntensity = GetF4();
- break;
- }
- // color highlights
- case AI_LWO_CLRH:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,CLRH,4);
- surf.mColorHighlights = GetF4();
- break;
- }
- // index of refraction
- case AI_LWO_RIND:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,RIND,4);
- surf.mIOR = GetF4();
- break;
- }
- // polygon sidedness
- case AI_LWO_SIDE:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SIDE,2);
- surf.bDoubleSided = (3 == GetU2());
- break;
- }
- // maximum smoothing angle
- case AI_LWO_SMAN:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,SMAN,4);
- surf.mMaximumSmoothAngle = std::fabs( GetF4() );
- break;
- }
- // vertex color channel to be applied to the surface
- case AI_LWO_VCOL:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,VCOL,12);
- surf.mDiffuseValue *= GetF4(); // strength
- ReadVSizedIntLWO2(mFileBuffer); // skip envelope
- surf.mVCMapType = GetU4(); // type of the channel
-
- // name of the channel
- GetS0(surf.mVCMap, (unsigned int) (next - mFileBuffer ));
- break;
- }
- // surface bock entry
- case AI_LWO_BLOK:
- {
- AI_LWO_VALIDATE_CHUNK_LENGTH(head.length,BLOK,4);
- IFF::SubChunkHeader head2 = IFF::LoadSubChunk(mFileBuffer);
-
- switch (head2.type)
- {
- case AI_LWO_PROC:
- case AI_LWO_GRAD:
- case AI_LWO_IMAP:
- LoadLWO2TextureBlock(&head2, head.length);
- break;
- case AI_LWO_SHDR:
- LoadLWO2ShaderBlock(&head2, head.length);
- break;
-
- default:
- DefaultLogger::get()->warn("LWO2: Found an unsupported surface BLOK");
- };
-
- break;
- }
- }
- mFileBuffer = next;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
diff --git a/src/3rdparty/assimp/code/LWSLoader.cpp b/src/3rdparty/assimp/code/LWSLoader.cpp
deleted file mode 100644
index 2017cdb9d..000000000
--- a/src/3rdparty/assimp/code/LWSLoader.cpp
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWSLoader.cpp
- * @brief Implementation of the LWS importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
-
-#include "LWSLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include <assimp/SceneCombiner.h>
-#include "GenericProperty.h"
-#include "SkeletonMeshBuilder.h"
-#include "ConvertToLHProcess.h"
-#include "Importer.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "LightWave Scene Importer",
- "",
- "",
- "http://www.newtek.com/lightwave.html=",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "lws mot"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Recursive parsing of LWS files
-void LWS::Element::Parse (const char*& buffer)
-{
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
-
- // begin of a new element with children
- bool sub = false;
- if (*buffer == '{') {
- ++buffer;
- SkipSpaces(&buffer);
- sub = true;
- }
- else if (*buffer == '}')
- return;
-
- children.push_back(Element());
-
- // copy data line - read token per token
-
- const char* cur = buffer;
- while (!IsSpaceOrNewLine(*buffer)) ++buffer;
- children.back().tokens[0] = std::string(cur,(size_t) (buffer-cur));
- SkipSpaces(&buffer);
-
- if (children.back().tokens[0] == "Plugin")
- {
- DefaultLogger::get()->debug("LWS: Skipping over plugin-specific data");
-
- // strange stuff inside Plugin/Endplugin blocks. Needn't
- // follow LWS syntax, so we skip over it
- for (;SkipSpacesAndLineEnd(&buffer);SkipLine(&buffer)) {
- if (!::strncmp(buffer,"EndPlugin",9)) {
- //SkipLine(&buffer);
- break;
- }
- }
- continue;
- }
-
- cur = buffer;
- while (!IsLineEnd(*buffer)) ++buffer;
- children.back().tokens[1] = std::string(cur,(size_t) (buffer-cur));
-
- // parse more elements recursively
- if (sub)
- children.back().Parse(buffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LWSImporter::LWSImporter()
- : configSpeedFlag(),
- io(),
- first(),
- last(),
- fps(),
- noSkeletonMesh()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LWSImporter::~LWSImporter()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool LWSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler,bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "lws" || extension == "mot")
- return true;
-
- // if check for extension is not enough, check for the magic tokens LWSC and LWMO
- if (!extension.length() || checkSig) {
- uint32_t tokens[2];
- tokens[0] = AI_MAKE_MAGIC("LWSC");
- tokens[1] = AI_MAKE_MAGIC("LWMO");
- return CheckMagicToken(pIOHandler,pFile,tokens,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of file extensions
-const aiImporterDesc* LWSImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void LWSImporter::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-
- // AI_CONFIG_IMPORT_LWS_ANIM_START
- first = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_START,
- 150392 /* magic hack */);
-
- // AI_CONFIG_IMPORT_LWS_ANIM_END
- last = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_LWS_ANIM_END,
- 150392 /* magic hack */);
-
- if (last < first) {
- std::swap(last,first);
- }
-
- noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read an envelope description
-void LWSImporter::ReadEnvelope(const LWS::Element& dad, LWO::Envelope& fill )
-{
- if (dad.children.empty()) {
- DefaultLogger::get()->error("LWS: Envelope descriptions must not be empty");
- return;
- }
-
- // reserve enough storage
- std::list< LWS::Element >::const_iterator it = dad.children.begin();;
- fill.keys.reserve(strtoul10(it->tokens[1].c_str()));
-
- for (++it; it != dad.children.end(); ++it) {
- const char* c = (*it).tokens[1].c_str();
-
- if ((*it).tokens[0] == "Key") {
- fill.keys.push_back(LWO::Key());
- LWO::Key& key = fill.keys.back();
-
- float f;
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c,key.value);
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c,f);
-
- key.time = f;
-
- unsigned int span = strtoul10(c,&c), num = 0;
- switch (span) {
-
- case 0:
- key.inter = LWO::IT_TCB;
- num = 5;
- break;
- case 1:
- case 2:
- key.inter = LWO::IT_HERM;
- num = 5;
- break;
- case 3:
- key.inter = LWO::IT_LINE;
- num = 0;
- break;
- case 4:
- key.inter = LWO::IT_STEP;
- num = 0;
- break;
- case 5:
- key.inter = LWO::IT_BEZ2;
- num = 4;
- break;
- default:
- DefaultLogger::get()->error("LWS: Unknown span type");
- }
- for (unsigned int i = 0; i < num;++i) {
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c,key.params[i]);
- }
- }
- else if ((*it).tokens[0] == "Behaviors") {
- SkipSpaces(&c);
- fill.pre = (LWO::PrePostBehaviour) strtoul10(c,&c);
- SkipSpaces(&c);
- fill.post = (LWO::PrePostBehaviour) strtoul10(c,&c);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read animation channels in the old LightWave animation format
-void LWSImporter::ReadEnvelope_Old(
- std::list< LWS::Element >::const_iterator& it,
- const std::list< LWS::Element >::const_iterator& end,
- LWS::NodeDesc& nodes,
- unsigned int /*version*/)
-{
- unsigned int num,sub_num;
- if (++it == end)goto unexpected_end;
-
- num = strtoul10((*it).tokens[0].c_str());
- for (unsigned int i = 0; i < num; ++i) {
-
- nodes.channels.push_back(LWO::Envelope());
- LWO::Envelope& envl = nodes.channels.back();
-
- envl.index = i;
- envl.type = (LWO::EnvelopeType)(i+1);
-
- if (++it == end)goto unexpected_end;
- sub_num = strtoul10((*it).tokens[0].c_str());
-
- for (unsigned int n = 0; n < sub_num;++n) {
-
- if (++it == end)goto unexpected_end;
-
- // parse value and time, skip the rest for the moment.
- LWO::Key key;
- const char* c = fast_atoreal_move<float>((*it).tokens[0].c_str(),key.value);
- SkipSpaces(&c);
- float f;
- fast_atoreal_move<float>((*it).tokens[0].c_str(),f);
- key.time = f;
-
- envl.keys.push_back(key);
- }
- }
- return;
-
-unexpected_end:
- DefaultLogger::get()->error("LWS: Encountered unexpected end of file while parsing object motion");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup a nice name for a node
-void LWSImporter::SetupNodeName(aiNode* nd, LWS::NodeDesc& src)
-{
- const unsigned int combined = src.number | ((unsigned int)src.type) << 28u;
-
- // the name depends on the type. We break LWS's strange naming convention
- // and return human-readable, but still machine-parsable and unique, strings.
- if (src.type == LWS::NodeDesc::OBJECT) {
-
- if (src.path.length()) {
- std::string::size_type s = src.path.find_last_of("\\/");
- if (s == std::string::npos)
- s = 0;
- else ++s;
- std::string::size_type t = src.path.substr(s).find_last_of(".");
-
- nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.path.substr(s).substr(0,t).c_str(),combined);
- return;
- }
- }
- nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)",src.name,combined);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively build the scenegraph
-void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<AttachmentInfo>& attach,
- BatchLoader& batch,
- aiCamera**& camOut,
- aiLight**& lightOut,
- std::vector<aiNodeAnim*>& animOut)
-{
- // Setup a very cryptic name for the node, we want the user to be happy
- SetupNodeName(nd,src);
- aiNode* ndAnim = nd;
-
- // If the node is an object
- if (src.type == LWS::NodeDesc::OBJECT) {
-
- // If the object is from an external file, get it
- aiScene* obj = NULL;
- if (src.path.length() ) {
- obj = batch.GetImport(src.id);
- if (!obj) {
- DefaultLogger::get()->error("LWS: Failed to read external file " + src.path);
- }
- else {
- if (obj->mRootNode->mNumChildren == 1) {
-
- //If the pivot is not set for this layer, get it from the external object
- if (!src.isPivotSet) {
- src.pivotPos.x = +obj->mRootNode->mTransformation.a4;
- src.pivotPos.y = +obj->mRootNode->mTransformation.b4;
- src.pivotPos.z = -obj->mRootNode->mTransformation.c4; //The sign is the RH to LH back conversion
- }
-
- //Remove first node from obj (the old pivot), reset transform of second node (the mesh node)
- aiNode* newRootNode = obj->mRootNode->mChildren[0];
- obj->mRootNode->mChildren[0] = NULL;
- delete obj->mRootNode;
-
- obj->mRootNode = newRootNode;
- obj->mRootNode->mTransformation.a4 = 0.0;
- obj->mRootNode->mTransformation.b4 = 0.0;
- obj->mRootNode->mTransformation.c4 = 0.0;
- }
- }
- }
-
- //Setup the pivot node (also the animation node), the one we received
- nd->mName = std::string("Pivot:") + nd->mName.data;
- ndAnim = nd;
-
- //Add the attachment node to it
- nd->mNumChildren = 1;
- nd->mChildren = new aiNode*[1];
- nd->mChildren[0] = new aiNode();
- nd->mChildren[0]->mParent = nd;
- nd->mChildren[0]->mTransformation.a4 = -src.pivotPos.x;
- nd->mChildren[0]->mTransformation.b4 = -src.pivotPos.y;
- nd->mChildren[0]->mTransformation.c4 = -src.pivotPos.z;
- SetupNodeName(nd->mChildren[0], src);
-
- //Update the attachment node
- nd = nd->mChildren[0];
-
- //Push attachment, if the object came from an external file
- if (obj) {
- attach.push_back(AttachmentInfo(obj,nd));
- }
- }
-
- // If object is a light source - setup a corresponding ai structure
- else if (src.type == LWS::NodeDesc::LIGHT) {
- aiLight* lit = *lightOut++ = new aiLight();
-
- // compute final light color
- lit->mColorDiffuse = lit->mColorSpecular = src.lightColor*src.lightIntensity;
-
- // name to attach light to node -> unique due to LWs indexing system
- lit->mName = nd->mName;
-
- // detemine light type and setup additional members
- if (src.lightType == 2) { /* spot light */
-
- lit->mType = aiLightSource_SPOT;
- lit->mAngleInnerCone = (float)AI_DEG_TO_RAD( src.lightConeAngle );
- lit->mAngleOuterCone = lit->mAngleInnerCone+(float)AI_DEG_TO_RAD( src.lightEdgeAngle );
-
- }
- else if (src.lightType == 1) { /* directional light source */
- lit->mType = aiLightSource_DIRECTIONAL;
- }
- else lit->mType = aiLightSource_POINT;
-
- // fixme: no proper handling of light falloffs yet
- if (src.lightFalloffType == 1)
- lit->mAttenuationConstant = 1.f;
- else if (src.lightFalloffType == 1)
- lit->mAttenuationLinear = 1.f;
- else
- lit->mAttenuationQuadratic = 1.f;
- }
-
- // If object is a camera - setup a corresponding ai structure
- else if (src.type == LWS::NodeDesc::CAMERA) {
- aiCamera* cam = *camOut++ = new aiCamera();
-
- // name to attach cam to node -> unique due to LWs indexing system
- cam->mName = nd->mName;
- }
-
- // Get the node transformation from the LWO key
- LWO::AnimResolver resolver(src.channels,fps);
- resolver.ExtractBindPose(ndAnim->mTransformation);
-
- // .. and construct animation channels
- aiNodeAnim* anim = NULL;
-
- if (first != last) {
- resolver.SetAnimationRange(first,last);
- resolver.ExtractAnimChannel(&anim,AI_LWO_ANIM_FLAG_SAMPLE_ANIMS|AI_LWO_ANIM_FLAG_START_AT_ZERO);
- if (anim) {
- anim->mNodeName = ndAnim->mName;
- animOut.push_back(anim);
- }
- }
-
- // Add children
- if (!src.children.empty()) {
- nd->mChildren = new aiNode*[src.children.size()];
- for (std::list<LWS::NodeDesc*>::iterator it = src.children.begin(); it != src.children.end(); ++it) {
- aiNode* ndd = nd->mChildren[nd->mNumChildren++] = new aiNode();
- ndd->mParent = nd;
-
- BuildGraph(ndd,**it,attach,batch,camOut,lightOut,animOut);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Determine the exact location of a LWO file
-std::string LWSImporter::FindLWOFile(const std::string& in)
-{
- // insert missing directory separator if necessary
- std::string tmp;
- if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
- {
- tmp = in[0] + (std::string(":\\") + in.substr(2));
- }
- else tmp = in;
-
- if (io->Exists(tmp)) {
- return in;
- }
-
- // file is not accessible for us ... maybe it's packed by
- // LightWave's 'Package Scene' command?
-
- // Relevant for us are the following two directories:
- // <folder>\Objects\<hh>\<*>.lwo
- // <folder>\Scenes\<hh>\<*>.lws
- // where <hh> is optional.
-
- std::string test = std::string("..") + (io->getOsSeparator() + tmp);
- if (io->Exists(test)) {
- return test;
- }
-
- test = std::string("..") + (io->getOsSeparator() + test);
- if (io->Exists(test)) {
- return test;
- }
-
-
- // return original path, maybe the IOsystem knows better
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read file into given scene data structure
-void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler)
-{
- io = pIOHandler;
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open LWS file " + pFile + ".");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector< char > mBuffer;
- TextFileToBuffer(file.get(),mBuffer);
-
- // Parse the file structure
- LWS::Element root; const char* dummy = &mBuffer[0];
- root.Parse(dummy);
-
- // Construct a Batchimporter to read more files recursively
- BatchLoader batch(pIOHandler);
-// batch.SetBasePath(pFile);
-
- // Construct an array to receive the flat output graph
- std::list<LWS::NodeDesc> nodes;
-
- unsigned int cur_light = 0, cur_camera = 0, cur_object = 0;
- unsigned int num_light = 0, num_camera = 0, num_object = 0;
-
- // check magic identifier, 'LWSC'
- bool motion_file = false;
- std::list< LWS::Element >::const_iterator it = root.children.begin();
-
- if ((*it).tokens[0] == "LWMO")
- motion_file = true;
-
- if ((*it).tokens[0] != "LWSC" && !motion_file)
- throw DeadlyImportError("LWS: Not a LightWave scene, magic tag LWSC not found");
-
- // get file format version and print to log
- ++it;
- unsigned int version = strtoul10((*it).tokens[0].c_str());
- DefaultLogger::get()->info("LWS file format version is " + (*it).tokens[0]);
- first = 0.;
- last = 60.;
- fps = 25.; /* seems to be a good default frame rate */
-
- // Now read all elements in a very straghtforward manner
- for (; it != root.children.end(); ++it) {
- const char* c = (*it).tokens[1].c_str();
-
- // 'FirstFrame': begin of animation slice
- if ((*it).tokens[0] == "FirstFrame") {
- if (150392. != first /* see SetupProperties() */)
- first = strtoul10(c,&c)-1.; /* we're zero-based */
- }
-
- // 'LastFrame': end of animation slice
- else if ((*it).tokens[0] == "LastFrame") {
- if (150392. != last /* see SetupProperties() */)
- last = strtoul10(c,&c)-1.; /* we're zero-based */
- }
-
- // 'FramesPerSecond': frames per second
- else if ((*it).tokens[0] == "FramesPerSecond") {
- fps = strtoul10(c,&c);
- }
-
- // 'LoadObjectLayer': load a layer of a specific LWO file
- else if ((*it).tokens[0] == "LoadObjectLayer") {
-
- // get layer index
- const int layer = strtoul10(c,&c);
-
- // setup the layer to be loaded
- BatchLoader::PropertyMap props;
- SetGenericProperty(props.ints,AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY,layer);
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- if (version >= 4) { // handle LWSC 4 explicit ID
- SkipSpaces(&c);
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_object++;
-
- // and add the file to the import list
- SkipSpaces(&c);
- std::string path = FindLWOFile( c );
- d.path = path;
- d.id = batch.AddLoadRequest(path,0,&props);
-
- nodes.push_back(d);
- num_object++;
- }
- // 'LoadObject': load a LWO file into the scenegraph
- else if ((*it).tokens[0] == "LoadObject") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
- SkipSpaces(&c);
- }
- else d.number = cur_object++;
- std::string path = FindLWOFile( c );
- d.id = batch.AddLoadRequest(path,0,NULL);
-
- d.path = path;
- nodes.push_back(d);
- num_object++;
- }
- // 'AddNullObject': add a dummy node to the hierarchy
- else if ((*it).tokens[0] == "AddNullObject") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
- SkipSpaces(&c);
- }
- else d.number = cur_object++;
- d.name = c;
- nodes.push_back(d);
-
- num_object++;
- }
- // 'NumChannels': Number of envelope channels assigned to last layer
- else if ((*it).tokens[0] == "NumChannels") {
- // ignore for now
- }
- // 'Channel': preceedes any envelope description
- else if ((*it).tokens[0] == "Channel") {
- if (nodes.empty()) {
- if (motion_file) {
-
- // LightWave motion file. Add dummy node
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::OBJECT;
- d.name = c;
- d.number = cur_object++;
- nodes.push_back(d);
- }
- else DefaultLogger::get()->error("LWS: Unexpected keyword: \'Channel\'");
- }
-
- // important: index of channel
- nodes.back().channels.push_back(LWO::Envelope());
- LWO::Envelope& env = nodes.back().channels.back();
-
- env.index = strtoul10(c);
-
- // currently we can just interpret the standard channels 0...9
- // (hack) assume that index-i yields the binary channel type from LWO
- env.type = (LWO::EnvelopeType)(env.index+1);
-
- }
- // 'Envelope': a single animation channel
- else if ((*it).tokens[0] == "Envelope") {
- if (nodes.empty() || nodes.back().channels.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'Envelope\'");
- else {
- ReadEnvelope((*it),nodes.back().channels.back());
- }
- }
- // 'ObjectMotion': animation information for older lightwave formats
- else if (version < 3 && ((*it).tokens[0] == "ObjectMotion" ||
- (*it).tokens[0] == "CameraMotion" ||
- (*it).tokens[0] == "LightMotion")) {
-
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'<Light|Object|Camera>Motion\'");
- else {
- ReadEnvelope_Old(it,root.children.end(),nodes.back(),version);
- }
- }
- // 'Pre/PostBehavior': pre/post animation behaviour for LWSC 2
- else if (version == 2 && (*it).tokens[0] == "Pre/PostBehavior") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'Pre/PostBehavior'");
- else {
- for (std::list<LWO::Envelope>::iterator it = nodes.back().channels.begin(); it != nodes.back().channels.end(); ++it) {
- // two ints per envelope
- LWO::Envelope& env = *it;
- env.pre = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
- env.post = (LWO::PrePostBehaviour) strtoul10(c,&c); SkipSpaces(&c);
- }
- }
- }
- // 'ParentItem': specifies the parent of the current element
- else if ((*it).tokens[0] == "ParentItem") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentItem\'");
-
- else nodes.back().parent = strtoul16(c,&c);
- }
- // 'ParentObject': deprecated one for older formats
- else if (version < 3 && (*it).tokens[0] == "ParentObject") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'ParentObject\'");
-
- else {
- nodes.back().parent = strtoul10(c,&c) | (1u << 28u);
- }
- }
- // 'AddCamera': add a camera to the scenegraph
- else if ((*it).tokens[0] == "AddCamera") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::CAMERA;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_camera++;
- nodes.push_back(d);
-
- num_camera++;
- }
- // 'CameraName': set name of currently active camera
- else if ((*it).tokens[0] == "CameraName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::CAMERA)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'CameraName\'");
-
- else nodes.back().name = c;
- }
- // 'AddLight': add a light to the scenegraph
- else if ((*it).tokens[0] == "AddLight") {
-
- // add node to list
- LWS::NodeDesc d;
- d.type = LWS::NodeDesc::LIGHT;
-
- if (version >= 4) { // handle LWSC 4 explicit ID
- d.number = strtoul16(c,&c) & AI_LWS_MASK;
- }
- else d.number = cur_light++;
- nodes.push_back(d);
-
- num_light++;
- }
- // 'LightName': set name of currently active light
- else if ((*it).tokens[0] == "LightName") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightName\'");
-
- else nodes.back().name = c;
- }
- // 'LightIntensity': set intensity of currently active light
- else if ((*it).tokens[0] == "LightIntensity" || (*it).tokens[0] == "LgtIntensity" ) {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightIntensity\'");
-
- else fast_atoreal_move<float>(c, nodes.back().lightIntensity );
-
- }
- // 'LightType': set type of currently active light
- else if ((*it).tokens[0] == "LightType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightType\'");
-
- else nodes.back().lightType = strtoul10(c);
-
- }
- // 'LightFalloffType': set falloff type of currently active light
- else if ((*it).tokens[0] == "LightFalloffType") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightFalloffType\'");
-
- else nodes.back().lightFalloffType = strtoul10(c);
-
- }
- // 'LightConeAngle': set cone angle of currently active light
- else if ((*it).tokens[0] == "LightConeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightConeAngle\'");
-
- else nodes.back().lightConeAngle = fast_atof(c);
-
- }
- // 'LightEdgeAngle': set area where we're smoothing from min to max intensity
- else if ((*it).tokens[0] == "LightEdgeAngle") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightEdgeAngle\'");
-
- else nodes.back().lightEdgeAngle = fast_atof(c);
-
- }
- // 'LightColor': set color of currently active light
- else if ((*it).tokens[0] == "LightColor") {
- if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT)
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'LightColor\'");
-
- else {
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.r );
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.g );
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c, (float&) nodes.back().lightColor.b );
- }
- }
-
- // 'PivotPosition': position of local transformation origin
- else if ((*it).tokens[0] == "PivotPosition" || (*it).tokens[0] == "PivotPoint") {
- if (nodes.empty())
- DefaultLogger::get()->error("LWS: Unexpected keyword: \'PivotPosition\'");
- else {
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.x );
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.y );
- SkipSpaces(&c);
- c = fast_atoreal_move<float>(c, (float&) nodes.back().pivotPos.z );
- // Mark pivotPos as set
- nodes.back().isPivotSet = true;
- }
- }
- }
-
- // resolve parenting
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
-
- // check whether there is another node which calls us a parent
- for (std::list<LWS::NodeDesc>::iterator dit = nodes.begin(); dit != nodes.end(); ++dit) {
- if (dit != it && *it == (*dit).parent) {
- if ((*dit).parent_resolved) {
- // fixme: it's still possible to produce an overflow due to cross references ..
- DefaultLogger::get()->error("LWS: Found cross reference in scenegraph");
- continue;
- }
-
- (*it).children.push_back(&*dit);
- (*dit).parent_resolved = &*it;
- }
- }
- }
-
- // find out how many nodes have no parent yet
- unsigned int no_parent = 0;
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
- if (!(*it).parent_resolved)
- ++ no_parent;
- }
- if (!no_parent)
- throw DeadlyImportError("LWS: Unable to find scene root node");
-
-
- // Load all subsequent files
- batch.LoadAll();
-
- // and build the final output graph by attaching the loaded external
- // files to ourselves. first build a master graph
- aiScene* master = new aiScene();
- aiNode* nd = master->mRootNode = new aiNode();
-
- // allocate storage for cameras&lights
- if (num_camera) {
- master->mCameras = new aiCamera*[master->mNumCameras = num_camera];
- }
- aiCamera** cams = master->mCameras;
- if (num_light) {
- master->mLights = new aiLight*[master->mNumLights = num_light];
- }
- aiLight** lights = master->mLights;
-
- std::vector<AttachmentInfo> attach;
- std::vector<aiNodeAnim*> anims;
-
- nd->mName.Set("<LWSRoot>");
- nd->mChildren = new aiNode*[no_parent];
- for (std::list<LWS::NodeDesc>::iterator it = nodes.begin(); it != nodes.end(); ++it) {
- if (!(*it).parent_resolved) {
- aiNode* ro = nd->mChildren[ nd->mNumChildren++ ] = new aiNode();
- ro->mParent = nd;
-
- // ... and build the scene graph. If we encounter object nodes,
- // add then to our attachment table.
- BuildGraph(ro,*it, attach, batch, cams, lights, anims);
- }
- }
-
- // create a master animation channel for us
- if (anims.size()) {
- master->mAnimations = new aiAnimation*[master->mNumAnimations = 1];
- aiAnimation* anim = master->mAnimations[0] = new aiAnimation();
- anim->mName.Set("LWSMasterAnim");
-
- // LWS uses seconds as time units, but we convert to frames
- anim->mTicksPerSecond = fps;
- anim->mDuration = last-(first-1); /* fixme ... zero or one-based?*/
-
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels = static_cast<unsigned int>(anims.size())];
- std::copy(anims.begin(),anims.end(),anim->mChannels);
- }
-
- // convert the master scene to RH
- MakeLeftHandedProcess monster_cheat;
- monster_cheat.Execute(master);
-
- // .. ccw
- FlipWindingOrderProcess flipper;
- flipper.Execute(master);
-
- // OK ... finally build the output graph
- SceneCombiner::MergeScenes(&pScene,master,attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES | (!configSpeedFlag ? (
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY | AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES) : 0));
-
- // Check flags
- if (!pScene->mNumMeshes || !pScene->mNumMaterials) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
-
- 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
deleted file mode 100644
index e36d27b77..000000000
--- a/src/3rdparty/assimp/code/LWSLoader.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LWSLoader.h
- * @brief Declaration of the LightWave scene importer class.
- */
-#ifndef AI_LWSLOADER_H_INCLUDED
-#define AI_LWSLOADER_H_INCLUDED
-
-#include "LWOFileData.h"
-#include <assimp/SceneCombiner.h>
-#include "BaseImporter.h"
-
-struct aiImporterDesc;
-
-namespace Assimp {
- class BatchLoader;
- class Importer;
- class IOSystem;
-
- namespace LWS {
-
-// ---------------------------------------------------------------------------
-/** Represents an element in a LWS file.
- *
- * This can either be a single data line - <name> <value> or a data
- * group - { name <data_line0> ... n }
- */
-class Element
-{
-public:
- Element()
- {}
-
- // first: name, second: rest
- std::string tokens[2];
- std::list<Element> children;
-
- //! Recursive parsing function
- void Parse (const char*& buffer);
-};
-
-#define AI_LWS_MASK (0xffffffff >> 4u)
-
-// ---------------------------------------------------------------------------
-/** Represents a LWS scenegraph element
- */
-struct NodeDesc
-{
- NodeDesc()
- : type()
- , id()
- , number (0)
- , parent (0)
- , name ("")
- , isPivotSet (false)
- , lightColor (1.f,1.f,1.f)
- , lightIntensity (1.f)
- , lightType (0)
- , lightFalloffType (0)
- , lightConeAngle (45.f)
- , lightEdgeAngle()
- , parent_resolved (NULL)
- {}
-
- enum {
-
- OBJECT = 1,
- LIGHT = 2,
- CAMERA = 3,
- BONE = 4
- } type; // type of node
-
- // if object: path
- std::string path;
- unsigned int id;
-
- // number of object
- unsigned int number;
-
- // index of parent index
- unsigned int parent;
-
- // lights & cameras & dummies: name
- const char* name;
-
- // animation channels
- std::list< LWO::Envelope > channels;
-
- // position of pivot point
- aiVector3D pivotPos;
- bool isPivotSet;
-
-
-
- // color of light source
- aiColor3D lightColor;
-
- // intensity of light source
- float lightIntensity;
-
- // type of light source
- unsigned int lightType;
-
- // falloff type of light source
- unsigned int lightFalloffType;
-
- // cone angle of (spot) light source
- float lightConeAngle;
-
- // soft cone angle of (spot) light source
- float lightEdgeAngle;
-
-
-
- // list of resolved children
- std::list< NodeDesc* > children;
-
- // resolved parent node
- NodeDesc* parent_resolved;
-
-
- // for std::find()
- bool operator == (unsigned int num) const {
- if (!num)
- return false;
- unsigned int _type = num >> 28u;
-
- return _type == static_cast<unsigned int>(type) && (num & AI_LWS_MASK) == number;
- }
-};
-
-} // end namespace LWS
-
-// ---------------------------------------------------------------------------
-/** LWS (LightWave Scene Format) importer class.
- *
- * This class does heavily depend on the LWO importer class. LWS files
- * contain mainly descriptions how LWO objects are composed together
- * in a scene.
-*/
-class LWSImporter : public BaseImporter
-{
-public:
- LWSImporter();
- ~LWSImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether we can read a specific file
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- // Get list of supported extensions
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- // Import file into given scene data structure
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- // Setup import properties
- void SetupProperties(const Importer* pImp);
-
-private:
-
-
- // -------------------------------------------------------------------
- // Read an envelope description
- void ReadEnvelope(const LWS::Element& dad, LWO::Envelope& out );
-
- // -------------------------------------------------------------------
- // Read an envelope description for the older LW file format
- void ReadEnvelope_Old(std::list< LWS::Element >::const_iterator& it,
- const std::list< LWS::Element >::const_iterator& end,
- LWS::NodeDesc& nodes,
- unsigned int version);
-
- // -------------------------------------------------------------------
- // Setup a nice name for a node
- void SetupNodeName(aiNode* nd, LWS::NodeDesc& src);
-
- // -------------------------------------------------------------------
- // Recursively build the scenegraph
- void BuildGraph(aiNode* nd,
- LWS::NodeDesc& src,
- std::vector<AttachmentInfo>& attach,
- BatchLoader& batch,
- aiCamera**& camOut,
- aiLight**& lightOut,
- std::vector<aiNodeAnim*>& animOut);
-
- // -------------------------------------------------------------------
- // Try several dirs until we find the right location of a LWS file.
- std::string FindLWOFile(const std::string& in);
-
-private:
-
- bool configSpeedFlag;
- IOSystem* io;
-
- double first,last,fps;
-
- bool noSkeletonMesh;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_LWSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp b/src/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp
deleted file mode 100644
index 0bb4a4be3..000000000
--- a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-/** Implementation of the LimitBoneWeightsProcess post processing step */
-
-
-#include "LimitBoneWeightsProcess.h"
-#include "StringUtils.h"
-#include <assimp/postprocess.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <stdio.h>
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-LimitBoneWeightsProcess::LimitBoneWeightsProcess()
-{
- mMaxWeights = AI_LMW_MAX_WEIGHTS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-LimitBoneWeightsProcess::~LimitBoneWeightsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool LimitBoneWeightsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_LimitBoneWeights) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void LimitBoneWeightsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("LimitBoneWeightsProcess begin");
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- ProcessMesh( pScene->mMeshes[a]);
-
- DefaultLogger::get()->debug("LimitBoneWeightsProcess end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
-{
- // get the current value of the property
- this->mMaxWeights = pImp->GetPropertyInteger(AI_CONFIG_PP_LBW_MAX_WEIGHTS,AI_LMW_MAX_WEIGHTS);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unites identical vertices in the given mesh
-void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
-{
- if( !pMesh->HasBones())
- return;
-
- // collect all bone weights per vertex
- typedef std::vector< std::vector< Weight > > WeightsPerVertex;
- WeightsPerVertex vertexWeights( pMesh->mNumVertices);
-
- // collect all weights per vertex
- for( unsigned int a = 0; a < pMesh->mNumBones; a++)
- {
- const aiBone* bone = pMesh->mBones[a];
- for( unsigned int b = 0; b < bone->mNumWeights; b++)
- {
- const aiVertexWeight& w = bone->mWeights[b];
- vertexWeights[w.mVertexId].push_back( Weight( a, w.mWeight));
- }
- }
-
- unsigned int removed = 0, old_bones = pMesh->mNumBones;
-
- // now cut the weight count if it exceeds the maximum
- bool bChanged = false;
- for( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
- {
- if( vit->size() <= mMaxWeights)
- continue;
-
- bChanged = true;
-
- // more than the defined maximum -> first sort by weight in descending order. That's
- // why we defined the < operator in such a weird way.
- std::sort( vit->begin(), vit->end());
-
- // now kill everything beyond the maximum count
- unsigned int m = static_cast<unsigned int>(vit->size());
- vit->erase( vit->begin() + mMaxWeights, vit->end());
- removed += static_cast<unsigned int>(m-vit->size());
-
- // and renormalize the weights
- float sum = 0.0f;
- for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it ) {
- sum += it->mWeight;
- }
- if( 0.0f != sum ) {
- const float invSum = 1.0f / sum;
- for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it ) {
- it->mWeight *= invSum;
- }
- }
- }
-
- if (bChanged) {
- // rebuild the vertex weight array for all bones
- typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
- WeightsPerBone boneWeights( pMesh->mNumBones);
- for( unsigned int a = 0; a < vertexWeights.size(); a++)
- {
- const std::vector<Weight>& vw = vertexWeights[a];
- for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
- boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
- }
-
- // and finally copy the vertex weight list over to the mesh's bones
- std::vector<bool> abNoNeed(pMesh->mNumBones,false);
- bChanged = false;
-
- for( unsigned int a = 0; a < pMesh->mNumBones; a++)
- {
- const std::vector<aiVertexWeight>& bw = boneWeights[a];
- aiBone* bone = pMesh->mBones[a];
-
- if ( bw.empty() )
- {
- abNoNeed[a] = bChanged = true;
- continue;
- }
-
- // copy the weight list. should always be less weights than before, so we don't need a new allocation
- ai_assert( bw.size() <= bone->mNumWeights);
- bone->mNumWeights = static_cast<unsigned int>( bw.size() );
- ::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
- }
-
- if (bChanged) {
- // the number of new bones is smaller than before, so we can reuse the old array
- aiBone** ppcCur = pMesh->mBones;aiBone** ppcSrc = ppcCur;
-
- for (std::vector<bool>::const_iterator iter = abNoNeed.begin();iter != abNoNeed.end() ;++iter) {
- if (*iter) {
- delete *ppcSrc;
- --pMesh->mNumBones;
- }
- else *ppcCur++ = *ppcSrc;
- ++ppcSrc;
- }
- }
-
- if (!DefaultLogger::isNullLogger()) {
- char buffer[1024];
- ai_snprintf(buffer,1024,"Removed %u weights. Input bones: %u. Output bones: %u",removed,old_bones,pMesh->mNumBones);
- DefaultLogger::get()->info(buffer);
- }
- }
-}
diff --git a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h b/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h
deleted file mode 100644
index 3826dbe58..000000000
--- a/src/3rdparty/assimp/code/LimitBoneWeightsProcess.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-/** Defines a post processing step to limit the number of bones affecting a single vertex. */
-#ifndef AI_LIMITBONEWEIGHTSPROCESS_H_INC
-#define AI_LIMITBONEWEIGHTSPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-class LimitBoneWeightsTest;
-
-namespace Assimp
-{
-
-// NOTE: If you change these limits, don't forget to change the
-// corresponding values in all Assimp ports
-
-// **********************************************************
-// Java: ConfigProperty.java,
-// ConfigProperty.DEFAULT_BONE_WEIGHT_LIMIT
-// **********************************************************
-
-#if (!defined AI_LMW_MAX_WEIGHTS)
-# define AI_LMW_MAX_WEIGHTS 0x4
-#endif // !! AI_LMW_MAX_WEIGHTS
-
-// ---------------------------------------------------------------------------
-/** This post processing step limits the number of bones affecting a vertex
-* to a certain maximum value. If a vertex is affected by more than that number
-* of bones, the bone weight with the least influence on this vertex are removed.
-* The other weights on this bone are then renormalized to assure the sum weight
-* to be 1.
-*/
-class ASSIMP_API LimitBoneWeightsProcess : public BaseProcess
-{
-public:
-
- LimitBoneWeightsProcess();
- ~LimitBoneWeightsProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with.
- * A bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-public:
-
- // -------------------------------------------------------------------
- /** Limits the bone weight count for all vertices in the given mesh.
- * @param pMesh The mesh to process.
- */
- void ProcessMesh( aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Describes a bone weight on a vertex */
- struct Weight
- {
- unsigned int mBone; ///< Index of the bone
- float mWeight; ///< Weight of that bone on this vertex
- Weight() { }
- Weight( unsigned int pBone, float pWeight)
- {
- mBone = pBone;
- mWeight = pWeight;
- }
-
- /** Comparison operator to sort bone weights by descending weight */
- bool operator < (const Weight& pWeight) const
- {
- return mWeight > pWeight.mWeight;
- }
- };
-
-public:
- /** Maximum number of bones influencing any single vertex. */
- unsigned int mMaxWeights;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_LIMITBONEWEIGHTSPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/LineSplitter.h b/src/3rdparty/assimp/code/LineSplitter.h
deleted file mode 100644
index 003b42d52..000000000
--- a/src/3rdparty/assimp/code/LineSplitter.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LineSplitter.h
- * @brief LineSplitter, a helper class to iterate through all lines
- * of a file easily. Works with StreamReader.
- */
-#ifndef INCLUDED_LINE_SPLITTER_H
-#define INCLUDED_LINE_SPLITTER_H
-
-#include <stdexcept>
-
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/** Usage:
-@code
-for(LineSplitter splitter(stream);splitter;++splitter) {
-
- if (*splitter == "hi!") {
- ...
- }
- else if (splitter->substr(0,5) == "hello") {
- ...
- // access the third token in the line (tokens are space-separated)
- if (strtol(splitter[2]) > 5) { .. }
- }
-
- std::cout << "Current line is: " << splitter.get_index() << std::endl;
-}
-@endcode
-*/
-// ------------------------------------------------------------------------------------------------
-class LineSplitter {
-public:
- typedef size_t line_idx;
-
- // -----------------------------------------
- /** construct from existing stream reader
- note: trim is *always* assumed true if skyp_empty_lines==true
- */
- LineSplitter(StreamReaderLE& stream, bool skip_empty_lines = true, bool trim = true)
- : idx( 0 )
- , stream(stream)
- , swallow()
- , skip_empty_lines(skip_empty_lines)
- , trim(trim) {
- cur.reserve(1024);
- operator++();
-
- idx = 0;
- }
-
- ~LineSplitter() {
- // empty
- }
-
-public:
-
- // -----------------------------------------
- /** pseudo-iterator increment */
- LineSplitter& operator++() {
- if(swallow) {
- 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') {
- if (skip_empty_lines) {
- while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\r' || s == '\n'));
- if (stream.GetRemainingSize()) {
- stream.IncPtr(-1);
- }
- }
- else {
- // skip both potential line terminators but don't read past this line.
- if (stream.GetRemainingSize() && (s == '\r' && stream.GetI1() != '\n')) {
- stream.IncPtr(-1);
- }
- if (trim) {
- while (stream.GetRemainingSize() && ((s = stream.GetI1()) == ' ' || s == '\t'));
- if (stream.GetRemainingSize()) {
- stream.IncPtr(-1);
- }
- }
- }
- break;
- }
- cur += s;
- }
- ++idx;
- return *this;
- }
-
- // -----------------------------------------
- LineSplitter& operator++(int) {
- return ++(*this);
- }
-
- // -----------------------------------------
- /** get a pointer to the beginning of a particular token */
- const char* operator[] (size_t idx) const {
- const char* s = operator->()->c_str();
-
- SkipSpaces(&s);
- for(size_t i = 0; i < idx; ++i) {
-
- for(;!IsSpace(*s); ++s) {
- if(IsLineEnd(*s)) {
- throw std::range_error("Token index out of range, EOL reached");
- }
- }
- SkipSpaces(&s);
- }
- return s;
- }
-
- // -----------------------------------------
- /** extract the start positions of N tokens from the current line*/
- template <size_t N>
- void get_tokens(const char* (&tokens)[N]) const {
- const char* s = operator->()->c_str();
-
- 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;
-
- for(;*s && !IsSpace(*s); ++s);
- SkipSpaces(&s);
- }
- }
-
- // -----------------------------------------
- /** member access */
- const std::string* operator -> () const {
- return &cur;
- }
-
- std::string operator* () const {
- return cur;
- }
-
- // -----------------------------------------
- /** boolean context */
- operator bool() const {
- return stream.GetRemainingSize()>0;
- }
-
- // -----------------------------------------
- /** line indices are zero-based, empty lines are included */
- operator line_idx() const {
- return idx;
- }
-
- line_idx get_index() const {
- return idx;
- }
-
- // -----------------------------------------
- /** access the underlying stream object */
- StreamReaderLE& get_stream() {
- return stream;
- }
-
- // -----------------------------------------
- /** !strcmp((*this)->substr(0,strlen(check)),check) */
- bool match_start(const char* check) {
- const size_t len = strlen(check);
-
- return len <= cur.length() && std::equal(check,check+len,cur.begin());
- }
-
-
- // -----------------------------------------
- /** swallow the next call to ++, return the previous value. */
- void swallow_next_increment() {
- swallow = true;
- }
-
-private:
- LineSplitter( const LineSplitter & );
- LineSplitter &operator = ( const LineSplitter & );
-
-private:
- line_idx idx;
- std::string cur;
- StreamReaderLE& stream;
- bool swallow, skip_empty_lines, trim;
-};
-
-}
-#endif // INCLUDED_LINE_SPLITTER_H
diff --git a/src/3rdparty/assimp/code/LogAux.h b/src/3rdparty/assimp/code/LogAux.h
deleted file mode 100644
index f2bc14d54..000000000
--- a/src/3rdparty/assimp/code/LogAux.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LogAux.h
- * @brief Common logging usage patterns for importer implementations
- */
-#ifndef INCLUDED_AI_LOGAUX_H
-#define INCLUDED_AI_LOGAUX_H
-
-#include "TinyFormatter.h"
-#include "Exceptional.h"
-#include <assimp/DefaultLogger.hpp>
-
-namespace Assimp {
-
-template <class TDeriving>
-class LogFunctions
-{
-
-public:
-
- // ------------------------------------------------------------------------------------------------
- static void ThrowException(const std::string& msg)
- {
- throw DeadlyImportError(Prefix()+msg);
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogWarn(const Formatter::format& message) {
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->warn(Prefix()+(std::string)message);
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogError(const Formatter::format& message) {
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->error(Prefix()+(std::string)message);
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogInfo(const Formatter::format& message) {
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->info(Prefix()+(std::string)message);
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogDebug(const Formatter::format& message) {
- if (!DefaultLogger::isNullLogger()) {
- DefaultLogger::get()->debug(Prefix()+(std::string)message);
- }
- }
-
- // https://sourceforge.net/tracker/?func=detail&atid=1067632&aid=3358562&group_id=226462
-#if !defined(__GNUC__) || !defined(__APPLE__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
-
- // ------------------------------------------------------------------------------------------------
- static void LogWarn (const char* message) {
- if (!DefaultLogger::isNullLogger()) {
- LogWarn(Formatter::format(message));
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogError (const char* message) {
- if (!DefaultLogger::isNullLogger()) {
- LogError(Formatter::format(message));
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogInfo (const char* message) {
- if (!DefaultLogger::isNullLogger()) {
- LogInfo(Formatter::format(message));
- }
- }
-
- // ------------------------------------------------------------------------------------------------
- static void LogDebug (const char* message) {
- if (!DefaultLogger::isNullLogger()) {
- LogDebug(Formatter::format(message));
- }
- }
-
-#endif
-
-private:
- static const char* Prefix();
-
-};
-
-} // ! Assimp
-#endif
diff --git a/src/3rdparty/assimp/code/MD2FileData.h b/src/3rdparty/assimp/code/MD2FileData.h
deleted file mode 100644
index f65193264..000000000
--- a/src/3rdparty/assimp/code/MD2FileData.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD2FileData.h
- * @brief Defines helper data structures for importing MD2 files
- * http://linux.ucla.edu/~phaethon/q3/formats/md2-schoenblum.html
- */
-#ifndef AI_MD2FILEHELPER_H_INC
-#define AI_MD2FILEHELPER_H_INC
-
-#include <assimp/types.h>
-#include <stdint.h>
-
-#include <assimp/Compiler/pushpack1.h>
-
-namespace Assimp {
-namespace MD2 {
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MD2_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP2")
-#define AI_MD2_MAGIC_NUMBER_LE AI_MAKE_MAGIC("2PDI")
-
-// common limitations
-#define AI_MD2_VERSION 15
-#define AI_MD2_MAXQPATH 64
-#define AI_MD2_MAX_FRAMES 512
-#define AI_MD2_MAX_SKINS 32
-#define AI_MD2_MAX_VERTS 2048
-#define AI_MD2_MAX_TRIANGLES 4096
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for the MD2 main header
- */
-struct Header
-{
- uint32_t magic;
- uint32_t version;
- uint32_t skinWidth;
- uint32_t skinHeight;
- uint32_t frameSize;
- uint32_t numSkins;
- uint32_t numVertices;
- uint32_t numTexCoords;
- uint32_t numTriangles;
- uint32_t numGlCommands;
- uint32_t numFrames;
- uint32_t offsetSkins;
- uint32_t offsetTexCoords;
- uint32_t offsetTriangles;
- uint32_t offsetFrames;
- uint32_t offsetGlCommands;
- uint32_t offsetEnd;
-
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 OpenGl draw command
- */
-struct GLCommand
-{
- float s, t;
- uint32_t vertexIndex;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 triangle
- */
-struct Triangle
-{
- uint16_t vertexIndices[3];
- uint16_t textureIndices[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 vertex
- */
-struct Vertex
-{
- uint8_t vertex[3];
- uint8_t lightNormalIndex;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 frame
- */
-struct Frame
-{
- float scale[3];
- float translate[3];
- char name[16];
- Vertex vertices[1];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 texture coordinate
- */
-struct TexCoord
-{
- uint16_t s;
- uint16_t t;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD2 skin
- */
-struct Skin
-{
- char name[AI_MD2_MAXQPATH]; /* texture file name */
-} PACK_STRUCT;
-
-#include <assimp/Compiler/poppack1.h>
-
-
-// ---------------------------------------------------------------------------
-//! Lookup a normal vector from Quake's normal lookup table
-//! \param index Input index (0-161)
-//! \param vOut Receives the output normal
-void LookupNormalIndex(uint8_t index,aiVector3D& vOut);
-
-
-}
-}
-
-#endif // !! include guard
-
diff --git a/src/3rdparty/assimp/code/MD2Loader.cpp b/src/3rdparty/assimp/code/MD2Loader.cpp
deleted file mode 100644
index f0a5432bf..000000000
--- a/src/3rdparty/assimp/code/MD2Loader.cpp
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_MD2_IMPORTER
-
-/** @file Implementation of the MD2 importer class */
-#include "MD2Loader.h"
-#include "ByteSwapper.h"
-#include "MD2NormalTable.h" // shouldn't be included by other units
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-using namespace Assimp;
-using namespace Assimp::MD2;
-
-// helper macro to determine the size of an array
-#if (!defined ARRAYSIZE)
-# define ARRAYSIZE(_array) (int(sizeof(_array) / sizeof(_array[0])))
-#endif
-
-static const aiImporterDesc desc = {
- "Quake II Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "md2"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Helper function to lookup a normal in Quake 2's precalculated table
-void MD2::LookupNormalIndex(uint8_t iNormalIndex,aiVector3D& vOut)
-{
- // make sure the normal index has a valid value
- if (iNormalIndex >= ARRAYSIZE(g_avNormals)) {
- DefaultLogger::get()->warn("Index overflow in Quake II normal vector list");
- iNormalIndex = ARRAYSIZE(g_avNormals) - 1;
- }
- vOut = *((const aiVector3D*)(&g_avNormals[iNormalIndex]));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD2Importer::MD2Importer()
- : configFrameID(),
- m_pcHeader(),
- mBuffer(),
- fileSize()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD2Importer::~MD2Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD2Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "md2")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MD2_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all extensions supported by this loader
-const aiImporterDesc* MD2Importer::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MD2Importer::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_MD2_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD2_KEYFRAME,-1);
- if(static_cast<unsigned int>(-1) == configFrameID){
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Validate the file header
-void MD2Importer::ValidateHeader( )
-{
- // check magic number
- if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
- m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
- {
- char szBuffer[5];
- szBuffer[0] = ((char*)&m_pcHeader->magic)[0];
- szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
- szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
- szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
- szBuffer[4] = '\0';
-
- throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
- "magic word found is " + std::string(szBuffer));
- }
-
- // check file format version
- if (m_pcHeader->version != 8)
- DefaultLogger::get()->warn( "Unsupported md2 file version. Continuing happily ...");
-
- // check some values whether they are valid
- if (0 == m_pcHeader->numFrames)
- throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0");
-
- if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
- throw DeadlyImportError( "Invalid md2 file: File is too small");
-
- if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) {
- throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow");
- }
-
- if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) {
- throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow");
- }
-
- if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) {
- throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow");
- }
-
- if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) {
- throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow");
- }
-
- if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) {
- throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow");
- }
-
- // -1 because Frame already contains one
- unsigned int frameSize = sizeof (MD2::Frame) + (m_pcHeader->numVertices - 1) * sizeof(MD2::Vertex);
-
- if (m_pcHeader->offsetSkins + m_pcHeader->numSkins * sizeof (MD2::Skin) >= fileSize ||
- m_pcHeader->offsetTexCoords + m_pcHeader->numTexCoords * sizeof (MD2::TexCoord) >= fileSize ||
- m_pcHeader->offsetTriangles + m_pcHeader->numTriangles * sizeof (MD2::Triangle) >= fileSize ||
- m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize ||
- m_pcHeader->offsetEnd > fileSize)
- {
- throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file");
- }
-
- if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
- DefaultLogger::get()->warn("The model contains more skins than Quake 2 supports");
- if ( m_pcHeader->numFrames > AI_MD2_MAX_FRAMES)
- DefaultLogger::get()->warn("The model contains more frames than Quake 2 supports");
- if (m_pcHeader->numVertices > AI_MD2_MAX_VERTS)
- DefaultLogger::get()->warn("The model contains more vertices than Quake 2 supports");
-
- if (m_pcHeader->numFrames <= configFrameID )
- throw DeadlyImportError("The requested frame is not existing the file");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD2Importer::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MD2 file " + pFile + "");
-
- // check whether the md3 file is large enough to contain
- // at least the file header
- fileSize = (unsigned int)file->FileSize();
- if( fileSize < sizeof(MD2::Header))
- throw DeadlyImportError( "MD2 File is too small");
-
- std::vector<uint8_t> mBuffer2(fileSize);
- file->Read(&mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
-
- m_pcHeader = (BE_NCONST MD2::Header*)mBuffer;
-
-#ifdef AI_BUILD_BIG_ENDIAN
-
- ByteSwap::Swap4(&m_pcHeader->frameSize);
- ByteSwap::Swap4(&m_pcHeader->magic);
- ByteSwap::Swap4(&m_pcHeader->numFrames);
- ByteSwap::Swap4(&m_pcHeader->numGlCommands);
- ByteSwap::Swap4(&m_pcHeader->numSkins);
- ByteSwap::Swap4(&m_pcHeader->numTexCoords);
- ByteSwap::Swap4(&m_pcHeader->numTriangles);
- ByteSwap::Swap4(&m_pcHeader->numVertices);
- ByteSwap::Swap4(&m_pcHeader->offsetEnd);
- ByteSwap::Swap4(&m_pcHeader->offsetFrames);
- ByteSwap::Swap4(&m_pcHeader->offsetGlCommands);
- ByteSwap::Swap4(&m_pcHeader->offsetSkins);
- ByteSwap::Swap4(&m_pcHeader->offsetTexCoords);
- ByteSwap::Swap4(&m_pcHeader->offsetTriangles);
- ByteSwap::Swap4(&m_pcHeader->skinHeight);
- ByteSwap::Swap4(&m_pcHeader->skinWidth);
- ByteSwap::Swap4(&m_pcHeader->version);
-
-#endif
-
- ValidateHeader();
-
- // there won't be more than one mesh inside the file
- pScene->mNumMaterials = 1;
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = new aiMaterial();
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
-
- aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // navigate to the begin of the current frame data
- BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetFrames + (m_pcHeader->frameSize * configFrameID));
-
- // navigate to the begin of the triangle data
- MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetTriangles);
-
- // navigate to the begin of the tex coords data
- BE_NCONST MD2::TexCoord* pcTexCoords = (BE_NCONST MD2::TexCoord*) ((uint8_t*)
- m_pcHeader + m_pcHeader->offsetTexCoords);
-
- // navigate to the begin of the vertex data
- BE_NCONST MD2::Vertex* pcVerts = (BE_NCONST MD2::Vertex*) (pcFrame->vertices);
-
-#ifdef AI_BUILD_BIG_ENDIAN
- for (uint32_t i = 0; i< m_pcHeader->numTriangles; ++i)
- {
- for (unsigned int p = 0; p < 3;++p)
- {
- ByteSwap::Swap2(& pcTriangles[i].textureIndices[p]);
- ByteSwap::Swap2(& pcTriangles[i].vertexIndices[p]);
- }
- }
- for (uint32_t i = 0; i < m_pcHeader->offsetTexCoords;++i)
- {
- ByteSwap::Swap2(& pcTexCoords[i].s);
- ByteSwap::Swap2(& pcTexCoords[i].t);
- }
- ByteSwap::Swap4( & pcFrame->scale[0] );
- ByteSwap::Swap4( & pcFrame->scale[1] );
- ByteSwap::Swap4( & pcFrame->scale[2] );
- ByteSwap::Swap4( & pcFrame->translate[0] );
- ByteSwap::Swap4( & pcFrame->translate[1] );
- ByteSwap::Swap4( & pcFrame->translate[2] );
-#endif
-
- pcMesh->mNumFaces = m_pcHeader->numTriangles;
- pcMesh->mFaces = new aiFace[m_pcHeader->numTriangles];
-
- // allocate output storage
- pcMesh->mNumVertices = (unsigned int)pcMesh->mNumFaces*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- // Not sure whether there are MD2 files without texture coordinates
- // NOTE: texture coordinates can be there without a texture,
- // but a texture can't be there without a valid UV channel
- aiMaterial* pcHelper = (aiMaterial*)pScene->mMaterials[0];
- const int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- if (m_pcHeader->numTexCoords && m_pcHeader->numSkins)
- {
- // navigate to the first texture associated with the mesh
- const MD2::Skin* pcSkins = (const MD2::Skin*) ((unsigned char*)m_pcHeader +
- m_pcHeader->offsetSkins);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- if (pcSkins->name[0])
- {
- aiString szString;
- const size_t iLen = ::strlen(pcSkins->name);
- ::memcpy(szString.data,pcSkins->name,iLen);
- szString.data[iLen] = '\0';
- szString.length = iLen;
-
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else{
- DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped.");
- }
- }
- else {
- // apply a default material
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- aiString sz;
-
- // TODO: Try to guess the name of the texture file from the model file name
-
- sz.Set("$texture_dummy.bmp");
- pcHelper->AddProperty(&sz,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
-
-
- // now read all triangles of the first frame, apply scaling and translation
- unsigned int iCurrent = 0;
-
- float fDivisorU = 1.0f,fDivisorV = 1.0f;
- if (m_pcHeader->numTexCoords) {
- // allocate storage for texture coordinates, too
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // check whether the skin width or height are zero (this would
- // cause a division through zero)
- if (!m_pcHeader->skinWidth) {
- DefaultLogger::get()->error("MD2: No valid skin width given");
- }
- else fDivisorU = (float)m_pcHeader->skinWidth;
- if (!m_pcHeader->skinHeight){
- DefaultLogger::get()->error("MD2: No valid skin height given");
- }
- else fDivisorV = (float)m_pcHeader->skinHeight;
- }
-
- for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i) {
- // Allocate the face
- pScene->mMeshes[0]->mFaces[i].mIndices = new unsigned int[3];
- pScene->mMeshes[0]->mFaces[i].mNumIndices = 3;
-
- // copy texture coordinates
- // check whether they are different from the previous value at this index.
- // In this case, create a full separate set of vertices/normals/texcoords
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
-
- // validate vertex indices
- unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
- if (iIndex >= m_pcHeader->numVertices) {
- DefaultLogger::get()->error("MD2: Vertex index is outside the allowed range");
- iIndex = m_pcHeader->numVertices-1;
- }
-
- // read x,y, and z component of the vertex
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
-
- vec.x = (float)pcVerts[iIndex].vertex[0] * pcFrame->scale[0];
- vec.x += pcFrame->translate[0];
-
- vec.y = (float)pcVerts[iIndex].vertex[1] * pcFrame->scale[1];
- vec.y += pcFrame->translate[1];
-
- vec.z = (float)pcVerts[iIndex].vertex[2] * pcFrame->scale[2];
- vec.z += pcFrame->translate[2];
-
- // read the normal vector from the precalculated normal table
- aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
- LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
-
- // flip z and y to become right-handed
- std::swap((float&)vNormal.z,(float&)vNormal.y);
- std::swap((float&)vec.z,(float&)vec.y);
-
- if (m_pcHeader->numTexCoords) {
- // validate texture coordinates
- iIndex = pcTriangles[i].textureIndices[c];
- if (iIndex >= m_pcHeader->numTexCoords) {
- DefaultLogger::get()->error("MD2: UV index is outside the allowed range");
- iIndex = m_pcHeader->numTexCoords-1;
- }
-
- aiVector3D& pcOut = pcMesh->mTextureCoords[0][iCurrent];
-
- // the texture coordinates are absolute values but we
- // need relative values between 0 and 1
- pcOut.x = pcTexCoords[iIndex].s / fDivisorU;
- pcOut.y = 1.f-pcTexCoords[iIndex].t / fDivisorV;
- }
- pScene->mMeshes[0]->mFaces[i].mIndices[c] = iCurrent;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD2_IMPORTER
diff --git a/src/3rdparty/assimp/code/MD2Loader.h b/src/3rdparty/assimp/code/MD2Loader.h
deleted file mode 100644
index a7566dc64..000000000
--- a/src/3rdparty/assimp/code/MD2Loader.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD2Loader.h
- * @brief Declaration of the .MD2 importer class.
- */
-#ifndef AI_MD2LOADER_H_INCLUDED
-#define AI_MD2LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include "ByteSwapper.h"
-#include "MD2FileData.h"
-
-struct aiNode;
-
-namespace Assimp {
-
-using namespace MD2;
-
-// ---------------------------------------------------------------------------
-/** Importer class for MD2
-*/
-class MD2Importer : public BaseImporter
-{
-public:
- MD2Importer();
- ~MD2Importer();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
- // -------------------------------------------------------------------
- /** Validate the header of the file
- */
- void ValidateHeader();
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Header of the MD2 file */
- BE_NCONST MD2::Header* m_pcHeader;
-
- /** Buffer to hold the loaded file */
- BE_NCONST uint8_t* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/MD2NormalTable.h b/src/3rdparty/assimp/code/MD2NormalTable.h
deleted file mode 100644
index 98fbc1d7a..000000000
--- a/src/3rdparty/assimp/code/MD2NormalTable.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Slightly modified version of the anorms.h header file
- * released by ID software with the Quake 2 source code.
- *
- * Table of normals used by MD2 models
- */
-
-#ifndef AI_MDL_NORMALTABLE_H_INC
-#define AI_MDL_NORMALTABLE_H_INC
-
-
-float g_avNormals[162][3] = {
-{ -0.525731f, 0.000000f, 0.850651f },
-{ -0.442863f, 0.238856f, 0.864188f },
-{ -0.295242f, 0.000000f, 0.955423f },
-{ -0.309017f, 0.500000f, 0.809017f },
-{ -0.162460f, 0.262866f, 0.951056f },
-{ 0.000000f, 0.000000f, 1.000000f },
-{ 0.000000f, 0.850651f, 0.525731f },
-{ -0.147621f, 0.716567f, 0.681718f },
-{ 0.147621f, 0.716567f, 0.681718f },
-{ 0.000000f, 0.525731f, 0.850651f },
-{ 0.309017f, 0.500000f, 0.809017f },
-{ 0.525731f, 0.000000f, 0.850651f },
-{ 0.295242f, 0.000000f, 0.955423f },
-{ 0.442863f, 0.238856f, 0.864188f },
-{ 0.162460f, 0.262866f, 0.951056f },
-{ -0.681718f, 0.147621f, 0.716567f },
-{ -0.809017f, 0.309017f, 0.500000f },
-{ -0.587785f, 0.425325f, 0.688191f },
-{ -0.850651f, 0.525731f, 0.000000f },
-{ -0.864188f, 0.442863f, 0.238856f },
-{ -0.716567f, 0.681718f, 0.147621f },
-{ -0.688191f, 0.587785f, 0.425325f },
-{ -0.500000f, 0.809017f, 0.309017f },
-{ -0.238856f, 0.864188f, 0.442863f },
-{ -0.425325f, 0.688191f, 0.587785f },
-{ -0.716567f, 0.681718f, -0.147621f },
-{ -0.500000f, 0.809017f, -0.309017f },
-{ -0.525731f, 0.850651f, 0.000000f },
-{ 0.000000f, 0.850651f, -0.525731f },
-{ -0.238856f, 0.864188f, -0.442863f },
-{ 0.000000f, 0.955423f, -0.295242f },
-{ -0.262866f, 0.951056f, -0.162460f },
-{ 0.000000f, 1.000000f, 0.000000f },
-{ 0.000000f, 0.955423f, 0.295242f },
-{ -0.262866f, 0.951056f, 0.162460f },
-{ 0.238856f, 0.864188f, 0.442863f },
-{ 0.262866f, 0.951056f, 0.162460f },
-{ 0.500000f, 0.809017f, 0.309017f },
-{ 0.238856f, 0.864188f, -0.442863f },
-{ 0.262866f, 0.951056f, -0.162460f },
-{ 0.500000f, 0.809017f, -0.309017f },
-{ 0.850651f, 0.525731f, 0.000000f },
-{ 0.716567f, 0.681718f, 0.147621f },
-{ 0.716567f, 0.681718f, -0.147621f },
-{ 0.525731f, 0.850651f, 0.000000f },
-{ 0.425325f, 0.688191f, 0.587785f },
-{ 0.864188f, 0.442863f, 0.238856f },
-{ 0.688191f, 0.587785f, 0.425325f },
-{ 0.809017f, 0.309017f, 0.500000f },
-{ 0.681718f, 0.147621f, 0.716567f },
-{ 0.587785f, 0.425325f, 0.688191f },
-{ 0.955423f, 0.295242f, 0.000000f },
-{ 1.000000f, 0.000000f, 0.000000f },
-{ 0.951056f, 0.162460f, 0.262866f },
-{ 0.850651f, -0.525731f, 0.000000f },
-{ 0.955423f, -0.295242f, 0.000000f },
-{ 0.864188f, -0.442863f, 0.238856f },
-{ 0.951056f, -0.162460f, 0.262866f },
-{ 0.809017f, -0.309017f, 0.500000f },
-{ 0.681718f, -0.147621f, 0.716567f },
-{ 0.850651f, 0.000000f, 0.525731f },
-{ 0.864188f, 0.442863f, -0.238856f },
-{ 0.809017f, 0.309017f, -0.500000f },
-{ 0.951056f, 0.162460f, -0.262866f },
-{ 0.525731f, 0.000000f, -0.850651f },
-{ 0.681718f, 0.147621f, -0.716567f },
-{ 0.681718f, -0.147621f, -0.716567f },
-{ 0.850651f, 0.000000f, -0.525731f },
-{ 0.809017f, -0.309017f, -0.500000f },
-{ 0.864188f, -0.442863f, -0.238856f },
-{ 0.951056f, -0.162460f, -0.262866f },
-{ 0.147621f, 0.716567f, -0.681718f },
-{ 0.309017f, 0.500000f, -0.809017f },
-{ 0.425325f, 0.688191f, -0.587785f },
-{ 0.442863f, 0.238856f, -0.864188f },
-{ 0.587785f, 0.425325f, -0.688191f },
-{ 0.688191f, 0.587785f, -0.425325f },
-{ -0.147621f, 0.716567f, -0.681718f },
-{ -0.309017f, 0.500000f, -0.809017f },
-{ 0.000000f, 0.525731f, -0.850651f },
-{ -0.525731f, 0.000000f, -0.850651f },
-{ -0.442863f, 0.238856f, -0.864188f },
-{ -0.295242f, 0.000000f, -0.955423f },
-{ -0.162460f, 0.262866f, -0.951056f },
-{ 0.000000f, 0.000000f, -1.000000f },
-{ 0.295242f, 0.000000f, -0.955423f },
-{ 0.162460f, 0.262866f, -0.951056f },
-{ -0.442863f, -0.238856f, -0.864188f },
-{ -0.309017f, -0.500000f, -0.809017f },
-{ -0.162460f, -0.262866f, -0.951056f },
-{ 0.000000f, -0.850651f, -0.525731f },
-{ -0.147621f, -0.716567f, -0.681718f },
-{ 0.147621f, -0.716567f, -0.681718f },
-{ 0.000000f, -0.525731f, -0.850651f },
-{ 0.309017f, -0.500000f, -0.809017f },
-{ 0.442863f, -0.238856f, -0.864188f },
-{ 0.162460f, -0.262866f, -0.951056f },
-{ 0.238856f, -0.864188f, -0.442863f },
-{ 0.500000f, -0.809017f, -0.309017f },
-{ 0.425325f, -0.688191f, -0.587785f },
-{ 0.716567f, -0.681718f, -0.147621f },
-{ 0.688191f, -0.587785f, -0.425325f },
-{ 0.587785f, -0.425325f, -0.688191f },
-{ 0.000000f, -0.955423f, -0.295242f },
-{ 0.000000f, -1.000000f, 0.000000f },
-{ 0.262866f, -0.951056f, -0.162460f },
-{ 0.000000f, -0.850651f, 0.525731f },
-{ 0.000000f, -0.955423f, 0.295242f },
-{ 0.238856f, -0.864188f, 0.442863f },
-{ 0.262866f, -0.951056f, 0.162460f },
-{ 0.500000f, -0.809017f, 0.309017f },
-{ 0.716567f, -0.681718f, 0.147621f },
-{ 0.525731f, -0.850651f, 0.000000f },
-{ -0.238856f, -0.864188f, -0.442863f },
-{ -0.500000f, -0.809017f, -0.309017f },
-{ -0.262866f, -0.951056f, -0.162460f },
-{ -0.850651f, -0.525731f, 0.000000f },
-{ -0.716567f, -0.681718f, -0.147621f },
-{ -0.716567f, -0.681718f, 0.147621f },
-{ -0.525731f, -0.850651f, 0.000000f },
-{ -0.500000f, -0.809017f, 0.309017f },
-{ -0.238856f, -0.864188f, 0.442863f },
-{ -0.262866f, -0.951056f, 0.162460f },
-{ -0.864188f, -0.442863f, 0.238856f },
-{ -0.809017f, -0.309017f, 0.500000f },
-{ -0.688191f, -0.587785f, 0.425325f },
-{ -0.681718f, -0.147621f, 0.716567f },
-{ -0.442863f, -0.238856f, 0.864188f },
-{ -0.587785f, -0.425325f, 0.688191f },
-{ -0.309017f, -0.500000f, 0.809017f },
-{ -0.147621f, -0.716567f, 0.681718f },
-{ -0.425325f, -0.688191f, 0.587785f },
-{ -0.162460f, -0.262866f, 0.951056f },
-{ 0.442863f, -0.238856f, 0.864188f },
-{ 0.162460f, -0.262866f, 0.951056f },
-{ 0.309017f, -0.500000f, 0.809017f },
-{ 0.147621f, -0.716567f, 0.681718f },
-{ 0.000000f, -0.525731f, 0.850651f },
-{ 0.425325f, -0.688191f, 0.587785f },
-{ 0.587785f, -0.425325f, 0.688191f },
-{ 0.688191f, -0.587785f, 0.425325f },
-{ -0.955423f, 0.295242f, 0.000000f },
-{ -0.951056f, 0.162460f, 0.262866f },
-{ -1.000000f, 0.000000f, 0.000000f },
-{ -0.850651f, 0.000000f, 0.525731f },
-{ -0.955423f, -0.295242f, 0.000000f },
-{ -0.951056f, -0.162460f, 0.262866f },
-{ -0.864188f, 0.442863f, -0.238856f },
-{ -0.951056f, 0.162460f, -0.262866f },
-{ -0.809017f, 0.309017f, -0.500000f },
-{ -0.864188f, -0.442863f, -0.238856f },
-{ -0.951056f, -0.162460f, -0.262866f },
-{ -0.809017f, -0.309017f, -0.500000f },
-{ -0.681718f, 0.147621f, -0.716567f },
-{ -0.681718f, -0.147621f, -0.716567f },
-{ -0.850651f, 0.000000f, -0.525731f },
-{ -0.688191f, 0.587785f, -0.425325f },
-{ -0.587785f, 0.425325f, -0.688191f },
-{ -0.425325f, 0.688191f, -0.587785f },
-{ -0.425325f, -0.688191f, -0.587785f },
-{ -0.587785f, -0.425325f, -0.688191f },
-{ -0.688191f, -0.587785f, -0.425325f }
-};
-
-#endif // !! include guard
diff --git a/src/3rdparty/assimp/code/MD3FileData.h b/src/3rdparty/assimp/code/MD3FileData.h
deleted file mode 100644
index 19740c30e..000000000
--- a/src/3rdparty/assimp/code/MD3FileData.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Md3FileData.h
- *
- * @brief Defines helper data structures for importing MD3 files.
- * http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
- */
-#ifndef AI_MD3FILEHELPER_H_INC
-#define AI_MD3FILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-#include <sstream>
-#include <stdint.h>
-
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-#include <assimp/anim.h>
-
-#include <assimp/Compiler/pushpack1.h>
-
-namespace Assimp {
-namespace MD3 {
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MD3_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDP3")
-#define AI_MD3_MAGIC_NUMBER_LE AI_MAKE_MAGIC("3PDI")
-
-// common limitations
-#define AI_MD3_VERSION 15
-#define AI_MD3_MAXQPATH 64
-#define AI_MD3_MAXFRAME 16
-#define AI_MD3_MAX_FRAMES 1024
-#define AI_MD3_MAX_TAGS 16
-#define AI_MD3_MAX_SURFACES 32
-#define AI_MD3_MAX_SHADERS 256
-#define AI_MD3_MAX_VERTS 4096
-#define AI_MD3_MAX_TRIANGLES 8192
-
-// master scale factor for all vertices in a MD3 model
-#define AI_MD3_XYZ_SCALE (1.0f/64.0f)
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the MD3 main header
- */
-struct Header
-{
- //! magic number
- uint32_t IDENT;
-
- //! file format version
- uint32_t VERSION;
-
- //! original name in .pak archive
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! unknown
- int32_t FLAGS;
-
- //! number of frames in the file
- uint32_t NUM_FRAMES;
-
- //! number of tags in the file
- uint32_t NUM_TAGS;
-
- //! number of surfaces in the file
- uint32_t NUM_SURFACES;
-
- //! number of skins in the file
- uint32_t NUM_SKINS;
-
- //! offset of the first frame
- uint32_t OFS_FRAMES;
-
- //! offset of the first tag
- uint32_t OFS_TAGS;
-
- //! offset of the first surface
- uint32_t OFS_SURFACES;
-
- //! end of file
- uint32_t OFS_EOF;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the frame header
- */
-struct Frame
-{
- //! minimum bounds
- aiVector3D min;
-
- //! maximum bounds
- aiVector3D max;
-
- //! local origin for this frame
- aiVector3D origin;
-
- //! radius of bounding sphere
- ai_real radius;
-
- //! name of frame
- char name[ AI_MD3_MAXFRAME ];
-
-} /* PACK_STRUCT */;
-
-
-// -------------------------------------------------------------------------------
-/**
- * @brief Data structure for the tag header
- */
-struct Tag {
- //! name of the tag
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! Local tag origin and orientation
- aiVector3D origin;
- ai_real orientation[3][3];
-
-} /* PACK_STRUCT */;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for the surface header
- */
-struct Surface {
- //! magic number
- int32_t IDENT;
-
- //! original name of the surface
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! unknown
- int32_t FLAGS;
-
- //! number of frames in the surface
- uint32_t NUM_FRAMES;
-
- //! number of shaders in the surface
- uint32_t NUM_SHADER;
-
- //! number of vertices in the surface
- uint32_t NUM_VERTICES;
-
- //! number of triangles in the surface
- uint32_t NUM_TRIANGLES;
-
- //! offset to the triangle data
- uint32_t OFS_TRIANGLES;
-
- //! offset to the shader data
- uint32_t OFS_SHADERS;
-
- //! offset to the texture coordinate data
- uint32_t OFS_ST;
-
- //! offset to the vertex/normal data
- uint32_t OFS_XYZNORMAL;
-
- //! offset to the end of the Surface object
- int32_t OFS_END;
-} /*PACK_STRUCT*/;
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a shader defined in there
- */
-struct Shader {
- //! filename of the shader
- char NAME[ AI_MD3_MAXQPATH ];
-
- //! index of the shader
- uint32_t SHADER_INDEX;
-} /*PACK_STRUCT*/;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a triangle
- */
-struct Triangle
-{
- //! triangle indices
- uint32_t INDEXES[3];
-} /*PACK_STRUCT*/;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for an UV coord
- */
-struct TexCoord
-{
- //! UV coordinates
- ai_real U,V;
-} /*PACK_STRUCT*/;
-
-
-// -------------------------------------------------------------------------------
-/** @brief Data structure for a vertex
- */
-struct Vertex
-{
- //! X/Y/Z coordinates
- int16_t X,Y,Z;
-
- //! encoded normal vector
- uint16_t NORMAL;
-} /*PACK_STRUCT*/;
-
-#include "./../include/assimp/Compiler/poppack1.h"
-
-// -------------------------------------------------------------------------------
-/** @brief Unpack a Q3 16 bit vector to its full float3 representation
- *
- * @param p_iNormal Input normal vector in latitude/longitude form
- * @param p_afOut Pointer to an array of three floats to receive the result
- *
- * @note This has been taken from q3 source (misc_model.c)
- */
-inline void LatLngNormalToVec3(uint16_t p_iNormal, ai_real* p_afOut)
-{
- ai_real lat = (ai_real)(( p_iNormal >> 8u ) & 0xff);
- ai_real lng = (ai_real)(( p_iNormal & 0xff ));
- const ai_real invVal( ai_real( 1.0 ) / ai_real( 128.0 ) );
- lat *= ai_real( 3.141926 ) * invVal;
- lng *= ai_real( 3.141926 ) * invVal;
-
- p_afOut[ 0 ] = std::cos(lat) * std::sin(lng);
- p_afOut[ 1 ] = std::sin(lat) * std::sin(lng);
- p_afOut[ 2 ] = std::cos(lng);
-}
-
-
-// -------------------------------------------------------------------------------
-/** @brief Pack a Q3 normal into 16bit latitute/longitude representation
- * @param p_vIn Input vector
- * @param p_iOut Output normal
- *
- * @note This has been taken from q3 source (mathlib.c)
- */
-inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
-{
- // check for singularities
- if ( 0.0f == p_vIn[0] && 0.0f == p_vIn[1] )
- {
- if ( p_vIn[2] > 0.0f )
- {
- ((unsigned char*)&p_iOut)[0] = 0;
- ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 0
- }
- else
- {
- ((unsigned char*)&p_iOut)[0] = 128;
- ((unsigned char*)&p_iOut)[1] = 0; // lat = 0, long = 128
- }
- }
- else
- {
- int a, b;
-
- a = int(57.2957795f * ( std::atan2( p_vIn[1], p_vIn[0] ) ) * (255.0f / 360.0f ));
- a &= 0xff;
-
- b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
- b &= 0xff;
-
- ((unsigned char*)&p_iOut)[0] = b; // longitude
- ((unsigned char*)&p_iOut)[1] = a; // latitude
- }
-}
-
-}
-}
-
-#endif // !! AI_MD3FILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/MD3Loader.cpp b/src/3rdparty/assimp/code/MD3Loader.cpp
deleted file mode 100644
index 11a6e56dd..000000000
--- a/src/3rdparty/assimp/code/MD3Loader.cpp
+++ /dev/null
@@ -1,1094 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD3Loader.cpp
- * @brief Implementation of the MD3 importer class
- *
- * Sources:
- * http://www.gamers.org/dEngine/quake3/UQ3S
- * http://linux.ucla.edu/~phaethon/q3/formats/md3format.html
- * http://www.heppler.com/shader/shader/
- */
-
-
-#ifndef ASSIMP_BUILD_NO_MD3_IMPORTER
-
-#include "MD3Loader.h"
-#include <assimp/SceneCombiner.h>
-#include "GenericProperty.h"
-#include "RemoveComments.h"
-#include "ParsingUtils.h"
-#include "Importer.h"
-#include <assimp/DefaultLogger.hpp>
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include <cctype>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Quake III Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "md3"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Convert a Q3 shader blend function to the appropriate enum value
-Q3Shader::BlendFunc StringToBlendFunc(const std::string& m)
-{
- if (m == "GL_ONE") {
- return Q3Shader::BLEND_GL_ONE;
- }
- if (m == "GL_ZERO") {
- return Q3Shader::BLEND_GL_ZERO;
- }
- if (m == "GL_SRC_ALPHA") {
- return Q3Shader::BLEND_GL_SRC_ALPHA;
- }
- if (m == "GL_ONE_MINUS_SRC_ALPHA") {
- return Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
- }
- if (m == "GL_ONE_MINUS_DST_COLOR") {
- return Q3Shader::BLEND_GL_ONE_MINUS_DST_COLOR;
- }
- DefaultLogger::get()->error("Q3Shader: Unknown blend function: " + m);
- return Q3Shader::BLEND_NONE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a Quake 3 shader
-bool Q3Shader::LoadShader(ShaderData& fill, const std::string& pFile,IOSystem* io)
-{
- std::unique_ptr<IOStream> file( io->Open( pFile, "rt"));
- if (!file.get())
- return false; // if we can't access the file, don't worry and return
-
- DefaultLogger::get()->info("Loading Quake3 shader file " + pFile);
-
- // read file in memory
- const size_t s = file->FileSize();
- std::vector<char> _buff(s+1);
- file->Read(&_buff[0],s,1);
- _buff[s] = 0;
-
- // remove comments from it (C++ style)
- CommentRemover::RemoveLineComments("//",&_buff[0]);
- const char* buff = &_buff[0];
-
- Q3Shader::ShaderDataBlock* curData = NULL;
- Q3Shader::ShaderMapBlock* curMap = NULL;
-
- // read line per line
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
-
- if (*buff == '{') {
- ++buff;
-
- // append to last section, if any
- if (!curData) {
- DefaultLogger::get()->error("Q3Shader: Unexpected shader section token \'{\'");
- return true; // still no failure, the file is there
- }
-
- // read this data section
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
- if (*buff == '{') {
- ++buff;
- // add new map section
- curData->maps.push_back(Q3Shader::ShaderMapBlock());
- curMap = &curData->maps.back();
-
- for (;SkipSpacesAndLineEnd(&buff);SkipLine(&buff)) {
- // 'map' - Specifies texture file name
- if (TokenMatchI(buff,"map",3) || TokenMatchI(buff,"clampmap",8)) {
- curMap->name = GetNextToken(buff);
- }
- // 'blendfunc' - Alpha blending mode
- else if (TokenMatchI(buff,"blendfunc",9)) {
- const std::string blend_src = GetNextToken(buff);
- if (blend_src == "add") {
- curMap->blend_src = Q3Shader::BLEND_GL_ONE;
- curMap->blend_dest = Q3Shader::BLEND_GL_ONE;
- }
- else if (blend_src == "filter") {
- curMap->blend_src = Q3Shader::BLEND_GL_DST_COLOR;
- curMap->blend_dest = Q3Shader::BLEND_GL_ZERO;
- }
- else if (blend_src == "blend") {
- curMap->blend_src = Q3Shader::BLEND_GL_SRC_ALPHA;
- curMap->blend_dest = Q3Shader::BLEND_GL_ONE_MINUS_SRC_ALPHA;
- }
- else {
- curMap->blend_src = StringToBlendFunc(blend_src);
- curMap->blend_dest = StringToBlendFunc(GetNextToken(buff));
- }
- }
- // 'alphafunc' - Alpha testing mode
- else if (TokenMatchI(buff,"alphafunc",9)) {
- const std::string at = GetNextToken(buff);
- if (at == "GT0") {
- curMap->alpha_test = Q3Shader::AT_GT0;
- }
- else if (at == "LT128") {
- curMap->alpha_test = Q3Shader::AT_LT128;
- }
- else if (at == "GE128") {
- curMap->alpha_test = Q3Shader::AT_GE128;
- }
- }
- else if (*buff == '}') {
- ++buff;
- // close this map section
- curMap = NULL;
- break;
- }
- }
-
- }
- else if (*buff == '}') {
- ++buff;
- curData = NULL;
- break;
- }
-
- // 'cull' specifies culling behaviour for the model
- else if (TokenMatchI(buff,"cull",4)) {
- SkipSpaces(&buff);
- if (!ASSIMP_strincmp(buff,"back",4)) {
- curData->cull = Q3Shader::CULL_CCW;
- }
- else if (!ASSIMP_strincmp(buff,"front",5)) {
- curData->cull = Q3Shader::CULL_CW;
- }
- else if (!ASSIMP_strincmp(buff,"none",4) || !ASSIMP_strincmp(buff,"disable",7)) {
- curData->cull = Q3Shader::CULL_NONE;
- }
- else DefaultLogger::get()->error("Q3Shader: Unrecognized cull mode");
- }
- }
- }
-
- else {
- // add new section
- fill.blocks.push_back(Q3Shader::ShaderDataBlock());
- curData = &fill.blocks.back();
-
- // get the name of this section
- curData->name = GetNextToken(buff);
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a Quake 3 skin
-bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
-{
- std::unique_ptr<IOStream> file( io->Open( pFile, "rt"));
- if (!file.get())
- return false; // if we can't access the file, don't worry and return
-
- DefaultLogger::get()->info("Loading Quake3 skin file " + pFile);
-
- // read file in memory
- const size_t s = file->FileSize();
- std::vector<char> _buff(s+1);const char* buff = &_buff[0];
- file->Read(&_buff[0],s,1);
- _buff[s] = 0;
-
- // remove commas
- std::replace(_buff.begin(),_buff.end(),',',' ');
-
- // read token by token and fill output table
- for (;*buff;) {
- SkipSpacesAndLineEnd(&buff);
-
- // get first identifier
- std::string ss = GetNextToken(buff);
-
- // ignore tokens starting with tag_
- if (!::strncmp(&ss[0],"tag_",std::min((size_t)4, ss.length())))
- continue;
-
- fill.textures.push_back(SkinData::TextureEntry());
- SkinData::TextureEntry& s = fill.textures.back();
-
- s.first = ss;
- s.second = GetNextToken(buff);
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert Q3Shader to material
-void Q3Shader::ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader)
-{
- ai_assert(NULL != out);
-
- /* IMPORTANT: This is not a real conversion. Actually we're just guessing and
- * hacking around to build an aiMaterial that looks nearly equal to the
- * original Quake 3 shader. We're missing some important features like
- * animatable material properties in our material system, but at least
- * multiple textures should be handled correctly.
- */
-
- // Two-sided material?
- if (shader.cull == Q3Shader::CULL_NONE) {
- const int twosided = 1;
- out->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
- }
-
- unsigned int cur_emissive = 0, cur_diffuse = 0, cur_lm =0;
-
- // Iterate through all textures
- for (std::list< Q3Shader::ShaderMapBlock >::const_iterator it = shader.maps.begin(); it != shader.maps.end();++it) {
-
- // CONVERSION BEHAVIOUR:
- //
- //
- // If the texture is additive
- // - if it is the first texture, assume additive blending for the whole material
- // - otherwise register it as emissive texture.
- //
- // If the texture is using standard blend (or if the blend mode is unknown)
- // - if first texture: assume default blending for material
- // - in any case: set it as diffuse texture
- //
- // If the texture is using 'filter' blending
- // - take as lightmap
- //
- // Textures with alpha funcs
- // - aiTextureFlags_UseAlpha is set (otherwise aiTextureFlags_NoAlpha is explicitly set)
- aiString s((*it).name);
- aiTextureType type; unsigned int index;
-
- if ((*it).blend_src == Q3Shader::BLEND_GL_ONE && (*it).blend_dest == Q3Shader::BLEND_GL_ONE) {
- if (it == shader.maps.begin()) {
- const int additive = aiBlendMode_Additive;
- out->AddProperty(&additive,1,AI_MATKEY_BLEND_FUNC);
-
- index = cur_diffuse++;
- type = aiTextureType_DIFFUSE;
- }
- else {
- index = cur_emissive++;
- type = aiTextureType_EMISSIVE;
- }
- }
- else if ((*it).blend_src == Q3Shader::BLEND_GL_DST_COLOR && (*it).blend_dest == Q3Shader::BLEND_GL_ZERO) {
- index = cur_lm++;
- type = aiTextureType_LIGHTMAP;
- }
- else {
- const int blend = aiBlendMode_Default;
- out->AddProperty(&blend,1,AI_MATKEY_BLEND_FUNC);
-
- index = cur_diffuse++;
- type = aiTextureType_DIFFUSE;
- }
-
- // setup texture
- out->AddProperty(&s,AI_MATKEY_TEXTURE(type,index));
-
- // setup texture flags
- const int use_alpha = ((*it).alpha_test != Q3Shader::AT_NONE ? aiTextureFlags_UseAlpha : aiTextureFlags_IgnoreAlpha);
- out->AddProperty(&use_alpha,1,AI_MATKEY_TEXFLAGS(type,index));
- }
- // If at least one emissive texture was set, set the emissive base color to 1 to ensure
- // the texture is actually displayed.
- if (0 != cur_emissive) {
- aiColor3D one(1.f,1.f,1.f);
- out->AddProperty(&one,1,AI_MATKEY_COLOR_EMISSIVE);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD3Importer::MD3Importer()
- : configFrameID (0)
- , configHandleMP (true)
- , configSpeedFlag()
- , pcHeader()
- , mBuffer()
- , fileSize()
- , mScene()
- , mIOHandler()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD3Importer::~MD3Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD3Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "md3")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MD3_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MD3Importer::ValidateHeaderOffsets()
-{
- // Check magic number
- if (pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_BE &&
- pcHeader->IDENT != AI_MD3_MAGIC_NUMBER_LE)
- throw DeadlyImportError( "Invalid MD3 file: Magic bytes not found");
-
- // Check file format version
- if (pcHeader->VERSION > 15)
- DefaultLogger::get()->warn( "Unsupported MD3 file version. Continuing happily ...");
-
- // Check some offset values whether they are valid
- if (!pcHeader->NUM_SURFACES)
- throw DeadlyImportError( "Invalid md3 file: NUM_SURFACES is 0");
-
- if (pcHeader->OFS_FRAMES >= fileSize || pcHeader->OFS_SURFACES >= fileSize ||
- pcHeader->OFS_EOF > fileSize) {
- throw DeadlyImportError("Invalid MD3 header: some offsets are outside the file");
- }
-
- if (pcHeader->NUM_SURFACES > AI_MAX_ALLOC(MD3::Surface)) {
- throw DeadlyImportError("Invalid MD3 header: too many surfaces, would overflow");
- }
-
- if (pcHeader->OFS_SURFACES + pcHeader->NUM_SURFACES * sizeof(MD3::Surface) >= fileSize) {
- throw DeadlyImportError("Invalid MD3 header: some surfaces are outside the file");
- }
-
- if (pcHeader->NUM_FRAMES <= configFrameID )
- throw DeadlyImportError("The requested frame is not existing the file");
-}
-
-// ------------------------------------------------------------------------------------------------
-void MD3Importer::ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurf)
-{
- // Calculate the relative offset of the surface
- const int32_t ofs = int32_t((const unsigned char*)pcSurf-this->mBuffer);
-
- // Check whether all data chunks are inside the valid range
- if (pcSurf->OFS_TRIANGLES + ofs + pcSurf->NUM_TRIANGLES * sizeof(MD3::Triangle) > fileSize ||
- pcSurf->OFS_SHADERS + ofs + pcSurf->NUM_SHADER * sizeof(MD3::Shader) > fileSize ||
- pcSurf->OFS_ST + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::TexCoord) > fileSize ||
- pcSurf->OFS_XYZNORMAL + ofs + pcSurf->NUM_VERTICES * sizeof(MD3::Vertex) > fileSize) {
-
- throw DeadlyImportError("Invalid MD3 surface header: some offsets are outside the file");
- }
-
- // Check whether all requirements for Q3 files are met. We don't
- // care, but probably someone does.
- if (pcSurf->NUM_TRIANGLES > AI_MD3_MAX_TRIANGLES) {
- DefaultLogger::get()->warn("MD3: Quake III triangle limit exceeded");
- }
-
- if (pcSurf->NUM_SHADER > AI_MD3_MAX_SHADERS) {
- DefaultLogger::get()->warn("MD3: Quake III shader limit exceeded");
- }
-
- if (pcSurf->NUM_VERTICES > AI_MD3_MAX_VERTS) {
- DefaultLogger::get()->warn("MD3: Quake III vertex limit exceeded");
- }
-
- if (pcSurf->NUM_FRAMES > AI_MD3_MAX_FRAMES) {
- DefaultLogger::get()->warn("MD3: Quake III frame limit exceeded");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* MD3Importer::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MD3Importer::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_MD3_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_KEYFRAME,-1);
- if(static_cast<unsigned int>(-1) == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART
- configHandleMP = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART,1));
-
- // AI_CONFIG_IMPORT_MD3_SKIN_NAME
- configSkinFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SKIN_NAME,"default"));
-
- // AI_CONFIG_IMPORT_MD3_SHADER_SRC
- configShaderFile = (pImp->GetPropertyString(AI_CONFIG_IMPORT_MD3_SHADER_SRC,""));
-
- // AI_CONFIG_FAVOUR_SPEED
- configSpeedFlag = (0 != pImp->GetPropertyInteger(AI_CONFIG_FAVOUR_SPEED,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to read the skin for a MD3 file
-void MD3Importer::ReadSkin(Q3Shader::SkinData& fill) const
-{
- // skip any postfixes (e.g. lower_1.md3)
- std::string::size_type s = filename.find_last_of('_');
- if (s == std::string::npos) {
- s = filename.find_last_of('.');
- if (s == std::string::npos) {
- s = filename.size();
- }
- }
- ai_assert(s != std::string::npos);
-
- const std::string skin_file = path + filename.substr(0,s) + "_" + configSkinFile + ".skin";
- Q3Shader::LoadSkin(fill,skin_file,mIOHandler);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to read the shader for a MD3 file
-void MD3Importer::ReadShader(Q3Shader::ShaderData& fill) const
-{
- // Determine Q3 model name from given path
- const std::string::size_type s = path.find_last_of("\\/",path.length()-2);
- const std::string model_file = path.substr(s+1,path.length()-(s+2));
-
- // If no specific dir or file is given, use our default search behaviour
- if (!configShaderFile.length()) {
- if(!Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + model_file + ".shader",mIOHandler)) {
- Q3Shader::LoadShader(fill,path + "..\\..\\..\\scripts\\" + filename + ".shader",mIOHandler);
- }
- }
- else {
- // If the given string specifies a file, load this file.
- // Otherwise it's a directory.
- const std::string::size_type st = configShaderFile.find_last_of('.');
- if (st == std::string::npos) {
-
- if(!Q3Shader::LoadShader(fill,configShaderFile + model_file + ".shader",mIOHandler)) {
- Q3Shader::LoadShader(fill,configShaderFile + filename + ".shader",mIOHandler);
- }
- }
- else {
- Q3Shader::LoadShader(fill,configShaderFile,mIOHandler);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Tiny helper to remove a single node from its parent' list
-void RemoveSingleNodeFromList(aiNode* nd)
-{
- if (!nd || nd->mNumChildren || !nd->mParent)return;
- aiNode* par = nd->mParent;
- for (unsigned int i = 0; i < par->mNumChildren;++i) {
- if (par->mChildren[i] == nd) {
- --par->mNumChildren;
- for (;i < par->mNumChildren;++i) {
- par->mChildren[i] = par->mChildren[i+1];
- }
- delete nd;
- break;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a multi-part Q3 player model
-bool MD3Importer::ReadMultipartFile()
-{
- // check whether the file name contains a common postfix, e.g lower_2.md3
- std::string::size_type s = filename.find_last_of('_'), t = filename.find_last_of('.');
-
- if (t == std::string::npos)
- t = filename.size();
- if (s == std::string::npos)
- s = t;
-
- const std::string mod_filename = filename.substr(0,s);
- const std::string suffix = filename.substr(s,t-s);
-
- if (mod_filename == "lower" || mod_filename == "upper" || mod_filename == "head"){
- const std::string lower = path + "lower" + suffix + ".md3";
- const std::string upper = path + "upper" + suffix + ".md3";
- const std::string head = path + "head" + suffix + ".md3";
-
- aiScene* scene_upper = NULL;
- aiScene* scene_lower = NULL;
- aiScene* scene_head = NULL;
- std::string failure;
-
- aiNode* tag_torso, *tag_head;
- std::vector<AttachmentInfo> attach;
-
- DefaultLogger::get()->info("Multi part MD3 player model: lower, upper and head parts are joined");
-
- // ensure we won't try to load ourselves recursively
- BatchLoader::PropertyMap props;
- SetGenericProperty( props.ints, AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART, 0);
-
- // now read these three files
- BatchLoader batch(mIOHandler);
- const unsigned int _lower = batch.AddLoadRequest(lower,0,&props);
- const unsigned int _upper = batch.AddLoadRequest(upper,0,&props);
- const unsigned int _head = batch.AddLoadRequest(head,0,&props);
- batch.LoadAll();
-
- // now construct a dummy scene to place these three parts in
- aiScene* master = new aiScene();
- aiNode* nd = master->mRootNode = new aiNode();
- nd->mName.Set("<MD3_Player>");
-
- // ... and get them. We need all of them.
- scene_lower = batch.GetImport(_lower);
- if (!scene_lower) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, lower.md3 fails to load");
- failure = "lower";
- goto error_cleanup;
- }
-
- scene_upper = batch.GetImport(_upper);
- if (!scene_upper) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, upper.md3 fails to load");
- failure = "upper";
- goto error_cleanup;
- }
-
- scene_head = batch.GetImport(_head);
- if (!scene_head) {
- DefaultLogger::get()->error("M3D: Failed to read multi part model, head.md3 fails to load");
- failure = "head";
- goto error_cleanup;
- }
-
- // build attachment infos. search for typical Q3 tags
-
- // original root
- scene_lower->mRootNode->mName.Set("lower");
- attach.push_back(AttachmentInfo(scene_lower, nd));
-
- // tag_torso
- tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
- if (!tag_torso) {
- DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_torso expected");
- goto error_cleanup;
- }
- scene_upper->mRootNode->mName.Set("upper");
- attach.push_back(AttachmentInfo(scene_upper,tag_torso));
-
- // tag_head
- tag_head = scene_upper->mRootNode->FindNode("tag_head");
- if (!tag_head) {
- DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_head expected");
- goto error_cleanup;
- }
- scene_head->mRootNode->mName.Set("head");
- attach.push_back(AttachmentInfo(scene_head,tag_head));
-
- // Remove tag_head and tag_torso from all other model parts ...
- // this ensures (together with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY)
- // that tag_torso/tag_head is also the name of the (unique) output node
- RemoveSingleNodeFromList (scene_upper->mRootNode->FindNode("tag_torso"));
- RemoveSingleNodeFromList (scene_head-> mRootNode->FindNode("tag_head" ));
-
- // Undo the rotations which we applied to the coordinate systems. We're
- // working in global Quake space here
- scene_head->mRootNode->mTransformation = aiMatrix4x4();
- scene_lower->mRootNode->mTransformation = aiMatrix4x4();
- scene_upper->mRootNode->mTransformation = aiMatrix4x4();
-
- // and merge the scenes
- SceneCombiner::MergeScenes(&mScene,master, attach,
- AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES |
- AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES |
- AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS |
- (!configSpeedFlag ? AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY : 0));
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- mScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- return true;
-
-error_cleanup:
- delete scene_upper;
- delete scene_lower;
- delete scene_head;
- delete master;
-
- if (failure == mod_filename) {
- throw DeadlyImportError("MD3: failure to read multipart host file");
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Convert a MD3 path to a proper value
-void MD3Importer::ConvertPath(const char* texture_name, const char* header_name, std::string& out) const
-{
- // If the MD3's internal path itself and the given path are using
- // the same directory, remove it completely to get right output paths.
- const char* end1 = ::strrchr(header_name,'\\');
- if (!end1)end1 = ::strrchr(header_name,'/');
-
- const char* end2 = ::strrchr(texture_name,'\\');
- if (!end2)end2 = ::strrchr(texture_name,'/');
-
- // HACK: If the paths starts with "models", ignore the
- // next two hierarchy levels, it specifies just the model name.
- // Ignored by Q3, it might be not equal to the real model location.
- if (end2) {
-
- size_t len2;
- const size_t len1 = (size_t)(end1 - header_name);
- if (!ASSIMP_strincmp(texture_name,"models",6) && (texture_name[6] == '/' || texture_name[6] == '\\')) {
- len2 = 6; // ignore the seventh - could be slash or backslash
-
- if (!header_name[0]) {
- // Use the file name only
- out = end2+1;
- return;
- }
- }
- else len2 = std::min (len1, (size_t)(end2 - texture_name ));
- if (!ASSIMP_strincmp(texture_name,header_name,static_cast<unsigned int>(len2))) {
- // Use the file name only
- out = end2+1;
- return;
- }
- }
- // Use the full path
- out = texture_name;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD3Importer::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- mFile = pFile;
- mScene = pScene;
- mIOHandler = pIOHandler;
-
- // get base path and file name
- // todo ... move to PathConverter
- std::string::size_type s = mFile.find_last_of("/\\");
- if (s == std::string::npos) {
- s = 0;
- }
- else ++s;
- filename = mFile.substr(s), path = mFile.substr(0,s);
- for( std::string::iterator it = filename .begin(); it != filename.end(); ++it)
- *it = tolower( *it);
-
- // Load multi-part model file, if necessary
- if (configHandleMP) {
- if (ReadMultipartFile())
- return;
- }
-
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MD3 file " + pFile + ".");
-
- // Check whether the md3 file is large enough to contain the header
- fileSize = (unsigned int)file->FileSize();
- if( fileSize < sizeof(MD3::Header))
- throw DeadlyImportError( "MD3 File is too small.");
-
- // Allocate storage and copy the contents of the file to a memory buffer
- std::vector<unsigned char> mBuffer2 (fileSize);
- file->Read( &mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
- pcHeader = (BE_NCONST MD3::Header*)mBuffer;
-
- // Ensure correct endianness
-#ifdef AI_BUILD_BIG_ENDIAN
-
- AI_SWAP4(pcHeader->VERSION);
- AI_SWAP4(pcHeader->FLAGS);
- AI_SWAP4(pcHeader->IDENT);
- AI_SWAP4(pcHeader->NUM_FRAMES);
- AI_SWAP4(pcHeader->NUM_SKINS);
- AI_SWAP4(pcHeader->NUM_SURFACES);
- AI_SWAP4(pcHeader->NUM_TAGS);
- AI_SWAP4(pcHeader->OFS_EOF);
- AI_SWAP4(pcHeader->OFS_FRAMES);
- AI_SWAP4(pcHeader->OFS_SURFACES);
- AI_SWAP4(pcHeader->OFS_TAGS);
-
-#endif
-
- // Validate the file header
- ValidateHeaderOffsets();
-
- // Navigate to the list of surfaces
- BE_NCONST MD3::Surface* pcSurfaces = (BE_NCONST MD3::Surface*)(mBuffer + pcHeader->OFS_SURFACES);
-
- // Navigate to the list of tags
- BE_NCONST MD3::Tag* pcTags = (BE_NCONST MD3::Tag*)(mBuffer + pcHeader->OFS_TAGS);
-
- // Allocate output storage
- pScene->mNumMeshes = pcHeader->NUM_SURFACES;
- if (pcHeader->NUM_SURFACES == 0) {
- throw DeadlyImportError("MD3: No surfaces");
- } else if (pcHeader->NUM_SURFACES > AI_MAX_ALLOC(aiMesh)) {
- // We allocate pointers but check against the size of aiMesh
- // since those pointers will eventually have to point to real objects
- throw DeadlyImportError("MD3: Too many surfaces, would run out of memory");
- }
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- pScene->mNumMaterials = pcHeader->NUM_SURFACES;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
-
- // Set arrays to zero to ensue proper destruction if an exception is raised
- ::memset(pScene->mMeshes,0,pScene->mNumMeshes*sizeof(aiMesh*));
- ::memset(pScene->mMaterials,0,pScene->mNumMaterials*sizeof(aiMaterial*));
-
- // Now read possible skins from .skin file
- Q3Shader::SkinData skins;
- ReadSkin(skins);
-
- // And check whether we can locate a shader file for this model
- Q3Shader::ShaderData shaders;
- ReadShader(shaders);
-
- // Adjust all texture paths in the shader
- const char* header_name = pcHeader->NAME;
- if (!shaders.blocks.empty()) {
- for (std::list< Q3Shader::ShaderDataBlock >::iterator dit = shaders.blocks.begin(); dit != shaders.blocks.end(); ++dit) {
- ConvertPath((*dit).name.c_str(),header_name,(*dit).name);
-
- for (std::list< Q3Shader::ShaderMapBlock >::iterator mit = (*dit).maps.begin(); mit != (*dit).maps.end(); ++mit) {
- ConvertPath((*mit).name.c_str(),header_name,(*mit).name);
- }
- }
- }
-
- // Read all surfaces from the file
- unsigned int iNum = pcHeader->NUM_SURFACES;
- unsigned int iNumMaterials = 0;
- while (iNum-- > 0) {
-
- // Ensure correct endianness
-#ifdef AI_BUILD_BIG_ENDIAN
-
- AI_SWAP4(pcSurfaces->FLAGS);
- AI_SWAP4(pcSurfaces->IDENT);
- AI_SWAP4(pcSurfaces->NUM_FRAMES);
- AI_SWAP4(pcSurfaces->NUM_SHADER);
- AI_SWAP4(pcSurfaces->NUM_TRIANGLES);
- AI_SWAP4(pcSurfaces->NUM_VERTICES);
- AI_SWAP4(pcSurfaces->OFS_END);
- AI_SWAP4(pcSurfaces->OFS_SHADERS);
- AI_SWAP4(pcSurfaces->OFS_ST);
- AI_SWAP4(pcSurfaces->OFS_TRIANGLES);
- AI_SWAP4(pcSurfaces->OFS_XYZNORMAL);
-
-#endif
-
- // Validate the surface header
- ValidateSurfaceHeaderOffsets(pcSurfaces);
-
- // Navigate to the vertex list of the surface
- BE_NCONST MD3::Vertex* pcVertices = (BE_NCONST MD3::Vertex*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_XYZNORMAL);
-
- // Navigate to the triangle list of the surface
- BE_NCONST MD3::Triangle* pcTriangles = (BE_NCONST MD3::Triangle*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_TRIANGLES);
-
- // Navigate to the texture coordinate list of the surface
- BE_NCONST MD3::TexCoord* pcUVs = (BE_NCONST MD3::TexCoord*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_ST);
-
- // Navigate to the shader list of the surface
- BE_NCONST MD3::Shader* pcShaders = (BE_NCONST MD3::Shader*)
- (((uint8_t*)pcSurfaces) + pcSurfaces->OFS_SHADERS);
-
- // If the submesh is empty ignore it
- if (0 == pcSurfaces->NUM_VERTICES || 0 == pcSurfaces->NUM_TRIANGLES)
- {
- pcSurfaces = (BE_NCONST MD3::Surface*)(((uint8_t*)pcSurfaces) + pcSurfaces->OFS_END);
- pScene->mNumMeshes--;
- continue;
- }
-
- // Allocate output mesh
- pScene->mMeshes[iNum] = new aiMesh();
- aiMesh* pcMesh = pScene->mMeshes[iNum];
-
- std::string _texture_name;
- const char* texture_name = NULL;
-
- // Check whether we have a texture record for this surface in the .skin file
- std::list< Q3Shader::SkinData::TextureEntry >::iterator it = std::find(
- skins.textures.begin(), skins.textures.end(), pcSurfaces->NAME );
-
- if (it != skins.textures.end()) {
- texture_name = &*( _texture_name = (*it).second).begin();
- DefaultLogger::get()->debug("MD3: Assigning skin texture " + (*it).second + " to surface " + pcSurfaces->NAME);
- (*it).resolved = true; // mark entry as resolved
- }
-
- // Get the first shader (= texture?) assigned to the surface
- if (!texture_name && pcSurfaces->NUM_SHADER) {
- texture_name = pcShaders->NAME;
- }
-
- std::string convertedPath;
- if (texture_name) {
- ConvertPath(texture_name,header_name,convertedPath);
- }
-
- const Q3Shader::ShaderDataBlock* shader = NULL;
-
- // Now search the current shader for a record with this name (
- // excluding texture file extension)
- if (!shaders.blocks.empty()) {
-
- std::string::size_type s = convertedPath.find_last_of('.');
- if (s == std::string::npos)
- s = convertedPath.length();
-
- const std::string without_ext = convertedPath.substr(0,s);
- std::list< Q3Shader::ShaderDataBlock >::const_iterator dit = std::find(shaders.blocks.begin(),shaders.blocks.end(),without_ext);
- if (dit != shaders.blocks.end()) {
- // Hurra, wir haben einen. Tolle Sache.
- shader = &*dit;
- DefaultLogger::get()->info("Found shader record for " +without_ext );
- }
- else DefaultLogger::get()->warn("Unable to find shader record for " +without_ext );
- }
-
- aiMaterial* pcHelper = new aiMaterial();
-
- const int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // Add a small ambient color value - Quake 3 seems to have one
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- // use surface name + skin_name as material name
- aiString name;
- name.Set("MD3_[" + configSkinFile + "][" + pcSurfaces->NAME + "]");
- pcHelper->AddProperty(&name,AI_MATKEY_NAME);
-
- if (!shader) {
- // Setup dummy texture file name to ensure UV coordinates are kept during postprocessing
- aiString szString;
- if (convertedPath.length()) {
- szString.Set(convertedPath);
- }
- else {
- DefaultLogger::get()->warn("Texture file name has zero length. Using default name");
- szString.Set("dummy_texture.bmp");
- }
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // prevent transparency by default
- int no_alpha = aiTextureFlags_IgnoreAlpha;
- pcHelper->AddProperty(&no_alpha,1,AI_MATKEY_TEXFLAGS_DIFFUSE(0));
- }
- else {
- Q3Shader::ConvertShaderToMaterial(pcHelper,*shader);
- }
-
- pScene->mMaterials[iNumMaterials] = (aiMaterial*)pcHelper;
- pcMesh->mMaterialIndex = iNumMaterials++;
-
- // Ensure correct endianness
-#ifdef AI_BUILD_BIG_ENDIAN
-
- for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i) {
- AI_SWAP2( pcVertices[i].NORMAL );
- AI_SWAP2( pcVertices[i].X );
- AI_SWAP2( pcVertices[i].Y );
- AI_SWAP2( pcVertices[i].Z );
-
- AI_SWAP4( pcUVs[i].U );
- AI_SWAP4( pcUVs[i].U );
- }
- for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i) {
- AI_SWAP4(pcTriangles[i].INDEXES[0]);
- AI_SWAP4(pcTriangles[i].INDEXES[1]);
- AI_SWAP4(pcTriangles[i].INDEXES[2]);
- }
-
-#endif
-
- // Fill mesh information
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pcMesh->mNumVertices = pcSurfaces->NUM_TRIANGLES*3;
- pcMesh->mNumFaces = pcSurfaces->NUM_TRIANGLES;
- pcMesh->mFaces = new aiFace[pcSurfaces->NUM_TRIANGLES];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // Fill in all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int)pcSurfaces->NUM_TRIANGLES;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- //unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- pcMesh->mFaces[i].mIndices[c] = iCurrent;
-
- // Read vertices
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- uint32_t index = pcTriangles->INDEXES[c];
- if (index >= pcSurfaces->NUM_VERTICES) {
- throw DeadlyImportError( "MD3: Invalid vertex index");
- }
- vec.x = pcVertices[index].X*AI_MD3_XYZ_SCALE;
- vec.y = pcVertices[index].Y*AI_MD3_XYZ_SCALE;
- vec.z = pcVertices[index].Z*AI_MD3_XYZ_SCALE;
-
- // Convert the normal vector to uncompressed float3 format
- aiVector3D& nor = pcMesh->mNormals[iCurrent];
- LatLngNormalToVec3(pcVertices[index].NORMAL,(ai_real*)&nor);
-
- // Read texture coordinates
- pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[index].U;
- pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[index].V;
- }
- // Flip face order if necessary
- if (!shader || shader->cull == Q3Shader::CULL_CW) {
- std::swap(pcMesh->mFaces[i].mIndices[2],pcMesh->mFaces[i].mIndices[1]);
- }
- pcTriangles++;
- }
-
- // Go to the next surface
- pcSurfaces = (BE_NCONST MD3::Surface*)(((unsigned char*)pcSurfaces) + pcSurfaces->OFS_END);
- }
-
- // For debugging purposes: check whether we found matches for all entries in the skins file
- if (!DefaultLogger::isNullLogger()) {
- for (std::list< Q3Shader::SkinData::TextureEntry>::const_iterator it = skins.textures.begin();it != skins.textures.end(); ++it) {
- if (!(*it).resolved) {
- DefaultLogger::get()->error("MD3: Failed to match skin " + (*it).first + " to surface " + (*it).second);
- }
- }
- }
-
- if (!pScene->mNumMeshes)
- throw DeadlyImportError( "MD3: File contains no valid mesh");
- pScene->mNumMaterials = iNumMaterials;
-
- // Now we need to generate an empty node graph
- pScene->mRootNode = new aiNode("<MD3Root>");
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- // Attach tiny children for all tags
- if (pcHeader->NUM_TAGS) {
- pScene->mRootNode->mNumChildren = pcHeader->NUM_TAGS;
- pScene->mRootNode->mChildren = new aiNode*[pcHeader->NUM_TAGS];
-
- for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
-
- aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
- nd->mName.Set((const char*)pcTags->NAME);
- nd->mParent = pScene->mRootNode;
-
- AI_SWAP4(pcTags->origin.x);
- AI_SWAP4(pcTags->origin.y);
- AI_SWAP4(pcTags->origin.z);
-
- // Copy local origin, again flip z,y
- nd->mTransformation.a4 = pcTags->origin.x;
- nd->mTransformation.b4 = pcTags->origin.y;
- nd->mTransformation.c4 = pcTags->origin.z;
-
- // Copy rest of transformation (need to transpose to match row-order matrix)
- for (unsigned int a = 0; a < 3;++a) {
- for (unsigned int m = 0; m < 3;++m) {
- nd->mTransformation[m][a] = pcTags->orientation[a][m];
- AI_SWAP4(nd->mTransformation[m][a]);
- }
- }
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER
diff --git a/src/3rdparty/assimp/code/MD3Loader.h b/src/3rdparty/assimp/code/MD3Loader.h
deleted file mode 100644
index ff5b56a52..000000000
--- a/src/3rdparty/assimp/code/MD3Loader.h
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Md3Loader.h
- * @brief Declaration of the .MD3 importer class.
- */
-#ifndef AI_MD3LOADER_H_INCLUDED
-#define AI_MD3LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "ByteSwapper.h"
-#include "MD3FileData.h"
-#include "StringComparison.h"
-#include <assimp/types.h>
-
-#include <list>
-
-struct aiMaterial;
-
-namespace Assimp {
-
-
-using namespace MD3;
-namespace Q3Shader {
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold the data of a .skin file
- */
-struct SkinData
-{
- //! A single entryin texture list
- struct TextureEntry : public std::pair<std::string,std::string>
- {
- // did we resolve this texture entry?
- bool resolved;
-
- // for std::find()
- bool operator == (const std::string& f) const {
- return f == first;
- }
- };
-
- //! List of textures
- std::list<TextureEntry> textures;
-
- // rest is ignored for the moment
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies cull modi for Quake shader files.
- */
-enum ShaderCullMode
-{
- CULL_NONE,
- CULL_CW,
- CULL_CCW
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies alpha blend modi (src + dest) for Quake shader files
- */
-enum BlendFunc
-{
- BLEND_NONE,
- BLEND_GL_ONE,
- BLEND_GL_ZERO,
- BLEND_GL_DST_COLOR,
- BLEND_GL_ONE_MINUS_DST_COLOR,
- BLEND_GL_SRC_ALPHA,
- BLEND_GL_ONE_MINUS_SRC_ALPHA
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Specifies alpha test modi for Quake texture maps
- */
-enum AlphaTestFunc
-{
- AT_NONE,
- AT_GT0,
- AT_LT128,
- AT_GE128
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold a .shader map data block
- */
-struct ShaderMapBlock
-{
- ShaderMapBlock()
- : blend_src (BLEND_NONE)
- , blend_dest (BLEND_NONE)
- , alpha_test (AT_NONE)
- {}
-
- //! Name of referenced map
- std::string name;
-
- //! Blend and alpha test settings for texture
- BlendFunc blend_src,blend_dest;
- AlphaTestFunc alpha_test;
-
-
- //! For std::find()
- bool operator== (const std::string& o) const {
- return !ASSIMP_stricmp(o,name);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold a .shader data block
- */
-struct ShaderDataBlock
-{
- ShaderDataBlock()
- : cull (CULL_CW)
- {}
-
- //! Name of referenced data element
- std::string name;
-
- //! Cull mode for the element
- ShaderCullMode cull;
-
- //! Maps defined in the shader
- std::list<ShaderMapBlock> maps;
-
-
- //! For std::find()
- bool operator== (const std::string& o) const {
- return !ASSIMP_stricmp(o,name);
- }
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Tiny utility data structure to hold the data of a .shader file
- */
-struct ShaderData
-{
- //! Shader data blocks
- std::list<ShaderDataBlock> blocks;
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Load a shader file
- *
- * Generally, parsing is error tolerant. There's no failure.
- * @param fill Receives output data
- * @param file File to be read.
- * @param io IOSystem to be used for reading
- * @return false if file is not accessible
- */
-bool LoadShader(ShaderData& fill, const std::string& file,IOSystem* io);
-
-
-// ---------------------------------------------------------------------------
-/** @brief Convert a Q3Shader to an aiMaterial
- *
- * @param[out] out Material structure to be filled.
- * @param[in] shader Input shader
- */
-void ConvertShaderToMaterial(aiMaterial* out, const ShaderDataBlock& shader);
-
-// ---------------------------------------------------------------------------
-/** @brief Load a skin file
- *
- * Generally, parsing is error tolerant. There's no failure.
- * @param fill Receives output data
- * @param file File to be read.
- * @param io IOSystem to be used for reading
- * @return false if file is not accessible
- */
-bool LoadSkin(SkinData& fill, const std::string& file,IOSystem* io);
-
-} // ! namespace Q3SHader
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load MD3 files
-*/
-class MD3Importer : public BaseImporter
-{
-public:
- MD3Importer();
- ~MD3Importer();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Validate offsets in the header
- */
- void ValidateHeaderOffsets();
- void ValidateSurfaceHeaderOffsets(const MD3::Surface* pcSurfHeader);
-
- // -------------------------------------------------------------------
- /** Read a Q3 multipart file
- * @return true if multi part has been processed
- */
- bool ReadMultipartFile();
-
- // -------------------------------------------------------------------
- /** Try to read the skin for a MD3 file
- * @param fill Receives output information
- */
- void ReadSkin(Q3Shader::SkinData& fill) const;
-
- // -------------------------------------------------------------------
- /** Try to read the shader for a MD3 file
- * @param fill Receives output information
- */
- void ReadShader(Q3Shader::ShaderData& fill) const;
-
- // -------------------------------------------------------------------
- /** Convert a texture path in a MD3 file to a proper value
- * @param[in] texture_name Path to be converted
- * @param[in] header_path Base path specified in MD3 header
- * @param[out] out Receives the converted output string
- */
- void ConvertPath(const char* texture_name, const char* header_path,
- std::string& out) const;
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Configuration option: process multi-part files */
- bool configHandleMP;
-
- /** Configuration option: name of skin file to be read */
- std::string configSkinFile;
-
- /** Configuration option: name or path of shader */
- std::string configShaderFile;
-
- /** Configuration option: speed flag was set? */
- bool configSpeedFlag;
-
- /** Header of the MD3 file */
- BE_NCONST MD3::Header* pcHeader;
-
- /** File buffer */
- BE_NCONST unsigned char* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Current file name */
- std::string mFile;
-
- /** Current base directory */
- std::string path;
-
- /** Pure file we're currently reading */
- std::string filename;
-
- /** Output scene to be filled */
- aiScene* mScene;
-
- /** IO system to be used to access the data*/
- IOSystem* mIOHandler;
- };
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/MD4FileData.h b/src/3rdparty/assimp/code/MD4FileData.h
deleted file mode 100644
index e515808ac..000000000
--- a/src/3rdparty/assimp/code/MD4FileData.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-Open Asset Import Library (ASSIMP)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2010, ASSIMP Development 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 Development 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 Defines the helper data structures for importing MD4 files */
-#ifndef AI_MD4FILEHELPER_H_INC
-#define AI_MD4FILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-#include <sstream>
-
-#include "../include/assimp/types.h"
-#include "../include/assimp/mesh.h"
-#include "../include/assimp/anim.h"
-
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack(push,1)
-# define PACK_STRUCT
-#elif defined( __GNUC__ )
-# define PACK_STRUCT __attribute__((packed))
-#else
-# error Compiler not supported
-#endif
-
-
-namespace Assimp
-{
-// http://gongo.quakedev.com/md4.html
-namespace MD4
-{
-
-#define AI_MD4_MAGIC_NUMBER_BE 'IDP4'
-#define AI_MD4_MAGIC_NUMBER_LE '4PDI'
-
-// common limitations
-#define AI_MD4_VERSION 4
-#define AI_MD4_MAXQPATH 64
-#define AI_MD4_MAX_FRAMES 2028
-#define AI_MD4_MAX_SURFACES 32
-#define AI_MD4_MAX_BONES 256
-#define AI_MD4_MAX_VERTS 4096
-#define AI_MD4_MAX_TRIANGLES 8192
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for the MD4 main header
- */
-// ---------------------------------------------------------------------------
-struct Header
-{
- //! magic number
- int32_t magic;
-
- //! file format version
- int32_t version;
-
- //! original name in .pak archive
- unsigned char name[ AI_MD4_MAXQPATH ];
-
- //! number of frames in the file
- int32_t NUM_FRAMES;
-
- //! number of bones in the file
- int32_t NUM_BONES;
-
- //! number of surfaces in the file
- int32_t NUM_SURFACES;
-
- //! offset of the first frame
- int32_t OFS_FRAMES;
-
- //! offset of the first bone
- int32_t OFS_BONES;
-
- //! offset of the first surface
- int32_t OFS_SURFACES;
-
- //! end of file
- int32_t OFS_EOF;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Stores the local transformation matrix of a bone
- */
-// ---------------------------------------------------------------------------
-struct BoneFrame
-{
- float matrix[3][4];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Stores the name / parent index / flag of a node
- */
-// ---------------------------------------------------------------------------
-struct BoneName
-{
- char name[32] ;
- int parent ;
- int flags ;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a surface in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Surface
-{
- int32_t ident;
- char name[64];
- char shader[64];
- int32_t shaderIndex;
- int32_t lodBias;
- int32_t minLod;
- int32_t ofsHeader;
- int32_t numVerts;
- int32_t ofsVerts;
- int32_t numTris;
- int32_t ofsTris;
- int32_t numBoneRefs;
- int32_t ofsBoneRefs;
- int32_t ofsCollapseMap;
- int32_t ofsEnd;
-} PACK_STRUCT;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD4 vertex' weight
- */
-// ---------------------------------------------------------------------------
-struct Weight
-{
- int32_t boneIndex;
- float boneWeight;
- float offset[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a vertex in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Vertex
-{
- float vertex[3];
- float normal[3];
- float texCoords[2];
- int32_t numWeights;
- Weight weights[1];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a triangle in a MD4 file
- */
-// ---------------------------------------------------------------------------
-struct Triangle
-{
- int32_t indexes[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MD4 frame
- */
-// ---------------------------------------------------------------------------
-struct Frame
-{
- float bounds[3][2];
- float localOrigin[3];
- float radius;
- BoneFrame bones[1];
-} PACK_STRUCT;
-
-
-// reset packing to the original value
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack( pop )
-#endif
-#undef PACK_STRUCT
-
-
-};
-};
-
-#endif // !! AI_MD4FILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/MD5Loader.cpp b/src/3rdparty/assimp/code/MD5Loader.cpp
deleted file mode 100644
index 172c98a30..000000000
--- a/src/3rdparty/assimp/code/MD5Loader.cpp
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD5Loader.cpp
- * @brief Implementation of the MD5 importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_MD5_IMPORTER
-
-// internal headers
-#include "RemoveComments.h"
-#include "MD5Loader.h"
-#include "StringComparison.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-using namespace Assimp;
-
-// Minimum weight value. Weights inside [-n ... n] are ignored
-#define AI_MD5_WEIGHT_EPSILON 1e-5f
-
-
-static const aiImporterDesc desc = {
- "Doom 3 / MD5 Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "md5mesh md5camera md5anim"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MD5Importer::MD5Importer()
- : mIOHandler()
- , mBuffer()
- , fileSize()
- , iLineNumber()
- , pScene()
- , pIOHandler()
- , bHadMD5Mesh()
- , bHadMD5Anim()
- , bHadMD5Camera()
- , configNoAutoLoad (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MD5Importer::~MD5Importer()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MD5Importer::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "md5anim" || extension == "md5mesh" || extension == "md5camera")
- return true;
- else if (!extension.length() || checkSig) {
- if (!pIOHandler) {
- return true;
- }
- const char* tokens[] = {"MD5Version"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get list of all supported extensions
-const aiImporterDesc* MD5Importer::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void MD5Importer::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD
- configNoAutoLoad = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD,0));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MD5Importer::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pIOHandler = _pIOHandler;
- pScene = _pScene;
- bHadMD5Mesh = bHadMD5Anim = bHadMD5Camera = false;
-
- // remove the file extension
- const std::string::size_type pos = pFile.find_last_of('.');
- mFile = (std::string::npos == pos ? pFile : pFile.substr(0,pos+1));
-
- const std::string extension = GetExtension(pFile);
- try {
- if (extension == "md5camera") {
- LoadMD5CameraFile();
- }
- else if (configNoAutoLoad || extension == "md5anim") {
- // determine file extension and process just *one* file
- if (extension.length() == 0) {
- throw DeadlyImportError("Failure, need file extension to determine MD5 part type");
- }
- if (extension == "md5anim") {
- LoadMD5AnimFile();
- }
- else if (extension == "md5mesh") {
- LoadMD5MeshFile();
- }
- }
- else {
- LoadMD5MeshFile();
- LoadMD5AnimFile();
- }
- }
- catch ( ... ) { // std::exception, Assimp::DeadlyImportError
- UnloadFileFromMemory();
- throw;
- }
-
- // make sure we have at least one file
- if (!bHadMD5Mesh && !bHadMD5Anim && !bHadMD5Camera) {
- throw DeadlyImportError("Failed to read valid contents out of this MD5* file");
- }
-
- // Now rotate the whole scene 90 degrees around the x axis to match our internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- // the output scene wouldn't pass the validation without this flag
- if (!bHadMD5Mesh) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- // clean the instance -- the BaseImporter instance may be reused later.
- UnloadFileFromMemory();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a file into a memory buffer
-void MD5Importer::LoadFileIntoMemory (IOStream* file)
-{
- // unload the previous buffer, if any
- UnloadFileFromMemory();
-
- ai_assert(NULL != file);
- fileSize = (unsigned int)file->FileSize();
- ai_assert(fileSize);
-
- // allocate storage and copy the contents of the file to a memory buffer
- mBuffer = new char[fileSize+1];
- file->Read( (void*)mBuffer, 1, fileSize);
- iLineNumber = 1;
-
- // append a terminal 0
- mBuffer[fileSize] = '\0';
-
- // now remove all line comments from the file
- CommentRemover::RemoveLineComments("//",mBuffer,' ');
-}
-
-// ------------------------------------------------------------------------------------------------
-// Unload the current memory buffer
-void MD5Importer::UnloadFileFromMemory ()
-{
- // delete the file buffer
- delete[] mBuffer;
- mBuffer = NULL;
- fileSize = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build unique vertices
-void MD5Importer::MakeDataUnique (MD5::MeshDesc& meshSrc)
-{
- std::vector<bool> abHad(meshSrc.mVertices.size(),false);
-
- // allocate enough storage to keep the output structures
- const unsigned int iNewNum = static_cast<unsigned int>(meshSrc.mFaces.size()*3);
- unsigned int iNewIndex = static_cast<unsigned int>(meshSrc.mVertices.size());
- meshSrc.mVertices.resize(iNewNum);
-
- // try to guess how much storage we'll need for new weights
- const float fWeightsPerVert = meshSrc.mWeights.size() / (float)iNewIndex;
- const unsigned int guess = (unsigned int)(fWeightsPerVert*iNewNum);
- meshSrc.mWeights.reserve(guess + (guess >> 3)); // + 12.5% as buffer
-
- for (FaceList::const_iterator iter = meshSrc.mFaces.begin(),iterEnd = meshSrc.mFaces.end();iter != iterEnd;++iter){
- const aiFace& face = *iter;
- for (unsigned int i = 0; i < 3;++i) {
- if (face.mIndices[0] >= meshSrc.mVertices.size()) {
- throw DeadlyImportError("MD5MESH: Invalid vertex index");
- }
-
- if (abHad[face.mIndices[i]]) {
- // generate a new vertex
- meshSrc.mVertices[iNewIndex] = meshSrc.mVertices[face.mIndices[i]];
- face.mIndices[i] = iNewIndex++;
- }
- else abHad[face.mIndices[i]] = true;
- }
- // swap face order
- std::swap(face.mIndices[0],face.mIndices[2]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive node graph construction from a MD5MESH
-void MD5Importer::AttachChilds_Mesh(int iParentID,aiNode* piParent, BoneList& bones)
-{
- ai_assert(NULL != piParent && !piParent->mNumChildren);
-
- // First find out how many children we'll have
- for (int i = 0; i < (int)bones.size();++i) {
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- ++piParent->mNumChildren;
- }
- }
- if (piParent->mNumChildren) {
- piParent->mChildren = new aiNode*[piParent->mNumChildren];
- for (int i = 0; i < (int)bones.size();++i) {
- // (avoid infinite recursion)
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- aiNode* pc;
- // setup a new node
- *piParent->mChildren++ = pc = new aiNode();
- pc->mName = aiString(bones[i].mName);
- pc->mParent = piParent;
-
- // get the transformation matrix from rotation and translational components
- aiQuaternion quat;
- MD5::ConvertQuaternion ( bones[i].mRotationQuat, quat );
-
- bones[i].mTransform = aiMatrix4x4 ( quat.GetMatrix());
- bones[i].mTransform.a4 = bones[i].mPositionXYZ.x;
- bones[i].mTransform.b4 = bones[i].mPositionXYZ.y;
- bones[i].mTransform.c4 = bones[i].mPositionXYZ.z;
-
- // store it for later use
- pc->mTransformation = bones[i].mInvTransform = bones[i].mTransform;
- bones[i].mInvTransform.Inverse();
-
- // the transformations for each bone are absolute, so we need to multiply them
- // with the inverse of the absolute matrix of the parent joint
- if (-1 != iParentID) {
- pc->mTransformation = bones[iParentID].mInvTransform * pc->mTransformation;
- }
-
- // add children to this node, too
- AttachChilds_Mesh( i, pc, bones);
- }
- }
- // undo offset computations
- piParent->mChildren -= piParent->mNumChildren;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive node graph construction from a MD5ANIM
-void MD5Importer::AttachChilds_Anim(int iParentID,aiNode* piParent, AnimBoneList& bones,const aiNodeAnim** node_anims)
-{
- ai_assert(NULL != piParent && !piParent->mNumChildren);
-
- // First find out how many children we'll have
- for (int i = 0; i < (int)bones.size();++i) {
- if (iParentID != i && bones[i].mParentIndex == iParentID) {
- ++piParent->mNumChildren;
- }
- }
- if (piParent->mNumChildren) {
- piParent->mChildren = new aiNode*[piParent->mNumChildren];
- for (int i = 0; i < (int)bones.size();++i) {
- // (avoid infinite recursion)
- if (iParentID != i && bones[i].mParentIndex == iParentID)
- {
- aiNode* pc;
- // setup a new node
- *piParent->mChildren++ = pc = new aiNode();
- pc->mName = aiString(bones[i].mName);
- pc->mParent = piParent;
-
- // get the corresponding animation channel and its first frame
- const aiNodeAnim** cur = node_anims;
- while ((**cur).mNodeName != pc->mName)++cur;
-
- aiMatrix4x4::Translation((**cur).mPositionKeys[0].mValue,pc->mTransformation);
- pc->mTransformation = pc->mTransformation * aiMatrix4x4((**cur).mRotationKeys[0].mValue.GetMatrix()) ;
-
- // add children to this node, too
- AttachChilds_Anim( i, pc, bones,node_anims);
- }
- }
- // undo offset computations
- piParent->mChildren -= piParent->mNumChildren;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load a MD5MESH file
-void MD5Importer::LoadMD5MeshFile ()
-{
- std::string pFile = mFile + "md5mesh";
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL || !file->FileSize()) {
- DefaultLogger::get()->warn("Failed to access MD5MESH file: " + pFile);
- return;
- }
- bHadMD5Mesh = true;
- LoadFileIntoMemory(file.get());
-
- // now construct a parser and parse the file
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the mesh information from it
- MD5::MD5MeshParser meshParser(parser.mSections);
-
- // create the bone hierarchy - first the root node and dummy nodes for all meshes
- pScene->mRootNode = new aiNode("<MD5_Root>");
- pScene->mRootNode->mNumChildren = 2;
- pScene->mRootNode->mChildren = new aiNode*[2];
-
- // build the hierarchy from the MD5MESH file
- aiNode* pcNode = pScene->mRootNode->mChildren[1] = new aiNode();
- pcNode->mName.Set("<MD5_Hierarchy>");
- pcNode->mParent = pScene->mRootNode;
- AttachChilds_Mesh(-1,pcNode,meshParser.mJoints);
-
- pcNode = pScene->mRootNode->mChildren[0] = new aiNode();
- pcNode->mName.Set("<MD5_Mesh>");
- pcNode->mParent = pScene->mRootNode;
-
-#if 0
- if (pScene->mRootNode->mChildren[1]->mNumChildren) /* start at the right hierarchy level */
- SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[1]->mChildren[0]);
-#else
-
- // FIX: MD5 files exported from Blender can have empty meshes
- for (std::vector<MD5::MeshDesc>::const_iterator it = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
- if (!(*it).mFaces.empty() && !(*it).mVertices.empty())
- ++pScene->mNumMaterials;
- }
-
- // generate all meshes
- pScene->mNumMeshes = pScene->mNumMaterials;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes];
-
- // storage for node mesh indices
- pcNode->mNumMeshes = pScene->mNumMeshes;
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- for (unsigned int m = 0; m < pcNode->mNumMeshes;++m)
- pcNode->mMeshes[m] = m;
-
- unsigned int n = 0;
- for (std::vector<MD5::MeshDesc>::iterator it = meshParser.mMeshes.begin(),end = meshParser.mMeshes.end(); it != end;++it) {
- MD5::MeshDesc& meshSrc = *it;
- if (meshSrc.mFaces.empty() || meshSrc.mVertices.empty())
- continue;
-
- aiMesh* mesh = pScene->mMeshes[n] = new aiMesh();
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // generate unique vertices in our internal verbose format
- MakeDataUnique(meshSrc);
-
- mesh->mNumVertices = (unsigned int) meshSrc.mVertices.size();
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
-
- // copy texture coordinates
- aiVector3D* pv = mesh->mTextureCoords[0];
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- pv->x = (*iter).mUV.x;
- pv->y = 1.0f-(*iter).mUV.y; // D3D to OpenGL
- pv->z = 0.0f;
- }
-
- // sort all bone weights - per bone
- unsigned int* piCount = new unsigned int[meshParser.mJoints.size()];
- ::memset(piCount,0,sizeof(unsigned int)*meshParser.mJoints.size());
-
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
- {
- MD5::WeightDesc& desc = meshSrc.mWeights[w];
- /* FIX for some invalid exporters */
- if (!(desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON ))
- ++piCount[desc.mBone];
- }
- }
-
- // check how many we will need
- for (unsigned int p = 0; p < meshParser.mJoints.size();++p)
- if (piCount[p])mesh->mNumBones++;
-
- if (mesh->mNumBones) // just for safety
- {
- mesh->mBones = new aiBone*[mesh->mNumBones];
- for (unsigned int q = 0,h = 0; q < meshParser.mJoints.size();++q)
- {
- if (!piCount[q])continue;
- aiBone* p = mesh->mBones[h] = new aiBone();
- p->mNumWeights = piCount[q];
- p->mWeights = new aiVertexWeight[p->mNumWeights];
- p->mName = aiString(meshParser.mJoints[q].mName);
- p->mOffsetMatrix = meshParser.mJoints[q].mInvTransform;
-
- // store the index for later use
- MD5::BoneDesc& boneSrc = meshParser.mJoints[q];
- boneSrc.mMap = h++;
-
- // compute w-component of quaternion
- MD5::ConvertQuaternion( boneSrc.mRotationQuat, boneSrc.mRotationQuatConverted );
- }
-
- //unsigned int g = 0;
- pv = mesh->mVertices;
- for (MD5::VertexList::const_iterator iter = meshSrc.mVertices.begin();iter != meshSrc.mVertices.end();++iter,++pv) {
- // compute the final vertex position from all single weights
- *pv = aiVector3D();
-
- // there are models which have weights which don't sum to 1 ...
- ai_real fSum = 0.0;
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w)
- fSum += meshSrc.mWeights[w].mWeight;
- if (!fSum) {
- DefaultLogger::get()->error("MD5MESH: The sum of all vertex bone weights is 0");
- continue;
- }
-
- // process bone weights
- for (unsigned int jub = (*iter).mFirstWeight, w = jub; w < jub + (*iter).mNumWeights;++w) {
- if (w >= meshSrc.mWeights.size())
- throw DeadlyImportError("MD5MESH: Invalid weight index");
-
- MD5::WeightDesc& desc = meshSrc.mWeights[w];
- if ( desc.mWeight < AI_MD5_WEIGHT_EPSILON && desc.mWeight >= -AI_MD5_WEIGHT_EPSILON) {
- continue;
- }
-
- const ai_real fNewWeight = desc.mWeight / fSum;
-
- // transform the local position into worldspace
- MD5::BoneDesc& boneSrc = meshParser.mJoints[desc.mBone];
- const aiVector3D v = boneSrc.mRotationQuatConverted.Rotate (desc.vOffsetPosition);
-
- // use the original weight to compute the vertex position
- // (some MD5s seem to depend on the invalid weight values ...)
- *pv += ((boneSrc.mPositionXYZ+v)* (ai_real)desc.mWeight);
-
- aiBone* bone = mesh->mBones[boneSrc.mMap];
- *bone->mWeights++ = aiVertexWeight((unsigned int)(pv-mesh->mVertices),fNewWeight);
- }
- }
-
- // undo our nice offset tricks ...
- for (unsigned int p = 0; p < mesh->mNumBones;++p) {
- mesh->mBones[p]->mWeights -= mesh->mBones[p]->mNumWeights;
- }
- }
-
- delete[] piCount;
-
- // now setup all faces - we can directly copy the list
- // (however, take care that the aiFace destructor doesn't delete the mIndices array)
- mesh->mNumFaces = (unsigned int)meshSrc.mFaces.size();
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- for (unsigned int c = 0; c < mesh->mNumFaces;++c) {
- mesh->mFaces[c].mNumIndices = 3;
- mesh->mFaces[c].mIndices = meshSrc.mFaces[c].mIndices;
- meshSrc.mFaces[c].mIndices = NULL;
- }
-
- // generate a material for the mesh
- aiMaterial* mat = new aiMaterial();
- pScene->mMaterials[n] = mat;
-
- // insert the typical doom3 textures:
- // nnn_local.tga - normal map
- // nnn_h.tga - height map
- // nnn_s.tga - specular map
- // nnn_d.tga - diffuse map
- if (meshSrc.mShader.length && !strchr(meshSrc.mShader.data,'.')) {
-
- aiString temp(meshSrc.mShader);
- temp.Append("_local.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_NORMALS(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_s.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_SPECULAR(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_d.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- temp = aiString(meshSrc.mShader);
- temp.Append("_h.tga");
- mat->AddProperty(&temp,AI_MATKEY_TEXTURE_HEIGHT(0));
-
- // set this also as material name
- mat->AddProperty(&meshSrc.mShader,AI_MATKEY_NAME);
- }
- else mat->AddProperty(&meshSrc.mShader,AI_MATKEY_TEXTURE_DIFFUSE(0));
- mesh->mMaterialIndex = n++;
- }
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load an MD5ANIM file
-void MD5Importer::LoadMD5AnimFile ()
-{
- std::string pFile = mFile + "md5anim";
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( !file.get() || !file->FileSize()) {
- DefaultLogger::get()->warn("Failed to read MD5ANIM file: " + pFile);
- return;
- }
- LoadFileIntoMemory(file.get());
-
- // parse the basic file structure
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the animation information from the parse tree
- MD5::MD5AnimParser animParser(parser.mSections);
-
- // generate and fill the output animation
- if (animParser.mAnimatedBones.empty() || animParser.mFrames.empty() ||
- animParser.mBaseFrames.size() != animParser.mAnimatedBones.size()) {
-
- DefaultLogger::get()->error("MD5ANIM: No frames or animated bones loaded");
- }
- else {
- bHadMD5Anim = true;
-
- pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations = 1];
- aiAnimation* anim = pScene->mAnimations[0] = new aiAnimation();
- anim->mNumChannels = (unsigned int)animParser.mAnimatedBones.size();
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* node = anim->mChannels[i] = new aiNodeAnim();
- node->mNodeName = aiString( animParser.mAnimatedBones[i].mName );
-
- // allocate storage for the keyframes
- node->mPositionKeys = new aiVectorKey[animParser.mFrames.size()];
- node->mRotationKeys = new aiQuatKey[animParser.mFrames.size()];
- }
-
- // 1 tick == 1 frame
- anim->mTicksPerSecond = animParser.fFrameRate;
-
- for (FrameList::const_iterator iter = animParser.mFrames.begin(), iterEnd = animParser.mFrames.end();iter != iterEnd;++iter){
- double dTime = (double)(*iter).iIndex;
- aiNodeAnim** pcAnimNode = anim->mChannels;
- if (!(*iter).mValues.empty() || iter == animParser.mFrames.begin()) /* be sure we have at least one frame */
- {
- // now process all values in there ... read all joints
- MD5::BaseFrameDesc* pcBaseFrame = &animParser.mBaseFrames[0];
- for (AnimBoneList::const_iterator iter2 = animParser.mAnimatedBones.begin(); iter2 != animParser.mAnimatedBones.end();++iter2,
- ++pcAnimNode,++pcBaseFrame)
- {
- if((*iter2).iFirstKeyIndex >= (*iter).mValues.size()) {
-
- // Allow for empty frames
- if ((*iter2).iFlags != 0) {
- throw DeadlyImportError("MD5: Keyframe index is out of range");
-
- }
- continue;
- }
- const float* fpCur = &(*iter).mValues[(*iter2).iFirstKeyIndex];
- aiNodeAnim* pcCurAnimBone = *pcAnimNode;
-
- aiVectorKey* vKey = &pcCurAnimBone->mPositionKeys[pcCurAnimBone->mNumPositionKeys++];
- aiQuatKey* qKey = &pcCurAnimBone->mRotationKeys [pcCurAnimBone->mNumRotationKeys++];
- aiVector3D vTemp;
-
- // translational component
- for (unsigned int i = 0; i < 3; ++i) {
- if ((*iter2).iFlags & (1u << i)) {
- vKey->mValue[i] = *fpCur++;
- }
- else vKey->mValue[i] = pcBaseFrame->vPositionXYZ[i];
- }
-
- // orientation component
- for (unsigned int i = 0; i < 3; ++i) {
- if ((*iter2).iFlags & (8u << i)) {
- vTemp[i] = *fpCur++;
- }
- else vTemp[i] = pcBaseFrame->vRotationQuat[i];
- }
-
- MD5::ConvertQuaternion(vTemp, qKey->mValue);
- qKey->mTime = vKey->mTime = dTime;
- }
- }
-
- // compute the duration of the animation
- anim->mDuration = std::max(dTime,anim->mDuration);
- }
-
- // If we didn't build the hierarchy yet (== we didn't load a MD5MESH),
- // construct it now from the data given in the MD5ANIM.
- if (!pScene->mRootNode) {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<MD5_Hierarchy>");
-
- AttachChilds_Anim(-1,pScene->mRootNode,animParser.mAnimatedBones,(const aiNodeAnim**)anim->mChannels);
-
- // Call SkeletonMeshBuilder to construct a mesh to represent the shape
- if (pScene->mRootNode->mNumChildren) {
- SkeletonMeshBuilder skeleton_maker(pScene,pScene->mRootNode->mChildren[0]);
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load an MD5CAMERA file
-void MD5Importer::LoadMD5CameraFile ()
-{
- std::string pFile = mFile + "md5camera";
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( !file.get() || !file->FileSize()) {
- throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
- }
- bHadMD5Camera = true;
- LoadFileIntoMemory(file.get());
-
- // parse the basic file structure
- MD5::MD5Parser parser(mBuffer,fileSize);
-
- // load the camera animation data from the parse tree
- MD5::MD5CameraParser cameraParser(parser.mSections);
-
- if (cameraParser.frames.empty()) {
- throw DeadlyImportError("MD5CAMERA: No frames parsed");
- }
-
- std::vector<unsigned int>& cuts = cameraParser.cuts;
- std::vector<MD5::CameraAnimFrameDesc>& frames = cameraParser.frames;
-
- // Construct output graph - a simple root with a dummy child.
- // The root node performs the coordinate system conversion
- aiNode* root = pScene->mRootNode = new aiNode("<MD5CameraRoot>");
- root->mChildren = new aiNode*[root->mNumChildren = 1];
- root->mChildren[0] = new aiNode("<MD5Camera>");
- root->mChildren[0]->mParent = root;
-
- // ... but with one camera assigned to it
- pScene->mCameras = new aiCamera*[pScene->mNumCameras = 1];
- aiCamera* cam = pScene->mCameras[0] = new aiCamera();
- cam->mName = "<MD5Camera>";
-
- // FIXME: Fov is currently set to the first frame's value
- cam->mHorizontalFOV = AI_DEG_TO_RAD( frames.front().fFOV );
-
- // every cut is written to a separate aiAnimation
- if (!cuts.size()) {
- cuts.push_back(0);
- cuts.push_back(static_cast<unsigned int>(frames.size()-1));
- }
- else {
- cuts.insert(cuts.begin(),0);
-
- if (cuts.back() < frames.size()-1)
- cuts.push_back(static_cast<unsigned int>(frames.size()-1));
- }
-
- pScene->mNumAnimations = static_cast<unsigned int>(cuts.size()-1);
- aiAnimation** tmp = pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations];
- for (std::vector<unsigned int>::const_iterator it = cuts.begin(); it != cuts.end()-1; ++it) {
-
- aiAnimation* anim = *tmp++ = new aiAnimation();
- anim->mName.length = ::ai_snprintf(anim->mName.data, MAXLEN, "anim%u_from_%u_to_%u",(unsigned int)(it-cuts.begin()),(*it),*(it+1));
-
- anim->mTicksPerSecond = cameraParser.fFrameRate;
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels = 1];
- aiNodeAnim* nd = anim->mChannels[0] = new aiNodeAnim();
- nd->mNodeName.Set("<MD5Camera>");
-
- nd->mNumPositionKeys = nd->mNumRotationKeys = *(it+1) - (*it);
- nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
- nd->mRotationKeys = new aiQuatKey [nd->mNumRotationKeys];
- for (unsigned int i = 0; i < nd->mNumPositionKeys; ++i) {
-
- nd->mPositionKeys[i].mValue = frames[*it+i].vPositionXYZ;
- MD5::ConvertQuaternion(frames[*it+i].vRotationQuat,nd->mRotationKeys[i].mValue);
- nd->mRotationKeys[i].mTime = nd->mPositionKeys[i].mTime = *it+i;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MD5_IMPORTER
diff --git a/src/3rdparty/assimp/code/MD5Loader.h b/src/3rdparty/assimp/code/MD5Loader.h
deleted file mode 100644
index afb07a62d..000000000
--- a/src/3rdparty/assimp/code/MD5Loader.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD5Loader.h
- * @brief Definition of the .MD5 importer class.
- * http://www.modwiki.net/wiki/MD5_(file_format)
-*/
-#ifndef AI_MD5LOADER_H_INCLUDED
-#define AI_MD5LOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "MD5Parser.h"
-
-#include <assimp/types.h>
-
-struct aiNode;
-struct aiNodeAnim;
-
-namespace Assimp {
-
-class IOStream;
-using namespace Assimp::MD5;
-
-// ---------------------------------------------------------------------------
-/** Importer class for the MD5 file format
-*/
-class MD5Importer : public BaseImporter
-{
-public:
- MD5Importer();
- ~MD5Importer();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Load a *.MD5MESH file.
- */
- void LoadMD5MeshFile ();
-
- // -------------------------------------------------------------------
- /** Load a *.MD5ANIM file.
- */
- void LoadMD5AnimFile ();
-
- // -------------------------------------------------------------------
- /** Load a *.MD5CAMERA file.
- */
- void LoadMD5CameraFile ();
-
- // -------------------------------------------------------------------
- /** Construct node hierarchy from a given MD5ANIM
- * @param iParentID Current parent ID
- * @param piParent Parent node to attach to
- * @param bones Input bones
- * @param node_anims Generated node animations
- */
- void AttachChilds_Anim(int iParentID,aiNode* piParent,
- AnimBoneList& bones,const aiNodeAnim** node_anims);
-
- // -------------------------------------------------------------------
- /** Construct node hierarchy from a given MD5MESH
- * @param iParentID Current parent ID
- * @param piParent Parent node to attach to
- * @param bones Input bones
- */
- void AttachChilds_Mesh(int iParentID,aiNode* piParent,BoneList& bones);
-
- // -------------------------------------------------------------------
- /** Build unique vertex buffers from a given MD5ANIM
- * @param meshSrc Input data
- */
- void MakeDataUnique (MD5::MeshDesc& meshSrc);
-
- // -------------------------------------------------------------------
- /** Load the contents of a specific file into memory and
- * alocates a buffer to keep it.
- *
- * mBuffer is modified to point to this buffer.
- * @param pFile File stream to be read
- */
- void LoadFileIntoMemory (IOStream* pFile);
- void UnloadFileFromMemory ();
-
-
- /** IOSystem to be used to access files */
- IOSystem* mIOHandler;
-
- /** Path to the file, excluding the file extension but
- with the dot */
- std::string mFile;
-
- /** Buffer to hold the loaded file */
- char* mBuffer;
-
- /** Size of the file */
- unsigned int fileSize;
-
- /** Current line number. For debugging purposes */
- unsigned int iLineNumber;
-
- /** Scene to be filled */
- aiScene* pScene;
-
- /** (Custom) I/O handler implementation */
- IOSystem* pIOHandler;
-
- /** true if a MD5MESH file has already been parsed */
- bool bHadMD5Mesh;
-
- /** true if a MD5ANIM file has already been parsed */
- bool bHadMD5Anim;
-
- /** true if a MD5CAMERA file has already been parsed */
- bool bHadMD5Camera;
-
- /** configuration option: prevent anim autoload */
- bool configNoAutoLoad;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/MD5Parser.cpp b/src/3rdparty/assimp/code/MD5Parser.cpp
deleted file mode 100644
index 8076e5bc4..000000000
--- a/src/3rdparty/assimp/code/MD5Parser.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD5Parser.cpp
- * @brief Implementation of the MD5 parser class
- */
-
-
-// internal headers
-#include "MD5Loader.h"
-#include "MaterialSystem.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "StringComparison.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/mesh.h>
-
-
-
-using namespace Assimp;
-using namespace Assimp::MD5;
-
-// ------------------------------------------------------------------------------------------------
-// Parse the segment structure fo a MD5 file
-MD5Parser::MD5Parser(char* _buffer, unsigned int _fileSize )
-{
- ai_assert(NULL != _buffer && 0 != _fileSize);
-
- buffer = _buffer;
- fileSize = _fileSize;
- lineNumber = 0;
-
- DefaultLogger::get()->debug("MD5Parser begin");
-
- // parse the file header
- ParseHeader();
-
- // and read all sections until we're finished
- bool running = true;
- while (running) {
- mSections.push_back(Section());
- Section& sec = mSections.back();
- if(!ParseSection(sec)) {
- break;
- }
- }
-
- if ( !DefaultLogger::isNullLogger()) {
- char szBuffer[128]; // should be sufficiently large
- ::ai_snprintf(szBuffer,128,"MD5Parser end. Parsed %i sections",(int)mSections.size());
- DefaultLogger::get()->debug(szBuffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Report error to the log stream
-/*static*/ AI_WONT_RETURN void MD5Parser::ReportError (const char* error, unsigned int line)
-{
- char szBuffer[1024];
- ::ai_snprintf(szBuffer, 1024, "[MD5] Line %u: %s",line,error);
- throw DeadlyImportError(szBuffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Report warning to the log stream
-/*static*/ void MD5Parser::ReportWarning (const char* warn, unsigned int line)
-{
- char szBuffer[1024];
- ::sprintf(szBuffer,"[MD5] Line %u: %s",line,warn);
- DefaultLogger::get()->warn(szBuffer);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse and validate the MD5 header
-void MD5Parser::ParseHeader()
-{
- // parse and validate the file version
- SkipSpaces();
- if (!TokenMatch(buffer,"MD5Version",10)) {
- ReportError("Invalid MD5 file: MD5Version tag has not been found");
- }
- SkipSpaces();
- unsigned int iVer = ::strtoul10(buffer,(const char**)&buffer);
- if (10 != iVer) {
- ReportError("MD5 version tag is unknown (10 is expected)");
- }
- SkipLine();
-
- // print the command line options to the console
- // FIX: can break the log length limit, so we need to be careful
- char* sz = buffer;
- while (!IsLineEnd( *buffer++));
- DefaultLogger::get()->info(std::string(sz,std::min((uintptr_t)MAX_LOG_MESSAGE_LENGTH, (uintptr_t)(buffer-sz))));
- SkipSpacesAndLineEnd();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursive MD5 parsing function
-bool MD5Parser::ParseSection(Section& out)
-{
- // store the current line number for use in error messages
- out.iLineNumber = lineNumber;
-
- // first parse the name of the section
- char* sz = buffer;
- while (!IsSpaceOrNewLine( *buffer))buffer++;
- out.mName = std::string(sz,(uintptr_t)(buffer-sz));
- SkipSpaces();
-
- bool running = true;
- while (running) {
- if ('{' == *buffer) {
- // it is a normal section so read all lines
- buffer++;
- bool run = true;
- while (run)
- {
- if (!SkipSpacesAndLineEnd()) {
- return false; // seems this was the last section
- }
- if ('}' == *buffer) {
- buffer++;
- break;
- }
-
- out.mElements.push_back(Element());
- Element& elem = out.mElements.back();
-
- elem.iLineNumber = lineNumber;
- elem.szStart = buffer;
-
- // terminate the line with zero
- while (!IsLineEnd( *buffer))buffer++;
- if (*buffer) {
- ++lineNumber;
- *buffer++ = '\0';
- }
- }
- break;
- }
- else if (!IsSpaceOrNewLine(*buffer)) {
- // it is an element at global scope. Parse its value and go on
- sz = buffer;
- while (!IsSpaceOrNewLine( *buffer++));
- out.mGlobalValue = std::string(sz,(uintptr_t)(buffer-sz));
- continue;
- }
- break;
- }
- return SkipSpacesAndLineEnd();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Some dirty macros just because they're so funny and easy to debug
-
-// skip all spaces ... handle EOL correctly
-#define AI_MD5_SKIP_SPACES() if(!SkipSpaces(&sz)) \
- MD5Parser::ReportWarning("Unexpected end of line",elem.iLineNumber);
-
- // read a triple float in brackets: (1.0 1.0 1.0)
-#define AI_MD5_READ_TRIPLE(vec) \
- AI_MD5_SKIP_SPACES(); \
- if ('(' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move<float>(sz,(float&)vec.x); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move<float>(sz,(float&)vec.y); \
- AI_MD5_SKIP_SPACES(); \
- sz = fast_atoreal_move<float>(sz,(float&)vec.z); \
- AI_MD5_SKIP_SPACES(); \
- if (')' != *sz++) \
- MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber);
-
- // parse a string, enclosed in quotation marks or not
-#define AI_MD5_PARSE_STRING(out) \
- bool bQuota = (*sz == '\"'); \
- const char* szStart = sz; \
- while (!IsSpaceOrNewLine(*sz))++sz; \
- const char* szEnd = sz; \
- if (bQuota) { \
- szStart++; \
- if ('\"' != *(szEnd-=1)) { \
- MD5Parser::ReportWarning("Expected closing quotation marks in string", \
- elem.iLineNumber); \
- continue; \
- } \
- } \
- out.length = (size_t)(szEnd - szStart); \
- ::memcpy(out.data,szStart,out.length); \
- out.data[out.length] = '\0';
-
- // parse a string, enclosed in quotation marks
-#define AI_MD5_PARSE_STRING_IN_QUOTATION(out) \
- while('\"'!=*sz)++sz; \
- const char* szStart = ++sz; \
- while('\"'!=*sz)++sz; \
- const char* szEnd = (sz++); \
- out.length = (size_t)(szEnd - szStart); \
- ::memcpy(out.data,szStart,out.length); \
- out.data[out.length] = '\0';
-// ------------------------------------------------------------------------------------------------
-// .MD5MESH parsing function
-MD5MeshParser::MD5MeshParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5MeshParser begin");
-
- // now parse all sections
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter){
- if ( (*iter).mName == "numMeshes") {
- mMeshes.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if ( (*iter).mName == "numJoints") {
- mJoints.reserve(::strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "joints") {
- // "origin" -1 ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000000 0.707107 )
- for (const auto & elem : (*iter).mElements){
- mJoints.push_back(BoneDesc());
- BoneDesc& desc = mJoints.back();
-
- const char* sz = elem.szStart;
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
- AI_MD5_SKIP_SPACES();
-
- // negative values, at least -1, is allowed here
- desc.mParentIndex = (int)strtol10(sz,&sz);
-
- AI_MD5_READ_TRIPLE(desc.mPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.mRotationQuat); // normalized quaternion, so w is not there
- }
- }
- else if ((*iter).mName == "mesh") {
- mMeshes.push_back(MeshDesc());
- MeshDesc& desc = mMeshes.back();
-
- for (const auto & elem : (*iter).mElements){
- const char* sz = elem.szStart;
-
- // shader attribute
- if (TokenMatch(sz,"shader",6)) {
- AI_MD5_SKIP_SPACES();
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mShader);
- }
- // numverts attribute
- else if (TokenMatch(sz,"numverts",8)) {
- AI_MD5_SKIP_SPACES();
- desc.mVertices.resize(strtoul10(sz));
- }
- // numtris attribute
- else if (TokenMatch(sz,"numtris",7)) {
- AI_MD5_SKIP_SPACES();
- desc.mFaces.resize(strtoul10(sz));
- }
- // numweights attribute
- else if (TokenMatch(sz,"numweights",10)) {
- AI_MD5_SKIP_SPACES();
- desc.mWeights.resize(strtoul10(sz));
- }
- // vert attribute
- // "vert 0 ( 0.394531 0.513672 ) 0 1"
- else if (TokenMatch(sz,"vert",4)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = ::strtoul10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- if (idx >= desc.mVertices.size())
- desc.mVertices.resize(idx+1);
-
- VertexDesc& vert = desc.mVertices[idx];
- if ('(' != *sz++)
- MD5Parser::ReportWarning("Unexpected token: ( was expected",elem.iLineNumber);
- AI_MD5_SKIP_SPACES();
- sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.x);
- AI_MD5_SKIP_SPACES();
- sz = fast_atoreal_move<float>(sz,(float&)vert.mUV.y);
- AI_MD5_SKIP_SPACES();
- if (')' != *sz++)
- MD5Parser::ReportWarning("Unexpected token: ) was expected",elem.iLineNumber);
- AI_MD5_SKIP_SPACES();
- vert.mFirstWeight = ::strtoul10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- vert.mNumWeights = ::strtoul10(sz,&sz);
- }
- // tri attribute
- // "tri 0 15 13 12"
- else if (TokenMatch(sz,"tri",3)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = strtoul10(sz,&sz);
- if (idx >= desc.mFaces.size())
- desc.mFaces.resize(idx+1);
-
- aiFace& face = desc.mFaces[idx];
- face.mIndices = new unsigned int[face.mNumIndices = 3];
- for (unsigned int i = 0; i < 3;++i) {
- AI_MD5_SKIP_SPACES();
- face.mIndices[i] = strtoul10(sz,&sz);
- }
- }
- // weight attribute
- // "weight 362 5 0.500000 ( -3.553583 11.893474 9.719339 )"
- else if (TokenMatch(sz,"weight",6)) {
- AI_MD5_SKIP_SPACES();
- const unsigned int idx = strtoul10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- if (idx >= desc.mWeights.size())
- desc.mWeights.resize(idx+1);
-
- WeightDesc& weight = desc.mWeights[idx];
- weight.mBone = strtoul10(sz,&sz);
- AI_MD5_SKIP_SPACES();
- sz = fast_atoreal_move<float>(sz,weight.mWeight);
- AI_MD5_READ_TRIPLE(weight.vOffsetPosition);
- }
- }
- }
- }
- DefaultLogger::get()->debug("MD5MeshParser end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// .MD5ANIM parsing function
-MD5AnimParser::MD5AnimParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5AnimParser begin");
-
- fFrameRate = 24.0f;
- mNumAnimatedComponents = UINT_MAX;
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
- if ((*iter).mName == "hierarchy") {
- // "sheath" 0 63 6
- for (const auto & elem : (*iter).mElements) {
- mAnimatedBones.push_back ( AnimBoneDesc () );
- AnimBoneDesc& desc = mAnimatedBones.back();
-
- const char* sz = elem.szStart;
- AI_MD5_PARSE_STRING_IN_QUOTATION(desc.mName);
- AI_MD5_SKIP_SPACES();
-
- // parent index - negative values are allowed (at least -1)
- desc.mParentIndex = ::strtol10(sz,&sz);
-
- // flags (highest is 2^6-1)
- AI_MD5_SKIP_SPACES();
- if(63 < (desc.iFlags = ::strtoul10(sz,&sz))){
- MD5Parser::ReportWarning("Invalid flag combination in hierarchy section",elem.iLineNumber);
- }
- AI_MD5_SKIP_SPACES();
-
- // index of the first animation keyframe component for this joint
- desc.iFirstKeyIndex = ::strtoul10(sz,&sz);
- }
- }
- else if((*iter).mName == "baseframe") {
- // ( -0.000000 0.016430 -0.006044 ) ( 0.707107 0.000242 0.707107 )
- for (const auto & elem : (*iter).mElements) {
- const char* sz = elem.szStart;
-
- mBaseFrames.push_back ( BaseFrameDesc () );
- BaseFrameDesc& desc = mBaseFrames.back();
-
- AI_MD5_READ_TRIPLE(desc.vPositionXYZ);
- AI_MD5_READ_TRIPLE(desc.vRotationQuat);
- }
- }
- else if((*iter).mName == "frame") {
- if (!(*iter).mGlobalValue.length()) {
- MD5Parser::ReportWarning("A frame section must have a frame index",(*iter).iLineNumber);
- continue;
- }
-
- mFrames.push_back ( FrameDesc () );
- FrameDesc& desc = mFrames.back();
- desc.iIndex = strtoul10((*iter).mGlobalValue.c_str());
-
- // we do already know how much storage we will presumably need
- if (UINT_MAX != mNumAnimatedComponents) {
- desc.mValues.reserve(mNumAnimatedComponents);
- }
-
- // now read all elements (continuous list of floats)
- for (const auto & elem : (*iter).mElements){
- const char* sz = elem.szStart;
- while (SkipSpacesAndLineEnd(&sz)) {
- float f;sz = fast_atoreal_move<float>(sz,f);
- desc.mValues.push_back(f);
- }
- }
- }
- else if((*iter).mName == "numFrames") {
- mFrames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if((*iter).mName == "numJoints") {
- const unsigned int num = strtoul10((*iter).mGlobalValue.c_str());
- mAnimatedBones.reserve(num);
-
- // try to guess the number of animated components if that element is not given
- if (UINT_MAX == mNumAnimatedComponents) {
- mNumAnimatedComponents = num * 6;
- }
- }
- else if((*iter).mName == "numAnimatedComponents") {
- mAnimatedBones.reserve( strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if((*iter).mName == "frameRate") {
- fast_atoreal_move<float>((*iter).mGlobalValue.c_str(),fFrameRate);
- }
- }
- DefaultLogger::get()->debug("MD5AnimParser end");
-}
-
-// ------------------------------------------------------------------------------------------------
-// .MD5CAMERA parsing function
-MD5CameraParser::MD5CameraParser(SectionList& mSections)
-{
- DefaultLogger::get()->debug("MD5CameraParser begin");
- fFrameRate = 24.0f;
-
- for (SectionList::const_iterator iter = mSections.begin(), iterEnd = mSections.end();iter != iterEnd;++iter) {
- if ((*iter).mName == "numFrames") {
- frames.reserve(strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "frameRate") {
- fFrameRate = fast_atof ((*iter).mGlobalValue.c_str());
- }
- else if ((*iter).mName == "numCuts") {
- cuts.reserve(strtoul10((*iter).mGlobalValue.c_str()));
- }
- else if ((*iter).mName == "cuts") {
- for (const auto & elem : (*iter).mElements){
- cuts.push_back(strtoul10(elem.szStart)+1);
- }
- }
- else if ((*iter).mName == "camera") {
- for (const auto & elem : (*iter).mElements){
- const char* sz = elem.szStart;
-
- frames.push_back(CameraAnimFrameDesc());
- CameraAnimFrameDesc& cur = frames.back();
- AI_MD5_READ_TRIPLE(cur.vPositionXYZ);
- AI_MD5_READ_TRIPLE(cur.vRotationQuat);
- AI_MD5_SKIP_SPACES();
- cur.fFOV = fast_atof(sz);
- }
- }
- }
- DefaultLogger::get()->debug("MD5CameraParser end");
-}
-
diff --git a/src/3rdparty/assimp/code/MD5Parser.h b/src/3rdparty/assimp/code/MD5Parser.h
deleted file mode 100644
index bafcaf962..000000000
--- a/src/3rdparty/assimp/code/MD5Parser.h
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MD5Parser.h
- * @brief Definition of the .MD5 parser class.
- * http://www.modwiki.net/wiki/MD5_(file_format)
- */
-#ifndef AI_MD5PARSER_H_INCLUDED
-#define AI_MD5PARSER_H_INCLUDED
-
-#include <assimp/types.h>
-#include "ParsingUtils.h"
-#include <vector>
-#include <stdint.h>
-
-struct aiFace;
-
-namespace Assimp {
-namespace MD5 {
-
-// ---------------------------------------------------------------------------
-/** Represents a single element in a MD5 file
- *
- * Elements are always contained in sections.
-*/
-struct Element
-{
- //! Points to the starting point of the element
- //! Whitespace at the beginning and at the end have been removed,
- //! Elements are terminated with \0
- char* szStart;
-
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
-};
-
-typedef std::vector< Element > ElementList;
-
-// ---------------------------------------------------------------------------
-/** Represents a section of a MD5 file (such as the mesh or the joints section)
- *
- * A section is always enclosed in { and } brackets.
-*/
-struct Section
-{
- //! Original line number (can be used in error messages
- //! if a parsing error occurs)
- unsigned int iLineNumber;
-
- //! List of all elements which have been parsed in this section.
- ElementList mElements;
-
- //! Name of the section
- std::string mName;
-
- //! For global elements: the value of the element as string
- //! Iif !length() the section is not a global element
- std::string mGlobalValue;
-};
-
-typedef std::vector< Section> SectionList;
-
-// ---------------------------------------------------------------------------
-/** Basic information about a joint
-*/
-struct BaseJointDescription
-{
- //! Name of the bone
- aiString mName;
-
- //! Parent index of the bone
- int mParentIndex;
-};
-
-// ---------------------------------------------------------------------------
-/** Represents a bone (joint) descriptor in a MD5Mesh file
-*/
-struct BoneDesc : BaseJointDescription
-{
- //! Absolute position of the bone
- aiVector3D mPositionXYZ;
-
- //! Absolute rotation of the bone
- aiVector3D mRotationQuat;
- aiQuaternion mRotationQuatConverted;
-
- //! Absolute transformation of the bone
- //! (temporary)
- aiMatrix4x4 mTransform;
-
- //! Inverse transformation of the bone
- //! (temporary)
- aiMatrix4x4 mInvTransform;
-
- //! Internal
- unsigned int mMap;
-};
-
-typedef std::vector< BoneDesc > BoneList;
-
-// ---------------------------------------------------------------------------
-/** Represents a bone (joint) descriptor in a MD5Anim file
-*/
-struct AnimBoneDesc : BaseJointDescription
-{
- //! Flags (AI_MD5_ANIMATION_FLAG_xxx)
- unsigned int iFlags;
-
- //! Index of the first key that corresponds to this anim bone
- unsigned int iFirstKeyIndex;
-};
-
-typedef std::vector< AnimBoneDesc > AnimBoneList;
-
-
-// ---------------------------------------------------------------------------
-/** Represents a base frame descriptor in a MD5Anim file
-*/
-struct BaseFrameDesc
-{
- aiVector3D vPositionXYZ;
- aiVector3D vRotationQuat;
-};
-
-typedef std::vector< BaseFrameDesc > BaseFrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a camera animation frame in a MDCamera file
-*/
-struct CameraAnimFrameDesc : BaseFrameDesc
-{
- float fFOV;
-};
-
-typedef std::vector< CameraAnimFrameDesc > CameraFrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a frame descriptor in a MD5Anim file
-*/
-struct FrameDesc
-{
- //! Index of the frame
- unsigned int iIndex;
-
- //! Animation keyframes - a large blob of data at first
- std::vector< float > mValues;
-};
-
-typedef std::vector< FrameDesc > FrameList;
-
-// ---------------------------------------------------------------------------
-/** Represents a vertex descriptor in a MD5 file
-*/
-struct VertexDesc
-{
- VertexDesc()
- : mFirstWeight (0)
- , mNumWeights (0)
- {}
-
- //! UV cordinate of the vertex
- aiVector2D mUV;
-
- //! Index of the first weight of the vertex in
- //! the vertex weight list
- unsigned int mFirstWeight;
-
- //! Number of weights assigned to this vertex
- unsigned int mNumWeights;
-};
-
-typedef std::vector< VertexDesc > VertexList;
-
-// ---------------------------------------------------------------------------
-/** Represents a vertex weight descriptor in a MD5 file
-*/
-struct WeightDesc
-{
- //! Index of the bone to which this weight refers
- unsigned int mBone;
-
- //! The weight value
- float mWeight;
-
- //! The offset position of this weight
- // ! (in the coordinate system defined by the parent bone)
- aiVector3D vOffsetPosition;
-};
-
-typedef std::vector< WeightDesc > WeightList;
-typedef std::vector< aiFace > FaceList;
-
-// ---------------------------------------------------------------------------
-/** Represents a mesh in a MD5 file
-*/
-struct MeshDesc
-{
- //! Weights of the mesh
- WeightList mWeights;
-
- //! Vertices of the mesh
- VertexList mVertices;
-
- //! Faces of the mesh
- FaceList mFaces;
-
- //! Name of the shader (=texture) to be assigned to the mesh
- aiString mShader;
-};
-
-typedef std::vector< MeshDesc > MeshList;
-
-// ---------------------------------------------------------------------------
-// Convert a quaternion to its usual representation
-inline void ConvertQuaternion (const aiVector3D& in, aiQuaternion& out) {
-
- out.x = in.x;
- out.y = in.y;
- out.z = in.z;
-
- const float t = 1.0f - (in.x*in.x) - (in.y*in.y) - (in.z*in.z);
-
- if (t < 0.0f)
- out.w = 0.0f;
- else out.w = std::sqrt (t);
-
- // Assimp convention.
- out.w *= -1.f;
-}
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 mesh file
-*/
-class MD5MeshParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5MeshParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5MeshParser(SectionList& mSections);
-
- //! List of all meshes
- MeshList mMeshes;
-
- //! List of all joints
- BoneList mJoints;
-};
-
-// remove this flag if you need to the bounding box data
-#define AI_MD5_PARSE_NO_BOUNDS
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 animation file
-*/
-class MD5AnimParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5AnimParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5AnimParser(SectionList& mSections);
-
-
- //! Output frame rate
- float fFrameRate;
-
- //! List of animation bones
- AnimBoneList mAnimatedBones;
-
- //! List of base frames
- BaseFrameList mBaseFrames;
-
- //! List of animation frames
- FrameList mFrames;
-
- //! Number of animated components
- unsigned int mNumAnimatedComponents;
-};
-
-// ---------------------------------------------------------------------------
-/** Parses the data sections of a MD5 camera animation file
-*/
-class MD5CameraParser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5CameraParser instance from an existing
- * preparsed list of file sections.
- *
- * @param mSections List of file sections (output of MD5Parser)
- */
- explicit MD5CameraParser(SectionList& mSections);
-
-
- //! Output frame rate
- float fFrameRate;
-
- //! List of cuts
- std::vector<unsigned int> cuts;
-
- //! Frames
- CameraFrameList frames;
-};
-
-// ---------------------------------------------------------------------------
-/** Parses the block structure of MD5MESH and MD5ANIM files (but does no
- * further processing)
-*/
-class MD5Parser
-{
-public:
-
- // -------------------------------------------------------------------
- /** Constructs a new MD5Parser instance from an existing buffer.
- *
- * @param buffer File buffer
- * @param fileSize Length of the file in bytes (excluding a terminal 0)
- */
- MD5Parser(char* buffer, unsigned int fileSize);
-
-
- // -------------------------------------------------------------------
- /** Report a specific error message and throw an exception
- * @param error Error message to be reported
- * @param line Index of the line where the error occurred
- */
- AI_WONT_RETURN static void ReportError (const char* error, unsigned int line) AI_WONT_RETURN_SUFFIX;
-
- // -------------------------------------------------------------------
- /** Report a specific warning
- * @param warn Warn message to be reported
- * @param line Index of the line where the error occurred
- */
- static void ReportWarning (const char* warn, unsigned int line);
-
-
- void ReportError (const char* error) {
- return ReportError(error, lineNumber);
- }
-
- void ReportWarning (const char* warn) {
- return ReportWarning(warn, lineNumber);
- }
-
-public:
-
- //! List of all sections which have been read
- SectionList mSections;
-
-private:
-
- // -------------------------------------------------------------------
- /** Parses a file section. The current file pointer must be outside
- * of a section.
- * @param out Receives the section data
- * @return true if the end of the file has been reached
- * @throws ImportErrorException if an error occurs
- */
- bool ParseSection(Section& out);
-
- // -------------------------------------------------------------------
- /** Parses the file header
- * @throws ImportErrorException if an error occurs
- */
- void ParseHeader();
-
-
- // override these functions to make sure the line counter gets incremented
- // -------------------------------------------------------------------
- bool SkipLine( const char* in, const char** out)
- {
- ++lineNumber;
- return Assimp::SkipLine(in,out);
- }
- // -------------------------------------------------------------------
- bool SkipLine( )
- {
- return SkipLine(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- bool SkipSpacesAndLineEnd( const char* in, const char** out)
- {
- bool bHad = false;
- bool running = true;
- while (running) {
- if( *in == '\r' || *in == '\n') {
- // we open files in binary mode, so there could be \r\n sequences ...
- if (!bHad) {
- bHad = true;
- ++lineNumber;
- }
- }
- else if (*in == '\t' || *in == ' ')bHad = false;
- else break;
- in++;
- }
- *out = in;
- return *in != '\0';
- }
- // -------------------------------------------------------------------
- bool SkipSpacesAndLineEnd( )
- {
- return SkipSpacesAndLineEnd(buffer,(const char**)&buffer);
- }
- // -------------------------------------------------------------------
- bool SkipSpaces( )
- {
- return Assimp::SkipSpaces((const char**)&buffer);
- }
-
- char* buffer;
- unsigned int fileSize;
- unsigned int lineNumber;
-};
-}}
-
-#endif // AI_MD5PARSER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/MDCFileData.h b/src/3rdparty/assimp/code/MDCFileData.h
deleted file mode 100644
index 9ea3d8f5e..000000000
--- a/src/3rdparty/assimp/code/MDCFileData.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the helper data structures for importing MDC files
-
-**********************************************************************
-File format specification:
-http://themdcfile.planetwolfenstein.gamespy.com/MDC_File_Format.pdf
-**********************************************************************
-
-*/
-#ifndef AI_MDCFILEHELPER_H_INC
-#define AI_MDCFILEHELPER_H_INC
-
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-#include <assimp/anim.h>
-
-#include <assimp/Compiler/pushpack1.h>
-#include <stdint.h>
-
-namespace Assimp {
-namespace MDC {
-
-
-// to make it easier for us, we test the magic word against both "endianesses"
-#define AI_MDC_MAGIC_NUMBER_BE AI_MAKE_MAGIC("CPDI")
-#define AI_MDC_MAGIC_NUMBER_LE AI_MAKE_MAGIC("IDPC")
-
-// common limitations
-#define AI_MDC_VERSION 2
-#define AI_MDC_MAXQPATH 64
-#define AI_MDC_MAX_BONES 128
-
-#define AI_MDC_CVERT_BIAS 127.0f
-#define AI_MDC_DELTA_SCALING 4.0f
-#define AI_MDC_BASE_SCALING (1.0f / 64.0f)
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC file's main header
- */
-struct Header
-{
- uint32_t ulIdent ;
- uint32_t ulVersion ;
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulFlags ;
- uint32_t ulNumFrames ;
- uint32_t ulNumTags ;
- uint32_t ulNumSurfaces ;
- uint32_t ulNumSkins ;
- uint32_t ulOffsetBorderFrames ;
- uint32_t ulOffsetTagNames ;
- uint32_t ulOffsetTagFrames ;
- uint32_t ulOffsetSurfaces ;
- uint32_t ulOffsetEnd ;
-} PACK_STRUCT ;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC file's surface header
- */
-struct Surface
-{
- uint32_t ulIdent ;
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulFlags ;
- uint32_t ulNumCompFrames ;
- uint32_t ulNumBaseFrames ;
- uint32_t ulNumShaders ;
- uint32_t ulNumVertices ;
- uint32_t ulNumTriangles ;
- uint32_t ulOffsetTriangles ;
- uint32_t ulOffsetShaders ;
- uint32_t ulOffsetTexCoords ;
- uint32_t ulOffsetBaseVerts ;
- uint32_t ulOffsetCompVerts ;
- uint32_t ulOffsetFrameBaseFrames ;
- uint32_t ulOffsetFrameCompFrames ;
- uint32_t ulOffsetEnd;
- Surface()
- : ulIdent(),
- ulFlags(),
- ulNumCompFrames(),
- ulNumBaseFrames(),
- ulNumShaders(),
- ulNumVertices(),
- ulNumTriangles(),
- ulOffsetTriangles(),
- ulOffsetShaders(),
- ulOffsetTexCoords(),
- ulOffsetBaseVerts(),
- ulOffsetCompVerts(),
- ulOffsetFrameBaseFrames(),
- ulOffsetFrameCompFrames(),
- ulOffsetEnd()
- {
- ucName[AI_MDC_MAXQPATH-1] = '\0';
- }
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC frame
- */
-struct Frame
-{
- //! bounding box minimum coords
- aiVector3D bboxMin ;
-
- //! bounding box maximum coords
- aiVector3D bboxMax ;
-
- //! local origin of the frame
- aiVector3D localOrigin ;
-
- //! radius of the BB
- float radius ;
-
- //! Name of the frame
- char name [ 16 ] ;
-} /*PACK_STRUCT*/;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC triangle
- */
-struct Triangle
-{
- uint32_t aiIndices[3];
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC texture coordinate
- */
-struct TexturCoord
-{
- float u,v;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC base vertex
- */
-struct BaseVertex
-{
- int16_t x,y,z;
- uint16_t normal;
-} PACK_STRUCT;
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC compressed vertex
- */
-struct CompressedVertex
-{
- uint8_t xd,yd,zd,nd;
-} PACK_STRUCT;
-
-
-// ---------------------------------------------------------------------------
-/** \brief Data structure for a MDC shader
- */
-struct Shader
-{
- char ucName [ AI_MDC_MAXQPATH ] ;
- uint32_t ulPath;
-
-} PACK_STRUCT;
-
-#include <assimp/Compiler/poppack1.h>
-
-
-// ---------------------------------------------------------------------------
-/** Build a floating point vertex from the compressed data in MDC files
- */
-void BuildVertex(const Frame& frame,
- const BaseVertex& bvert,
- const CompressedVertex& cvert,
- aiVector3D& vXYZOut,
- aiVector3D& vNorOut);
-}}
-
-#endif // !! AI_MDCFILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/MDCLoader.cpp b/src/3rdparty/assimp/code/MDCLoader.cpp
deleted file mode 100644
index 21aca53ff..000000000
--- a/src/3rdparty/assimp/code/MDCLoader.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the MDC importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_MDC_IMPORTER
-
-// internal headers
-#include "MDCLoader.h"
-#include "MD3FileData.h"
-#include "MDCNormalTable.h" // shouldn't be included by other units
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-
-using namespace Assimp;
-using namespace Assimp::MDC;
-
-static const aiImporterDesc desc = {
- "Return To Castle Wolfenstein Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "mdc"
-};
-
-// ------------------------------------------------------------------------------------------------
-void MDC::BuildVertex(const Frame& frame,
- const BaseVertex& bvert,
- const CompressedVertex& cvert,
- aiVector3D& vXYZOut,
- aiVector3D& vNorOut)
-{
- // compute the position
- const float xd = (cvert.xd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float yd = (cvert.yd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- const float zd = (cvert.zd - AI_MDC_CVERT_BIAS) * AI_MDC_DELTA_SCALING;
- vXYZOut.x = frame.localOrigin.x + AI_MDC_BASE_SCALING * (bvert.x + xd);
- vXYZOut.y = frame.localOrigin.y + AI_MDC_BASE_SCALING * (bvert.y + yd);
- vXYZOut.z = frame.localOrigin.z + AI_MDC_BASE_SCALING * (bvert.z + zd);
-
- // compute the normal vector .. ehm ... lookup it in the table :-)
- vNorOut.x = mdcNormals[cvert.nd][0];
- vNorOut.y = mdcNormals[cvert.nd][1];
- vNorOut.z = mdcNormals[cvert.nd][2];
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MDCImporter::MDCImporter()
- : configFrameID(),
- pcHeader(),
- mBuffer(),
- fileSize()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MDCImporter::~MDCImporter()
-{
-}
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MDCImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
- if (extension == "mdc")
- return true;
-
- // if check for extension is not enough, check for the magic tokens
- if (!extension.length() || checkSig) {
- uint32_t tokens[1];
- tokens[0] = AI_MDC_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* MDCImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of the given MDC file
-void MDCImporter::ValidateHeader()
-{
- AI_SWAP4( this->pcHeader->ulVersion );
- AI_SWAP4( this->pcHeader->ulFlags );
- AI_SWAP4( this->pcHeader->ulNumFrames );
- AI_SWAP4( this->pcHeader->ulNumTags );
- AI_SWAP4( this->pcHeader->ulNumSurfaces );
- AI_SWAP4( this->pcHeader->ulNumSkins );
- AI_SWAP4( this->pcHeader->ulOffsetBorderFrames );
-
- if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
- pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE)
- {
- char szBuffer[5];
- szBuffer[0] = ((char*)&pcHeader->ulIdent)[0];
- szBuffer[1] = ((char*)&pcHeader->ulIdent)[1];
- szBuffer[2] = ((char*)&pcHeader->ulIdent)[2];
- szBuffer[3] = ((char*)&pcHeader->ulIdent)[3];
- szBuffer[4] = '\0';
-
- throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
- "magic word found is " + std::string( szBuffer ));
- }
-
- if (pcHeader->ulVersion != AI_MDC_VERSION)
- DefaultLogger::get()->warn("Unsupported MDC file version (2 (AI_MDC_VERSION) was expected)");
-
- if (pcHeader->ulOffsetBorderFrames + pcHeader->ulNumFrames * sizeof(MDC::Frame) > this->fileSize ||
- pcHeader->ulOffsetSurfaces + pcHeader->ulNumSurfaces * sizeof(MDC::Surface) > this->fileSize)
- {
- throw DeadlyImportError("Some of the offset values in the MDC header are invalid "
- "and point to something behind the file.");
- }
-
- if (this->configFrameID >= this->pcHeader->ulNumFrames)
- throw DeadlyImportError("The requested frame is not available");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of a given MDC file surface
-void MDCImporter::ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf)
-{
- AI_SWAP4(pcSurf->ulFlags);
- AI_SWAP4(pcSurf->ulNumCompFrames);
- AI_SWAP4(pcSurf->ulNumBaseFrames);
- AI_SWAP4(pcSurf->ulNumShaders);
- AI_SWAP4(pcSurf->ulNumVertices);
- AI_SWAP4(pcSurf->ulNumTriangles);
- AI_SWAP4(pcSurf->ulOffsetTriangles);
- AI_SWAP4(pcSurf->ulOffsetTexCoords);
- AI_SWAP4(pcSurf->ulOffsetBaseVerts);
- AI_SWAP4(pcSurf->ulOffsetCompVerts);
- AI_SWAP4(pcSurf->ulOffsetFrameBaseFrames);
- AI_SWAP4(pcSurf->ulOffsetFrameCompFrames);
- AI_SWAP4(pcSurf->ulOffsetEnd);
-
- const unsigned int iMax = this->fileSize - (unsigned int)((int8_t*)pcSurf-(int8_t*)pcHeader);
-
- if (pcSurf->ulOffsetBaseVerts + pcSurf->ulNumVertices * sizeof(MDC::BaseVertex) > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetCompVerts + pcSurf->ulNumVertices * sizeof(MDC::CompressedVertex) > iMax) ||
- pcSurf->ulOffsetTriangles + pcSurf->ulNumTriangles * sizeof(MDC::Triangle) > iMax ||
- pcSurf->ulOffsetTexCoords + pcSurf->ulNumVertices * sizeof(MDC::TexturCoord) > iMax ||
- pcSurf->ulOffsetShaders + pcSurf->ulNumShaders * sizeof(MDC::Shader) > iMax ||
- pcSurf->ulOffsetFrameBaseFrames + pcSurf->ulNumBaseFrames * 2 > iMax ||
- (pcSurf->ulNumCompFrames && pcSurf->ulOffsetFrameCompFrames + pcSurf->ulNumCompFrames * 2 > iMax))
- {
- throw DeadlyImportError("Some of the offset values in the MDC surface header "
- "are invalid and point somewhere behind the file.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MDCImporter::SetupProperties(const Importer* pImp)
-{
- // The AI_CONFIG_IMPORT_MDC_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- if(static_cast<unsigned int>(-1) == (configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDC_KEYFRAME,-1))){
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MDCImporter::InternReadFile(
- const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open MDC file " + pFile + ".");
-
- // check whether the mdc file is large enough to contain the file header
- fileSize = (unsigned int)file->FileSize();
- if( fileSize < sizeof(MDC::Header))
- throw DeadlyImportError( "MDC File is too small.");
-
- std::vector<unsigned char> mBuffer2(fileSize);
- file->Read( &mBuffer2[0], 1, fileSize);
- mBuffer = &mBuffer2[0];
-
- // validate the file header
- this->pcHeader = (BE_NCONST MDC::Header*)this->mBuffer;
- this->ValidateHeader();
-
- std::vector<std::string> aszShaders;
-
- // get a pointer to the frame we want to read
- BE_NCONST MDC::Frame* pcFrame = (BE_NCONST MDC::Frame*)(this->mBuffer+
- this->pcHeader->ulOffsetBorderFrames);
-
- // no need to swap the other members, we won't need them
- pcFrame += configFrameID;
- AI_SWAP4( pcFrame->localOrigin[0] );
- AI_SWAP4( pcFrame->localOrigin[1] );
- AI_SWAP4( pcFrame->localOrigin[2] );
-
- // get the number of valid surfaces
- BE_NCONST MDC::Surface* pcSurface, *pcSurface2;
- pcSurface = pcSurface2 = new (mBuffer + pcHeader->ulOffsetSurfaces) MDC::Surface;
- unsigned int iNumShaders = 0;
- for (unsigned int i = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- // validate the surface header
- this->ValidateSurfaceHeader(pcSurface2);
-
- if (pcSurface2->ulNumVertices && pcSurface2->ulNumTriangles)++pScene->mNumMeshes;
- iNumShaders += pcSurface2->ulNumShaders;
- pcSurface2 = new ((int8_t*)pcSurface2 + pcSurface2->ulOffsetEnd) MDC::Surface;
- }
- aszShaders.reserve(iNumShaders);
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- // necessary that we don't crash if an exception occurs
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i] = NULL;
-
- // now read all surfaces
- unsigned int iDefaultMatIndex = UINT_MAX;
- for (unsigned int i = 0, iNum = 0; i < pcHeader->ulNumSurfaces;++i)
- {
- if (!pcSurface->ulNumVertices || !pcSurface->ulNumTriangles)continue;
- aiMesh* pcMesh = pScene->mMeshes[iNum++] = new aiMesh();
-
- pcMesh->mNumFaces = pcSurface->ulNumTriangles;
- pcMesh->mNumVertices = pcMesh->mNumFaces * 3;
-
- // store the name of the surface for use as node name.
- // FIX: make sure there is a 0 termination
- const_cast<char&>(pcSurface->ucName[AI_MDC_MAXQPATH-1]) = '\0';
- pcMesh->mTextureCoords[3] = (aiVector3D*)pcSurface->ucName;
-
- // go to the first shader in the file. ignore the others.
- if (pcSurface->ulNumShaders)
- {
- const MDC::Shader* pcShader = (const MDC::Shader*)((int8_t*)pcSurface + pcSurface->ulOffsetShaders);
- pcMesh->mMaterialIndex = (unsigned int)aszShaders.size();
-
- // create a new shader
- aszShaders.push_back(std::string( pcShader->ucName, std::min(
- ::strlen(pcShader->ucName),sizeof(pcShader->ucName)) ));
- }
- // need to create a default material
- else if (UINT_MAX == iDefaultMatIndex)
- {
- pcMesh->mMaterialIndex = iDefaultMatIndex = (unsigned int)aszShaders.size();
- aszShaders.push_back(std::string());
- }
- // otherwise assign a reference to the default material
- else pcMesh->mMaterialIndex = iDefaultMatIndex;
-
- // allocate output storage for the mesh
- aiVector3D* pcVertCur = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcNorCur = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcUVCur = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- aiFace* pcFaceCur = pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- // create all vertices/faces
- BE_NCONST MDC::Triangle* pcTriangle = (BE_NCONST MDC::Triangle*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTriangles);
-
- BE_NCONST MDC::TexturCoord* const pcUVs = (BE_NCONST MDC::TexturCoord*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetTexCoords);
-
- // get a pointer to the uncompressed vertices
- int16_t iOfs = *((int16_t*) ((int8_t*) pcSurface +
- pcSurface->ulOffsetFrameBaseFrames) + this->configFrameID);
-
- AI_SWAP2(iOfs);
-
- BE_NCONST MDC::BaseVertex* const pcVerts = (BE_NCONST MDC::BaseVertex*)
- ((int8_t*)pcSurface+pcSurface->ulOffsetBaseVerts) +
- ((int)iOfs * pcSurface->ulNumVertices * 4);
-
- // do the main swapping stuff ...
-#if (defined AI_BUILD_BIG_ENDIAN)
-
- // swap all triangles
- for (unsigned int i = 0; i < pcSurface->ulNumTriangles;++i)
- {
- AI_SWAP4( pcTriangle[i].aiIndices[0] );
- AI_SWAP4( pcTriangle[i].aiIndices[1] );
- AI_SWAP4( pcTriangle[i].aiIndices[2] );
- }
-
- // swap all vertices
- for (unsigned int i = 0; i < pcSurface->ulNumVertices*pcSurface->ulNumBaseFrames;++i)
- {
- AI_SWAP2( pcVerts->normal );
- AI_SWAP2( pcVerts->x );
- AI_SWAP2( pcVerts->y );
- AI_SWAP2( pcVerts->z );
- }
-
- // swap all texture coordinates
- for (unsigned int i = 0; i < pcSurface->ulNumVertices;++i)
- {
- AI_SWAP4( pcUVs->v );
- AI_SWAP4( pcUVs->v );
- }
-
-#endif
-
- const MDC::CompressedVertex* pcCVerts = NULL;
- int16_t* mdcCompVert = NULL;
-
- // access compressed frames for large frame numbers, but never for the first
- if( this->configFrameID && pcSurface->ulNumCompFrames > 0 )
- {
- mdcCompVert = (int16_t*) ((int8_t*)pcSurface+pcSurface->ulOffsetFrameCompFrames) + this->configFrameID;
- AI_SWAP2P(mdcCompVert);
- if( *mdcCompVert >= 0 )
- {
- pcCVerts = (const MDC::CompressedVertex*)((int8_t*)pcSurface +
- pcSurface->ulOffsetCompVerts) + *mdcCompVert * pcSurface->ulNumVertices;
- }
- else mdcCompVert = NULL;
- }
-
- // copy all faces
- for (unsigned int iFace = 0; iFace < pcSurface->ulNumTriangles;++iFace,
- ++pcTriangle,++pcFaceCur)
- {
- const unsigned int iOutIndex = iFace*3;
- pcFaceCur->mNumIndices = 3;
- pcFaceCur->mIndices = new unsigned int[3];
-
- for (unsigned int iIndex = 0; iIndex < 3;++iIndex,
- ++pcVertCur,++pcUVCur,++pcNorCur)
- {
- uint32_t quak = pcTriangle->aiIndices[iIndex];
- if (quak >= pcSurface->ulNumVertices)
- {
- DefaultLogger::get()->error("MDC vertex index is out of range");
- quak = pcSurface->ulNumVertices-1;
- }
-
- // compressed vertices?
- if (mdcCompVert)
- {
- MDC::BuildVertex(*pcFrame,pcVerts[quak],pcCVerts[quak],
- *pcVertCur,*pcNorCur);
- }
- else
- {
- // copy position
- pcVertCur->x = pcVerts[quak].x * AI_MDC_BASE_SCALING;
- pcVertCur->y = pcVerts[quak].y * AI_MDC_BASE_SCALING;
- pcVertCur->z = pcVerts[quak].z * AI_MDC_BASE_SCALING;
-
- // copy normals
- MD3::LatLngNormalToVec3( pcVerts[quak].normal, &pcNorCur->x );
-
- // copy texture coordinates
- pcUVCur->x = pcUVs[quak].u;
- pcUVCur->y = ai_real( 1.0 )-pcUVs[quak].v; // DX to OGL
- }
- pcVertCur->x += pcFrame->localOrigin[0] ;
- pcVertCur->y += pcFrame->localOrigin[1] ;
- pcVertCur->z += pcFrame->localOrigin[2] ;
- }
-
- // swap the face order - DX to OGL
- pcFaceCur->mIndices[0] = iOutIndex + 2;
- pcFaceCur->mIndices[1] = iOutIndex + 1;
- pcFaceCur->mIndices[2] = iOutIndex + 0;
- }
-
- pcSurface = new ((int8_t*)pcSurface + pcSurface->ulOffsetEnd) MDC::Surface;
- }
-
- // create a flat node graph with a root node and one child for each surface
- if (!pScene->mNumMeshes)
- throw DeadlyImportError( "Invalid MDC file: File contains no valid mesh");
- else if (1 == pScene->mNumMeshes)
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set(std::string((const char*)pScene->mMeshes[0]->mTextureCoords[3]));
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumChildren = pScene->mNumMeshes;
- pScene->mRootNode->mChildren = new aiNode*[pScene->mNumMeshes];
- pScene->mRootNode->mName.Set("<root>");
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiNode* pcNode = pScene->mRootNode->mChildren[i] = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.Set(std::string((const char*)pScene->mMeshes[i]->mTextureCoords[3]));
- pcNode->mNumMeshes = 1;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- }
- }
-
- // make sure we invalidate the pointer to the mesh name
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mMeshes[i]->mTextureCoords[3] = NULL;
-
- // create materials
- pScene->mNumMaterials = (unsigned int)aszShaders.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- aiMaterial* pcMat = new aiMaterial();
- pScene->mMaterials[i] = pcMat;
-
- const std::string& name = aszShaders[i];
-
- int iMode = (int)aiShadingMode_Gouraud;
- pcMat->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // add a small ambient color value - RtCW seems to have one
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.05f;
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- if (name.length())clr.b = clr.g = clr.r = 1.0f;
- else clr.b = clr.g = clr.r = 0.6f;
-
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcMat->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- if (name.length())
- {
- aiString path;
- path.Set(name);
- pcMat->AddProperty(&path,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER
diff --git a/src/3rdparty/assimp/code/MDCLoader.h b/src/3rdparty/assimp/code/MDCLoader.h
deleted file mode 100644
index 5f3b365fd..000000000
--- a/src/3rdparty/assimp/code/MDCLoader.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MDCLoader.h
- * @brief Definition of the MDC importer class.
- */
-#ifndef AI_MDCLOADER_H_INCLUDED
-#define AI_MDCLOADER_H_INCLUDED
-
-#include <assimp/types.h>
-
-#include "BaseImporter.h"
-#include "MDCFileData.h"
-#include "ByteSwapper.h"
-
-namespace Assimp {
-
-using namespace MDC;
-
-// ---------------------------------------------------------------------------
-/** Importer class to load the RtCW MDC file format
-*/
-class MDCImporter : public BaseImporter
-{
-public:
- MDCImporter();
- ~MDCImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Validate the header of the file
- */
- void ValidateHeader();
-
- // -------------------------------------------------------------------
- /** Validate the header of a MDC surface
- */
- void ValidateSurfaceHeader(BE_NCONST MDC::Surface* pcSurf);
-
-protected:
-
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Header of the MDC file */
- BE_NCONST MDC::Header* pcHeader;
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** size of the file, in bytes */
- unsigned int fileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/MDCNormalTable.h b/src/3rdparty/assimp/code/MDCNormalTable.h
deleted file mode 100644
index f47e97f33..000000000
--- a/src/3rdparty/assimp/code/MDCNormalTable.h
+++ /dev/null
@@ -1,299 +0,0 @@
-/* -----------------------------------------------------------------------------
-
-PicoModel Library
-
-Copyright (c) 2002, Randy Reddig & seaw0lf
-All rights reserved.
-
-Redistribution and use 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 names of the copyright holders nor the names of its contributors may
-be used to endorse or promote products derived from this software without
-specific prior written permission.
-
-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.
-
------------------------------------------------------------------------------ */
-
-#if (!defined MDC_NORMAL_TABLE_INCLUDED)
-#define MDC_NORMAL_TABLE_INCLUDED
-
-/* mdc decoding normal table */
-float mdcNormals[ 256 ][ 3 ] =
-{
- { 1.000000f, 0.000000f, 0.000000f },
- { 0.980785f, 0.195090f, 0.000000f },
- { 0.923880f, 0.382683f, 0.000000f },
- { 0.831470f, 0.555570f, 0.000000f },
- { 0.707107f, 0.707107f, 0.000000f },
- { 0.555570f, 0.831470f, 0.000000f },
- { 0.382683f, 0.923880f, 0.000000f },
- { 0.195090f, 0.980785f, 0.000000f },
- { -0.000000f, 1.000000f, 0.000000f },
- { -0.195090f, 0.980785f, 0.000000f },
- { -0.382683f, 0.923880f, 0.000000f },
- { -0.555570f, 0.831470f, 0.000000f },
- { -0.707107f, 0.707107f, 0.000000f },
- { -0.831470f, 0.555570f, 0.000000f },
- { -0.923880f, 0.382683f, 0.000000f },
- { -0.980785f, 0.195090f, 0.000000f },
- { -1.000000f, -0.000000f, 0.000000f },
- { -0.980785f, -0.195090f, 0.000000f },
- { -0.923880f, -0.382683f, 0.000000f },
- { -0.831470f, -0.555570f, 0.000000f },
- { -0.707107f, -0.707107f, 0.000000f },
- { -0.555570f, -0.831469f, 0.000000f },
- { -0.382684f, -0.923880f, 0.000000f },
- { -0.195090f, -0.980785f, 0.000000f },
- { 0.000000f, -1.000000f, 0.000000f },
- { 0.195090f, -0.980785f, 0.000000f },
- { 0.382684f, -0.923879f, 0.000000f },
- { 0.555570f, -0.831470f, 0.000000f },
- { 0.707107f, -0.707107f, 0.000000f },
- { 0.831470f, -0.555570f, 0.000000f },
- { 0.923880f, -0.382683f, 0.000000f },
- { 0.980785f, -0.195090f, 0.000000f },
- { 0.980785f, 0.000000f, -0.195090f },
- { 0.956195f, 0.218245f, -0.195090f },
- { 0.883657f, 0.425547f, -0.195090f },
- { 0.766809f, 0.611510f, -0.195090f },
- { 0.611510f, 0.766809f, -0.195090f },
- { 0.425547f, 0.883657f, -0.195090f },
- { 0.218245f, 0.956195f, -0.195090f },
- { -0.000000f, 0.980785f, -0.195090f },
- { -0.218245f, 0.956195f, -0.195090f },
- { -0.425547f, 0.883657f, -0.195090f },
- { -0.611510f, 0.766809f, -0.195090f },
- { -0.766809f, 0.611510f, -0.195090f },
- { -0.883657f, 0.425547f, -0.195090f },
- { -0.956195f, 0.218245f, -0.195090f },
- { -0.980785f, -0.000000f, -0.195090f },
- { -0.956195f, -0.218245f, -0.195090f },
- { -0.883657f, -0.425547f, -0.195090f },
- { -0.766809f, -0.611510f, -0.195090f },
- { -0.611510f, -0.766809f, -0.195090f },
- { -0.425547f, -0.883657f, -0.195090f },
- { -0.218245f, -0.956195f, -0.195090f },
- { 0.000000f, -0.980785f, -0.195090f },
- { 0.218245f, -0.956195f, -0.195090f },
- { 0.425547f, -0.883657f, -0.195090f },
- { 0.611510f, -0.766809f, -0.195090f },
- { 0.766809f, -0.611510f, -0.195090f },
- { 0.883657f, -0.425547f, -0.195090f },
- { 0.956195f, -0.218245f, -0.195090f },
- { 0.923880f, 0.000000f, -0.382683f },
- { 0.892399f, 0.239118f, -0.382683f },
- { 0.800103f, 0.461940f, -0.382683f },
- { 0.653281f, 0.653281f, -0.382683f },
- { 0.461940f, 0.800103f, -0.382683f },
- { 0.239118f, 0.892399f, -0.382683f },
- { -0.000000f, 0.923880f, -0.382683f },
- { -0.239118f, 0.892399f, -0.382683f },
- { -0.461940f, 0.800103f, -0.382683f },
- { -0.653281f, 0.653281f, -0.382683f },
- { -0.800103f, 0.461940f, -0.382683f },
- { -0.892399f, 0.239118f, -0.382683f },
- { -0.923880f, -0.000000f, -0.382683f },
- { -0.892399f, -0.239118f, -0.382683f },
- { -0.800103f, -0.461940f, -0.382683f },
- { -0.653282f, -0.653281f, -0.382683f },
- { -0.461940f, -0.800103f, -0.382683f },
- { -0.239118f, -0.892399f, -0.382683f },
- { 0.000000f, -0.923880f, -0.382683f },
- { 0.239118f, -0.892399f, -0.382683f },
- { 0.461940f, -0.800103f, -0.382683f },
- { 0.653281f, -0.653282f, -0.382683f },
- { 0.800103f, -0.461940f, -0.382683f },
- { 0.892399f, -0.239117f, -0.382683f },
- { 0.831470f, 0.000000f, -0.555570f },
- { 0.790775f, 0.256938f, -0.555570f },
- { 0.672673f, 0.488726f, -0.555570f },
- { 0.488726f, 0.672673f, -0.555570f },
- { 0.256938f, 0.790775f, -0.555570f },
- { -0.000000f, 0.831470f, -0.555570f },
- { -0.256938f, 0.790775f, -0.555570f },
- { -0.488726f, 0.672673f, -0.555570f },
- { -0.672673f, 0.488726f, -0.555570f },
- { -0.790775f, 0.256938f, -0.555570f },
- { -0.831470f, -0.000000f, -0.555570f },
- { -0.790775f, -0.256938f, -0.555570f },
- { -0.672673f, -0.488726f, -0.555570f },
- { -0.488725f, -0.672673f, -0.555570f },
- { -0.256938f, -0.790775f, -0.555570f },
- { 0.000000f, -0.831470f, -0.555570f },
- { 0.256938f, -0.790775f, -0.555570f },
- { 0.488725f, -0.672673f, -0.555570f },
- { 0.672673f, -0.488726f, -0.555570f },
- { 0.790775f, -0.256938f, -0.555570f },
- { 0.707107f, 0.000000f, -0.707107f },
- { 0.653281f, 0.270598f, -0.707107f },
- { 0.500000f, 0.500000f, -0.707107f },
- { 0.270598f, 0.653281f, -0.707107f },
- { -0.000000f, 0.707107f, -0.707107f },
- { -0.270598f, 0.653282f, -0.707107f },
- { -0.500000f, 0.500000f, -0.707107f },
- { -0.653281f, 0.270598f, -0.707107f },
- { -0.707107f, -0.000000f, -0.707107f },
- { -0.653281f, -0.270598f, -0.707107f },
- { -0.500000f, -0.500000f, -0.707107f },
- { -0.270598f, -0.653281f, -0.707107f },
- { 0.000000f, -0.707107f, -0.707107f },
- { 0.270598f, -0.653281f, -0.707107f },
- { 0.500000f, -0.500000f, -0.707107f },
- { 0.653282f, -0.270598f, -0.707107f },
- { 0.555570f, 0.000000f, -0.831470f },
- { 0.481138f, 0.277785f, -0.831470f },
- { 0.277785f, 0.481138f, -0.831470f },
- { -0.000000f, 0.555570f, -0.831470f },
- { -0.277785f, 0.481138f, -0.831470f },
- { -0.481138f, 0.277785f, -0.831470f },
- { -0.555570f, -0.000000f, -0.831470f },
- { -0.481138f, -0.277785f, -0.831470f },
- { -0.277785f, -0.481138f, -0.831470f },
- { 0.000000f, -0.555570f, -0.831470f },
- { 0.277785f, -0.481138f, -0.831470f },
- { 0.481138f, -0.277785f, -0.831470f },
- { 0.382683f, 0.000000f, -0.923880f },
- { 0.270598f, 0.270598f, -0.923880f },
- { -0.000000f, 0.382683f, -0.923880f },
- { -0.270598f, 0.270598f, -0.923880f },
- { -0.382683f, -0.000000f, -0.923880f },
- { -0.270598f, -0.270598f, -0.923880f },
- { 0.000000f, -0.382683f, -0.923880f },
- { 0.270598f, -0.270598f, -0.923880f },
- { 0.195090f, 0.000000f, -0.980785f },
- { -0.000000f, 0.195090f, -0.980785f },
- { -0.195090f, -0.000000f, -0.980785f },
- { 0.000000f, -0.195090f, -0.980785f },
- { 0.980785f, 0.000000f, 0.195090f },
- { 0.956195f, 0.218245f, 0.195090f },
- { 0.883657f, 0.425547f, 0.195090f },
- { 0.766809f, 0.611510f, 0.195090f },
- { 0.611510f, 0.766809f, 0.195090f },
- { 0.425547f, 0.883657f, 0.195090f },
- { 0.218245f, 0.956195f, 0.195090f },
- { -0.000000f, 0.980785f, 0.195090f },
- { -0.218245f, 0.956195f, 0.195090f },
- { -0.425547f, 0.883657f, 0.195090f },
- { -0.611510f, 0.766809f, 0.195090f },
- { -0.766809f, 0.611510f, 0.195090f },
- { -0.883657f, 0.425547f, 0.195090f },
- { -0.956195f, 0.218245f, 0.195090f },
- { -0.980785f, -0.000000f, 0.195090f },
- { -0.956195f, -0.218245f, 0.195090f },
- { -0.883657f, -0.425547f, 0.195090f },
- { -0.766809f, -0.611510f, 0.195090f },
- { -0.611510f, -0.766809f, 0.195090f },
- { -0.425547f, -0.883657f, 0.195090f },
- { -0.218245f, -0.956195f, 0.195090f },
- { 0.000000f, -0.980785f, 0.195090f },
- { 0.218245f, -0.956195f, 0.195090f },
- { 0.425547f, -0.883657f, 0.195090f },
- { 0.611510f, -0.766809f, 0.195090f },
- { 0.766809f, -0.611510f, 0.195090f },
- { 0.883657f, -0.425547f, 0.195090f },
- { 0.956195f, -0.218245f, 0.195090f },
- { 0.923880f, 0.000000f, 0.382683f },
- { 0.892399f, 0.239118f, 0.382683f },
- { 0.800103f, 0.461940f, 0.382683f },
- { 0.653281f, 0.653281f, 0.382683f },
- { 0.461940f, 0.800103f, 0.382683f },
- { 0.239118f, 0.892399f, 0.382683f },
- { -0.000000f, 0.923880f, 0.382683f },
- { -0.239118f, 0.892399f, 0.382683f },
- { -0.461940f, 0.800103f, 0.382683f },
- { -0.653281f, 0.653281f, 0.382683f },
- { -0.800103f, 0.461940f, 0.382683f },
- { -0.892399f, 0.239118f, 0.382683f },
- { -0.923880f, -0.000000f, 0.382683f },
- { -0.892399f, -0.239118f, 0.382683f },
- { -0.800103f, -0.461940f, 0.382683f },
- { -0.653282f, -0.653281f, 0.382683f },
- { -0.461940f, -0.800103f, 0.382683f },
- { -0.239118f, -0.892399f, 0.382683f },
- { 0.000000f, -0.923880f, 0.382683f },
- { 0.239118f, -0.892399f, 0.382683f },
- { 0.461940f, -0.800103f, 0.382683f },
- { 0.653281f, -0.653282f, 0.382683f },
- { 0.800103f, -0.461940f, 0.382683f },
- { 0.892399f, -0.239117f, 0.382683f },
- { 0.831470f, 0.000000f, 0.555570f },
- { 0.790775f, 0.256938f, 0.555570f },
- { 0.672673f, 0.488726f, 0.555570f },
- { 0.488726f, 0.672673f, 0.555570f },
- { 0.256938f, 0.790775f, 0.555570f },
- { -0.000000f, 0.831470f, 0.555570f },
- { -0.256938f, 0.790775f, 0.555570f },
- { -0.488726f, 0.672673f, 0.555570f },
- { -0.672673f, 0.488726f, 0.555570f },
- { -0.790775f, 0.256938f, 0.555570f },
- { -0.831470f, -0.000000f, 0.555570f },
- { -0.790775f, -0.256938f, 0.555570f },
- { -0.672673f, -0.488726f, 0.555570f },
- { -0.488725f, -0.672673f, 0.555570f },
- { -0.256938f, -0.790775f, 0.555570f },
- { 0.000000f, -0.831470f, 0.555570f },
- { 0.256938f, -0.790775f, 0.555570f },
- { 0.488725f, -0.672673f, 0.555570f },
- { 0.672673f, -0.488726f, 0.555570f },
- { 0.790775f, -0.256938f, 0.555570f },
- { 0.707107f, 0.000000f, 0.707107f },
- { 0.653281f, 0.270598f, 0.707107f },
- { 0.500000f, 0.500000f, 0.707107f },
- { 0.270598f, 0.653281f, 0.707107f },
- { -0.000000f, 0.707107f, 0.707107f },
- { -0.270598f, 0.653282f, 0.707107f },
- { -0.500000f, 0.500000f, 0.707107f },
- { -0.653281f, 0.270598f, 0.707107f },
- { -0.707107f, -0.000000f, 0.707107f },
- { -0.653281f, -0.270598f, 0.707107f },
- { -0.500000f, -0.500000f, 0.707107f },
- { -0.270598f, -0.653281f, 0.707107f },
- { 0.000000f, -0.707107f, 0.707107f },
- { 0.270598f, -0.653281f, 0.707107f },
- { 0.500000f, -0.500000f, 0.707107f },
- { 0.653282f, -0.270598f, 0.707107f },
- { 0.555570f, 0.000000f, 0.831470f },
- { 0.481138f, 0.277785f, 0.831470f },
- { 0.277785f, 0.481138f, 0.831470f },
- { -0.000000f, 0.555570f, 0.831470f },
- { -0.277785f, 0.481138f, 0.831470f },
- { -0.481138f, 0.277785f, 0.831470f },
- { -0.555570f, -0.000000f, 0.831470f },
- { -0.481138f, -0.277785f, 0.831470f },
- { -0.277785f, -0.481138f, 0.831470f },
- { 0.000000f, -0.555570f, 0.831470f },
- { 0.277785f, -0.481138f, 0.831470f },
- { 0.481138f, -0.277785f, 0.831470f },
- { 0.382683f, 0.000000f, 0.923880f },
- { 0.270598f, 0.270598f, 0.923880f },
- { -0.000000f, 0.382683f, 0.923880f },
- { -0.270598f, 0.270598f, 0.923880f },
- { -0.382683f, -0.000000f, 0.923880f },
- { -0.270598f, -0.270598f, 0.923880f },
- { 0.000000f, -0.382683f, 0.923880f },
- { 0.270598f, -0.270598f, 0.923880f },
- { 0.195090f, 0.000000f, 0.980785f },
- { -0.000000f, 0.195090f, 0.980785f },
- { -0.195090f, -0.000000f, 0.980785f },
- { 0.000000f, -0.195090f, 0.980785f }
-};
-
-#endif // !! MDC_NORMAL_TABLE_INCLUDED
diff --git a/src/3rdparty/assimp/code/MDLDefaultColorMap.h b/src/3rdparty/assimp/code/MDLDefaultColorMap.h
deleted file mode 100644
index 800c717c5..000000000
--- a/src/3rdparty/assimp/code/MDLDefaultColorMap.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the default color map used for Quake 1 model textures
- *
- * The lib tries to load colormap.lmp from the model's directory.
- * This table is only used when required.
- */
-
-#ifndef AI_MDL_DEFAULTLMP_H_INC
-#define AI_MDL_DEFAULTLMP_H_INC
-
-const unsigned char g_aclrDefaultColorMap[256][3] = {
-{ 0, 0, 0}, { 15, 15, 15}, { 31, 31, 31}, { 47, 47, 47},
-{ 63, 63, 63}, { 75, 75, 75}, { 91, 91, 91}, {107, 107, 107},
-{123, 123, 123}, {139, 139, 139}, {155, 155, 155}, {171, 171, 171},
-{187, 187, 187}, {203, 203, 203}, {219, 219, 219}, {235, 235, 235},
-{ 15, 11, 7}, { 23, 15, 11}, { 31, 23, 11}, { 39, 27, 15},
-{ 47, 35, 19}, { 55, 43, 23}, { 63, 47, 23}, { 75, 55, 27},
-{ 83, 59, 27}, { 91, 67, 31}, { 99, 75, 31}, {107, 83, 31},
-{115, 87, 31}, {123, 95, 35}, {131, 103, 35}, {143, 111, 35},
-{ 11, 11, 15}, { 19, 19, 27}, { 27, 27, 39}, { 39, 39, 51},
-{ 47, 47, 63}, { 55, 55, 75}, { 63, 63, 87}, { 71, 71, 103},
-{ 79, 79, 115}, { 91, 91, 127}, { 99, 99, 139}, {107, 107, 151},
-{115, 115, 163}, {123, 123, 175}, {131, 131, 187}, {139, 139, 203},
-{ 0, 0, 0}, { 7, 7, 0}, { 11, 11, 0}, { 19, 19, 0},
-{ 27, 27, 0}, { 35, 35, 0}, { 43, 43, 7}, { 47, 47, 7},
-{ 55, 55, 7}, { 63, 63, 7}, { 71, 71, 7}, { 75, 75, 11},
-{ 83, 83, 11}, { 91, 91, 11}, { 99, 99, 11}, {107, 107, 15},
-{ 7, 0, 0}, { 15, 0, 0}, { 23, 0, 0}, { 31, 0, 0},
-{ 39, 0, 0}, { 47, 0, 0}, { 55, 0, 0}, { 63, 0, 0},
-{ 71, 0, 0}, { 79, 0, 0}, { 87, 0, 0}, { 95, 0, 0},
-{103, 0, 0}, {111, 0, 0}, {119, 0, 0}, {127, 0, 0},
-{ 19, 19, 0}, { 27, 27, 0}, { 35, 35, 0}, { 47, 43, 0},
-{ 55, 47, 0}, { 67, 55, 0}, { 75, 59, 7}, { 87, 67, 7},
-{ 95, 71, 7}, {107, 75, 11}, {119, 83, 15}, {131, 87, 19},
-{139, 91, 19}, {151, 95, 27}, {163, 99, 31}, {175, 103, 35},
-{ 35, 19, 7}, { 47, 23, 11}, { 59, 31, 15}, { 75, 35, 19},
-{ 87, 43, 23}, { 99, 47, 31}, {115, 55, 35}, {127, 59, 43},
-{143, 67, 51}, {159, 79, 51}, {175, 99, 47}, {191, 119, 47},
-{207, 143, 43}, {223, 171, 39}, {239, 203, 31}, {255, 243, 27},
-{ 11, 7, 0}, { 27, 19, 0}, { 43, 35, 15}, { 55, 43, 19},
-{ 71, 51, 27}, { 83, 55, 35}, { 99, 63, 43}, {111, 71, 51},
-{127, 83, 63}, {139, 95, 71}, {155, 107, 83}, {167, 123, 95},
-{183, 135, 107}, {195, 147, 123}, {211, 163, 139}, {227, 179, 151},
-{171, 139, 163}, {159, 127, 151}, {147, 115, 135}, {139, 103, 123},
-{127, 91, 111}, {119, 83, 99}, {107, 75, 87}, { 95, 63, 75},
-{ 87, 55, 67}, { 75, 47, 55}, { 67, 39, 47}, { 55, 31, 35},
-{ 43, 23, 27}, { 35, 19, 19}, { 23, 11, 11}, { 15, 7, 7},
-{187, 115, 159}, {175, 107, 143}, {163, 95, 131}, {151, 87, 119},
-{139, 79, 107}, {127, 75, 95}, {115, 67, 83}, {107, 59, 75},
-{ 95, 51, 63}, { 83, 43, 55}, { 71, 35, 43}, { 59, 31, 35},
-{ 47, 23, 27}, { 35, 19, 19}, { 23, 11, 11}, { 15, 7, 7},
-{219, 195, 187}, {203, 179, 167}, {191, 163, 155}, {175, 151, 139},
-{163, 135, 123}, {151, 123, 111}, {135, 111, 95}, {123, 99, 83},
-{107, 87, 71}, { 95, 75, 59}, { 83, 63, 51}, { 67, 51, 39},
-{ 55, 43, 31}, { 39, 31, 23}, { 27, 19, 15}, { 15, 11, 7},
-{111, 131, 123}, {103, 123, 111}, { 95, 115, 103}, { 87, 107, 95},
-{ 79, 99, 87}, { 71, 91, 79}, { 63, 83, 71}, { 55, 75, 63},
-{ 47, 67, 55}, { 43, 59, 47}, { 35, 51, 39}, { 31, 43, 31},
-{ 23, 35, 23}, { 15, 27, 19}, { 11, 19, 11}, { 7, 11, 7},
-{255, 243, 27}, {239, 223, 23}, {219, 203, 19}, {203, 183, 15},
-{187, 167, 15}, {171, 151, 11}, {155, 131, 7}, {139, 115, 7},
-{123, 99, 7}, {107, 83, 0}, { 91, 71, 0}, { 75, 55, 0},
-{ 59, 43, 0}, { 43, 31, 0}, { 27, 15, 0}, { 11, 7, 0},
-{ 0, 0, 255}, { 11, 11, 239}, { 19, 19, 223}, { 27, 27, 207},
-{ 35, 35, 191}, { 43, 43, 175}, { 47, 47, 159}, { 47, 47, 143},
-{ 47, 47, 127}, { 47, 47, 111}, { 47, 47, 95}, { 43, 43, 79},
-{ 35, 35, 63}, { 27, 27, 47}, { 19, 19, 31}, { 11, 11, 15},
-{ 43, 0, 0}, { 59, 0, 0}, { 75, 7, 0}, { 95, 7, 0},
-{111, 15, 0}, {127, 23, 7}, {147, 31, 7}, {163, 39, 11},
-{183, 51, 15}, {195, 75, 27}, {207, 99, 43}, {219, 127, 59},
-{227, 151, 79}, {231, 171, 95}, {239, 191, 119}, {247, 211, 139},
-{167, 123, 59}, {183, 155, 55}, {199, 195, 55}, {231, 227, 87},
-{127, 191, 255}, {171, 231, 255}, {215, 255, 255}, {103, 0, 0},
-{139, 0, 0}, {179, 0, 0}, {215, 0, 0}, {255, 0, 0},
-{255, 243, 147}, {255, 247, 199}, {255, 255, 255}, {159, 91, 83} };
-
-
-#endif // !! AI_MDL_DEFAULTLMP_H_INC
diff --git a/src/3rdparty/assimp/code/MDLFileData.h b/src/3rdparty/assimp/code/MDLFileData.h
deleted file mode 100644
index 3ef58ca5a..000000000
--- a/src/3rdparty/assimp/code/MDLFileData.h
+++ /dev/null
@@ -1,947 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MDLFileData.h
- * @brief Definition of in-memory structures for the MDL file format.
- *
- * The specification has been taken from various sources on the internet.
- * - http://tfc.duke.free.fr/coding/mdl-specs-en.html
- * - Conitec's MED SDK
- * - Many quite long HEX-editor sessions
- */
-
-#ifndef AI_MDLFILEHELPER_H_INC
-#define AI_MDLFILEHELPER_H_INC
-
-#include <assimp/anim.h>
-#include <assimp/mesh.h>
-#include <assimp/Compiler/pushpack1.h>
-#include "ByteSwapper.h"
-#include <stdint.h>
-#include <vector>
-
-struct aiMaterial;
-
-namespace Assimp {
-namespace MDL {
-
-// -------------------------------------------------------------------------------------
-// to make it easier for us, we test the magic word against both "endianesses"
-
-// magic bytes used in Quake 1 MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE AI_MAKE_MAGIC("IDPO")
-#define AI_MDL_MAGIC_NUMBER_LE AI_MAKE_MAGIC("OPDI")
-
-// magic bytes used in GameStudio A<very low> MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS3 AI_MAKE_MAGIC("MDL2")
-#define AI_MDL_MAGIC_NUMBER_LE_GS3 AI_MAKE_MAGIC("2LDM")
-
-// magic bytes used in GameStudio A4 MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS4 AI_MAKE_MAGIC("MDL3")
-#define AI_MDL_MAGIC_NUMBER_LE_GS4 AI_MAKE_MAGIC("3LDM")
-
-// magic bytes used in GameStudio A5+ MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS5a AI_MAKE_MAGIC("MDL4")
-#define AI_MDL_MAGIC_NUMBER_LE_GS5a AI_MAKE_MAGIC("4LDM")
-#define AI_MDL_MAGIC_NUMBER_BE_GS5b AI_MAKE_MAGIC("MDL5")
-#define AI_MDL_MAGIC_NUMBER_LE_GS5b AI_MAKE_MAGIC("5LDM")
-
-// magic bytes used in GameStudio A7+ MDL meshes
-#define AI_MDL_MAGIC_NUMBER_BE_GS7 AI_MAKE_MAGIC("MDL7")
-#define AI_MDL_MAGIC_NUMBER_LE_GS7 AI_MAKE_MAGIC("7LDM")
-
-// common limitations for Quake1 meshes. The loader does not check them,
-// (however it warns) but models should not exceed these limits.
-#if (!defined AI_MDL_VERSION)
-# define AI_MDL_VERSION 6
-#endif
-#if (!defined AI_MDL_MAX_FRAMES)
-# define AI_MDL_MAX_FRAMES 256
-#endif
-#if (!defined AI_MDL_MAX_UVS)
-# define AI_MDL_MAX_UVS 1024
-#endif
-#if (!defined AI_MDL_MAX_VERTS)
-# define AI_MDL_MAX_VERTS 1024
-#endif
-#if (!defined AI_MDL_MAX_TRIANGLES)
-# define AI_MDL_MAX_TRIANGLES 2048
-#endif
-
-// material key that is set for dummy materials that are
-// just referencing another material
-#if (!defined AI_MDL7_REFERRER_MATERIAL)
-# define AI_MDL7_REFERRER_MATERIAL "&&&referrer&&&",0,0
-#endif
-
-// -------------------------------------------------------------------------------------
-/** \struct Header
- * \brief Data structure for the MDL main header
- */
-struct Header {
- //! magic number: "IDPO"
- uint32_t ident;
-
- //! version number: 6
- int32_t version;
-
- //! scale factors for each axis
- ai_real scale[3];
-
- //! translation factors for each axis
- ai_real translate[3];
-
- //! bounding radius of the mesh
- float boundingradius;
-
- //! Position of the viewer's exe. Ignored
- ai_real vEyePos[3];
-
- //! Number of textures
- int32_t num_skins;
-
- //! Texture width in pixels
- int32_t skinwidth;
-
- //! Texture height in pixels
- int32_t skinheight;
-
- //! Number of vertices contained in the file
- int32_t num_verts;
-
- //! Number of triangles contained in the file
- int32_t num_tris;
-
- //! Number of frames contained in the file
- int32_t num_frames;
-
- //! 0 = synchron, 1 = random . Ignored
- //! (MDLn formats: number of texture coordinates)
- int32_t synctype;
-
- //! State flag
- int32_t flags;
-
- //! Could be the total size of the file (and not a float)
- float size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Header_MDL7
- * \brief Data structure for the MDL 7 main header
- */
-struct Header_MDL7 {
- //! magic number: "MDL7"
- char ident[4];
-
- //! Version number. Ignored
- int32_t version;
-
- //! Number of bones in file
- uint32_t bones_num;
-
- //! Number of groups in file
- uint32_t groups_num;
-
- //! Size of data in the file
- uint32_t data_size;
-
- //! Ignored. Used to store entity specific information
- int32_t entlump_size;
-
- //! Ignored. Used to store MED related data
- int32_t medlump_size;
-
- //! Size of the Bone_MDL7 data structure used in the file
- uint16_t bone_stc_size;
-
- //! Size of the Skin_MDL 7 data structure used in the file
- uint16_t skin_stc_size;
-
- //! Size of a single color (e.g. in a material)
- uint16_t colorvalue_stc_size;
-
- //! Size of the Material_MDL7 data structure used in the file
- uint16_t material_stc_size;
-
- //! Size of a texture coordinate set in the file
- uint16_t skinpoint_stc_size;
-
- //! Size of a triangle in the file
- uint16_t triangle_stc_size;
-
- //! Size of a normal vertex in the file
- uint16_t mainvertex_stc_size;
-
- //! Size of a per-frame animated vertex in the file
- //! (this is not supported)
- uint16_t framevertex_stc_size;
-
- //! Size of a bone animation matrix
- uint16_t bonetrans_stc_size;
-
- //! Size of the Frame_MDL7 data structure used in the file
- uint16_t frame_stc_size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Bone_MDL7
- * \brief Data structure for a bone in a MDL7 file
- */
-struct Bone_MDL7 {
- //! Index of the parent bone of *this* bone. 0xffff means:
- //! "hey, I have no parent, I'm an orphan"
- uint16_t parent_index;
- uint8_t _unused_[2];
-
- //! Relative position of the bone (relative to the
- //! parent bone)
- float x,y,z;
-
- //! Optional name of the bone
- char name[1 /* DUMMY SIZE */];
-} PACK_STRUCT;
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS (16 + 20)
-#endif
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS (16 + 32)
-#endif
-
-#if (!defined AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE)
-# define AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE (16)
-#endif
-
-#if (!defined AI_MDL7_MAX_GROUPNAMESIZE)
-# define AI_MDL7_MAX_GROUPNAMESIZE 16
-#endif // ! AI_MDL7_MAX_GROUPNAMESIZE
-
-// -------------------------------------------------------------------------------------
-/** \struct Group_MDL7
- * \brief Group in a MDL7 file
- */
-struct Group_MDL7 {
- //! = '1' -> triangle based Mesh
- unsigned char typ;
-
- int8_t deformers;
- int8_t max_weights;
- int8_t _unused_;
-
- //! size of data for this group in bytes ( MD7_GROUP stc. included).
- int32_t groupdata_size;
- char name[AI_MDL7_MAX_GROUPNAMESIZE];
-
- //! Number of skins
- int32_t numskins;
-
- //! Number of texture coordinates
- int32_t num_stpts;
-
- //! Number of triangles
- int32_t numtris;
-
- //! Number of vertices
- int32_t numverts;
-
- //! Number of frames
- int32_t numframes;
-} PACK_STRUCT;
-
-#define AI_MDL7_SKINTYPE_MIPFLAG 0x08
-#define AI_MDL7_SKINTYPE_MATERIAL 0x10
-#define AI_MDL7_SKINTYPE_MATERIAL_ASCDEF 0x20
-#define AI_MDL7_SKINTYPE_RGBFLAG 0x80
-
-#if (!defined AI_MDL7_MAX_BONENAMESIZE)
-# define AI_MDL7_MAX_BONENAMESIZE 20
-#endif // !! AI_MDL7_MAX_BONENAMESIZE
-
-// -------------------------------------------------------------------------------------
-/** \struct Deformer_MDL7
- * \brief Deformer in a MDL7 file
- */
-struct Deformer_MDL7 {
- int8_t deformer_version; // 0
- int8_t deformer_typ; // 0 - bones
- int8_t _unused_[2];
- int32_t group_index;
- int32_t elements;
- int32_t deformerdata_size;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct DeformerElement_MDL7
- * \brief Deformer element in a MDL7 file
- */
-struct DeformerElement_MDL7 {
- //! bei deformer_typ==0 (==bones) element_index == bone index
- int32_t element_index;
- char element_name[AI_MDL7_MAX_BONENAMESIZE];
- int32_t weights;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct DeformerWeight_MDL7
- * \brief Deformer weight in a MDL7 file
- */
-struct DeformerWeight_MDL7 {
- //! for deformer_typ==0 (==bones) index == vertex index
- int32_t index;
- float weight;
-} PACK_STRUCT;
-
-// don't know why this was in the original headers ...
-typedef int32_t MD7_MATERIAL_ASCDEFSIZE;
-
-// -------------------------------------------------------------------------------------
-/** \struct ColorValue_MDL7
- * \brief Data structure for a color value in a MDL7 file
- */
-struct ColorValue_MDL7 {
- float r,g,b,a;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Material_MDL7
- * \brief Data structure for a Material in a MDL7 file
- */
-struct Material_MDL7 {
- //! Diffuse base color of the material
- ColorValue_MDL7 Diffuse;
-
- //! Ambient base color of the material
- ColorValue_MDL7 Ambient;
-
- //! Specular base color of the material
- ColorValue_MDL7 Specular;
-
- //! Emissive base color of the material
- ColorValue_MDL7 Emissive;
-
- //! Phong power
- float Power;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Skin
- * \brief Skin data structure #1 - used by Quake1, MDL2, MDL3 and MDL4
- */
-struct Skin {
- //! 0 = single (Skin), 1 = group (GroupSkin)
- //! For MDL3-5: Defines the type of the skin and there
- //! fore the size of the data to skip:
- //-------------------------------------------------------
- //! 2 for 565 RGB,
- //! 3 for 4444 ARGB,
- //! 10 for 565 mipmapped,
- //! 11 for 4444 mipmapped (bpp = 2),
- //! 12 for 888 RGB mipmapped (bpp = 3),
- //! 13 for 8888 ARGB mipmapped (bpp = 4)
- //-------------------------------------------------------
- int32_t group;
-
- //! Texture data
- uint8_t *data;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-/** \struct Skin
- * \brief Skin data structure #2 - used by MDL5, MDL6 and MDL7
- * \see Skin
- */
-struct Skin_MDL5 {
- int32_t size, width, height;
- uint8_t *data;
-} PACK_STRUCT;
-
-// maximum length of texture file name
-#if (!defined AI_MDL7_MAX_TEXNAMESIZE)
-# define AI_MDL7_MAX_TEXNAMESIZE 0x10
-#endif
-
-// ---------------------------------------------------------------------------
-/** \struct Skin_MDL7
- * \brief Skin data structure #3 - used by MDL7 and HMP7
- */
-struct Skin_MDL7 {
- uint8_t typ;
- int8_t _unused_[3];
- int32_t width;
- int32_t height;
- char texture_name[AI_MDL7_MAX_TEXNAMESIZE];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct RGB565
- * \brief Data structure for a RGB565 pixel in a texture
- */
-struct RGB565 {
- uint16_t r : 5;
- uint16_t g : 6;
- uint16_t b : 5;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct ARGB4
- * \brief Data structure for a ARGB4444 pixel in a texture
- */
-struct ARGB4 {
- uint16_t a : 4;
- uint16_t r : 4;
- uint16_t g : 4;
- uint16_t b : 4;
-} /*PACK_STRUCT*/;
-
-// -------------------------------------------------------------------------------------
-/** \struct GroupSkin
- * \brief Skin data structure #2 (group of pictures)
- */
-struct GroupSkin {
- //! 0 = single (Skin), 1 = group (GroupSkin)
- int32_t group;
-
- //! Number of images
- int32_t nb;
-
- //! Time for each image
- float *time;
-
- //! Data of each image
- uint8_t **data;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord
- * \brief Texture coordinate data structure used by the Quake1 MDL format
- */
-struct TexCoord {
- //! Is the vertex on the noundary between front and back piece?
- int32_t onseam;
-
- //! Texture coordinate in the tx direction
- int32_t s;
-
- //! Texture coordinate in the ty direction
- int32_t t;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord_MDL3
- * \brief Data structure for an UV coordinate in the 3DGS MDL3 format
- */
-struct TexCoord_MDL3 {
- //! position, horizontally in range 0..skinwidth-1
- int16_t u;
-
- //! position, vertically in range 0..skinheight-1
- int16_t v;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct TexCoord_MDL7
- * \brief Data structure for an UV coordinate in the 3DGS MDL7 format
- */
-struct TexCoord_MDL7 {
- //! position, horizontally in range 0..1
- float u;
-
- //! position, vertically in range 0..1
- float v;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct SkinSet_MDL7
- * \brief Skin set data structure for the 3DGS MDL7 format
- * MDL7 references UV coordinates per face via an index list.
- * This allows the use of multiple skins per face with just one
- * UV coordinate set.
- */
-struct SkinSet_MDL7
-{
- //! Index into the UV coordinate list
- uint16_t st_index[3]; // size 6
-
- //! Material index
- int32_t material; // size 4
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle
- * \brief Triangle data structure for the Quake1 MDL format
- */
-struct Triangle
-{
- //! 0 = backface, 1 = frontface
- int32_t facesfront;
-
- //! Vertex indices
- int32_t vertex[3];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle_MDL3
- * \brief Triangle data structure for the 3DGS MDL3 format
- */
-struct Triangle_MDL3
-{
- //! Index of 3 3D vertices in range 0..numverts
- uint16_t index_xyz[3];
-
- //! Index of 3 skin vertices in range 0..numskinverts
- uint16_t index_uv[3];
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Triangle_MDL7
- * \brief Triangle data structure for the 3DGS MDL7 format
- */
-struct Triangle_MDL7
-{
- //! Vertex indices
- uint16_t v_index[3]; // size 6
-
- //! Two skinsets. The second will be used for multi-texturing
- SkinSet_MDL7 skinsets[2];
-} PACK_STRUCT;
-
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV)
-# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV (6+sizeof(SkinSet_MDL7)-sizeof(uint32_t))
-#endif
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX)
-# define AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX (6+sizeof(SkinSet_MDL7))
-#endif
-#if (!defined AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV)
-# define AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV (6+2*sizeof(SkinSet_MDL7))
-#endif
-
-// Helper constants for Triangle::facesfront
-#if (!defined AI_MDL_BACKFACE)
-# define AI_MDL_BACKFACE 0x0
-#endif
-#if (!defined AI_MDL_FRONTFACE)
-# define AI_MDL_FRONTFACE 0x1
-#endif
-
-// -------------------------------------------------------------------------------------
-/** \struct Vertex
- * \brief Vertex data structure
- */
-struct Vertex
-{
- uint8_t v[3];
- uint8_t normalIndex;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-struct Vertex_MDL4
-{
- uint16_t v[3];
- uint8_t normalIndex;
- uint8_t unused;
-} PACK_STRUCT;
-
-#define AI_MDL7_FRAMEVERTEX120503_STCSIZE 16
-#define AI_MDL7_FRAMEVERTEX030305_STCSIZE 26
-
-// -------------------------------------------------------------------------------------
-/** \struct Vertex_MDL7
- * \brief Vertex data structure used in MDL7 files
- */
-struct Vertex_MDL7
-{
- float x,y,z;
- uint16_t vertindex; // = bone index
- union {
- uint8_t norm162index;
- float norm[3];
- };
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct BoneTransform_MDL7
- * \brief bone transformation matrix structure used in MDL7 files
- */
-struct BoneTransform_MDL7
-{
- //! 4*3
- float m [4*4];
-
- //! the index of this vertex, 0.. header::bones_num - 1
- uint16_t bone_index;
-
- //! I HATE 3DGS AND THE SILLY DEVELOPER WHO DESIGNED
- //! THIS STUPID FILE FORMAT!
- int8_t _unused_[2];
-} PACK_STRUCT;
-
-
-#define AI_MDL7_MAX_FRAMENAMESIZE 16
-
-// -------------------------------------------------------------------------------------
-/** \struct Frame_MDL7
- * \brief Frame data structure used by MDL7 files
- */
-struct Frame_MDL7
-{
- char frame_name[AI_MDL7_MAX_FRAMENAMESIZE];
- uint32_t vertices_count;
- uint32_t transmatrix_count;
-};
-
-
-// -------------------------------------------------------------------------------------
-/** \struct SimpleFrame
- * \brief Data structure for a simple frame
- */
-struct SimpleFrame
-{
- //! Minimum vertex of the bounding box
- Vertex bboxmin;
-
- //! Maximum vertex of the bounding box
- Vertex bboxmax;
-
- //! Name of the frame
- char name[16];
-
- //! Vertex list of the frame
- Vertex *verts;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct Frame
- * \brief Model frame data structure
- */
-struct Frame
-{
- //! 0 = simple frame, !0 = group frame
- int32_t type;
-
- //! Frame data
- SimpleFrame frame;
-} PACK_STRUCT;
-
-
-// -------------------------------------------------------------------------------------
-struct SimpleFrame_MDLn_SP
-{
- //! Minimum vertex of the bounding box
- Vertex_MDL4 bboxmin;
-
- //! Maximum vertex of the bounding box
- Vertex_MDL4 bboxmax;
-
- //! Name of the frame
- char name[16];
-
- //! Vertex list of the frame
- Vertex_MDL4 *verts;
-} PACK_STRUCT;
-
-// -------------------------------------------------------------------------------------
-/** \struct GroupFrame
- * \brief Data structure for a group of frames
- */
-struct GroupFrame
-{
- //! 0 = simple frame, !0 = group frame
- int32_t type;
-
- //! Minimum vertex for all single frames
- Vertex min;
-
- //! Maximum vertex for all single frames
- Vertex max;
-
- //! Time for all single frames
- float *time;
-
- //! List of single frames
- SimpleFrame *frames;
-} PACK_STRUCT;
-
-#include "./../include/assimp/Compiler/poppack1.h"
-
-// -------------------------------------------------------------------------------------
-/** \struct IntFace_MDL7
- * \brief Internal data structure to temporarily represent a face
- */
-struct IntFace_MDL7 {
- // provide a constructor for our own convenience
- IntFace_MDL7()
- {
- // set everything to zero
- mIndices[0] = mIndices[1] = mIndices[2] = 0;
- iMatIndex[0] = iMatIndex[1] = 0;
- }
-
- //! Vertex indices
- uint32_t mIndices[3];
-
- //! Material index (maximally two channels, which are joined later)
- unsigned int iMatIndex[2];
-};
-
-// -------------------------------------------------------------------------------------
-/** \struct IntMaterial_MDL7
- * \brief Internal data structure to temporarily represent a material
- * which has been created from two single materials along with the
- * original material indices.
- */
-struct IntMaterial_MDL7
-{
- // provide a constructor for our own convenience
- IntMaterial_MDL7()
- {
- pcMat = NULL;
- iOldMatIndices[0] = iOldMatIndices[1] = 0;
- }
-
- //! Material instance
- aiMaterial* pcMat;
-
- //! Old material indices
- unsigned int iOldMatIndices[2];
-};
-
-// -------------------------------------------------------------------------------------
-/** \struct IntBone_MDL7
- * \brief Internal data structure to represent a bone in a MDL7 file with
- * all of its animation channels assigned to it.
- */
-struct IntBone_MDL7 : aiBone
-{
- //! Default constructor
- IntBone_MDL7() : iParent (0xffff)
- {
- pkeyPositions.reserve(30);
- pkeyScalings.reserve(30);
- pkeyRotations.reserve(30);
- }
-
- //! Parent bone of the bone
- uint64_t iParent;
-
- //! Relative position of the bone
- aiVector3D vPosition;
-
- //! Array of position keys
- std::vector<aiVectorKey> pkeyPositions;
-
- //! Array of scaling keys
- std::vector<aiVectorKey> pkeyScalings;
-
- //! Array of rotation keys
- std::vector<aiQuatKey> pkeyRotations;
-};
-
-// -------------------------------------------------------------------------------------
-//! Describes a MDL7 frame
-struct IntFrameInfo_MDL7
-{
- //! Construction from an existing frame header
- IntFrameInfo_MDL7(BE_NCONST MDL::Frame_MDL7* _pcFrame,unsigned int _iIndex)
- : iIndex(_iIndex)
- , pcFrame(_pcFrame)
- {}
-
- //! Index of the frame
- unsigned int iIndex;
-
- //! Points to the header of the frame
- BE_NCONST MDL::Frame_MDL7* pcFrame;
-};
-
-// -------------------------------------------------------------------------------------
-//! Describes a MDL7 mesh group
-struct IntGroupInfo_MDL7
-{
- //! Default constructor
- IntGroupInfo_MDL7()
- : iIndex(0)
- , pcGroup(NULL)
- , pcGroupUVs(NULL)
- , pcGroupTris(NULL)
- , pcGroupVerts(NULL)
- {}
-
- //! Construction from an existing group header
- IntGroupInfo_MDL7(BE_NCONST MDL::Group_MDL7* _pcGroup, unsigned int _iIndex)
- : iIndex(_iIndex)
- , pcGroup(_pcGroup)
- , pcGroupUVs()
- , pcGroupTris()
- , pcGroupVerts()
- {}
-
- //! Index of the group
- unsigned int iIndex;
-
- //! Points to the header of the group
- BE_NCONST MDL::Group_MDL7* pcGroup;
-
- //! Points to the beginning of the uv coordinate section
- BE_NCONST MDL::TexCoord_MDL7* pcGroupUVs;
-
- //! Points to the beginning of the triangle section
- MDL::Triangle_MDL7* pcGroupTris;
-
- //! Points to the beginning of the vertex section
- BE_NCONST MDL::Vertex_MDL7* pcGroupVerts;
-};
-
-// -------------------------------------------------------------------------------------
-//! Holds the data that belongs to a MDL7 mesh group
-struct IntGroupData_MDL7
-{
- IntGroupData_MDL7()
- : pcFaces(NULL), bNeed2UV(false)
- {}
-
- //! Array of faces that belong to the group
- MDL::IntFace_MDL7* pcFaces;
-
- //! Array of vertex positions
- std::vector<aiVector3D> vPositions;
-
- //! Array of vertex normals
- std::vector<aiVector3D> vNormals;
-
- //! Array of bones indices
- std::vector<unsigned int> aiBones;
-
- //! First UV coordinate set
- std::vector<aiVector3D> vTextureCoords1;
-
- //! Optional second UV coordinate set
- std::vector<aiVector3D> vTextureCoords2;
-
- //! Specifies whether there are two texture
- //! coordinate sets required
- bool bNeed2UV;
-};
-
-// -------------------------------------------------------------------------------------
-//! Holds data from an MDL7 file that is shared by all mesh groups
-struct IntSharedData_MDL7
-{
- //! Default constructor
- IntSharedData_MDL7()
- : apcOutBones(),
- iNum()
- {
- abNeedMaterials.reserve(10);
- }
-
- //! Destruction: properly delete all allocated resources
- ~IntSharedData_MDL7()
- {
- // kill all bones
- if (this->apcOutBones)
- {
- for (unsigned int m = 0; m < iNum;++m)
- delete this->apcOutBones[m];
- delete[] this->apcOutBones;
- }
- }
-
- //! Specifies which materials are used
- std::vector<bool> abNeedMaterials;
-
- //! List of all materials
- std::vector<aiMaterial*> pcMats;
-
- //! List of all bones
- IntBone_MDL7** apcOutBones;
-
- //! number of bones
- unsigned int iNum;
-};
-
-// -------------------------------------------------------------------------------------
-//! Contains input data for GenerateOutputMeshes_3DGS_MDL7
-struct IntSplitGroupData_MDL7
-{
- //! Construction from a given shared data set
- IntSplitGroupData_MDL7(IntSharedData_MDL7& _shared,
- std::vector<aiMesh*>& _avOutList)
-
- : aiSplit(), shared(_shared), avOutList(_avOutList)
- {
- }
-
- //! Destruction: properly delete all allocated resources
- ~IntSplitGroupData_MDL7()
- {
- // kill all face lists
- if(this->aiSplit)
- {
- for (unsigned int m = 0; m < shared.pcMats.size();++m)
- delete this->aiSplit[m];
- delete[] this->aiSplit;
- }
- }
-
- //! Contains a list of all faces per material
- std::vector<unsigned int>** aiSplit;
-
- //! Shared data for all groups of the model
- IntSharedData_MDL7& shared;
-
- //! List of meshes
- std::vector<aiMesh*>& avOutList;
-};
-
-
-}
-} // end namespaces
-
-#endif // !! AI_MDLFILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/MDLLoader.cpp b/src/3rdparty/assimp/code/MDLLoader.cpp
deleted file mode 100644
index 2025d79b3..000000000
--- a/src/3rdparty/assimp/code/MDLLoader.cpp
+++ /dev/null
@@ -1,1972 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MDLLoader.cpp
- * @brief Implementation of the main parts of the MDL importer class
- * *TODO* Cleanup and further testing of some parts necessary
- */
-
-// internal headers
-
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-
-#include "MDLLoader.h"
-#include "Macros.h"
-#include "qnan.h"
-#include "MDLDefaultColorMap.h"
-#include "MD2FileData.h"
-#include "StringUtils.h"
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Quake Mesh / 3D GameStudio Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 7,
- 0,
- "mdl"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Ugly stuff ... nevermind
-#define _AI_MDL7_ACCESS(_data, _index, _limit, _type) \
- (*((const _type*)(((const char*)_data) + _index * _limit)))
-
-#define _AI_MDL7_ACCESS_PTR(_data, _index, _limit, _type) \
- ((BE_NCONST _type*)(((const char*)_data) + _index * _limit))
-
-#define _AI_MDL7_ACCESS_VERT(_data, _index, _limit) \
- _AI_MDL7_ACCESS(_data,_index,_limit,MDL::Vertex_MDL7)
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MDLImporter::MDLImporter()
- : configFrameID(),
- mBuffer(),
- iGSFileVersion(),
- pIOHandler(),
- pScene(),
- iFileSize()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MDLImporter::~MDLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- // if check for extension is not enough, check for the magic tokens
- if (extension == "mdl" || !extension.length() || checkSig) {
- uint32_t tokens[8];
- tokens[0] = AI_MDL_MAGIC_NUMBER_LE_HL2a;
- tokens[1] = AI_MDL_MAGIC_NUMBER_LE_HL2b;
- tokens[2] = AI_MDL_MAGIC_NUMBER_LE_GS7;
- tokens[3] = AI_MDL_MAGIC_NUMBER_LE_GS5b;
- tokens[4] = AI_MDL_MAGIC_NUMBER_LE_GS5a;
- tokens[5] = AI_MDL_MAGIC_NUMBER_LE_GS4;
- tokens[6] = AI_MDL_MAGIC_NUMBER_LE_GS3;
- tokens[7] = AI_MDL_MAGIC_NUMBER_LE;
- return CheckMagicToken(pIOHandler,pFile,tokens,8,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void MDLImporter::SetupProperties(const Importer* pImp)
-{
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_MDL_KEYFRAME,-1);
-
- // The
- // AI_CONFIG_IMPORT_MDL_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- if(static_cast<unsigned int>(-1) == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_MDL_COLORMAP - pallette file
- configPalette = pImp->GetPropertyString(AI_CONFIG_IMPORT_MDL_COLORMAP,"colormap.lmp");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported extensions
-const aiImporterDesc* MDLImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MDLImporter::InternReadFile( const std::string& pFile,
- aiScene* _pScene, IOSystem* _pIOHandler)
-{
- pScene = _pScene;
- pIOHandler = _pIOHandler;
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open MDL file " + pFile + ".");
- }
-
- // This should work for all other types of MDL files, too ...
- // the quake header is one of the smallest, afaik
- iFileSize = (unsigned int)file->FileSize();
- if( iFileSize < sizeof(MDL::Header)) {
- throw DeadlyImportError( "MDL File is too small.");
- }
-
- // Allocate storage and copy the contents of the file to a memory buffer
- mBuffer =new unsigned char[iFileSize+1];
- file->Read( (void*)mBuffer, 1, iFileSize);
-
- // Append a binary zero to the end of the buffer.
- // this is just for safety that string parsing routines
- // find the end of the buffer ...
- mBuffer[iFileSize] = '\0';
- const uint32_t iMagicWord = *((uint32_t*)mBuffer);
-
- // Determine the file subtype and call the appropriate member function
-
- // Original Quake1 format
- if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: Quake 1, magic word is IDPO");
- iGSFileVersion = 0;
- InternReadFile_Quake1();
- }
- // GameStudio A<old> MDL2 format - used by some test models that come with 3DGS
- else if (AI_MDL_MAGIC_NUMBER_BE_GS3 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS3 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A2, magic word is MDL2");
- iGSFileVersion = 2;
- InternReadFile_Quake1();
- }
- // GameStudio A4 MDL3 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS4 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS4 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL3");
- iGSFileVersion = 3;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A5+ MDL4 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS5a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5a == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A4, magic word is MDL4");
- iGSFileVersion = 4;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A5+ MDL5 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS5b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS5b == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A5, magic word is MDL5");
- iGSFileVersion = 5;
- InternReadFile_3DGS_MDL345();
- }
- // GameStudio A7 MDL7 format
- else if (AI_MDL_MAGIC_NUMBER_BE_GS7 == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_GS7 == iMagicWord) {
- DefaultLogger::get()->debug("MDL subtype: 3D GameStudio A7, magic word is MDL7");
- iGSFileVersion = 7;
- InternReadFile_3DGS_MDL7();
- }
- // IDST/IDSQ Format (CS:S/HL^2, etc ...)
- else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
- AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord)
- {
- DefaultLogger::get()->debug("MDL subtype: Source(tm) Engine, magic word is IDST/IDSQ");
- iGSFileVersion = 0;
- InternReadFile_HL2();
- }
- else {
- // print the magic word to the log file
- throw DeadlyImportError( "Unknown MDL subformat " + pFile +
- ". Magic word (" + std::string((char*)&iMagicWord,4) + ") is not known");
- }
-
- // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
- pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
- 0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
-
- // delete the file buffer and cleanup
- delete [] mBuffer;
- mBuffer= nullptr;
- AI_DEBUG_INVALIDATE_PTR(pIOHandler);
- AI_DEBUG_INVALIDATE_PTR(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether we're still inside the valid file range
-void MDLImporter::SizeCheck(const void* szPos)
-{
- if (!szPos || (const unsigned char*)szPos > this->mBuffer + this->iFileSize)
- {
- throw DeadlyImportError("Invalid MDL file. The file is too small "
- "or contains invalid data.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Just for debgging purposes
-void MDLImporter::SizeCheck(const void* szPos, const char* szFile, unsigned int iLine)
-{
- ai_assert(NULL != szFile);
- if (!szPos || (const unsigned char*)szPos > mBuffer + iFileSize)
- {
- // remove a directory if there is one
- const char* szFilePtr = ::strrchr(szFile,'\\');
- if (!szFilePtr) {
- if(!(szFilePtr = ::strrchr(szFile,'/')))
- szFilePtr = szFile;
- }
- if (szFilePtr)++szFilePtr;
-
- char szBuffer[1024];
- ::sprintf(szBuffer,"Invalid MDL file. The file is too small "
- "or contains invalid data (File: %s Line: %u)",szFilePtr,iLine);
-
- throw DeadlyImportError(szBuffer);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate a quake file header
-void MDLImporter::ValidateHeader_Quake1(const MDL::Header* pcHeader)
-{
- // some values may not be NULL
- if (!pcHeader->num_frames)
- throw DeadlyImportError( "[Quake 1 MDL] There are no frames in the file");
-
- if (!pcHeader->num_verts)
- throw DeadlyImportError( "[Quake 1 MDL] There are no vertices in the file");
-
- if (!pcHeader->num_tris)
- throw DeadlyImportError( "[Quake 1 MDL] There are no triangles in the file");
-
- // check whether the maxima are exceeded ...however, this applies for Quake 1 MDLs only
- if (!this->iGSFileVersion)
- {
- if (pcHeader->num_verts > AI_MDL_MAX_VERTS)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_VERTS vertices");
-
- if (pcHeader->num_tris > AI_MDL_MAX_TRIANGLES)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_TRIANGLES triangles");
-
- if (pcHeader->num_frames > AI_MDL_MAX_FRAMES)
- DefaultLogger::get()->warn("Quake 1 MDL model has more than AI_MDL_MAX_FRAMES frames");
-
- // (this does not apply for 3DGS MDLs)
- if (!this->iGSFileVersion && pcHeader->version != AI_MDL_VERSION)
- DefaultLogger::get()->warn("Quake 1 MDL model has an unknown version: AI_MDL_VERSION (=6) is "
- "the expected file format version");
- if(pcHeader->num_skins && (!pcHeader->skinwidth || !pcHeader->skinheight))
- DefaultLogger::get()->warn("Skin width or height are 0");
- }
-}
-
-#ifdef AI_BUILD_BIG_ENDIAN
-// ------------------------------------------------------------------------------------------------
-void FlipQuakeHeader(BE_NCONST MDL::Header* pcHeader)
-{
- AI_SWAP4( pcHeader->ident);
- AI_SWAP4( pcHeader->version);
- AI_SWAP4( pcHeader->boundingradius);
- AI_SWAP4( pcHeader->flags);
- AI_SWAP4( pcHeader->num_frames);
- AI_SWAP4( pcHeader->num_skins);
- AI_SWAP4( pcHeader->num_tris);
- AI_SWAP4( pcHeader->num_verts);
- for (unsigned int i = 0; i < 3;++i)
- {
- AI_SWAP4( pcHeader->scale[i]);
- AI_SWAP4( pcHeader->translate[i]);
- }
- AI_SWAP4( pcHeader->size);
- AI_SWAP4( pcHeader->skinheight);
- AI_SWAP4( pcHeader->skinwidth);
- AI_SWAP4( pcHeader->synctype);
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Read a Quake 1 file
-void MDLImporter::InternReadFile_Quake1( )
-{
- ai_assert(NULL != pScene);
- BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
-
-#ifdef AI_BUILD_BIG_ENDIAN
- FlipQuakeHeader(pcHeader);
-#endif
-
- ValidateHeader_Quake1(pcHeader);
-
- // current cursor position in the file
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
-
- // need to read all textures
- for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)
- {
- union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;};
- if (szCurrent + sizeof(MDL::Skin) > this->mBuffer + this->iFileSize) {
- throw DeadlyImportError("[Quake 1 MDL] Unexpected EOF");
- }
- pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
-
- AI_SWAP4( pcSkin->group );
-
- // Quake 1 groupskins
- if (1 == pcSkin->group)
- {
- AI_SWAP4( pcGroupSkin->nb );
-
- // need to skip multiple images
- const unsigned int iNumImages = (unsigned int)pcGroupSkin->nb;
- szCurrent += sizeof(uint32_t) * 2;
-
- if (0 != iNumImages)
- {
- if (!i) {
- // however, create only one output image (the first)
- this->CreateTextureARGB8_3DGS_MDL3(szCurrent + iNumImages * sizeof(float));
- }
- // go to the end of the skin section / the beginning of the next skin
- szCurrent += pcHeader->skinheight * pcHeader->skinwidth +
- sizeof(float) * iNumImages;
- }
- }
- // 3DGS has a few files that are using other 3DGS like texture formats here
- else
- {
- szCurrent += sizeof(uint32_t);
- unsigned int iSkip = i ? UINT_MAX : 0;
- CreateTexture_3DGS_MDL4(szCurrent,pcSkin->group,&iSkip);
- szCurrent += iSkip;
- }
- }
- // get a pointer to the texture coordinates
- BE_NCONST MDL::TexCoord* pcTexCoords = (BE_NCONST MDL::TexCoord*)szCurrent;
- szCurrent += sizeof(MDL::TexCoord) * pcHeader->num_verts;
-
- // get a pointer to the triangles
- BE_NCONST MDL::Triangle* pcTriangles = (BE_NCONST MDL::Triangle*)szCurrent;
- szCurrent += sizeof(MDL::Triangle) * pcHeader->num_tris;
- VALIDATE_FILE_SIZE(szCurrent);
-
- // now get a pointer to the first frame in the file
- BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
- BE_NCONST MDL::SimpleFrame* pcFirstFrame;
-
- if (0 == pcFrames->type)
- {
- // get address of single frame
- pcFirstFrame = &pcFrames->frame;
- }
- else
- {
- // get the first frame in the group
- BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
- pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
- }
- BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
- VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));
-
-#ifdef AI_BUILD_BIG_ENDIAN
- for (int i = 0; i<pcHeader->num_verts;++i)
- {
- AI_SWAP4( pcTexCoords[i].onseam );
- AI_SWAP4( pcTexCoords[i].s );
- AI_SWAP4( pcTexCoords[i].t );
- }
-
- for (int i = 0; i<pcHeader->num_tris;++i)
- {
- AI_SWAP4( pcTriangles[i].facesfront);
- AI_SWAP4( pcTriangles[i].vertex[0]);
- AI_SWAP4( pcTriangles[i].vertex[1]);
- AI_SWAP4( pcTriangles[i].vertex[2]);
- }
-#endif
-
- // setup materials
- SetupMaterialProperties_3DGS_MDL5_Quake1();
-
- // allocate enough storage to hold all vertices and triangles
- aiMesh* pcMesh = new aiMesh();
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mNumVertices = pcHeader->num_tris * 3;
- pcMesh->mNumFaces = pcHeader->num_tris;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
-
- // there won't be more than one mesh inside the file
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = pcMesh;
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i)
- {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent)
- {
- pcMesh->mFaces[i].mIndices[c] = iCurrent;
-
- // read vertices
- unsigned int iIndex = pcTriangles->vertex[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts)
- {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in Q1-MDL vertex list.");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- //vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- //pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- float s = (float)pcTexCoords[iIndex].s;
- float t = (float)pcTexCoords[iIndex].t;
-
- // translate texture coordinates
- if (0 == pcTriangles->facesfront && 0 != pcTexCoords[iIndex].onseam) {
- s += pcHeader->skinwidth * 0.5f;
- }
-
- // Scale s and t to range from 0.0 to 1.0
- pcMesh->mTextureCoords[0][iCurrent].x = (s + 0.5f) / pcHeader->skinwidth;
- pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-(t + 0.5f) / pcHeader->skinheight;
-
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup material properties for Quake and older GameStudio files
-void MDLImporter::SetupMaterialProperties_3DGS_MDL5_Quake1( )
-{
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
-
- // allocate ONE material
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = new aiMaterial();
- pScene->mNumMaterials = 1;
-
- // setup the material's properties
- const int iMode = (int)aiShadingMode_Gouraud;
- aiMaterial* const pcHelper = (aiMaterial*)pScene->mMaterials[0];
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor4D clr;
- if (0 != pcHeader->num_skins && pScene->mNumTextures) {
- // can we replace the texture with a single color?
- clr = this->ReplaceTextureWithColor(pScene->mTextures[0]);
- if (is_not_qnan(clr.r)) {
- delete pScene->mTextures[0];
- delete[] pScene->mTextures;
-
- pScene->mTextures = NULL;
- pScene->mNumTextures = 0;
- }
- else {
- clr.b = clr.a = clr.g = clr.r = 1.0f;
- aiString szString;
- ::memcpy(szString.data,AI_MAKE_EMBEDDED_TEXNAME(0),3);
- szString.length = 2;
- pcHelper->AddProperty(&szString,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.r *= 0.05f;clr.g *= 0.05f;
- clr.b *= 0.05f;clr.a = 1.0f;
- pcHelper->AddProperty<aiColor4D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a MDL 3,4,5 file
-void MDLImporter::InternReadFile_3DGS_MDL345( )
-{
- ai_assert(NULL != pScene);
-
- // the header of MDL 3/4/5 is nearly identical to the original Quake1 header
- BE_NCONST MDL::Header *pcHeader = (BE_NCONST MDL::Header*)this->mBuffer;
-#ifdef AI_BUILD_BIG_ENDIAN
- FlipQuakeHeader(pcHeader);
-#endif
- ValidateHeader_Quake1(pcHeader);
-
- // current cursor position in the file
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
- const unsigned char* szEnd = mBuffer + iFileSize;
-
- // need to read all textures
- for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i) {
- if (szCurrent >= szEnd) {
- throw DeadlyImportError( "Texture data past end of file.");
- }
- BE_NCONST MDL::Skin* pcSkin;
- pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
- AI_SWAP4( pcSkin->group);
- // create one output image
- unsigned int iSkip = i ? UINT_MAX : 0;
- if (5 <= iGSFileVersion)
- {
- // MDL5 format could contain MIPmaps
- CreateTexture_3DGS_MDL5((unsigned char*)pcSkin + sizeof(uint32_t),
- pcSkin->group,&iSkip);
- }
- else {
- CreateTexture_3DGS_MDL4((unsigned char*)pcSkin + sizeof(uint32_t),
- pcSkin->group,&iSkip);
- }
- // need to skip one image
- szCurrent += iSkip + sizeof(uint32_t);
-
- }
- // get a pointer to the texture coordinates
- BE_NCONST MDL::TexCoord_MDL3* pcTexCoords = (BE_NCONST MDL::TexCoord_MDL3*)szCurrent;
- szCurrent += sizeof(MDL::TexCoord_MDL3) * pcHeader->synctype;
-
- // NOTE: for MDLn formats "synctype" corresponds to the number of UV coords
-
- // get a pointer to the triangles
- BE_NCONST MDL::Triangle_MDL3* pcTriangles = (BE_NCONST MDL::Triangle_MDL3*)szCurrent;
- szCurrent += sizeof(MDL::Triangle_MDL3) * pcHeader->num_tris;
-
-#ifdef AI_BUILD_BIG_ENDIAN
-
- for (int i = 0; i<pcHeader->synctype;++i) {
- AI_SWAP2( pcTexCoords[i].u );
- AI_SWAP2( pcTexCoords[i].v );
- }
-
- for (int i = 0; i<pcHeader->num_tris;++i) {
- AI_SWAP2( pcTriangles[i].index_xyz[0]);
- AI_SWAP2( pcTriangles[i].index_xyz[1]);
- AI_SWAP2( pcTriangles[i].index_xyz[2]);
- AI_SWAP2( pcTriangles[i].index_uv[0]);
- AI_SWAP2( pcTriangles[i].index_uv[1]);
- AI_SWAP2( pcTriangles[i].index_uv[2]);
- }
-
-#endif
-
- VALIDATE_FILE_SIZE(szCurrent);
-
- // setup materials
- SetupMaterialProperties_3DGS_MDL5_Quake1();
-
- // allocate enough storage to hold all vertices and triangles
- aiMesh* pcMesh = new aiMesh();
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pcMesh->mNumVertices = pcHeader->num_tris * 3;
- pcMesh->mNumFaces = pcHeader->num_tris;
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- // there won't be more than one mesh inside the file
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = pcMesh;
-
- // allocate output storage
- pcMesh->mNumVertices = (unsigned int)pcHeader->num_tris*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- if (pcHeader->synctype) {
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
- }
-
- // now get a pointer to the first frame in the file
- BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
- AI_SWAP4(pcFrames->type);
-
- // byte packed vertices
- // FIXME: these two snippets below are almost identical ... join them?
- /////////////////////////////////////////////////////////////////////////////////////
- if (0 == pcFrames->type || 3 >= this->iGSFileVersion) {
-
- const MDL::SimpleFrame* pcFirstFrame = (const MDL::SimpleFrame*)(szCurrent + sizeof(uint32_t));
- const MDL::Vertex* pcVertices = (const MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
-
- VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- // read vertices
- unsigned int iIndex = pcTriangles->index_xyz[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts) {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- // vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- // pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- if (pcHeader->synctype) {
- ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
- pcTexCoords,pcTriangles->index_uv[c]);
- }
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
-
- }
- // short packed vertices
- /////////////////////////////////////////////////////////////////////////////////////
- else {
- // now get a pointer to the first frame in the file
- const MDL::SimpleFrame_MDLn_SP* pcFirstFrame = (const MDL::SimpleFrame_MDLn_SP*) (szCurrent + sizeof(uint32_t));
-
- // get a pointer to the vertices
- const MDL::Vertex_MDL4* pcVertices = (const MDL::Vertex_MDL4*) ((pcFirstFrame->name) +
- sizeof(pcFirstFrame->name));
-
- VALIDATE_FILE_SIZE(pcVertices + pcHeader->num_verts);
-
- // now iterate through all triangles
- unsigned int iCurrent = 0;
- for (unsigned int i = 0; i < (unsigned int) pcHeader->num_tris;++i) {
- pcMesh->mFaces[i].mIndices = new unsigned int[3];
- pcMesh->mFaces[i].mNumIndices = 3;
-
- unsigned int iTemp = iCurrent;
- for (unsigned int c = 0; c < 3;++c,++iCurrent) {
- // read vertices
- unsigned int iIndex = pcTriangles->index_xyz[c];
- if (iIndex >= (unsigned int)pcHeader->num_verts) {
- iIndex = pcHeader->num_verts-1;
- DefaultLogger::get()->warn("Index overflow in MDLn vertex list");
- }
-
- aiVector3D& vec = pcMesh->mVertices[iCurrent];
- vec.x = (float)pcVertices[iIndex].v[0] * pcHeader->scale[0];
- vec.x += pcHeader->translate[0];
-
- vec.y = (float)pcVertices[iIndex].v[1] * pcHeader->scale[1];
- vec.y += pcHeader->translate[1];
- // vec.y *= -1.0f;
-
- vec.z = (float)pcVertices[iIndex].v[2] * pcHeader->scale[2];
- vec.z += pcHeader->translate[2];
-
- // read the normal vector from the precalculated normal table
- MD2::LookupNormalIndex(pcVertices[iIndex].normalIndex,pcMesh->mNormals[iCurrent]);
- // pcMesh->mNormals[iCurrent].y *= -1.0f;
-
- // read texture coordinates
- if (pcHeader->synctype) {
- ImportUVCoordinate_3DGS_MDL345(pcMesh->mTextureCoords[0][iCurrent],
- pcTexCoords,pcTriangles->index_uv[c]);
- }
- }
- pcMesh->mFaces[i].mIndices[0] = iTemp+2;
- pcMesh->mFaces[i].mIndices[1] = iTemp+1;
- pcMesh->mFaces[i].mIndices[2] = iTemp+0;
- pcTriangles++;
- }
- }
-
- // For MDL5 we will need to build valid texture coordinates
- // basing upon the file loaded (only support one file as skin)
- if (0x5 == iGSFileVersion)
- CalculateUVCoordinates_MDL5();
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a single UV coordinate for Quake and older GameStudio files
-void MDLImporter::ImportUVCoordinate_3DGS_MDL345(
- aiVector3D& vOut,
- const MDL::TexCoord_MDL3* pcSrc,
- unsigned int iIndex)
-{
- ai_assert(NULL != pcSrc);
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
-
- // validate UV indices
- if (iIndex >= (unsigned int) pcHeader->synctype) {
- iIndex = pcHeader->synctype-1;
- DefaultLogger::get()->warn("Index overflow in MDLn UV coord list");
- }
-
- float s = (float)pcSrc[iIndex].u;
- float t = (float)pcSrc[iIndex].v;
-
- // Scale s and t to range from 0.0 to 1.0
- if (0x5 != iGSFileVersion) {
- s = (s + 0.5f) / pcHeader->skinwidth;
- t = 1.0f-(t + 0.5f) / pcHeader->skinheight;
- }
-
- vOut.x = s;
- vOut.y = t;
- vOut.z = 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compute UV coordinates for a MDL5 file
-void MDLImporter::CalculateUVCoordinates_MDL5()
-{
- const MDL::Header* const pcHeader = (const MDL::Header*)this->mBuffer;
- if (pcHeader->num_skins && this->pScene->mNumTextures) {
- const aiTexture* pcTex = this->pScene->mTextures[0];
-
- // if the file is loaded in DDS format: get the size of the
- // texture from the header of the DDS file
- // skip three DWORDs and read first height, then the width
- unsigned int iWidth, iHeight;
- if (!pcTex->mHeight) {
- const uint32_t* piPtr = (uint32_t*)pcTex->pcData;
-
- piPtr += 3;
- iHeight = (unsigned int)*piPtr++;
- iWidth = (unsigned int)*piPtr;
- if (!iHeight || !iWidth)
- {
- DefaultLogger::get()->warn("Either the width or the height of the "
- "embedded DDS texture is zero. Unable to compute final texture "
- "coordinates. The texture coordinates remain in their original "
- "0-x/0-y (x,y = texture size) range.");
- iWidth = 1;
- iHeight = 1;
- }
- }
- else {
- iWidth = pcTex->mWidth;
- iHeight = pcTex->mHeight;
- }
-
- if (1 != iWidth || 1 != iHeight) {
- const float fWidth = (float)iWidth;
- const float fHeight = (float)iHeight;
- aiMesh* pcMesh = this->pScene->mMeshes[0];
- for (unsigned int i = 0; i < pcMesh->mNumVertices;++i)
- {
- pcMesh->mTextureCoords[0][i].x /= fWidth;
- pcMesh->mTextureCoords[0][i].y /= fHeight;
- pcMesh->mTextureCoords[0][i].y = 1.0f - pcMesh->mTextureCoords[0][i].y; // DX to OGL
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Validate the header of a MDL7 file
-void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
-{
- ai_assert(NULL != pcHeader);
-
- // There are some fixed sizes ...
- if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size) {
- throw DeadlyImportError(
- "[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
- }
- if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size) {
- throw DeadlyImportError(
- "[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
- }
- if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size) {
- throw DeadlyImportError(
- "sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
- }
-
- // if there are no groups ... how should we load such a file?
- if(!pcHeader->groups_num) {
- throw DeadlyImportError( "[3DGS MDL7] No frames found");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// resolve bone animation matrices
-void MDLImporter::CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones)
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- const MDL::Bone_MDL7* pcBones = (const MDL::Bone_MDL7*)(pcHeader+1);
- ai_assert(NULL != apcOutBones);
-
- // first find the bone that has NO parent, calculate the
- // animation matrix for it, then go on and search for the next parent
- // index (0) and so on until we can't find a new node.
- uint16_t iParent = 0xffff;
- uint32_t iIterations = 0;
- while (iIterations++ < pcHeader->bones_num) {
- for (uint32_t iBone = 0; iBone < pcHeader->bones_num;++iBone) {
- BE_NCONST MDL::Bone_MDL7* pcBone = _AI_MDL7_ACCESS_PTR(pcBones,iBone,
- pcHeader->bone_stc_size,MDL::Bone_MDL7);
-
- AI_SWAP2(pcBone->parent_index);
- AI_SWAP4(pcBone->x);
- AI_SWAP4(pcBone->y);
- AI_SWAP4(pcBone->z);
-
- if (iParent == pcBone->parent_index) {
- // MDL7 readme
- ////////////////////////////////////////////////////////////////
- /*
- The animation matrix is then calculated the following way:
-
- vector3 bPos = <absolute bone position>
- matrix44 laM; // local animation matrix
- sphrvector key_rotate = <bone rotation>
-
- matrix44 m1,m2;
- create_trans_matrix(m1, -bPos.x, -bPos.y, -bPos.z);
- create_trans_matrix(m2, -bPos.x, -bPos.y, -bPos.z);
-
- create_rotation_matrix(laM,key_rotate);
-
- laM = sm1 * laM;
- laM = laM * sm2;
- */
- /////////////////////////////////////////////////////////////////
-
- MDL::IntBone_MDL7* const pcOutBone = apcOutBones[iBone];
-
- // store the parent index of the bone
- pcOutBone->iParent = pcBone->parent_index;
- if (0xffff != iParent) {
- const MDL::IntBone_MDL7* pcParentBone = apcOutBones[iParent];
- pcOutBone->mOffsetMatrix.a4 = -pcParentBone->vPosition.x;
- pcOutBone->mOffsetMatrix.b4 = -pcParentBone->vPosition.y;
- pcOutBone->mOffsetMatrix.c4 = -pcParentBone->vPosition.z;
- }
- pcOutBone->vPosition.x = pcBone->x;
- pcOutBone->vPosition.y = pcBone->y;
- pcOutBone->vPosition.z = pcBone->z;
- pcOutBone->mOffsetMatrix.a4 -= pcBone->x;
- pcOutBone->mOffsetMatrix.b4 -= pcBone->y;
- pcOutBone->mOffsetMatrix.c4 -= pcBone->z;
-
- if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE == pcHeader->bone_stc_size) {
- // no real name for our poor bone is specified :-(
- pcOutBone->mName.length = ai_snprintf(pcOutBone->mName.data, MAXLEN,
- "UnnamedBone_%i",iBone);
- }
- else {
- // Make sure we won't run over the buffer's end if there is no
- // terminal 0 character (however the documentation says there
- // should be one)
- uint32_t iMaxLen = pcHeader->bone_stc_size-16;
- for (uint32_t qq = 0; qq < iMaxLen;++qq) {
- if (!pcBone->name[qq]) {
- iMaxLen = qq;
- break;
- }
- }
-
- // store the name of the bone
- pcOutBone->mName.length = (size_t)iMaxLen;
- ::memcpy(pcOutBone->mName.data,pcBone->name,pcOutBone->mName.length);
- pcOutBone->mName.data[pcOutBone->mName.length] = '\0';
- }
- }
- }
- ++iParent;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// read bones from a MDL7 file
-MDL::IntBone_MDL7** MDLImporter::LoadBones_3DGS_MDL7()
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- if (pcHeader->bones_num) {
- // validate the size of the bone data structure in the file
- if (AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_20_CHARS != pcHeader->bone_stc_size &&
- AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_32_CHARS != pcHeader->bone_stc_size &&
- AI_MDL7_BONE_STRUCT_SIZE__NAME_IS_NOT_THERE != pcHeader->bone_stc_size)
- {
- DefaultLogger::get()->warn("Unknown size of bone data structure");
- return NULL;
- }
-
- MDL::IntBone_MDL7** apcBonesOut = new MDL::IntBone_MDL7*[pcHeader->bones_num];
- for (uint32_t crank = 0; crank < pcHeader->bones_num;++crank)
- apcBonesOut[crank] = new MDL::IntBone_MDL7();
-
- // and calculate absolute bone offset matrices ...
- CalcAbsBoneMatrices_3DGS_MDL7(apcBonesOut);
- return apcBonesOut;
- }
- return NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// read faces from a MDL7 file
-void MDLImporter::ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData)
-{
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
-
- // iterate through all triangles and build valid display lists
- unsigned int iOutIndex = 0;
- for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
- AI_SWAP2(pcGroupTris->v_index[0]);
- AI_SWAP2(pcGroupTris->v_index[1]);
- AI_SWAP2(pcGroupTris->v_index[2]);
-
- // iterate through all indices of the current triangle
- for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
-
- // validate the vertex index
- unsigned int iIndex = pcGroupTris->v_index[c];
- if(iIndex > (unsigned int)groupInfo.pcGroup->numverts) {
- // (we might need to read this section a second time - to process frame vertices correctly)
- pcGroupTris->v_index[c] = iIndex = groupInfo.pcGroup->numverts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 vertex list");
- }
-
- // write the output face index
- groupData.pcFaces[iTriangle].mIndices[2-c] = iOutIndex;
-
- aiVector3D& vPosition = groupData.vPositions[ iOutIndex ];
- vPosition.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex, pcHeader->mainvertex_stc_size) .x;
- vPosition.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .y;
- vPosition.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .z;
-
- // if we have bones, save the index
- if (!groupData.aiBones.empty()) {
- groupData.aiBones[iOutIndex] = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,
- iIndex,pcHeader->mainvertex_stc_size).vertindex;
- }
-
- // now read the normal vector
- if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the full normal vector
- aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
- vNormal.x = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[0];
- AI_SWAP4(vNormal.x);
- vNormal.y = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[1];
- AI_SWAP4(vNormal.y);
- vNormal.z = _AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,pcHeader->mainvertex_stc_size) .norm[2];
- AI_SWAP4(vNormal.z);
- }
- else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the normal vector from Quake2's smart table
- aiVector3D& vNormal = groupData.vNormals[ iOutIndex ];
- MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(groupInfo.pcGroupVerts,iIndex,
- pcHeader->mainvertex_stc_size) .norm162index,vNormal);
- }
- // validate and process the first uv coordinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV) {
-
- if (groupInfo.pcGroup->num_stpts) {
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[0]);
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[1]);
- AI_SWAP2(pcGroupTris->skinsets[0].st_index[2]);
-
- iIndex = pcGroupTris->skinsets[0].st_index[c];
- if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
- iIndex = groupInfo.pcGroup->num_stpts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#1)");
- }
-
- float u = groupInfo.pcGroupUVs[iIndex].u;
- float v = 1.0f-groupInfo.pcGroupUVs[iIndex].v; // DX to OGL
-
- groupData.vTextureCoords1[iOutIndex].x = u;
- groupData.vTextureCoords1[iOutIndex].y = v;
- }
- // assign the material index, but only if it is existing
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_ONE_UV_WITH_MATINDEX){
- AI_SWAP4(pcGroupTris->skinsets[0].material);
- groupData.pcFaces[iTriangle].iMatIndex[0] = pcGroupTris->skinsets[0].material;
- }
- }
- // validate and process the second uv coordinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
-
- if (groupInfo.pcGroup->num_stpts) {
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[0]);
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[1]);
- AI_SWAP2(pcGroupTris->skinsets[1].st_index[2]);
- AI_SWAP4(pcGroupTris->skinsets[1].material);
-
- iIndex = pcGroupTris->skinsets[1].st_index[c];
- if(iIndex > (unsigned int)groupInfo.pcGroup->num_stpts) {
- iIndex = groupInfo.pcGroup->num_stpts-1;
- DefaultLogger::get()->warn("Index overflow in MDL7 UV coordinate list (#2)");
- }
-
- float u = groupInfo.pcGroupUVs[ iIndex ].u;
- float v = 1.0f-groupInfo.pcGroupUVs[ iIndex ].v;
-
- groupData.vTextureCoords2[ iOutIndex ].x = u;
- groupData.vTextureCoords2[ iOutIndex ].y = v; // DX to OGL
-
- // check whether we do really need the second texture
- // coordinate set ... wastes memory and loading time
- if (0 != iIndex && (u != groupData.vTextureCoords1[ iOutIndex ].x ||
- v != groupData.vTextureCoords1[ iOutIndex ].y ) )
- groupData.bNeed2UV = true;
-
- // if the material differs, we need a second skin, too
- if (pcGroupTris->skinsets[ 1 ].material != pcGroupTris->skinsets[ 0 ].material)
- groupData.bNeed2UV = true;
- }
- // assign the material index
- groupData.pcFaces[ iTriangle ].iMatIndex[ 1 ] = pcGroupTris->skinsets[ 1 ].material;
- }
- }
- // get the next triangle in the list
- pcGroupTris = (MDL::Triangle_MDL7*)((const char*)pcGroupTris + pcHeader->triangle_stc_size);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// handle frames in a MDL7 file
-bool MDLImporter::ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSharedData_MDL7& shared,
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut)
-{
- ai_assert( nullptr != szCurrent );
- ai_assert( nullptr != szCurrentOut);
-
- const MDL::Header_MDL7 *pcHeader = (const MDL::Header_MDL7*)mBuffer;
-
- // if we have no bones we can simply skip all frames,
- // otherwise we'll need to process them.
- // FIX: If we need another frame than the first we must apply frame vertex replacements ...
- for(unsigned int iFrame = 0; iFrame < (unsigned int)groupInfo.pcGroup->numframes;++iFrame) {
- MDL::IntFrameInfo_MDL7 frame ((BE_NCONST MDL::Frame_MDL7*)szCurrent,iFrame);
-
- AI_SWAP4(frame.pcFrame->vertices_count);
- AI_SWAP4(frame.pcFrame->transmatrix_count);
-
- const unsigned int iAdd = pcHeader->frame_stc_size +
- frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size +
- frame.pcFrame->transmatrix_count * pcHeader->bonetrans_stc_size;
-
- if (((const char*)szCurrent - (const char*)pcHeader) + iAdd > (unsigned int)pcHeader->data_size) {
- DefaultLogger::get()->warn("Index overflow in frame area. "
- "Ignoring all frames and all further mesh groups, too.");
-
- // don't parse more groups if we can't even read one
- // FIXME: sometimes this seems to occur even for valid files ...
- *szCurrentOut = szCurrent;
- return false;
- }
- // our output frame?
- if (configFrameID == iFrame) {
- BE_NCONST MDL::Vertex_MDL7* pcFrameVertices = (BE_NCONST MDL::Vertex_MDL7*)(szCurrent+pcHeader->frame_stc_size);
-
- for (unsigned int qq = 0; qq < frame.pcFrame->vertices_count;++qq) {
- // I assume this are simple replacements for normal vertices, the bone index serving
- // as the index of the vertex to be replaced.
- uint16_t iIndex = _AI_MDL7_ACCESS(pcFrameVertices,qq,pcHeader->framevertex_stc_size,MDL::Vertex_MDL7).vertindex;
- AI_SWAP2(iIndex);
- if (iIndex >= groupInfo.pcGroup->numverts) {
- DefaultLogger::get()->warn("Invalid vertex index in frame vertex section");
- continue;
- }
-
- aiVector3D vPosition,vNormal;
-
- vPosition.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .x;
- AI_SWAP4(vPosition.x);
- vPosition.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .y;
- AI_SWAP4(vPosition.y);
- vPosition.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .z;
- AI_SWAP4(vPosition.z);
-
- // now read the normal vector
- if (AI_MDL7_FRAMEVERTEX030305_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the full normal vector
- vNormal.x = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[0];
- AI_SWAP4(vNormal.x);
- vNormal.y = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[1];
- AI_SWAP4(vNormal.y);
- vNormal.z = _AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,pcHeader->framevertex_stc_size) .norm[2];
- AI_SWAP4(vNormal.z);
- }
- else if (AI_MDL7_FRAMEVERTEX120503_STCSIZE <= pcHeader->mainvertex_stc_size) {
- // read the normal vector from Quake2's smart table
- MD2::LookupNormalIndex(_AI_MDL7_ACCESS_VERT(pcFrameVertices,qq,
- pcHeader->framevertex_stc_size) .norm162index,vNormal);
- }
-
- // FIXME: O(n^2) at the moment ...
- BE_NCONST MDL::Triangle_MDL7* pcGroupTris = groupInfo.pcGroupTris;
- unsigned int iOutIndex = 0;
- for (unsigned int iTriangle = 0; iTriangle < (unsigned int)groupInfo.pcGroup->numtris; ++iTriangle) {
- // iterate through all indices of the current triangle
- for (unsigned int c = 0; c < 3;++c,++iOutIndex) {
- // replace the vertex with the new data
- const unsigned int iCurIndex = pcGroupTris->v_index[c];
- if (iCurIndex == iIndex) {
- groupData.vPositions[iOutIndex] = vPosition;
- groupData.vNormals[iOutIndex] = vNormal;
- }
- }
- // get the next triangle in the list
- pcGroupTris = (BE_NCONST MDL::Triangle_MDL7*)((const char*)
- pcGroupTris + pcHeader->triangle_stc_size);
- }
- }
- }
- // parse bone trafo matrix keys (only if there are bones ...)
- if (shared.apcOutBones) {
- ParseBoneTrafoKeys_3DGS_MDL7(groupInfo,frame,shared);
- }
- szCurrent += iAdd;
- }
- *szCurrentOut = szCurrent;
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Sort faces by material, handle multiple UVs correctly
-void MDLImporter::SortByMaterials_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplitGroupData_MDL7& splitGroupData)
-{
- const unsigned int iNumMaterials = (unsigned int)splitGroupData.shared.pcMats.size();
- if (!groupData.bNeed2UV) {
- // if we don't need a second set of texture coordinates there is no reason to keep it in memory ...
- groupData.vTextureCoords2.clear();
-
- // allocate the array
- splitGroupData.aiSplit = new std::vector<unsigned int>*[iNumMaterials];
-
- for (unsigned int m = 0; m < iNumMaterials;++m)
- splitGroupData.aiSplit[m] = new std::vector<unsigned int>();
-
- // iterate through all faces and sort by material
- for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
- // check range
- if (groupData.pcFaces[iFace].iMatIndex[0] >= iNumMaterials) {
- // use the last material instead
- splitGroupData.aiSplit[iNumMaterials-1]->push_back(iFace);
-
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- if(0xFFFFFFFF != groupData.pcFaces[iFace].iMatIndex[0])
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#0]");
- }
- else splitGroupData.aiSplit[groupData.pcFaces[iFace].
- iMatIndex[0]]->push_back(iFace);
- }
- }
- else
- {
- // we need to build combined materials for each combination of
- std::vector<MDL::IntMaterial_MDL7> avMats;
- avMats.reserve(iNumMaterials*2);
-
- // fixme: why on the heap?
- std::vector<std::vector<unsigned int>* > aiTempSplit(iNumMaterials*2);
- for (unsigned int m = 0; m < iNumMaterials;++m)
- aiTempSplit[m] = new std::vector<unsigned int>();
-
- // iterate through all faces and sort by material
- for (unsigned int iFace = 0; iFace < (unsigned int)groupInfo.pcGroup->numtris;++iFace) {
- // check range
- unsigned int iMatIndex = groupData.pcFaces[iFace].iMatIndex[0];
- if (iMatIndex >= iNumMaterials) {
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- if(UINT_MAX != iMatIndex)
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#1]");
- iMatIndex = iNumMaterials-1;
- }
- unsigned int iMatIndex2 = groupData.pcFaces[iFace].iMatIndex[1];
-
- unsigned int iNum = iMatIndex;
- if (UINT_MAX != iMatIndex2 && iMatIndex != iMatIndex2) {
- if (iMatIndex2 >= iNumMaterials) {
- // sometimes MED writes -1, but normally only if there is only
- // one skin assigned. No warning in this case
- DefaultLogger::get()->warn("Index overflow in MDL7 material list [#2]");
- iMatIndex2 = iNumMaterials-1;
- }
-
- // do a slow search in the list ...
- iNum = 0;
- bool bFound = false;
- for (std::vector<MDL::IntMaterial_MDL7>::iterator i = avMats.begin();i != avMats.end();++i,++iNum){
- if ((*i).iOldMatIndices[0] == iMatIndex && (*i).iOldMatIndices[1] == iMatIndex2) {
- // reuse this material
- bFound = true;
- break;
- }
- }
- if (!bFound) {
- // build a new material ...
- MDL::IntMaterial_MDL7 sHelper;
- sHelper.pcMat = new aiMaterial();
- sHelper.iOldMatIndices[0] = iMatIndex;
- sHelper.iOldMatIndices[1] = iMatIndex2;
- JoinSkins_3DGS_MDL7(splitGroupData.shared.pcMats[iMatIndex],
- splitGroupData.shared.pcMats[iMatIndex2],sHelper.pcMat);
-
- // and add it to the list
- avMats.push_back(sHelper);
- iNum = (unsigned int)avMats.size()-1;
- }
- // adjust the size of the file array
- if (iNum == aiTempSplit.size()) {
- aiTempSplit.push_back(new std::vector<unsigned int>());
- }
- }
- aiTempSplit[iNum]->push_back(iFace);
- }
-
- // now add the newly created materials to the old list
- if (0 == groupInfo.iIndex) {
- splitGroupData.shared.pcMats.resize(avMats.size());
- for (unsigned int o = 0; o < avMats.size();++o)
- splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
- }
- else {
- // This might result in redundant materials ...
- splitGroupData.shared.pcMats.resize(iNumMaterials + avMats.size());
- for (unsigned int o = iNumMaterials; o < avMats.size();++o)
- splitGroupData.shared.pcMats[o] = avMats[o].pcMat;
- }
-
- // and build the final face-to-material array
- splitGroupData.aiSplit = new std::vector<unsigned int>*[aiTempSplit.size()];
- for (unsigned int m = 0; m < iNumMaterials;++m)
- splitGroupData.aiSplit[m] = aiTempSplit[m];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a MDL7 file
-void MDLImporter::InternReadFile_3DGS_MDL7( )
-{
- ai_assert(NULL != pScene);
-
- MDL::IntSharedData_MDL7 sharedData;
-
- // current cursor position in the file
- BE_NCONST MDL::Header_MDL7 *pcHeader = (BE_NCONST MDL::Header_MDL7*)this->mBuffer;
- const unsigned char* szCurrent = (const unsigned char*)(pcHeader+1);
-
- AI_SWAP4(pcHeader->version);
- AI_SWAP4(pcHeader->bones_num);
- AI_SWAP4(pcHeader->groups_num);
- AI_SWAP4(pcHeader->data_size);
- AI_SWAP4(pcHeader->entlump_size);
- AI_SWAP4(pcHeader->medlump_size);
- AI_SWAP2(pcHeader->bone_stc_size);
- AI_SWAP2(pcHeader->skin_stc_size);
- AI_SWAP2(pcHeader->colorvalue_stc_size);
- AI_SWAP2(pcHeader->material_stc_size);
- AI_SWAP2(pcHeader->skinpoint_stc_size);
- AI_SWAP2(pcHeader->triangle_stc_size);
- AI_SWAP2(pcHeader->mainvertex_stc_size);
- AI_SWAP2(pcHeader->framevertex_stc_size);
- AI_SWAP2(pcHeader->bonetrans_stc_size);
- AI_SWAP2(pcHeader->frame_stc_size);
-
- // validate the header of the file. There are some structure
- // sizes that are expected by the loader to be constant
- this->ValidateHeader_3DGS_MDL7(pcHeader);
-
- // load all bones (they are shared by all groups, so
- // we'll need to add them to all groups/meshes later)
- // apcBonesOut is a list of all bones or NULL if they could not been loaded
- szCurrent += pcHeader->bones_num * pcHeader->bone_stc_size;
- sharedData.apcOutBones = this->LoadBones_3DGS_MDL7();
-
- // vector to held all created meshes
- std::vector<aiMesh*>* avOutList;
-
- // 3 meshes per group - that should be OK for most models
- avOutList = new std::vector<aiMesh*>[pcHeader->groups_num];
- for (uint32_t i = 0; i < pcHeader->groups_num;++i)
- avOutList[i].reserve(3);
-
- // buffer to held the names of all groups in the file
- const size_t buffersize( AI_MDL7_MAX_GROUPNAMESIZE*pcHeader->groups_num );
- char* aszGroupNameBuffer = new char[ buffersize ];
-
- // read all groups
- for (unsigned int iGroup = 0; iGroup < (unsigned int)pcHeader->groups_num;++iGroup) {
- MDL::IntGroupInfo_MDL7 groupInfo((BE_NCONST MDL::Group_MDL7*)szCurrent,iGroup);
- szCurrent = (const unsigned char*)(groupInfo.pcGroup+1);
-
- VALIDATE_FILE_SIZE(szCurrent);
-
- AI_SWAP4(groupInfo.pcGroup->groupdata_size);
- AI_SWAP4(groupInfo.pcGroup->numskins);
- AI_SWAP4(groupInfo.pcGroup->num_stpts);
- AI_SWAP4(groupInfo.pcGroup->numtris);
- AI_SWAP4(groupInfo.pcGroup->numverts);
- AI_SWAP4(groupInfo.pcGroup->numframes);
-
- if (1 != groupInfo.pcGroup->typ) {
- // Not a triangle-based mesh
- DefaultLogger::get()->warn("[3DGS MDL7] Not a triangle mesh group. Continuing happily");
- }
-
- // store the name of the group
- const unsigned int ofs = iGroup*AI_MDL7_MAX_GROUPNAMESIZE;
- ::memcpy(&aszGroupNameBuffer[ofs],
- groupInfo.pcGroup->name,AI_MDL7_MAX_GROUPNAMESIZE);
-
- // make sure '\0' is at the end
- aszGroupNameBuffer[ofs+AI_MDL7_MAX_GROUPNAMESIZE-1] = '\0';
-
- // read all skins
- sharedData.pcMats.reserve(sharedData.pcMats.size() + groupInfo.pcGroup->numskins);
- sharedData.abNeedMaterials.resize(sharedData.abNeedMaterials.size() +
- groupInfo.pcGroup->numskins,false);
-
- for (unsigned int iSkin = 0; iSkin < (unsigned int)groupInfo.pcGroup->numskins;++iSkin) {
- ParseSkinLump_3DGS_MDL7(szCurrent,&szCurrent,sharedData.pcMats);
- }
- // if we have absolutely no skin loaded we need to generate a default material
- if (sharedData.pcMats.empty()) {
- const int iMode = (int)aiShadingMode_Gouraud;
- sharedData.pcMats.push_back(new aiMaterial());
- aiMaterial* pcHelper = (aiMaterial*)sharedData.pcMats[0];
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.6f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
-
- sharedData.abNeedMaterials.resize(1,false);
- }
-
- // now get a pointer to all texture coords in the group
- groupInfo.pcGroupUVs = (BE_NCONST MDL::TexCoord_MDL7*)szCurrent;
- for(int i = 0; i < groupInfo.pcGroup->num_stpts; ++i){
- AI_SWAP4(groupInfo.pcGroupUVs[i].u);
- AI_SWAP4(groupInfo.pcGroupUVs[i].v);
- }
- szCurrent += pcHeader->skinpoint_stc_size * groupInfo.pcGroup->num_stpts;
-
- // now get a pointer to all triangle in the group
- groupInfo.pcGroupTris = (Triangle_MDL7*)szCurrent;
- szCurrent += pcHeader->triangle_stc_size * groupInfo.pcGroup->numtris;
-
- // now get a pointer to all vertices in the group
- groupInfo.pcGroupVerts = (BE_NCONST MDL::Vertex_MDL7*)szCurrent;
- for(int i = 0; i < groupInfo.pcGroup->numverts; ++i){
- AI_SWAP4(groupInfo.pcGroupVerts[i].x);
- AI_SWAP4(groupInfo.pcGroupVerts[i].y);
- AI_SWAP4(groupInfo.pcGroupVerts[i].z);
-
- AI_SWAP2(groupInfo.pcGroupVerts[i].vertindex);
- //We can not swap the normal information now as we don't know which of the two kinds it is
- }
- szCurrent += pcHeader->mainvertex_stc_size * groupInfo.pcGroup->numverts;
- VALIDATE_FILE_SIZE(szCurrent);
-
- MDL::IntSplitGroupData_MDL7 splitGroupData(sharedData,avOutList[iGroup]);
- MDL::IntGroupData_MDL7 groupData;
- if (groupInfo.pcGroup->numtris && groupInfo.pcGroup->numverts)
- {
- // build output vectors
- const unsigned int iNumVertices = groupInfo.pcGroup->numtris*3;
- groupData.vPositions.resize(iNumVertices);
- groupData.vNormals.resize(iNumVertices);
-
- if (sharedData.apcOutBones)groupData.aiBones.resize(iNumVertices,UINT_MAX);
-
- // it is also possible that there are 0 UV coordinate sets
- if (groupInfo.pcGroup->num_stpts){
- groupData.vTextureCoords1.resize(iNumVertices,aiVector3D());
-
- // check whether the triangle data structure is large enough
- // to contain a second UV coodinate set
- if (pcHeader->triangle_stc_size >= AI_MDL7_TRIANGLE_STD_SIZE_TWO_UV) {
- groupData.vTextureCoords2.resize(iNumVertices,aiVector3D());
- groupData.bNeed2UV = true;
- }
- }
- groupData.pcFaces = new MDL::IntFace_MDL7[groupInfo.pcGroup->numtris];
-
- // read all faces into the preallocated arrays
- ReadFaces_3DGS_MDL7(groupInfo, groupData);
-
- // sort by materials
- SortByMaterials_3DGS_MDL7(groupInfo, groupData,
- splitGroupData);
-
- for (unsigned int qq = 0; qq < sharedData.pcMats.size();++qq) {
- if (!splitGroupData.aiSplit[qq]->empty())
- sharedData.abNeedMaterials[qq] = true;
- }
- }
- else DefaultLogger::get()->warn("[3DGS MDL7] Mesh group consists of 0 "
- "vertices or faces. It will be skipped.");
-
- // process all frames and generate output meshes
- ProcessFrames_3DGS_MDL7(groupInfo,groupData, sharedData,szCurrent,&szCurrent);
- GenerateOutputMeshes_3DGS_MDL7(groupData,splitGroupData);
- }
-
- // generate a nodegraph and subnodes for each group
- pScene->mRootNode = new aiNode();
-
- // now we need to build a final mesh list
- for (uint32_t i = 0; i < pcHeader->groups_num;++i)
- pScene->mNumMeshes += (unsigned int)avOutList[i].size();
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; {
- unsigned int p = 0,q = 0;
- for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
- for (unsigned int a = 0; a < avOutList[i].size();++a) {
- pScene->mMeshes[p++] = avOutList[i][a];
- }
- if (!avOutList[i].empty())++pScene->mRootNode->mNumChildren;
- }
- // we will later need an extra node to serve as parent for all bones
- if (sharedData.apcOutBones)++pScene->mRootNode->mNumChildren;
- this->pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
- p = 0;
- for (uint32_t i = 0; i < pcHeader->groups_num;++i) {
- if (avOutList[i].empty())continue;
-
- aiNode* const pcNode = pScene->mRootNode->mChildren[p] = new aiNode();
- pcNode->mNumMeshes = (unsigned int)avOutList[i].size();
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
- pcNode->mParent = this->pScene->mRootNode;
- for (unsigned int a = 0; a < pcNode->mNumMeshes;++a)
- pcNode->mMeshes[a] = q + a;
- q += (unsigned int)avOutList[i].size();
-
- // setup the name of the node
- char* const szBuffer = &aszGroupNameBuffer[i*AI_MDL7_MAX_GROUPNAMESIZE];
- if ('\0' == *szBuffer) {
- const size_t maxSize(buffersize - (i*AI_MDL7_MAX_GROUPNAMESIZE));
- pcNode->mName.length = ai_snprintf(szBuffer, maxSize, "Group_%u", p);
- } else {
- pcNode->mName.length = ::strlen(szBuffer);
- }
- ::strncpy(pcNode->mName.data,szBuffer,MAXLEN-1);
- ++p;
- }
- }
-
- // if there is only one root node with a single child we can optimize it a bit ...
- if (1 == pScene->mRootNode->mNumChildren && !sharedData.apcOutBones) {
- aiNode* pcOldRoot = this->pScene->mRootNode;
- pScene->mRootNode = pcOldRoot->mChildren[0];
- pcOldRoot->mChildren[0] = NULL;
- delete pcOldRoot;
- pScene->mRootNode->mParent = NULL;
- }
- else pScene->mRootNode->mName.Set("<mesh_root>");
-
- delete[] avOutList;
- delete[] aszGroupNameBuffer;
- AI_DEBUG_INVALIDATE_PTR(avOutList);
- AI_DEBUG_INVALIDATE_PTR(aszGroupNameBuffer);
-
- // build a final material list.
- CopyMaterials_3DGS_MDL7(sharedData);
- HandleMaterialReferences_3DGS_MDL7();
-
- // generate output bone animations and add all bones to the scenegraph
- if (sharedData.apcOutBones) {
- // this step adds empty dummy bones to the nodegraph
- // insert another dummy node to avoid name conflicts
- aiNode* const pc = pScene->mRootNode->mChildren[pScene->mRootNode->mNumChildren-1] = new aiNode();
-
- pc->mName.Set("<skeleton_root>");
-
- // add bones to the nodegraph
- AddBonesToNodeGraph_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
- sharedData.apcOutBones,pc,0xffff);
-
- // this steps build a valid output animation
- BuildOutputAnims_3DGS_MDL7((const Assimp::MDL::IntBone_MDL7 **)
- sharedData.apcOutBones);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Copy materials
-void MDLImporter::CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared)
-{
- pScene->mNumMaterials = (unsigned int)shared.pcMats.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- pScene->mMaterials[i] = shared.pcMats[i];
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Process material references
-void MDLImporter::HandleMaterialReferences_3DGS_MDL7()
-{
- // search for referrer materials
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- int iIndex = 0;
- if (AI_SUCCESS == aiGetMaterialInteger(pScene->mMaterials[i],AI_MDL7_REFERRER_MATERIAL, &iIndex) ) {
- for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
- aiMesh* const pcMesh = pScene->mMeshes[a];
- if (i == pcMesh->mMaterialIndex) {
- pcMesh->mMaterialIndex = iIndex;
- }
- }
- // collapse the rest of the array
- delete pScene->mMaterials[i];
- for (unsigned int pp = i; pp < pScene->mNumMaterials-1;++pp) {
-
- pScene->mMaterials[pp] = pScene->mMaterials[pp+1];
- for (unsigned int a = 0; a < pScene->mNumMeshes;++a) {
- aiMesh* const pcMesh = pScene->mMeshes[a];
- if (pcMesh->mMaterialIndex > i)--pcMesh->mMaterialIndex;
- }
- }
- --pScene->mNumMaterials;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read bone transformation keys
-void MDLImporter::ParseBoneTrafoKeys_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- IntFrameInfo_MDL7& frame,
- MDL::IntSharedData_MDL7& shared)
-{
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
-
- // only the first group contains bone animation keys
- if (frame.pcFrame->transmatrix_count) {
- if (!groupInfo.iIndex) {
- // skip all frames vertices. We can't support them
- const MDL::BoneTransform_MDL7* pcBoneTransforms = (const MDL::BoneTransform_MDL7*)
- (((const char*)frame.pcFrame) + pcHeader->frame_stc_size +
- frame.pcFrame->vertices_count * pcHeader->framevertex_stc_size);
-
- // read all transformation matrices
- for (unsigned int iTrafo = 0; iTrafo < frame.pcFrame->transmatrix_count;++iTrafo) {
- if(pcBoneTransforms->bone_index >= pcHeader->bones_num) {
- DefaultLogger::get()->warn("Index overflow in frame area. "
- "Unable to parse this bone transformation");
- }
- else {
- AddAnimationBoneTrafoKey_3DGS_MDL7(frame.iIndex,
- pcBoneTransforms,shared.apcOutBones);
- }
- pcBoneTransforms = (const MDL::BoneTransform_MDL7*)(
- (const char*)pcBoneTransforms + pcHeader->bonetrans_stc_size);
- }
- }
- else {
- DefaultLogger::get()->warn("Ignoring animation keyframes in groups != 0");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Attach bones to the output nodegraph
-void MDLImporter::AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBones,
- aiNode* pcParent,uint16_t iParentIndex)
-{
- ai_assert(NULL != apcBones && NULL != pcParent);
-
- // get a pointer to the header ...
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
-
- const MDL::IntBone_MDL7** apcBones2 = apcBones;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
-
- const MDL::IntBone_MDL7* const pcBone = *apcBones2++;
- if (pcBone->iParent == iParentIndex) {
- ++pcParent->mNumChildren;
- }
- }
- pcParent->mChildren = new aiNode*[pcParent->mNumChildren];
- unsigned int qq = 0;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
-
- const MDL::IntBone_MDL7* const pcBone = *apcBones++;
- if (pcBone->iParent != iParentIndex)continue;
-
- aiNode* pcNode = pcParent->mChildren[qq++] = new aiNode();
- pcNode->mName = aiString( pcBone->mName );
-
- AddBonesToNodeGraph_3DGS_MDL7(apcBones,pcNode,(uint16_t)i);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build output animations
-void MDLImporter::BuildOutputAnims_3DGS_MDL7(
- const MDL::IntBone_MDL7** apcBonesOut)
-{
- ai_assert(NULL != apcBonesOut);
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)mBuffer;
-
- // one animation ...
- aiAnimation* pcAnim = new aiAnimation();
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
- if (!apcBonesOut[i]->pkeyPositions.empty()) {
-
- // get the last frame ... (needn't be equal to pcHeader->frames_num)
- for (size_t qq = 0; qq < apcBonesOut[i]->pkeyPositions.size();++qq) {
- pcAnim->mDuration = std::max(pcAnim->mDuration, (double)
- apcBonesOut[i]->pkeyPositions[qq].mTime);
- }
- ++pcAnim->mNumChannels;
- }
- }
- if (pcAnim->mDuration) {
- pcAnim->mChannels = new aiNodeAnim*[pcAnim->mNumChannels];
-
- unsigned int iCnt = 0;
- for (uint32_t i = 0; i < pcHeader->bones_num;++i) {
- if (!apcBonesOut[i]->pkeyPositions.empty()) {
- const MDL::IntBone_MDL7* const intBone = apcBonesOut[i];
-
- aiNodeAnim* const pcNodeAnim = pcAnim->mChannels[iCnt++] = new aiNodeAnim();
- pcNodeAnim->mNodeName = aiString( intBone->mName );
-
- // allocate enough storage for all keys
- pcNodeAnim->mNumPositionKeys = (unsigned int)intBone->pkeyPositions.size();
- pcNodeAnim->mNumScalingKeys = (unsigned int)intBone->pkeyPositions.size();
- pcNodeAnim->mNumRotationKeys = (unsigned int)intBone->pkeyPositions.size();
-
- pcNodeAnim->mPositionKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
- pcNodeAnim->mScalingKeys = new aiVectorKey[pcNodeAnim->mNumPositionKeys];
- pcNodeAnim->mRotationKeys = new aiQuatKey[pcNodeAnim->mNumPositionKeys];
-
- // copy all keys
- for (unsigned int qq = 0; qq < pcNodeAnim->mNumPositionKeys;++qq) {
- pcNodeAnim->mPositionKeys[qq] = intBone->pkeyPositions[qq];
- pcNodeAnim->mScalingKeys[qq] = intBone->pkeyScalings[qq];
- pcNodeAnim->mRotationKeys[qq] = intBone->pkeyRotations[qq];
- }
- }
- }
-
- // store the output animation
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- pScene->mAnimations[0] = pcAnim;
- }
- else delete pcAnim;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MDLImporter::AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
- const MDL::BoneTransform_MDL7* pcBoneTransforms,
- MDL::IntBone_MDL7** apcBonesOut)
-{
- ai_assert(NULL != pcBoneTransforms);
- ai_assert(NULL != apcBonesOut);
-
- // first .. get the transformation matrix
- aiMatrix4x4 mTransform;
- mTransform.a1 = pcBoneTransforms->m[0];
- mTransform.b1 = pcBoneTransforms->m[1];
- mTransform.c1 = pcBoneTransforms->m[2];
- mTransform.d1 = pcBoneTransforms->m[3];
-
- mTransform.a2 = pcBoneTransforms->m[4];
- mTransform.b2 = pcBoneTransforms->m[5];
- mTransform.c2 = pcBoneTransforms->m[6];
- mTransform.d2 = pcBoneTransforms->m[7];
-
- mTransform.a3 = pcBoneTransforms->m[8];
- mTransform.b3 = pcBoneTransforms->m[9];
- mTransform.c3 = pcBoneTransforms->m[10];
- mTransform.d3 = pcBoneTransforms->m[11];
-
- // now decompose the transformation matrix into separate
- // scaling, rotation and translation
- aiVectorKey vScaling,vPosition;
- aiQuatKey qRotation;
-
- // FIXME: Decompose will assert in debug builds if the matrix is invalid ...
- mTransform.Decompose(vScaling.mValue,qRotation.mValue,vPosition.mValue);
-
- // now generate keys
- vScaling.mTime = qRotation.mTime = vPosition.mTime = (double)iTrafo;
-
- // add the keys to the bone
- MDL::IntBone_MDL7* const pcBoneOut = apcBonesOut[pcBoneTransforms->bone_index];
- pcBoneOut->pkeyPositions.push_back ( vPosition );
- pcBoneOut->pkeyScalings.push_back ( vScaling );
- pcBoneOut->pkeyRotations.push_back ( qRotation );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct output meshes
-void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplitGroupData_MDL7& splitGroupData)
-{
- const MDL::IntSharedData_MDL7& shared = splitGroupData.shared;
-
- // get a pointer to the header ...
- const MDL::Header_MDL7* const pcHeader = (const MDL::Header_MDL7*)this->mBuffer;
- const unsigned int iNumOutBones = pcHeader->bones_num;
-
- for (std::vector<aiMaterial*>::size_type i = 0; i < shared.pcMats.size();++i) {
- if (!splitGroupData.aiSplit[i]->empty()) {
-
- // allocate the output mesh
- aiMesh* pcMesh = new aiMesh();
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mMaterialIndex = (unsigned int)i;
-
- // allocate output storage
- pcMesh->mNumFaces = (unsigned int)splitGroupData.aiSplit[i]->size();
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- pcMesh->mNumVertices = pcMesh->mNumFaces*3;
- pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
-
- if (!groupData.vTextureCoords1.empty()) {
- pcMesh->mNumUVComponents[0] = 2;
- pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- if (!groupData.vTextureCoords2.empty()) {
- pcMesh->mNumUVComponents[1] = 2;
- pcMesh->mTextureCoords[1] = new aiVector3D[pcMesh->mNumVertices];
- }
- }
-
- // iterate through all faces and build an unique set of vertices
- unsigned int iCurrent = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
- pcMesh->mFaces[iFace].mNumIndices = 3;
- pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
-
- unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
- const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
-
- // iterate through all face indices
- for (unsigned int c = 0; c < 3;++c) {
- const uint32_t iIndex = oldFace.mIndices[c];
- pcMesh->mVertices[iCurrent] = groupData.vPositions[iIndex];
- pcMesh->mNormals[iCurrent] = groupData.vNormals[iIndex];
-
- if (!groupData.vTextureCoords1.empty()) {
-
- pcMesh->mTextureCoords[0][iCurrent] = groupData.vTextureCoords1[iIndex];
- if (!groupData.vTextureCoords2.empty()) {
- pcMesh->mTextureCoords[1][iCurrent] = groupData.vTextureCoords2[iIndex];
- }
- }
- pcMesh->mFaces[iFace].mIndices[c] = iCurrent++;
- }
- }
-
- // if we have bones in the mesh we'll need to generate
- // proper vertex weights for them
- if (!groupData.aiBones.empty()) {
- std::vector<std::vector<unsigned int> > aaiVWeightList;
- aaiVWeightList.resize(iNumOutBones);
-
- int iCurrent = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace) {
- unsigned int iSrcFace = splitGroupData.aiSplit[i]->operator[](iFace);
- const MDL::IntFace_MDL7& oldFace = groupData.pcFaces[iSrcFace];
-
- // iterate through all face indices
- for (unsigned int c = 0; c < 3;++c) {
- unsigned int iBone = groupData.aiBones[ oldFace.mIndices[c] ];
- if (UINT_MAX != iBone) {
- if (iBone >= iNumOutBones) {
- DefaultLogger::get()->error("Bone index overflow. "
- "The bone index of a vertex exceeds the allowed range. ");
- iBone = iNumOutBones-1;
- }
- aaiVWeightList[ iBone ].push_back ( iCurrent );
- }
- ++iCurrent;
- }
- }
- // now check which bones are required ...
- for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k != aaiVWeightList.end();++k) {
- if (!(*k).empty()) {
- ++pcMesh->mNumBones;
- }
- }
- pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
- iCurrent = 0;
- for (std::vector<std::vector<unsigned int> >::const_iterator k = aaiVWeightList.begin();k!= aaiVWeightList.end();++k,++iCurrent)
- {
- if ((*k).empty())
- continue;
-
- // seems we'll need this node
- aiBone* pcBone = pcMesh->mBones[ iCurrent ] = new aiBone();
- pcBone->mName = aiString(shared.apcOutBones[ iCurrent ]->mName);
- pcBone->mOffsetMatrix = shared.apcOutBones[ iCurrent ]->mOffsetMatrix;
-
- // setup vertex weights
- pcBone->mNumWeights = (unsigned int)(*k).size();
- pcBone->mWeights = new aiVertexWeight[pcBone->mNumWeights];
-
- for (unsigned int weight = 0; weight < pcBone->mNumWeights;++weight) {
- pcBone->mWeights[weight].mVertexId = (*k)[weight];
- pcBone->mWeights[weight].mWeight = 1.0f;
- }
- }
- }
- // add the mesh to the list of output meshes
- splitGroupData.avOutList.push_back(pcMesh);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Join to materials
-void MDLImporter::JoinSkins_3DGS_MDL7(
- aiMaterial* pcMat1,
- aiMaterial* pcMat2,
- aiMaterial* pcMatOut)
-{
- ai_assert(NULL != pcMat1 && NULL != pcMat2 && NULL != pcMatOut);
-
- // first create a full copy of the first skin property set
- // and assign it to the output material
- aiMaterial::CopyPropertyList(pcMatOut,pcMat1);
-
- int iVal = 0;
- pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(0));
-
- // then extract the diffuse texture from the second skin,
- // setup 1 as UV source and we have it
- aiString sString;
- if(AI_SUCCESS == aiGetMaterialString ( pcMat2, AI_MATKEY_TEXTURE_DIFFUSE(0),&sString )) {
- iVal = 1;
- pcMatOut->AddProperty<int>(&iVal,1,AI_MATKEY_UVWSRC_DIFFUSE(1));
- pcMatOut->AddProperty(&sString,AI_MATKEY_TEXTURE_DIFFUSE(1));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a half-life 2 MDL
-void MDLImporter::InternReadFile_HL2( )
-{
- //const MDL::Header_HL2* pcHeader = (const MDL::Header_HL2*)this->mBuffer;
- throw DeadlyImportError("HL2 MDLs are not implemented");
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
diff --git a/src/3rdparty/assimp/code/MDLLoader.h b/src/3rdparty/assimp/code/MDLLoader.h
deleted file mode 100644
index 8709426e6..000000000
--- a/src/3rdparty/assimp/code/MDLLoader.h
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MDLLoader.h
- * @brief Declaration of the loader for MDL files
- */
-
-#ifndef AI_MDLLOADER_H_INCLUDED
-#define AI_MDLLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "MDLFileData.h"
-#include "HalfLifeFileData.h"
-
-struct aiNode;
-struct aiTexture;
-
-namespace Assimp {
-
-
-using namespace MDL;
-
-// --------------------------------------------------------------------------------------
-// Include file/line information in debug builds
-#ifdef ASSIMP_BUILD_DEBUG
-# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg,__FILE__,__LINE__)
-#else
-# define VALIDATE_FILE_SIZE(msg) SizeCheck(msg)
-#endif
-
-// --------------------------------------------------------------------------------------
-/** @brief Class to load MDL files.
- *
- * Several subformats exist:
- * <ul>
- * <li>Quake I</li>
- * <li>3D Game Studio MDL3, MDL4</li>
- * <li>3D Game Studio MDL5</li>
- * <li>3D Game Studio MDL7</li>
- * <li>Halflife 2</li>
- * </ul>
- * These formats are partially identical and it would be possible to load
- * them all with a single 1000-line function-beast. However, it has been
- * split into several code paths to make the code easier to read and maintain.
-*/
-class MDLImporter : public BaseImporter
-{
-public:
- MDLImporter();
- ~MDLImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Import a quake 1 MDL file (IDPO)
- */
- void InternReadFile_Quake1( );
-
- // -------------------------------------------------------------------
- /** Import a GameStudio A4/A5 file (MDL 3,4,5)
- */
- void InternReadFile_3DGS_MDL345( );
-
- // -------------------------------------------------------------------
- /** Import a GameStudio A7 file (MDL 7)
- */
- void InternReadFile_3DGS_MDL7( );
-
- // -------------------------------------------------------------------
- /** Import a CS:S/HL2 MDL file (not fully implemented)
- */
- void InternReadFile_HL2( );
-
- // -------------------------------------------------------------------
- /** Check whether a given position is inside the valid range
- * Throw a DeadlyImportError if it is not
- * \param szPos Cursor position
- * \param szFile Name of the source file from which the function was called
- * \param iLine Source code line from which the function was called
- */
- void SizeCheck(const void* szPos);
- void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
-
-
- // -------------------------------------------------------------------
- /** Validate the header data structure of a game studio MDL7 file
- * \param pcHeader Input header to be validated
- */
- void ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader);
-
- // -------------------------------------------------------------------
- /** Validate the header data structure of a Quake 1 model
- * \param pcHeader Input header to be validated
- */
- void ValidateHeader_Quake1(const MDL::Header* pcHeader);
-
-
- // -------------------------------------------------------------------
- /** Try to load a palette from the current directory (colormap.lmp)
- * If it is not found the default palette of Quake1 is returned
- */
- void SearchPalette(const unsigned char** pszColorMap);
-
- // -------------------------------------------------------------------
- /** Free a palette created with a previous call to SearchPalette()
- */
- void FreePalette(const unsigned char* pszColorMap);
-
-
- // -------------------------------------------------------------------
- /** Load a paletized texture from the file and convert it to 32bpp
- */
- void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
-
- // -------------------------------------------------------------------
- /** Used to load textures from MDL3/4
- * \param szData Input data
- * \param iType Color data type
- * \param piSkip Receive: Size to skip, in bytes
- */
- void CreateTexture_3DGS_MDL4(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip);
-
-
- // -------------------------------------------------------------------
- /** Used to load textures from MDL5
- * \param szData Input data
- * \param iType Color data type
- * \param piSkip Receive: Size to skip, in bytes
- */
- void CreateTexture_3DGS_MDL5(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip);
-
-
- // -------------------------------------------------------------------
- /** Checks whether a texture can be replaced with a single color
- * This is useful for all file formats before MDL7 (all those
- * that are not containing material colors separate from textures).
- * MED seems to write dummy 8x8 monochrome images instead.
- * \param pcTexture Input texture
- * \return aiColor.r is set to qnan if the function fails and no
- * color can be found.
- */
- aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
-
-
- // -------------------------------------------------------------------
- /** Converts the absolute texture coordinates in MDL5 files to
- * relative in a range between 0 and 1
- */
- void CalculateUVCoordinates_MDL5();
-
-
- // -------------------------------------------------------------------
- /** Read an UV coordinate from the file. If the file format is not
- * MDL5, the function calculates relative texture coordinates
- * \param vOut Receives the output UV coord
- * \param pcSrc UV coordinate buffer
- * \param UV coordinate index
- */
- void ImportUVCoordinate_3DGS_MDL345( aiVector3D& vOut,
- const MDL::TexCoord_MDL3* pcSrc,
- unsigned int iIndex);
-
- // -------------------------------------------------------------------
- /** Setup the material properties for Quake and MDL<7 models.
- * These formats don't support more than one material per mesh,
- * therefore the method processes only ONE skin and removes
- * all others.
- */
- void SetupMaterialProperties_3DGS_MDL5_Quake1( );
-
-
- // -------------------------------------------------------------------
- /** Parse a skin lump in a MDL7/HMP7 file with all of its features
- * variant 1: Current cursor position is the beginning of the skin header
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer
- * \param pcMats Material list for this group. To be filled ...
- */
- void ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- std::vector<aiMaterial*>& pcMats);
-
- // -------------------------------------------------------------------
- /** Parse a skin lump in a MDL7/HMP7 file with all of its features
- * variant 2: Current cursor position is the beginning of the skin data
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer
- * \param pcMatOut Output material
- * \param iType header.typ
- * \param iWidth header.width
- * \param iHeight header.height
- */
- void ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- aiMaterial* pcMatOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight);
-
- // -------------------------------------------------------------------
- /** Skip a skin lump in a MDL7/HMP7 file
- * \param szCurrent Current data pointer
- * \param szCurrentOut Output data pointer. Points to the byte just
- * behind the last byte of the skin.
- * \param iType header.typ
- * \param iWidth header.width
- * \param iHeight header.height
- */
- void SkipSkinLump_3DGS_MDL7(const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight);
-
- // -------------------------------------------------------------------
- /** Parse texture color data for MDL5, MDL6 and MDL7 formats
- * \param szData Current data pointer
- * \param iType type of the texture data. No DDS or external
- * \param piSkip Receive the number of bytes to skip
- * \param pcNew Must point to fully initialized data. Width and
- * height must be set. If pcNew->pcData is set to UINT_MAX,
- * piSkip will receive the size of the texture, in bytes, but no
- * color data will be read.
- */
- void ParseTextureColorData(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip,
- aiTexture* pcNew);
-
- // -------------------------------------------------------------------
- /** Join two materials / skins. Setup UV source ... etc
- * \param pcMat1 First input material
- * \param pcMat2 Second input material
- * \param pcMatOut Output material instance to be filled. Must be empty
- */
- void JoinSkins_3DGS_MDL7(aiMaterial* pcMat1,
- aiMaterial* pcMat2,
- aiMaterial* pcMatOut);
-
- // -------------------------------------------------------------------
- /** Add a bone transformation key to an animation
- * \param iTrafo Index of the transformation (always==frame index?)
- * No need to validate this index, it is always valid.
- * \param pcBoneTransforms Bone transformation for this index
- * \param apcOutBones Output bones array
- */
- void AddAnimationBoneTrafoKey_3DGS_MDL7(unsigned int iTrafo,
- const MDL::BoneTransform_MDL7* pcBoneTransforms,
- MDL::IntBone_MDL7** apcBonesOut);
-
- // -------------------------------------------------------------------
- /** Load the bone list of a MDL7 file
- * \return If the bones could be loaded successfully, a valid
- * array containing pointers to a temporary bone
- * representation. NULL if the bones could not be loaded.
- */
- MDL::IntBone_MDL7** LoadBones_3DGS_MDL7();
-
- // -------------------------------------------------------------------
- /** Load bone transformation keyframes from a file chunk
- * \param groupInfo -> doc of data structure
- * \param frame -> doc of data structure
- * \param shared -> doc of data structure
- */
- void ParseBoneTrafoKeys_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- IntFrameInfo_MDL7& frame,
- MDL::IntSharedData_MDL7& shared);
-
- // -------------------------------------------------------------------
- /** Calculate absolute bone animation matrices for each bone
- * \param apcOutBones Output bones array
- */
- void CalcAbsBoneMatrices_3DGS_MDL7(MDL::IntBone_MDL7** apcOutBones);
-
- // -------------------------------------------------------------------
- /** Add all bones to the nodegraph (as children of the root node)
- * \param apcBonesOut List of bones
- * \param pcParent Parent node. New nodes will be added to this node
- * \param iParentIndex Index of the parent bone
- */
- void AddBonesToNodeGraph_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut,
- aiNode* pcParent,uint16_t iParentIndex);
-
- // -------------------------------------------------------------------
- /** Build output animations
- * \param apcBonesOut List of bones
- */
- void BuildOutputAnims_3DGS_MDL7(const MDL::IntBone_MDL7** apcBonesOut);
-
- // -------------------------------------------------------------------
- /** Handles materials that are just referencing another material
- * There is no test file for this feature, but Conitec's doc
- * say it is used.
- */
- void HandleMaterialReferences_3DGS_MDL7();
-
- // -------------------------------------------------------------------
- /** Copies only the material that are referenced by at least one
- * mesh to the final output material list. All other materials
- * will be discarded.
- * \param shared -> doc of data structure
- */
- void CopyMaterials_3DGS_MDL7(MDL::IntSharedData_MDL7 &shared);
-
- // -------------------------------------------------------------------
- /** Process the frame section at the end of a group
- * \param groupInfo -> doc of data structure
- * \param shared -> doc of data structure
- * \param szCurrent Pointer to the start of the frame section
- * \param szCurrentOut Receives a pointer to the first byte of the
- * next data section.
- * \return false to read no further groups (a small workaround for
- * some tiny and unsolved problems ... )
- */
- bool ProcessFrames_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSharedData_MDL7& shared,
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Sort all faces by their materials. If the mesh is using
- * multiple materials per face (that are blended together) the function
- * might create new materials.
- * \param groupInfo -> doc of data structure
- * \param groupData -> doc of data structure
- * \param splitGroupData -> doc of data structure
- */
- void SortByMaterials_3DGS_MDL7(
- const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplitGroupData_MDL7& splitGroupData);
-
- // -------------------------------------------------------------------
- /** Read all faces and vertices from a MDL7 group. The function fills
- * preallocated memory buffers.
- * \param groupInfo -> doc of data structure
- * \param groupData -> doc of data structure
- */
- void ReadFaces_3DGS_MDL7(const MDL::IntGroupInfo_MDL7& groupInfo,
- MDL::IntGroupData_MDL7& groupData);
-
- // -------------------------------------------------------------------
- /** Generate the final output meshes for a7 models
- * \param groupData -> doc of data structure
- * \param splitGroupData -> doc of data structure
- */
- void GenerateOutputMeshes_3DGS_MDL7(
- MDL::IntGroupData_MDL7& groupData,
- MDL::IntSplitGroupData_MDL7& splitGroupData);
-
-protected:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Configuration option: palette to be used to decode palletized images*/
- std::string configPalette;
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** For GameStudio MDL files: The number in the magic word, either 3,4 or 5
- * (MDL7 doesn't need this, the format has a separate loader) */
- unsigned int iGSFileVersion;
-
- /** Output I/O handler. used to load external lmp files */
- IOSystem* pIOHandler;
-
- /** Output scene to be filled */
- aiScene* pScene;
-
- /** Size of the input file in bytes */
- unsigned int iFileSize;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp b/src/3rdparty/assimp/code/MDLMaterialLoader.cpp
deleted file mode 100644
index 9086925aa..000000000
--- a/src/3rdparty/assimp/code/MDLMaterialLoader.cpp
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the material part of the MDL importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_MDL_IMPORTER
-
-// internal headers
-#include "MDLLoader.h"
-#include "MDLDefaultColorMap.h"
-#include "StringUtils.h"
-#include <assimp/texture.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/Defines.h>
-#include "qnan.h"
-
-
-using namespace Assimp;
-static aiTexel* const bad_texel = reinterpret_cast<aiTexel*>(SIZE_MAX);
-
-// ------------------------------------------------------------------------------------------------
-// Find a suitable pallette file or take the default one
-void MDLImporter::SearchPalette(const unsigned char** pszColorMap)
-{
- // now try to find the color map in the current directory
- IOStream* pcStream = pIOHandler->Open(configPalette,"rb");
-
- const unsigned char* szColorMap = (const unsigned char*)::g_aclrDefaultColorMap;
- if(pcStream)
- {
- if (pcStream->FileSize() >= 768)
- {
- unsigned char* colorMap = new unsigned char[256*3];
- szColorMap = colorMap;
- pcStream->Read(colorMap,256*3,1);
- DefaultLogger::get()->info("Found valid colormap.lmp in directory. "
- "It will be used to decode embedded textures in palletized formats.");
- }
- delete pcStream;
- pcStream = NULL;
- }
- *pszColorMap = szColorMap;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Free the palette again
-void MDLImporter::FreePalette(const unsigned char* szColorMap)
-{
- if (szColorMap != (const unsigned char*)::g_aclrDefaultColorMap)
- delete[] szColorMap;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether we can replace a texture with a single color
-aiColor4D MDLImporter::ReplaceTextureWithColor(const aiTexture* pcTexture)
-{
- ai_assert(NULL != pcTexture);
-
- aiColor4D clrOut;
- clrOut.r = get_qnan();
- if (!pcTexture->mHeight || !pcTexture->mWidth)
- return clrOut;
-
- const unsigned int iNumPixels = pcTexture->mHeight*pcTexture->mWidth;
- const aiTexel* pcTexel = pcTexture->pcData+1;
- const aiTexel* const pcTexelEnd = &pcTexture->pcData[iNumPixels];
-
- while (pcTexel != pcTexelEnd)
- {
- if (*pcTexel != *(pcTexel-1))
- {
- pcTexel = NULL;
- break;
- }
- ++pcTexel;
- }
- if (pcTexel)
- {
- clrOut.r = pcTexture->pcData->r / 255.0f;
- clrOut.g = pcTexture->pcData->g / 255.0f;
- clrOut.b = pcTexture->pcData->b / 255.0f;
- clrOut.a = pcTexture->pcData->a / 255.0f;
- }
- return clrOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a texture from a MDL3 file
-void MDLImporter::CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData)
-{
- const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
-
- VALIDATE_FILE_SIZE(szData + pcHeader->skinwidth *
- pcHeader->skinheight);
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
- pcNew->mWidth = pcHeader->skinwidth;
- pcNew->mHeight = pcHeader->skinheight;
-
- pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
-
- const unsigned char* szColorMap;
- this->SearchPalette(&szColorMap);
-
- // copy texture data
- for (unsigned int i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char val = szData[i];
- const unsigned char* sz = &szColorMap[val*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = *sz++;
- pcNew->pcData[i].g = *sz++;
- pcNew->pcData[i].b = *sz;
- }
-
- FreePalette(szColorMap);
-
- // store the texture
- aiTexture** pc = this->pScene->mTextures;
- this->pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i <pScene->mNumTextures;++i)
- pScene->mTextures[i] = pc[i];
-
- pScene->mTextures[this->pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a texture from a MDL4 file
-void MDLImporter::CreateTexture_3DGS_MDL4(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip)
-{
- ai_assert(NULL != piSkip);
-
- const MDL::Header *pcHeader = (const MDL::Header*)mBuffer; //the endianness is already corrected in the InternReadFile_3DGS_MDL345 function
-
- if (iType == 1 || iType > 3)
- {
- DefaultLogger::get()->error("Unsupported texture file format");
- return;
- }
-
- const bool bNoRead = *piSkip == UINT_MAX;
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
- pcNew->mWidth = pcHeader->skinwidth;
- pcNew->mHeight = pcHeader->skinheight;
-
- if (bNoRead)pcNew->pcData = bad_texel;
- ParseTextureColorData(szData,iType,piSkip,pcNew);
-
- // store the texture
- if (!bNoRead)
- {
- if (!this->pScene->mNumTextures)
- {
- pScene->mNumTextures = 1;
- pScene->mTextures = new aiTexture*[1];
- pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = pScene->mTextures;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i < this->pScene->mNumTextures;++i)
- pScene->mTextures[i] = pc[i];
- pScene->mTextures[pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- }
- }
- else {
- pcNew->pcData = NULL;
- delete pcNew;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Load color data of a texture and convert it to our output format
-void MDLImporter::ParseTextureColorData(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip,
- aiTexture* pcNew)
-{
- const bool do_read = bad_texel != pcNew->pcData;
-
- // allocate storage for the texture image
- if (do_read) {
- pcNew->pcData = new aiTexel[pcNew->mWidth * pcNew->mHeight];
- }
-
- // R5G6B5 format (with or without MIPs)
- // ****************************************************************
- if (2 == iType || 10 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*2);
-
- // copy texture data
- unsigned int i;
- if (do_read)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- MDL::RGB565 val = ((MDL::RGB565*)szData)[i];
- AI_SWAP2(val);
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = (unsigned char)val.b << 3;
- pcNew->pcData[i].g = (unsigned char)val.g << 2;
- pcNew->pcData[i].b = (unsigned char)val.r << 3;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i * 2;
-
- // apply MIP maps
- if (10 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // ARGB4 format (with or without MIPs)
- // ****************************************************************
- else if (3 == iType || 11 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
-
- // copy texture data
- unsigned int i;
- if (do_read)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- MDL::ARGB4 val = ((MDL::ARGB4*)szData)[i];
- AI_SWAP2(val);
-
- pcNew->pcData[i].a = (unsigned char)val.a << 4;
- pcNew->pcData[i].r = (unsigned char)val.r << 4;
- pcNew->pcData[i].g = (unsigned char)val.g << 4;
- pcNew->pcData[i].b = (unsigned char)val.b << 4;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i * 2;
-
- // apply MIP maps
- if (11 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 1;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // RGB8 format (with or without MIPs)
- // ****************************************************************
- else if (4 == iType || 12 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*3);
-
- // copy texture data
- unsigned int i;
- if (do_read)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char* _szData = &szData[i*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].b = *_szData++;
- pcNew->pcData[i].g = *_szData++;
- pcNew->pcData[i].r = *_szData;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
-
-
- // apply MIP maps
- *piSkip = i * 3;
- if (12 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) *3;
- VALIDATE_FILE_SIZE(szData + *piSkip);
- }
- }
- // ARGB8 format (with ir without MIPs)
- // ****************************************************************
- else if (5 == iType || 13 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight*4);
-
- // copy texture data
- unsigned int i;
- if (do_read)
- {
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char* _szData = &szData[i*4];
-
- pcNew->pcData[i].b = *_szData++;
- pcNew->pcData[i].g = *_szData++;
- pcNew->pcData[i].r = *_szData++;
- pcNew->pcData[i].a = *_szData;
- }
- }
- else i = pcNew->mWidth*pcNew->mHeight;
-
- // apply MIP maps
- *piSkip = i << 2;
- if (13 == iType)
- {
- *piSkip += ((i >> 2) + (i >> 4) + (i >> 6)) << 2;
- }
- }
- // palletized 8 bit texture. As for Quake 1
- // ****************************************************************
- else if (0 == iType)
- {
- VALIDATE_FILE_SIZE(szData + pcNew->mWidth*pcNew->mHeight);
-
- // copy texture data
- unsigned int i;
- if (do_read)
- {
-
- const unsigned char* szColorMap;
- SearchPalette(&szColorMap);
-
- for (i = 0; i < pcNew->mWidth*pcNew->mHeight;++i)
- {
- const unsigned char val = szData[i];
- const unsigned char* sz = &szColorMap[val*3];
-
- pcNew->pcData[i].a = 0xFF;
- pcNew->pcData[i].r = *sz++;
- pcNew->pcData[i].g = *sz++;
- pcNew->pcData[i].b = *sz;
- }
- this->FreePalette(szColorMap);
-
- }
- else i = pcNew->mWidth*pcNew->mHeight;
- *piSkip = i;
-
- // FIXME: Also support for MIP maps?
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a texture from a MDL5 file
-void MDLImporter::CreateTexture_3DGS_MDL5(const unsigned char* szData,
- unsigned int iType,
- unsigned int* piSkip)
-{
- ai_assert(NULL != piSkip);
- bool bNoRead = *piSkip == UINT_MAX;
-
- // allocate a new texture object
- aiTexture* pcNew = new aiTexture();
-
- VALIDATE_FILE_SIZE(szData+8);
-
- // first read the size of the texture
- pcNew->mWidth = *((uint32_t*)szData);
- AI_SWAP4(pcNew->mWidth);
- szData += sizeof(uint32_t);
-
- pcNew->mHeight = *((uint32_t*)szData);
- AI_SWAP4(pcNew->mHeight);
- szData += sizeof(uint32_t);
-
- if (bNoRead) {
- pcNew->pcData = bad_texel;
- }
-
- // this should not occur - at least the docs say it shouldn't.
- // however, one can easily try out what MED does if you have
- // a model with a DDS texture and export it to MDL5 ...
- // yeah, it embedds the DDS file.
- if (6 == iType)
- {
- // this is a compressed texture in DDS format
- *piSkip = pcNew->mWidth;
- VALIDATE_FILE_SIZE(szData + *piSkip);
-
- if (!bNoRead)
- {
- // place a hint and let the application know that this is a DDS file
- pcNew->mHeight = 0;
- pcNew->achFormatHint[0] = 'd';
- pcNew->achFormatHint[1] = 'd';
- pcNew->achFormatHint[2] = 's';
- pcNew->achFormatHint[3] = '\0';
-
- pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
- ::memcpy(pcNew->pcData,szData,pcNew->mWidth);
- }
- }
- else
- {
- // parse the color data of the texture
- ParseTextureColorData(szData,iType,piSkip,pcNew);
- }
- *piSkip += sizeof(uint32_t) * 2;
-
- if (!bNoRead)
- {
- // store the texture
- if (!this->pScene->mNumTextures)
- {
- pScene->mNumTextures = 1;
- pScene->mTextures = new aiTexture*[1];
- pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = pScene->mTextures;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i < pScene->mNumTextures;++i)
- this->pScene->mTextures[i] = pc[i];
-
- pScene->mTextures[pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- }
- }
- else {
- pcNew->pcData = NULL;
- delete pcNew;
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a skin from a MDL7 file - more complex than all other subformats
-void MDLImporter::ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- aiMaterial* pcMatOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight)
-{
- aiTexture* pcNew = nullptr;
-
- // get the type of the skin
- unsigned int iMasked = (unsigned int)(iType & 0xF);
-
- if (0x1 == iMasked)
- {
- // ***** REFERENCE TO ANOTHER SKIN INDEX *****
- int referrer = (int)iWidth;
- pcMatOut->AddProperty<int>(&referrer,1,AI_MDL7_REFERRER_MATERIAL);
- }
- else if (0x6 == iMasked)
- {
- // ***** EMBEDDED DDS FILE *****
- if (1 != iHeight)
- {
- DefaultLogger::get()->warn("Found a reference to an embedded DDS texture, "
- "but texture height is not equal to 1, which is not supported by MED");
- }
-
- pcNew = new aiTexture();
- pcNew->mHeight = 0;
- pcNew->mWidth = iWidth;
-
- // place a proper format hint
- pcNew->achFormatHint[0] = 'd';
- pcNew->achFormatHint[1] = 'd';
- pcNew->achFormatHint[2] = 's';
- pcNew->achFormatHint[3] = '\0';
-
- pcNew->pcData = (aiTexel*) new unsigned char[pcNew->mWidth];
- memcpy(pcNew->pcData,szCurrent,pcNew->mWidth);
- szCurrent += iWidth;
- }
- else if (0x7 == iMasked)
- {
- // ***** REFERENCE TO EXTERNAL FILE *****
- if (1 != iHeight)
- {
- DefaultLogger::get()->warn("Found a reference to an external texture, "
- "but texture height is not equal to 1, which is not supported by MED");
- }
-
- aiString szFile;
- const size_t iLen = strlen((const char*)szCurrent);
- size_t iLen2 = iLen+1;
- iLen2 = iLen2 > MAXLEN ? MAXLEN : iLen2;
- memcpy(szFile.data,(const char*)szCurrent,iLen2);
- szFile.length = iLen;
-
- szCurrent += iLen2;
-
- // place this as diffuse texture
- pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- else if (iMasked || !iType || (iType && iWidth && iHeight))
- {
- pcNew = new aiTexture();
- if (!iHeight || !iWidth)
- {
- DefaultLogger::get()->warn("Found embedded texture, but its width "
- "an height are both 0. Is this a joke?");
-
- // generate an empty chess pattern
- pcNew->mWidth = pcNew->mHeight = 8;
- pcNew->pcData = new aiTexel[64];
- for (unsigned int x = 0; x < 8;++x)
- {
- for (unsigned int y = 0; y < 8;++y)
- {
- const bool bSet = ((0 == x % 2 && 0 != y % 2) ||
- (0 != x % 2 && 0 == y % 2));
-
- aiTexel* pc = &pcNew->pcData[y * 8 + x];
- pc->r = pc->b = pc->g = (bSet?0xFF:0);
- pc->a = 0xFF;
- }
- }
- }
- else
- {
- // it is a standard color texture. Fill in width and height
- // and call the same function we used for loading MDL5 files
-
- pcNew->mWidth = iWidth;
- pcNew->mHeight = iHeight;
-
- unsigned int iSkip = 0;
- ParseTextureColorData(szCurrent,iMasked,&iSkip,pcNew);
-
- // skip length of texture data
- szCurrent += iSkip;
- }
- }
-
- // sometimes there are MDL7 files which have a monochrome
- // texture instead of material colors ... posssible they have
- // been converted to MDL7 from other formats, such as MDL5
- aiColor4D clrTexture;
- if (pcNew)clrTexture = ReplaceTextureWithColor(pcNew);
- else clrTexture.r = get_qnan();
-
- // check whether a material definition is contained in the skin
- if (iType & AI_MDL7_SKINTYPE_MATERIAL)
- {
- BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
- szCurrent = (unsigned char*)(pcMatIn+1);
- VALIDATE_FILE_SIZE(szCurrent);
-
- aiColor3D clrTemp;
-
-#define COLOR_MULTIPLY_RGB() \
- if (is_not_qnan(clrTexture.r)) \
- { \
- clrTemp.r *= clrTexture.r; \
- clrTemp.g *= clrTexture.g; \
- clrTemp.b *= clrTexture.b; \
- }
-
- // read diffuse color
- clrTemp.r = pcMatIn->Diffuse.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Diffuse.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Diffuse.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // read specular color
- clrTemp.r = pcMatIn->Specular.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Specular.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Specular.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_SPECULAR);
-
- // read ambient color
- clrTemp.r = pcMatIn->Ambient.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Ambient.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Ambient.b;
- AI_SWAP4(clrTemp.b);
- COLOR_MULTIPLY_RGB();
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_AMBIENT);
-
- // read emissive color
- clrTemp.r = pcMatIn->Emissive.r;
- AI_SWAP4(clrTemp.r);
- clrTemp.g = pcMatIn->Emissive.g;
- AI_SWAP4(clrTemp.g);
- clrTemp.b = pcMatIn->Emissive.b;
- AI_SWAP4(clrTemp.b);
- pcMatOut->AddProperty<aiColor3D>(&clrTemp,1,AI_MATKEY_COLOR_EMISSIVE);
-
-#undef COLOR_MULITPLY_RGB
-
- // FIX: Take the opacity from the ambient color.
- // The doc say something else, but it is fact that MED exports the
- // opacity like this .... oh well.
- clrTemp.r = pcMatIn->Ambient.a;
- AI_SWAP4(clrTemp.r);
- if (is_not_qnan(clrTexture.r)) {
- clrTemp.r *= clrTexture.a;
- }
- pcMatOut->AddProperty<ai_real>(&clrTemp.r,1,AI_MATKEY_OPACITY);
-
- // read phong power
- int iShadingMode = (int)aiShadingMode_Gouraud;
- AI_SWAP4(pcMatIn->Power);
- if (0.0f != pcMatIn->Power)
- {
- iShadingMode = (int)aiShadingMode_Phong;
- // pcMatIn is packed, we can't form pointers to its members
- float power = pcMatIn->Power;
- pcMatOut->AddProperty<float>(&power,1,AI_MATKEY_SHININESS);
- }
- pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
- }
- else if (is_not_qnan(clrTexture.r))
- {
- pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_DIFFUSE);
- pcMatOut->AddProperty<aiColor4D>(&clrTexture,1,AI_MATKEY_COLOR_SPECULAR);
- }
- // if the texture could be replaced by a single material color
- // we don't need the texture anymore
- if (is_not_qnan(clrTexture.r))
- {
- delete pcNew;
- pcNew = NULL;
- }
-
- // If an ASCII effect description (HLSL?) is contained in the file,
- // we can simply ignore it ...
- if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
- {
- VALIDATE_FILE_SIZE(szCurrent);
- int32_t iMe = *((int32_t*)szCurrent);
- AI_SWAP4(iMe);
- szCurrent += sizeof(char) * iMe + sizeof(int32_t);
- VALIDATE_FILE_SIZE(szCurrent);
- }
-
- // If an embedded texture has been loaded setup the corresponding
- // data structures in the aiScene instance
- if (pcNew && pScene->mNumTextures <= 999)
- {
-
- // place this as diffuse texture
- char szCurrent[5];
- ai_snprintf(szCurrent,5,"*%i",this->pScene->mNumTextures);
-
- aiString szFile;
- const size_t iLen = strlen((const char*)szCurrent);
- ::memcpy(szFile.data,(const char*)szCurrent,iLen+1);
- szFile.length = iLen;
-
- pcMatOut->AddProperty(&szFile,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- // store the texture
- if (!pScene->mNumTextures)
- {
- pScene->mNumTextures = 1;
- pScene->mTextures = new aiTexture*[1];
- pScene->mTextures[0] = pcNew;
- }
- else
- {
- aiTexture** pc = pScene->mTextures;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures+1];
- for (unsigned int i = 0; i < pScene->mNumTextures;++i) {
- pScene->mTextures[i] = pc[i];
- }
-
- pScene->mTextures[pScene->mNumTextures] = pcNew;
- pScene->mNumTextures++;
- delete[] pc;
- }
- }
- VALIDATE_FILE_SIZE(szCurrent);
- *szCurrentOut = szCurrent;
- if ( nullptr != pcNew ) {
- delete pcNew;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Skip a skin lump
-void MDLImporter::SkipSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- unsigned int iType,
- unsigned int iWidth,
- unsigned int iHeight)
-{
- // get the type of the skin
- const unsigned int iMasked = (unsigned int)(iType & 0xF);
-
- if (0x6 == iMasked)
- {
- szCurrent += iWidth;
- }
- if (0x7 == iMasked)
- {
- const size_t iLen = ::strlen((const char*)szCurrent);
- szCurrent += iLen+1;
- }
- else if (iMasked || !iType)
- {
- if (iMasked || !iType || (iType && iWidth && iHeight))
- {
- // ParseTextureColorData(..., aiTexture::pcData == bad_texel) will simply
- // return the size of the color data in bytes in iSkip
- unsigned int iSkip = 0;
-
- aiTexture tex;
- tex.pcData = bad_texel;
- tex.mHeight = iHeight;
- tex.mWidth = iWidth;
- ParseTextureColorData(szCurrent,iMasked,&iSkip,&tex);
-
- // FIX: Important, otherwise the destructor will crash
- tex.pcData = NULL;
-
- // skip length of texture data
- szCurrent += iSkip;
- }
- }
-
- // check whether a material definition is contained in the skin
- if (iType & AI_MDL7_SKINTYPE_MATERIAL)
- {
- BE_NCONST MDL::Material_MDL7* pcMatIn = (BE_NCONST MDL::Material_MDL7*)szCurrent;
- szCurrent = (unsigned char*)(pcMatIn+1);
- }
-
- // if an ASCII effect description (HLSL?) is contained in the file,
- // we can simply ignore it ...
- if (iType & AI_MDL7_SKINTYPE_MATERIAL_ASCDEF)
- {
- int32_t iMe = *((int32_t*)szCurrent);
- AI_SWAP4(iMe);
- szCurrent += sizeof(char) * iMe + sizeof(int32_t);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MDLImporter::ParseSkinLump_3DGS_MDL7(
- const unsigned char* szCurrent,
- const unsigned char** szCurrentOut,
- std::vector<aiMaterial*>& pcMats)
-{
- ai_assert(NULL != szCurrent);
- ai_assert(NULL != szCurrentOut);
-
- *szCurrentOut = szCurrent;
- BE_NCONST MDL::Skin_MDL7* pcSkin = (BE_NCONST MDL::Skin_MDL7*)szCurrent;
- AI_SWAP4(pcSkin->width);
- AI_SWAP4(pcSkin->height);
- szCurrent += 12;
-
- // allocate an output material
- aiMaterial* pcMatOut = new aiMaterial();
- pcMats.push_back(pcMatOut);
-
- // skip length of file name
- szCurrent += AI_MDL7_MAX_TEXNAMESIZE;
-
- ParseSkinLump_3DGS_MDL7(szCurrent,szCurrentOut,pcMatOut,
- pcSkin->typ,pcSkin->width,pcSkin->height);
-
- // place the name of the skin in the material
- if (pcSkin->texture_name[0])
- {
- // the 0 termination could be there or not - we can't know
- aiString szFile;
- ::memcpy(szFile.data,pcSkin->texture_name,sizeof(pcSkin->texture_name));
- szFile.data[sizeof(pcSkin->texture_name)] = '\0';
- szFile.length = ::strlen(szFile.data);
-
- pcMatOut->AddProperty(&szFile,AI_MATKEY_NAME);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_MDL_IMPORTER
diff --git a/src/3rdparty/assimp/code/MMDCpp14.h b/src/3rdparty/assimp/code/MMDCpp14.h
deleted file mode 100644
index f6f81f827..000000000
--- a/src/3rdparty/assimp/code/MMDCpp14.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#ifndef MMD_CPP14_H
-#define MMD_CPP14_H
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace mmd {
- template<class T> struct _Unique_if {
- typedef std::unique_ptr<T> _Single_object;
- };
-
- template<class T> struct _Unique_if<T[]> {
- typedef std::unique_ptr<T[]> _Unknown_bound;
- };
-
- template<class T, size_t N> struct _Unique_if<T[N]> {
- typedef void _Known_bound;
- };
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Single_object
- make_unique(Args&&... args) {
- return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
- }
-
- template<class T>
- typename _Unique_if<T>::_Unknown_bound
- make_unique(size_t n) {
- typedef typename std::remove_extent<T>::type U;
- return std::unique_ptr<T>(new U[n]());
- }
-
- template<class T, class... Args>
- typename _Unique_if<T>::_Known_bound
- make_unique(Args&&...) = delete;
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/MMDImporter.cpp b/src/3rdparty/assimp/code/MMDImporter.cpp
deleted file mode 100644
index 01f009519..000000000
--- a/src/3rdparty/assimp/code/MMDImporter.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2016, 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 ASSIMP_BUILD_NO_MMD_IMPORTER
-
-#include "MMDImporter.h"
-#include "MMDPmdParser.h"
-#include "MMDPmxParser.h"
-#include "MMDVmdParser.h"
-#include "ConvertToLHProcess.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Importer.hpp>
-#include <assimp/ai_assert.h>
-#include <assimp/scene.h>
-#include <fstream>
-#include <iomanip>
-#include <memory>
-
-static const aiImporterDesc desc = {"MMD Importer",
- "",
- "",
- "surfaces supported?",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "pmx"};
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-// Default constructor
-MMDImporter::MMDImporter()
- : m_Buffer(),
- // m_pRootObject( NULL ),
- m_strAbsPath("") {
- DefaultIOSystem io;
- m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-MMDImporter::~MMDImporter() {
- // delete m_pRootObject;
- // m_pRootObject = NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if file is an pmx file.
-bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
- bool checkSig) const {
- if (!checkSig) // Check File Extension
- {
- return SimpleExtensionCheck(pFile, "pmx");
- } else // Check file Header
- {
- static const char *pTokens[] = {"PMX "};
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens,
- 1);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
-
-// ------------------------------------------------------------------------------------------------
-// MMD import implementation
-void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
- IOSystem * /*pIOHandler*/) {
- // Read file by istream
- std::filebuf fb;
- if (!fb.open(file, std::ios::in | std::ios::binary)) {
- throw DeadlyImportError("Failed to open file " + file + ".");
- }
-
- std::istream fileStream(&fb);
-
- // Get the file-size and validate it, throwing an exception when fails
- fileStream.seekg(0, fileStream.end);
- size_t fileSize = static_cast<size_t>(fileStream.tellg());
- fileStream.seekg(0, fileStream.beg);
-
- if (fileSize < sizeof(pmx::PmxModel)) {
- throw DeadlyImportError(file + " is too small.");
- }
-
- pmx::PmxModel model;
- model.Read(&fileStream);
-
- CreateDataFromImport(&model, pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
- aiScene *pScene) {
- if (pModel == NULL) {
- return;
- }
-
- aiNode *pNode = new aiNode;
- if (!pModel->model_name.empty()) {
- pNode->mName.Set(pModel->model_name);
- } else {
- ai_assert(false);
- }
-
- pScene->mRootNode = pNode;
-
- pNode = new aiNode;
- pScene->mRootNode->addChildren(1, &pNode);
- pNode->mName.Set(string(pModel->model_name) + string("_mesh"));
-
- // split mesh by materials
- pNode->mNumMeshes = pModel->material_count;
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
- for (unsigned int index = 0; index < pNode->mNumMeshes; index++) {
- pNode->mMeshes[index] = index;
- }
-
- pScene->mNumMeshes = pModel->material_count;
- pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
- for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) {
- const int indexCount = pModel->materials[i].index_count;
-
- pScene->mMeshes[i] = CreateMesh(pModel, indexStart, indexCount);
- pScene->mMeshes[i]->mName = pModel->materials[i].material_name;
- pScene->mMeshes[i]->mMaterialIndex = i;
- indexStart += indexCount;
- }
-
- // create node hierarchy for bone position
- aiNode **ppNode = new aiNode *[pModel->bone_count];
- for (auto i = 0; i < pModel->bone_count; i++) {
- ppNode[i] = new aiNode(pModel->bones[i].bone_name);
- }
-
- for (auto i = 0; i < pModel->bone_count; i++) {
- const pmx::PmxBone &bone = pModel->bones[i];
-
- if (bone.parent_index < 0) {
- pScene->mRootNode->addChildren(1, ppNode + i);
- } else {
- ppNode[bone.parent_index]->addChildren(1, ppNode + i);
-
- aiVector3D v3 = aiVector3D(
- bone.position[0] - pModel->bones[bone.parent_index].position[0],
- bone.position[1] - pModel->bones[bone.parent_index].position[1],
- bone.position[2] - pModel->bones[bone.parent_index].position[2]);
- aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation);
- }
- }
-
- // create materials
- pScene->mNumMaterials = pModel->material_count;
- pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
- pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel);
- }
-
- // Convert everything to OpenGL space
- MakeLeftHandedProcess convertProcess;
- convertProcess.Execute(pScene);
-
- FlipUVsProcess uvFlipper;
- uvFlipper.Execute(pScene);
-
- FlipWindingOrderProcess windingFlipper;
- windingFlipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
- const int indexStart, const int indexCount) {
- aiMesh *pMesh = new aiMesh;
-
- pMesh->mNumVertices = indexCount;
-
- pMesh->mNumFaces = indexCount / 3;
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
-
- const int numIndices = 3; // trianglular face
- for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
- pMesh->mFaces[index].mNumIndices = numIndices;
- unsigned int *indices = new unsigned int[numIndices];
- indices[0] = numIndices * index;
- indices[1] = numIndices * index + 1;
- indices[2] = numIndices * index + 2;
- pMesh->mFaces[index].mIndices = indices;
- }
-
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[0] = 2;
-
- // additional UVs
- for (int i = 1; i <= pModel->setting.uv; i++) {
- pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices];
- pMesh->mNumUVComponents[i] = 4;
- }
-
- map<int, vector<aiVertexWeight>> bone_vertex_map;
-
- // fill in contents and create bones
- for (int index = 0; index < indexCount; index++) {
- const pmx::PmxVertex *v =
- &pModel->vertices[pModel->indices[indexStart + index]];
- const float *position = v->position;
- pMesh->mVertices[index].Set(position[0], position[1], position[2]);
- const float *normal = v->normal;
-
- pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]);
- pMesh->mTextureCoords[0][index].x = v->uv[0];
- pMesh->mTextureCoords[0][index].y = v->uv[1];
-
- for (int i = 1; i <= pModel->setting.uv; i++) {
- // TODO: wrong here? use quaternion transform?
- pMesh->mTextureCoords[i][index].x = v->uva[i][0];
- pMesh->mTextureCoords[i][index].y = v->uva[i][1];
- }
-
- // handle bone map
- const auto vsBDEF1_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF1 *>(v->skinning.get());
- const auto vsBDEF2_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF2 *>(v->skinning.get());
- const auto vsBDEF4_ptr =
- dynamic_cast<pmx::PmxVertexSkinningBDEF4 *>(v->skinning.get());
- const auto vsSDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
- switch (v->skinning_type) {
- case pmx::PmxVertexSkinningType::BDEF1:
- bone_vertex_map[vsBDEF1_ptr->bone_index].push_back(
- aiVertexWeight(index, 1.0));
- break;
- case pmx::PmxVertexSkinningType::BDEF2:
- bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
- bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::BDEF4:
- bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight1));
- bone_vertex_map[vsBDEF4_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight2));
- bone_vertex_map[vsBDEF4_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight3));
- bone_vertex_map[vsBDEF4_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsBDEF4_ptr->bone_weight4));
- break;
- case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
- // sdef_r1?
- bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsSDEF_ptr->bone_weight));
- bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
- break;
- case pmx::PmxVertexSkinningType::QDEF:
- const auto vsQDEF_ptr =
- dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get());
- bone_vertex_map[vsQDEF_ptr->bone_index1].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight1));
- bone_vertex_map[vsQDEF_ptr->bone_index2].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight2));
- bone_vertex_map[vsQDEF_ptr->bone_index3].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight3));
- bone_vertex_map[vsQDEF_ptr->bone_index4].push_back(
- aiVertexWeight(index, vsQDEF_ptr->bone_weight4));
- break;
- }
- }
-
- // make all bones for each mesh
- // assign bone weights to skinned bones (otherwise just initialize)
- auto bone_ptr_ptr = new aiBone *[pModel->bone_count];
- pMesh->mNumBones = pModel->bone_count;
- pMesh->mBones = bone_ptr_ptr;
- for (auto ii = 0; ii < pModel->bone_count; ++ii) {
- auto pBone = new aiBone;
- const auto &pmxBone = pModel->bones[ii];
- pBone->mName = pmxBone.bone_name;
- aiVector3D pos(pmxBone.position[0], pmxBone.position[1], pmxBone.position[2]);
- aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
- auto it = bone_vertex_map.find(ii);
- if (it != bone_vertex_map.end()) {
- pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
- pBone->mWeights = it->second.data();
- it->second.swap(*(new vector<aiVertexWeight>));
- }
- bone_ptr_ptr[ii] = pBone;
- }
-
- return pMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
- const pmx::PmxModel *pModel) {
- aiMaterial *mat = new aiMaterial();
- aiString name(pMat->material_english_name);
- mat->AddProperty(&name, AI_MATKEY_NAME);
-
- aiColor3D diffuse(pMat->diffuse[0], pMat->diffuse[1], pMat->diffuse[2]);
- mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
- aiColor3D specular(pMat->specular[0], pMat->specular[1], pMat->specular[2]);
- mat->AddProperty(&specular, 1, AI_MATKEY_COLOR_SPECULAR);
- aiColor3D ambient(pMat->ambient[0], pMat->ambient[1], pMat->ambient[2]);
- mat->AddProperty(&ambient, 1, AI_MATKEY_COLOR_AMBIENT);
-
- float opacity = pMat->diffuse[3];
- mat->AddProperty(&opacity, 1, AI_MATKEY_OPACITY);
- float shininess = pMat->specularlity;
- mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
-
- aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
- mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
- int mapping_uvwsrc = 0;
- mat->AddProperty(&mapping_uvwsrc, 1,
- AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));
-
- return mat;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER
diff --git a/src/3rdparty/assimp/code/MMDImporter.h b/src/3rdparty/assimp/code/MMDImporter.h
deleted file mode 100644
index 2620ccc9f..000000000
--- a/src/3rdparty/assimp/code/MMDImporter.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, 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 MMD_FILE_IMPORTER_H_INC
-#define MMD_FILE_IMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include "MMDPmxParser.h"
-#include <assimp/material.h>
-#include <vector>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/// \class MMDImporter
-/// \brief Imports MMD a pmx/pmd/vmd file
-// ------------------------------------------------------------------------------------------------
-class MMDImporter : public BaseImporter {
-public:
- /// \brief Default constructor
- MMDImporter();
-
- /// \brief Destructor
- ~MMDImporter();
-
-public:
- /// \brief Returns whether the class can handle the format of the given file.
- /// \remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
- //! \brief Appends the supported extension.
- const aiImporterDesc* GetInfo () const;
-
- //! \brief File import implementation.
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- //! \brief Create the data from imported content.
- void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
-
- //! \brief Create the mesh
- aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
-
- //! \brief Create the material
- aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
-
-private:
- //! Data buffer
- std::vector<char> m_Buffer;
- //! Absolute pathname of model in file system
- std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/MMDPmdParser.h b/src/3rdparty/assimp/code/MMDPmdParser.h
deleted file mode 100644
index 586f20a5f..000000000
--- a/src/3rdparty/assimp/code/MMDPmdParser.h
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include "MMDCpp14.h"
-
-namespace pmd
-{
- class PmdHeader
- {
- public:
- std::string name;
- std::string name_english;
- std::string comment;
- std::string comment_english;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read(buffer, 256);
- comment = std::string(buffer);
- return true;
- }
-
- bool ReadExtension(std::ifstream* stream)
- {
- char buffer[256];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- stream->read(buffer, 256);
- comment_english = std::string(buffer);
- return true;
- }
- };
-
- class PmdVertex
- {
- public:
- float position[3];
-
- float normal[3];
-
- float uv[2];
-
- uint16_t bone_index[2];
-
- uint8_t bone_weight;
-
- bool edge_invisible;
-
- bool Read(std::ifstream* stream)
- {
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) normal, sizeof(float) * 3);
- stream->read((char*) uv, sizeof(float) * 2);
- stream->read((char*) bone_index, sizeof(uint16_t) * 2);
- stream->read((char*) &bone_weight, sizeof(uint8_t));
- stream->read((char*) &edge_invisible, sizeof(uint8_t));
- return true;
- }
- };
-
- class PmdMaterial
- {
- public:
- float diffuse[4];
- float power;
- float specular[3];
- float ambient[3];
- uint8_t toon_index;
- uint8_t edge_flag;
- uint32_t index_count;
- std::string texture_filename;
- std::string sphere_filename;
-
- bool Read(std::ifstream* stream)
- {
- char buffer[20];
- stream->read((char*) &diffuse, sizeof(float) * 4);
- stream->read((char*) &power, sizeof(float));
- stream->read((char*) &specular, sizeof(float) * 3);
- stream->read((char*) &ambient, sizeof(float) * 3);
- stream->read((char*) &toon_index, sizeof(uint8_t));
- stream->read((char*) &edge_flag, sizeof(uint8_t));
- stream->read((char*) &index_count, sizeof(uint32_t));
- stream->read((char*) &buffer, sizeof(char) * 20);
- char* pstar = strchr(buffer, '*');
- if (NULL == pstar)
- {
- texture_filename = std::string(buffer);
- sphere_filename.clear();
- }
- else {
- *pstar = 0;
- texture_filename = std::string(buffer);
- sphere_filename = std::string(pstar+1);
- }
- return true;
- }
- };
-
- enum class BoneType : uint8_t
- {
- Rotation,
- RotationAndMove,
- IkEffector,
- Unknown,
- IkEffectable,
- RotationEffectable,
- IkTarget,
- Invisible,
- Twist,
- RotationMovement
- };
-
- class PmdBone
- {
- public:
- std::string name;
- std::string name_english;
- uint16_t parent_bone_index;
- uint16_t tail_pos_bone_index;
- BoneType bone_type;
- uint16_t ik_parent_bone_index;
- float bone_head_pos[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char*) &parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_type, sizeof(uint8_t));
- stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_head_pos, sizeof(float) * 3);
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdIk
- {
- public:
- uint16_t ik_bone_index;
- uint16_t target_bone_index;
- uint16_t interations;
- float angle_limit;
- std::vector<uint16_t> ik_child_bone_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &ik_bone_index, sizeof(uint16_t));
- stream->read((char *) &target_bone_index, sizeof(uint16_t));
- uint8_t ik_chain_length;
- stream->read((char*) &ik_chain_length, sizeof(uint8_t));
- stream->read((char *) &interations, sizeof(uint16_t));
- stream->read((char *) &angle_limit, sizeof(float));
- ik_child_bone_index.resize(ik_chain_length);
- for (int i = 0; i < ik_chain_length; i++)
- {
- stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
- }
- }
- };
-
- class PmdFaceVertex
- {
- public:
- int vertex_index;
- float position[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char *) &vertex_index, sizeof(int));
- stream->read((char *) position, sizeof(float) * 3);
- }
- };
-
- enum class FaceCategory : uint8_t
- {
- Base,
- Eyebrow,
- Eye,
- Mouth,
- Other
- };
-
- class PmdFace
- {
- public:
- std::string name;
- FaceCategory type;
- std::vector<PmdFaceVertex> vertices;
- std::string name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- int vertex_count;
- stream->read((char*) &vertex_count, sizeof(int));
- stream->read((char*) &type, sizeof(uint8_t));
- vertices.resize(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream);
- }
- }
-
- void ReadExpantion(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDispName
- {
- public:
- std::string bone_disp_name;
- std::string bone_disp_name_english;
-
- void Read(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name = std::string(buffer);
- bone_disp_name_english.clear();
- }
- void ReadExpantion(std::istream *stream)
- {
- char buffer[50];
- stream->read(buffer, 50);
- bone_disp_name_english = std::string(buffer);
- }
- };
-
- class PmdBoneDisp
- {
- public:
- uint16_t bone_index;
- uint8_t bone_disp_index;
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &bone_index, sizeof(uint16_t));
- stream->read((char*) &bone_disp_index, sizeof(uint8_t));
- }
- };
-
- enum class RigidBodyShape : uint8_t
- {
- Sphere = 0,
- Box = 1,
- Cpusel = 2
- };
-
- enum class RigidBodyType : uint8_t
- {
- BoneConnected = 0,
- Physics = 1,
- ConnectedPhysics = 2
- };
-
- class PmdRigidBody
- {
- public:
- std::string name;
- uint16_t related_bone_index;
- uint8_t group_index;
- uint16_t mask;
- RigidBodyShape shape;
- float size[3];
- float position[3];
- float orientation[3];
- float weight;
- float linear_damping;
- float anglar_damping;
- float restitution;
- float friction;
- RigidBodyType rigid_type;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, sizeof(char) * 20);
- name = (std::string(buffer));
- stream->read((char*) &related_bone_index, sizeof(uint16_t));
- stream->read((char*) &group_index, sizeof(uint8_t));
- stream->read((char*) &mask, sizeof(uint16_t));
- stream->read((char*) &shape, sizeof(uint8_t));
- stream->read((char*) size, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) &weight, sizeof(float));
- stream->read((char*) &linear_damping, sizeof(float));
- stream->read((char*) &anglar_damping, sizeof(float));
- stream->read((char*) &restitution, sizeof(float));
- stream->read((char*) &friction, sizeof(float));
- stream->read((char*) &rigid_type, sizeof(char));
- }
- };
-
- class PmdConstraint
- {
- public:
- std::string name;
- uint32_t rigid_body_index_a;
- uint32_t rigid_body_index_b;
- float position[3];
- float orientation[3];
- float linear_lower_limit[3];
- float linear_upper_limit[3];
- float angular_lower_limit[3];
- float angular_upper_limit[3];
- float linear_stiffness[3];
- float angular_stiffness[3];
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read(buffer, 20);
- name = std::string(buffer);
- stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
- stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
- stream->read((char *) position, sizeof(float) * 3);
- stream->read((char *) orientation, sizeof(float) * 3);
- stream->read((char *) linear_lower_limit, sizeof(float) * 3);
- stream->read((char *) linear_upper_limit, sizeof(float) * 3);
- stream->read((char *) angular_lower_limit, sizeof(float) * 3);
- stream->read((char *) angular_upper_limit, sizeof(float) * 3);
- stream->read((char *) linear_stiffness, sizeof(float) * 3);
- stream->read((char *) angular_stiffness, sizeof(float) * 3);
- }
- };
-
- class PmdModel
- {
- public:
- float version;
- PmdHeader header;
- std::vector<PmdVertex> vertices;
- std::vector<uint16_t> indices;
- std::vector<PmdMaterial> materials;
- std::vector<PmdBone> bones;
- std::vector<PmdIk> iks;
- std::vector<PmdFace> faces;
- std::vector<uint16_t> faces_indices;
- std::vector<PmdBoneDispName> bone_disp_name;
- std::vector<PmdBoneDisp> bone_disp;
- std::vector<std::string> toon_filenames;
- std::vector<PmdRigidBody> rigid_bodies;
- std::vector<PmdConstraint> constraints;
-
- static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- if (stream.fail())
- {
- std::cerr << "could not open \"" << filename << "\"" << std::endl;
- return nullptr;
- }
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
- {
- auto result = mmd::make_unique<PmdModel>();
- char buffer[100];
-
- // magic
- char magic[3];
- stream->read(magic, 3);
- if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
- {
- std::cerr << "invalid file" << std::endl;
- return nullptr;
- }
-
- // version
- stream->read((char*) &(result->version), sizeof(float));
- if (result ->version != 1.0f)
- {
- std::cerr << "invalid version" << std::endl;
- return nullptr;
- }
-
- // header
- result->header.Read(stream);
-
- // vertices
- uint32_t vertex_num;
- stream->read((char*) &vertex_num, sizeof(uint32_t));
- result->vertices.resize(vertex_num);
- for (uint32_t i = 0; i < vertex_num; i++)
- {
- result->vertices[i].Read(stream);
- }
-
- // indices
- uint32_t index_num;
- stream->read((char*) &index_num, sizeof(uint32_t));
- result->indices.resize(index_num);
- for (uint32_t i = 0; i < index_num; i++)
- {
- stream->read((char*) &result->indices[i], sizeof(uint16_t));
- }
-
- // materials
- uint32_t material_num;
- stream->read((char*) &material_num, sizeof(uint32_t));
- result->materials.resize(material_num);
- for (uint32_t i = 0; i < material_num; i++)
- {
- result->materials[i].Read(stream);
- }
-
- // bones
- uint16_t bone_num;
- stream->read((char*) &bone_num, sizeof(uint16_t));
- result->bones.resize(bone_num);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].Read(stream);
- }
-
- // iks
- uint16_t ik_num;
- stream->read((char*) &ik_num, sizeof(uint16_t));
- result->iks.resize(ik_num);
- for (uint32_t i = 0; i < ik_num; i++)
- {
- result->iks[i].Read(stream);
- }
-
- // faces
- uint16_t face_num;
- stream->read((char*) &face_num, sizeof(uint16_t));
- result->faces.resize(face_num);
- for (uint32_t i = 0; i < face_num; i++)
- {
- result->faces[i].Read(stream);
- }
-
- // face frames
- uint8_t face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(uint8_t));
- result->faces_indices.resize(face_frame_num);
- for (uint32_t i = 0; i < face_frame_num; i++)
- {
- stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
- }
-
- // bone names
- uint8_t bone_disp_num;
- stream->read((char*) &bone_disp_num, sizeof(uint8_t));
- result->bone_disp_name.resize(bone_disp_num);
- for (uint32_t i = 0; i < bone_disp_num; i++)
- {
- result->bone_disp_name[i].Read(stream);
- }
-
- // bone frame
- uint32_t bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(uint32_t));
- result->bone_disp.resize(bone_frame_num);
- for (uint32_t i = 0; i < bone_frame_num; i++)
- {
- result->bone_disp[i].Read(stream);
- }
-
- // english name
- bool english;
- stream->read((char*) &english, sizeof(char));
- if (english)
- {
- result->header.ReadExtension(stream);
- for (uint32_t i = 0; i < bone_num; i++)
- {
- result->bones[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < face_num; i++)
- {
- if (result->faces[i].type == pmd::FaceCategory::Base)
- {
- continue;
- }
- result->faces[i].ReadExpantion(stream);
- }
- for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
- {
- result->bone_disp_name[i].ReadExpantion(stream);
- }
- }
-
- // toon textures
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->toon_filenames.clear();
- }
- else {
- result->toon_filenames.resize(10);
- for (uint32_t i = 0; i < 10; i++)
- {
- stream->read(buffer, 100);
- result->toon_filenames[i] = std::string(buffer);
- }
- }
-
- // physics
- if (stream->peek() == std::ios::traits_type::eof())
- {
- result->rigid_bodies.clear();
- result->constraints.clear();
- }
- else {
- uint32_t rigid_body_num;
- stream->read((char*) &rigid_body_num, sizeof(uint32_t));
- result->rigid_bodies.resize(rigid_body_num);
- for (uint32_t i = 0; i < rigid_body_num; i++)
- {
- result->rigid_bodies[i].Read(stream);
- }
- uint32_t constraint_num;
- stream->read((char*) &constraint_num, sizeof(uint32_t));
- result->constraints.resize(constraint_num);
- for (uint32_t i = 0; i < constraint_num; i++)
- {
- result->constraints[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "there is unknown data" << std::endl;
- }
-
- return result;
- }
- };
-}
diff --git a/src/3rdparty/assimp/code/MMDPmxParser.cpp b/src/3rdparty/assimp/code/MMDPmxParser.cpp
deleted file mode 100644
index 970cbc31e..000000000
--- a/src/3rdparty/assimp/code/MMDPmxParser.cpp
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#include <utility>
-#include "MMDPmxParser.h"
-#include "../contrib/utf8cpp/source/utf8.h"
-#include "Exceptional.h"
-
-namespace pmx
-{
- int ReadIndex(std::istream *stream, int size)
- {
- switch (size)
- {
- case 1:
- uint8_t tmp8;
- stream->read((char*) &tmp8, sizeof(uint8_t));
- if (255 == tmp8)
- {
- return -1;
- }
- else {
- return (int) tmp8;
- }
- case 2:
- uint16_t tmp16;
- stream->read((char*) &tmp16, sizeof(uint16_t));
- if (65535 == tmp16)
- {
- return -1;
- }
- else {
- return (int) tmp16;
- }
- case 4:
- int tmp32;
- stream->read((char*) &tmp32, sizeof(int));
- return tmp32;
- default:
- return -1;
- }
- }
-
- std::string ReadString(std::istream *stream, uint8_t encoding)
- {
- int size;
- stream->read((char*) &size, sizeof(int));
- std::vector<char> buffer;
- if (size == 0)
- {
- return std::string("");
- }
- buffer.reserve(size);
- stream->read((char*) buffer.data(), size);
- if (encoding == 0)
- {
- // UTF16 to UTF8
- std::string result;
-
- const char* sourceStart = buffer.data();
- const unsigned int targetSize = size * 3; // enough to encode
- char* targetStart = new char[targetSize]();
- const char* targetReserved = targetStart;
- utf8::utf16to8( sourceStart, sourceStart + size, targetStart );
-
- result.assign(targetReserved, targetStart - targetReserved);
- delete[] targetReserved;
- return result;
- }
- else
- {
- // the name is already UTF8
- return std::string((const char*)buffer.data(), size);
- }
- }
-
- void PmxSetting::Read(std::istream *stream)
- {
- uint8_t count;
- stream->read((char*) &count, sizeof(uint8_t));
- if (count < 8)
- {
- throw;
- }
- stream->read((char*) &encoding, sizeof(uint8_t));
- stream->read((char*) &uv, sizeof(uint8_t));
- stream->read((char*) &vertex_index_size, sizeof(uint8_t));
- stream->read((char*) &texture_index_size, sizeof(uint8_t));
- stream->read((char*) &material_index_size, sizeof(uint8_t));
- stream->read((char*) &bone_index_size, sizeof(uint8_t));
- stream->read((char*) &morph_index_size, sizeof(uint8_t));
- stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
- uint8_t temp;
- for (int i = 8; i < count; i++)
- {
- stream->read((char*)&temp, sizeof(uint8_t));
- }
- }
-
- void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- }
-
- void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- }
-
- void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight, sizeof(float));
- stream->read((char*) this->sdef_c, sizeof(float) * 3);
- stream->read((char*) this->sdef_r0, sizeof(float) * 3);
- stream->read((char*) this->sdef_r1, sizeof(float) * 3);
- }
-
- void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
- this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->bone_weight1, sizeof(float));
- stream->read((char*) &this->bone_weight2, sizeof(float));
- stream->read((char*) &this->bone_weight3, sizeof(float));
- stream->read((char*) &this->bone_weight4, sizeof(float));
- }
-
- void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->normal, sizeof(float) * 3);
- stream->read((char*) this->uv, sizeof(float) * 2);
- for (int i = 0; i < setting->uv; ++i)
- {
- stream->read((char*) this->uva[i], sizeof(float) * 4);
- }
- stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
- switch (this->skinning_type)
- {
- case PmxVertexSkinningType::BDEF1:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>();
- break;
- case PmxVertexSkinningType::BDEF2:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>();
- break;
- case PmxVertexSkinningType::BDEF4:
- this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>();
- break;
- case PmxVertexSkinningType::SDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>();
- break;
- case PmxVertexSkinningType::QDEF:
- this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>();
- break;
- default:
- throw "invalid skinning type";
- }
- this->skinning->Read(stream, setting);
- stream->read((char*) &this->edge, sizeof(float));
- }
-
- void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_name = ReadString(stream, setting->encoding);
- this->material_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->diffuse, sizeof(float) * 4);
- stream->read((char*) this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularlity, sizeof(float));
- stream->read((char*) this->ambient, sizeof(float) * 3);
- stream->read((char*) &this->flag, sizeof(uint8_t));
- stream->read((char*) this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
- this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
- stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
- stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
- if (this->common_toon_flag)
- {
- stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
- }
- else {
- this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
- }
- this->memo = ReadString(stream, setting->encoding);
- stream->read((char*) &this->index_count, sizeof(int));
- }
-
- void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
- {
- this->link_target = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->angle_lock, sizeof(uint8_t));
- if (angle_lock == 1)
- {
- stream->read((char*) this->max_radian, sizeof(float) * 3);
- stream->read((char*) this->min_radian, sizeof(float) * 3);
- }
- }
-
- void PmxBone::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_name = ReadString(stream, setting->encoding);
- this->bone_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) this->position, sizeof(float) * 3);
- this->parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->level, sizeof(int));
- stream->read((char*) &this->bone_flag, sizeof(uint16_t));
- if (this->bone_flag & 0x0001) {
- this->target_index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- stream->read((char*)this->offset, sizeof(float) * 3);
- }
- if (this->bone_flag & (0x0100 | 0x0200)) {
- this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->grant_weight, sizeof(float));
- }
- if (this->bone_flag & 0x0400) {
- stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x0800) {
- stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
- stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
- }
- if (this->bone_flag & 0x2000) {
- stream->read((char*) &this->key, sizeof(int));
- }
- if (this->bone_flag & 0x0020) {
- this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &ik_loop, sizeof(int));
- stream->read((char*) &ik_loop_angle_limit, sizeof(float));
- stream->read((char*) &ik_link_count, sizeof(int));
- this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count);
- for (int i = 0; i < ik_link_count; i++) {
- ik_links[i].Read(stream, setting);
- }
- }
- }
-
- void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->position_offset, sizeof(float) * 3);
- }
-
- void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*)this->uv_offset, sizeof(float) * 4);
- }
-
- void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->bone_index = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*)this->translation, sizeof(float) * 3);
- stream->read((char*)this->rotation, sizeof(float) * 4);
- }
-
- void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->material_index = ReadIndex(stream, setting->material_index_size);
- stream->read((char*) &this->offset_operation, sizeof(uint8_t));
- stream->read((char*)this->diffuse, sizeof(float) * 4);
- stream->read((char*)this->specular, sizeof(float) * 3);
- stream->read((char*) &this->specularity, sizeof(float));
- stream->read((char*)this->ambient, sizeof(float) * 3);
- stream->read((char*)this->edge_color, sizeof(float) * 4);
- stream->read((char*) &this->edge_size, sizeof(float));
- stream->read((char*)this->texture_argb, sizeof(float) * 4);
- stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
- stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
- }
-
- void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_weight, sizeof(float));
- }
-
- void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_index = ReadIndex(stream, setting->morph_index_size);
- stream->read((char*) &this->morph_value, sizeof(float));
- }
-
- void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) &this->is_local, sizeof(uint8_t));
- stream->read((char*)this->velocity, sizeof(float) * 3);
- stream->read((char*)this->angular_torque, sizeof(float) * 3);
- }
-
- void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
- {
- this->morph_name = ReadString(stream, setting->encoding);
- this->morph_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &category, sizeof(MorphCategory));
- stream->read((char*) &morph_type, sizeof(MorphType));
- stream->read((char*) &this->offset_count, sizeof(int));
- switch (this->morph_type)
- {
- case MorphType::Group:
- group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- group_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Vertex:
- vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- vertex_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Bone:
- bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- bone_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::Matrial:
- material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- material_offsets[i].Read(stream, setting);
- }
- break;
- case MorphType::UV:
- case MorphType::AdditionalUV1:
- case MorphType::AdditionalUV2:
- case MorphType::AdditionalUV3:
- case MorphType::AdditionalUV4:
- uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count);
- for (int i = 0; i < offset_count; i++)
- {
- uv_offsets[i].Read(stream, setting);
- }
- break;
- default:
- throw;
- }
- }
-
- void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
- {
- stream->read((char*) &this->element_target, sizeof(uint8_t));
- if (this->element_target == 0x00)
- {
- this->index = ReadIndex(stream, setting->bone_index_size);
- }
- else {
- this->index = ReadIndex(stream, setting->morph_index_size);
- }
- }
-
- void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
- {
- this->frame_name = ReadString(stream, setting->encoding);
- this->frame_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->frame_flag, sizeof(uint8_t));
- stream->read((char*) &this->element_count, sizeof(int));
- this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count);
- for (int i = 0; i < this->element_count; i++)
- {
- this->elements[i].Read(stream, setting);
- }
- }
-
- void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->girid_body_name = ReadString(stream, setting->encoding);
- this->girid_body_english_name = ReadString(stream, setting->encoding);
- this->target_bone = ReadIndex(stream, setting->bone_index_size);
- stream->read((char*) &this->group, sizeof(uint8_t));
- stream->read((char*) &this->mask, sizeof(uint16_t));
- stream->read((char*) &this->shape, sizeof(uint8_t));
- stream->read((char*) this->size, sizeof(float) * 3);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientation, sizeof(float) * 3);
- stream->read((char*) &this->mass, sizeof(float));
- stream->read((char*) &this->move_attenuation, sizeof(float));
- stream->read((char*) &this->rotation_attenuation, sizeof(float));
- stream->read((char*) &this->repulsion, sizeof(float));
- stream->read((char*) &this->friction, sizeof(float));
- stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
- }
-
- void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
- {
- this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
- this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
- stream->read((char*) this->position, sizeof(float) * 3);
- stream->read((char*) this->orientaiton, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
- stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
- stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
- stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
- }
-
- void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
- {
- this->joint_name = ReadString(stream, setting->encoding);
- this->joint_english_name = ReadString(stream, setting->encoding);
- stream->read((char*) &this->joint_type, sizeof(uint8_t));
- this->param.Read(stream, setting);
- }
-
- void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
- {
- this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
- this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
- stream->read((char*) &this->is_near, sizeof(uint8_t));
- }
-
- void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
- {
- // 未実装
- std::cerr << "Not Implemented Exception" << std::endl;
- throw;
- }
-
- void PmxModel::Init()
- {
- this->version = 0.0f;
- this->model_name.clear();
- this->model_english_name.clear();
- this->model_comment.clear();
- this->model_english_comment.clear();
- this->vertex_count = 0;
- this->vertices = nullptr;
- this->index_count = 0;
- this->indices = nullptr;
- this->texture_count = 0;
- this->textures = nullptr;
- this->material_count = 0;
- this->materials = nullptr;
- this->bone_count = 0;
- this->bones = nullptr;
- this->morph_count = 0;
- this->morphs = nullptr;
- this->frame_count = 0;
- this->frames = nullptr;
- this->rigid_body_count = 0;
- this->rigid_bodies = nullptr;
- this->joint_count = 0;
- this->joints = nullptr;
- this->soft_body_count = 0;
- this->soft_bodies = nullptr;
- }
-
- void PmxModel::Read(std::istream *stream)
- {
- // マジック
- char magic[4];
- stream->read((char*) magic, sizeof(char) * 4);
- if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
- {
- std::cerr << "invalid magic number." << std::endl;
- throw;
- }
- // ãƒãƒ¼ã‚¸ãƒ§ãƒ³
- stream->read((char*) &version, sizeof(float));
- if (version != 2.0f && version != 2.1f)
- {
- std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
- throw;
- }
- // ファイル設定
- this->setting.Read(stream);
-
- // モデル情報
- this->model_name = ReadString(stream, setting.encoding);
- this->model_english_name = ReadString(stream, setting.encoding);
- this->model_comment = ReadString(stream, setting.encoding);
- this->model_english_comment = ReadString(stream, setting.encoding);
-
- // 頂点
- stream->read((char*) &vertex_count, sizeof(int));
- this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
- for (int i = 0; i < vertex_count; i++)
- {
- vertices[i].Read(stream, &setting);
- }
-
- // é¢
- stream->read((char*) &index_count, sizeof(int));
- this->indices = mmd::make_unique<int []>(index_count);
- for (int i = 0; i < index_count; i++)
- {
- this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
- }
-
- // テクスãƒãƒ£
- stream->read((char*) &texture_count, sizeof(int));
- this->textures = mmd::make_unique<std::string []>(texture_count);
- for (int i = 0; i < texture_count; i++)
- {
- this->textures[i] = ReadString(stream, setting.encoding);
- }
-
- // マテリアル
- stream->read((char*) &material_count, sizeof(int));
- this->materials = mmd::make_unique<PmxMaterial []>(material_count);
- for (int i = 0; i < material_count; i++)
- {
- this->materials[i].Read(stream, &setting);
- }
-
- // ボーン
- stream->read((char*) &this->bone_count, sizeof(int));
- this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
- for (int i = 0; i < this->bone_count; i++)
- {
- this->bones[i].Read(stream, &setting);
- }
-
- // モーフ
- stream->read((char*) &this->morph_count, sizeof(int));
- this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
- for (int i = 0; i < this->morph_count; i++)
- {
- this->morphs[i].Read(stream, &setting);
- }
-
- // 表示枠
- stream->read((char*) &this->frame_count, sizeof(int));
- this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
- for (int i = 0; i < this->frame_count; i++)
- {
- this->frames[i].Read(stream, &setting);
- }
-
- // 剛体
- stream->read((char*) &this->rigid_body_count, sizeof(int));
- this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
- for (int i = 0; i < this->rigid_body_count; i++)
- {
- this->rigid_bodies[i].Read(stream, &setting);
- }
-
- // ジョイント
- stream->read((char*) &this->joint_count, sizeof(int));
- this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
- for (int i = 0; i < this->joint_count; i++)
- {
- this->joints[i].Read(stream, &setting);
- }
-
- //if (this->version == 2.1f)
- //{
- // stream->read((char*) &this->soft_body_count, sizeof(int));
- // this->soft_bodies = mmd::make_unique<PmxSoftBody []>(this->soft_body_count);
- // for (int i = 0; i < this->soft_body_count; i++)
- // {
- // this->soft_bodies[i].Read(stream, &setting);
- // }
- //}
- }
-
- //std::unique_ptr<PmxModel> ReadFromFile(const char *filename)
- //{
- // auto stream = std::ifstream(filename, std::ios_base::binary);
- // auto pmx = PmxModel::ReadFromStream(&stream);
- // if (!stream.eof())
- // {
- // std::cerr << "don't reach the end of file." << std::endl;
- // }
- // stream.close();
- // return pmx;
- //}
-
- //std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream)
- //{
- // auto pmx = mmd::make_unique<PmxModel>();
- // pmx->Read(stream);
- // return pmx;
- //}
-}
diff --git a/src/3rdparty/assimp/code/MMDPmxParser.h b/src/3rdparty/assimp/code/MMDPmxParser.h
deleted file mode 100644
index 989cffed6..000000000
--- a/src/3rdparty/assimp/code/MMDPmxParser.h
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <memory>
-#include "MMDCpp14.h"
-
-namespace pmx
-{
- class PmxSetting
- {
- public:
- PmxSetting()
- : encoding(0)
- , uv(0)
- , vertex_index_size(0)
- , texture_index_size(0)
- , material_index_size(0)
- , bone_index_size(0)
- , morph_index_size(0)
- , rigidbody_index_size(0)
- {}
-
- uint8_t encoding;
- uint8_t uv;
- uint8_t vertex_index_size;
- uint8_t texture_index_size;
- uint8_t material_index_size;
- uint8_t bone_index_size;
- uint8_t morph_index_size;
- uint8_t rigidbody_index_size;
- void Read(std::istream *stream);
- };
-
- enum class PmxVertexSkinningType : uint8_t
- {
- BDEF1 = 0,
- BDEF2 = 1,
- BDEF4 = 2,
- SDEF = 3,
- QDEF = 4,
- };
-
- class PmxVertexSkinning
- {
- public:
- virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
- };
-
- class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF1()
- : bone_index(0)
- {}
-
- int bone_index;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF2()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningBDEF4()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningSDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningSDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_weight(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- sdef_c[i] = 0.0f;
- sdef_r0[i] = 0.0f;
- sdef_r1[i] = 0.0f;
- }
- }
-
- int bone_index1;
- int bone_index2;
- float bone_weight;
- float sdef_c[3];
- float sdef_r0[3];
- float sdef_r1[3];
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertexSkinningQDEF : public PmxVertexSkinning
- {
- public:
- PmxVertexSkinningQDEF()
- : bone_index1(0)
- , bone_index2(0)
- , bone_index3(0)
- , bone_index4(0)
- , bone_weight1(0.0f)
- , bone_weight2(0.0f)
- , bone_weight3(0.0f)
- , bone_weight4(0.0f)
- {}
-
- int bone_index1;
- int bone_index2;
- int bone_index3;
- int bone_index4;
- float bone_weight1;
- float bone_weight2;
- float bone_weight3;
- float bone_weight4;
- void Read(std::istream *stresam, PmxSetting *setting);
- };
-
- class PmxVertex
- {
- public:
- PmxVertex()
- : edge(0.0f)
- {
- uv[0] = uv[1] = 0.0f;
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- normal[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- for (int k = 0; k < 4; ++k) {
- uva[i][k] = 0.0f;
- }
- }
- }
-
- float position[3];
- float normal[3];
- float uv[2];
- float uva[4][4];
- PmxVertexSkinningType skinning_type;
- std::unique_ptr<PmxVertexSkinning> skinning;
- float edge;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxMaterial
- {
- public:
- PmxMaterial()
- : specularlity(0.0f)
- , flag(0)
- , edge_size(0.0f)
- , diffuse_texture_index(0)
- , sphere_texture_index(0)
- , sphere_op_mode(0)
- , common_toon_flag(0)
- , toon_texture_index(0)
- , index_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- edge_color[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- }
- }
-
- std::string material_name;
- std::string material_english_name;
- float diffuse[4];
- float specular[3];
- float specularlity;
- float ambient[3];
- uint8_t flag;
- float edge_color[4];
- float edge_size;
- int diffuse_texture_index;
- int sphere_texture_index;
- uint8_t sphere_op_mode;
- uint8_t common_toon_flag;
- int toon_texture_index;
- std::string memo;
- int index_count;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxIkLink
- {
- public:
- PmxIkLink()
- : link_target(0)
- , angle_lock(0)
- {
- for (int i = 0; i < 3; ++i) {
- max_radian[i] = 0.0f;
- min_radian[i] = 0.0f;
- }
- }
-
- int link_target;
- uint8_t angle_lock;
- float max_radian[3];
- float min_radian[3];
- void Read(std::istream *stream, PmxSetting *settingn);
- };
-
- class PmxBone
- {
- public:
- PmxBone()
- : parent_index(0)
- , level(0)
- , bone_flag(0)
- , target_index(0)
- , grant_parent_index(0)
- , grant_weight(0.0f)
- , key(0)
- , ik_target_bone_index(0)
- , ik_loop(0)
- , ik_loop_angle_limit(0.0f)
- , ik_link_count(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- offset[i] = 0.0f;
- lock_axis_orientation[i] = 0.0f;
- local_axis_x_orientation[i] = 0.0f;
- local_axis_y_orientation[i] = 0.0f;
- }
- }
-
- std::string bone_name;
- std::string bone_english_name;
- float position[3];
- int parent_index;
- int level;
- uint16_t bone_flag;
- float offset[3];
- int target_index;
- int grant_parent_index;
- float grant_weight;
- float lock_axis_orientation[3];
- float local_axis_x_orientation[3];
- float local_axis_y_orientation[3];
- int key;
- int ik_target_bone_index;
- int ik_loop;
- float ik_loop_angle_limit;
- int ik_link_count;
- std::unique_ptr<PmxIkLink []> ik_links;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class MorphType : uint8_t
- {
- Group = 0,
- Vertex = 1,
- Bone = 2,
- UV = 3,
- AdditionalUV1 = 4,
- AdditionalUV2 = 5,
- AdditionalUV3 = 6,
- AdditionalUV4 = 7,
- Matrial = 8,
- Flip = 9,
- Implus = 10,
- };
-
- enum class MorphCategory : uint8_t
- {
- ReservedCategory = 0,
- Eyebrow = 1,
- Eye = 2,
- Mouth = 3,
- Other = 4,
- };
-
- class PmxMorphOffset
- {
- public:
- void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
- };
-
- class PmxMorphVertexOffset : public PmxMorphOffset
- {
- public:
- PmxMorphVertexOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- position_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float position_offset[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphUVOffset : public PmxMorphOffset
- {
- public:
- PmxMorphUVOffset()
- : vertex_index(0)
- {
- for (int i = 0; i < 4; ++i) {
- uv_offset[i] = 0.0f;
- }
- }
- int vertex_index;
- float uv_offset[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphBoneOffset : public PmxMorphOffset
- {
- public:
- PmxMorphBoneOffset()
- : bone_index(0)
- {
- for (int i = 0; i < 3; ++i) {
- translation[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- rotation[i] = 0.0f;
- }
- }
- int bone_index;
- float translation[3];
- float rotation[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphMaterialOffset : public PmxMorphOffset
- {
- public:
- PmxMorphMaterialOffset()
- : specularity(0.0f)
- , edge_size(0.0f)
- {
- for (int i = 0; i < 3; ++i) {
- specular[i] = 0.0f;
- ambient[i] = 0.0f;
- }
- for (int i = 0; i < 4; ++i) {
- diffuse[i] = 0.0f;
- edge_color[i] = 0.0f;
- texture_argb[i] = 0.0f;
- sphere_texture_argb[i] = 0.0f;
- toon_texture_argb[i] = 0.0f;
- }
- }
- int material_index;
- uint8_t offset_operation;
- float diffuse[4];
- float specular[3];
- float specularity;
- float ambient[3];
- float edge_color[4];
- float edge_size;
- float texture_argb[4];
- float sphere_texture_argb[4];
- float toon_texture_argb[4];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphGroupOffset : public PmxMorphOffset
- {
- public:
- PmxMorphGroupOffset()
- : morph_index(0)
- , morph_weight(0.0f)
- {}
- int morph_index;
- float morph_weight;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphFlipOffset : public PmxMorphOffset
- {
- public:
- PmxMorphFlipOffset()
- : morph_index(0)
- , morph_value(0.0f)
- {}
- int morph_index;
- float morph_value;
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorphImplusOffset : public PmxMorphOffset
- {
- public:
- PmxMorphImplusOffset()
- : rigid_body_index(0)
- , is_local(0)
- {
- for (int i = 0; i < 3; ++i) {
- velocity[i] = 0.0f;
- angular_torque[i] = 0.0f;
- }
- }
- int rigid_body_index;
- uint8_t is_local;
- float velocity[3];
- float angular_torque[3];
- void Read(std::istream *stream, PmxSetting *setting); //override;
- };
-
- class PmxMorph
- {
- public:
- PmxMorph()
- : offset_count(0)
- {
- }
- std::string morph_name;
- std::string morph_english_name;
- MorphCategory category;
- MorphType morph_type;
- int offset_count;
- std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
- std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
- std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
- std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
- std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
- std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
- std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrameElement
- {
- public:
- PmxFrameElement()
- : element_target(0)
- , index(0)
- {
- }
- uint8_t element_target;
- int index;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxFrame
- {
- public:
- PmxFrame()
- : frame_flag(0)
- , element_count(0)
- {
- }
- std::string frame_name;
- std::string frame_english_name;
- uint8_t frame_flag;
- int element_count;
- std::unique_ptr<PmxFrameElement []> elements;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxRigidBody
- {
- public:
- PmxRigidBody()
- : target_bone(0)
- , group(0)
- , mask(0)
- , shape(0)
- , mass(0.0f)
- , move_attenuation(0.0f)
- , rotation_attenuation(0.0f)
- , repulsion(0.0f)
- , friction(0.0f)
- , physics_calc_type(0)
- {
- for (int i = 0; i < 3; ++i) {
- size[i] = 0.0f;
- position[i] = 0.0f;
- orientation[i] = 0.0f;
- }
- }
- std::string girid_body_name;
- std::string girid_body_english_name;
- int target_bone;
- uint8_t group;
- uint16_t mask;
- uint8_t shape;
- float size[3];
- float position[3];
- float orientation[3];
- float mass;
- float move_attenuation;
- float rotation_attenuation;
- float repulsion;
- float friction;
- uint8_t physics_calc_type;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum class PmxJointType : uint8_t
- {
- Generic6DofSpring = 0,
- Generic6Dof = 1,
- Point2Point = 2,
- ConeTwist = 3,
- Slider = 5,
- Hinge = 6
- };
-
- class PmxJointParam
- {
- public:
- PmxJointParam()
- : rigid_body1(0)
- , rigid_body2(0)
- {
- for (int i = 0; i < 3; ++i) {
- position[i] = 0.0f;
- orientaiton[i] = 0.0f;
- move_limitation_min[i] = 0.0f;
- move_limitation_max[i] = 0.0f;
- rotation_limitation_min[i] = 0.0f;
- rotation_limitation_max[i] = 0.0f;
- spring_move_coefficient[i] = 0.0f;
- spring_rotation_coefficient[i] = 0.0f;
- }
- }
- int rigid_body1;
- int rigid_body2;
- float position[3];
- float orientaiton[3];
- float move_limitation_min[3];
- float move_limitation_max[3];
- float rotation_limitation_min[3];
- float rotation_limitation_max[3];
- float spring_move_coefficient[3];
- float spring_rotation_coefficient[3];
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxJoint
- {
- public:
- std::string joint_name;
- std::string joint_english_name;
- PmxJointType joint_type;
- PmxJointParam param;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- enum PmxSoftBodyFlag : uint8_t
- {
- BLink = 0x01,
- Cluster = 0x02,
- Link = 0x04
- };
-
- class PmxAncherRigidBody
- {
- public:
- PmxAncherRigidBody()
- : related_rigid_body(0)
- , related_vertex(0)
- , is_near(false)
- {}
- int related_rigid_body;
- int related_vertex;
- bool is_near;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxSoftBody
- {
- public:
- PmxSoftBody()
- : shape(0)
- , target_material(0)
- , group(0)
- , mask(0)
- , blink_distance(0)
- , cluster_count(0)
- , mass(0.0)
- , collisioni_margin(0.0)
- , aero_model(0)
- , VCF(0.0f)
- , DP(0.0f)
- , DG(0.0f)
- , LF(0.0f)
- , PR(0.0f)
- , VC(0.0f)
- , DF(0.0f)
- , MT(0.0f)
- , CHR(0.0f)
- , KHR(0.0f)
- , SHR(0.0f)
- , AHR(0.0f)
- , SRHR_CL(0.0f)
- , SKHR_CL(0.0f)
- , SSHR_CL(0.0f)
- , SR_SPLT_CL(0.0f)
- , SK_SPLT_CL(0.0f)
- , SS_SPLT_CL(0.0f)
- , V_IT(0)
- , P_IT(0)
- , D_IT(0)
- , C_IT(0)
- , LST(0.0f)
- , AST(0.0f)
- , VST(0.0f)
- , anchor_count(0)
- , pin_vertex_count(0)
- {}
- std::string soft_body_name;
- std::string soft_body_english_name;
- uint8_t shape;
- int target_material;
- uint8_t group;
- uint16_t mask;
- PmxSoftBodyFlag flag;
- int blink_distance;
- int cluster_count;
- float mass;
- float collisioni_margin;
- int aero_model;
- float VCF;
- float DP;
- float DG;
- float LF;
- float PR;
- float VC;
- float DF;
- float MT;
- float CHR;
- float KHR;
- float SHR;
- float AHR;
- float SRHR_CL;
- float SKHR_CL;
- float SSHR_CL;
- float SR_SPLT_CL;
- float SK_SPLT_CL;
- float SS_SPLT_CL;
- int V_IT;
- int P_IT;
- int D_IT;
- int C_IT;
- float LST;
- float AST;
- float VST;
- int anchor_count;
- std::unique_ptr<PmxAncherRigidBody []> anchers;
- int pin_vertex_count;
- std::unique_ptr<int []> pin_vertices;
- void Read(std::istream *stream, PmxSetting *setting);
- };
-
- class PmxModel
- {
- public:
- PmxModel()
- : version(0.0f)
- , vertex_count(0)
- , index_count(0)
- , texture_count(0)
- , material_count(0)
- , bone_count(0)
- , morph_count(0)
- , frame_count(0)
- , rigid_body_count(0)
- , joint_count(0)
- , soft_body_count(0)
- {}
-
- float version;
- PmxSetting setting;
- std::string model_name;
- std::string model_english_name;
- std::string model_comment;
- std::string model_english_comment;
- int vertex_count;
- std::unique_ptr<PmxVertex []> vertices;
- int index_count;
- std::unique_ptr<int []> indices;
- int texture_count;
- std::unique_ptr< std::string []> textures;
- int material_count;
- std::unique_ptr<PmxMaterial []> materials;
- int bone_count;
- std::unique_ptr<PmxBone []> bones;
- int morph_count;
- std::unique_ptr<PmxMorph []> morphs;
- int frame_count;
- std::unique_ptr<PmxFrame [] > frames;
- int rigid_body_count;
- std::unique_ptr<PmxRigidBody []> rigid_bodies;
- int joint_count;
- std::unique_ptr<PmxJoint []> joints;
- int soft_body_count;
- std::unique_ptr<PmxSoftBody []> soft_bodies;
- void Init();
- void Read(std::istream *stream);
- //static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
- //static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
- };
-}
diff --git a/src/3rdparty/assimp/code/MMDVmdParser.h b/src/3rdparty/assimp/code/MMDVmdParser.h
deleted file mode 100644
index 43e7a923a..000000000
--- a/src/3rdparty/assimp/code/MMDVmdParser.h
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include <ostream>
-#include "MMDCpp14.h"
-
-namespace vmd
-{
- class VmdBoneFrame
- {
- public:
- std::string name;
- int frame;
- float position[3];
- float orientation[4];
- char interpolation[4][4][4];
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) buffer, sizeof(char)*15);
- name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) position, sizeof(float)*3);
- stream->read((char*) orientation, sizeof(float)*4);
- stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 4);
- stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4);
- }
- };
-
- class VmdFaceFrame
- {
- public:
- std::string face_name;
- float weight;
- uint32_t frame;
-
- void Read(std::istream* stream)
- {
- char buffer[15];
- stream->read((char*) &buffer, sizeof(char) * 15);
- face_name = std::string(buffer);
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &weight, sizeof(float));
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)face_name.c_str(), sizeof(char) * 15);
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&weight, sizeof(float));
- }
- };
-
- class VmdCameraFrame
- {
- public:
- int frame;
- float distance;
- float position[3];
- float orientation[3];
- char interpolation[6][4];
- float angle;
- char unknown[3];
-
- void Read(std::istream *stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &distance, sizeof(float));
- stream->read((char*) position, sizeof(float) * 3);
- stream->read((char*) orientation, sizeof(float) * 3);
- stream->read((char*) interpolation, sizeof(char) * 24);
- stream->read((char*) &angle, sizeof(float));
- stream->read((char*) unknown, sizeof(char) * 3);
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&distance, sizeof(float));
- stream->write((char*)position, sizeof(float) * 3);
- stream->write((char*)orientation, sizeof(float) * 3);
- stream->write((char*)interpolation, sizeof(char) * 24);
- stream->write((char*)&angle, sizeof(float));
- stream->write((char*)unknown, sizeof(char) * 3);
- }
- };
-
- class VmdLightFrame
- {
- public:
- int frame;
- float color[3];
- float position[3];
-
- void Read(std::istream* stream)
- {
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) color, sizeof(float) * 3);
- stream->read((char*) position, sizeof(float) * 3);
- }
-
- void Write(std::ostream* stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)color, sizeof(float) * 3);
- stream->write((char*)position, sizeof(float) * 3);
- }
- };
-
- class VmdIkEnable
- {
- public:
- std::string ik_name;
- bool enable;
- };
-
- class VmdIkFrame
- {
- public:
- int frame;
- bool display;
- std::vector<VmdIkEnable> ik_enable;
-
- void Read(std::istream *stream)
- {
- char buffer[20];
- stream->read((char*) &frame, sizeof(int));
- stream->read((char*) &display, sizeof(uint8_t));
- int ik_count;
- stream->read((char*) &ik_count, sizeof(int));
- ik_enable.resize(ik_count);
- for (int i = 0; i < ik_count; i++)
- {
- stream->read(buffer, 20);
- ik_enable[i].ik_name = std::string(buffer);
- stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t));
- }
- }
-
- void Write(std::ostream *stream)
- {
- stream->write((char*)&frame, sizeof(int));
- stream->write((char*)&display, sizeof(uint8_t));
- int ik_count = static_cast<int>(ik_enable.size());
- stream->write((char*)&ik_count, sizeof(int));
- for (int i = 0; i < ik_count; i++)
- {
- const VmdIkEnable& ik_enable = this->ik_enable.at(i);
- stream->write(ik_enable.ik_name.c_str(), 20);
- stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
- }
- }
- };
-
- class VmdMotion
- {
- public:
- std::string model_name;
- int version;
- std::vector<VmdBoneFrame> bone_frames;
- std::vector<VmdFaceFrame> face_frames;
- std::vector<VmdCameraFrame> camera_frames;
- std::vector<VmdLightFrame> light_frames;
- std::vector<VmdIkFrame> ik_frames;
-
- static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
- {
- std::ifstream stream(filename, std::ios::binary);
- auto result = LoadFromStream(&stream);
- stream.close();
- return result;
- }
-
- static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream)
- {
-
- char buffer[30];
- auto result = mmd::make_unique<VmdMotion>();
-
- // magic and version
- stream->read((char*) buffer, 30);
- if (strncmp(buffer, "Vocaloid Motion Data", 20))
- {
- std::cerr << "invalid vmd file." << std::endl;
- return nullptr;
- }
- result->version = std::atoi(buffer + 20);
-
- // name
- stream->read(buffer, 20);
- result->model_name = std::string(buffer);
-
- // bone frames
- int bone_frame_num;
- stream->read((char*) &bone_frame_num, sizeof(int));
- result->bone_frames.resize(bone_frame_num);
- for (int i = 0; i < bone_frame_num; i++)
- {
- result->bone_frames[i].Read(stream);
- }
-
- // face frames
- int face_frame_num;
- stream->read((char*) &face_frame_num, sizeof(int));
- result->face_frames.resize(face_frame_num);
- for (int i = 0; i < face_frame_num; i++)
- {
- result->face_frames[i].Read(stream);
- }
-
- // camera frames
- int camera_frame_num;
- stream->read((char*) &camera_frame_num, sizeof(int));
- result->camera_frames.resize(camera_frame_num);
- for (int i = 0; i < camera_frame_num; i++)
- {
- result->camera_frames[i].Read(stream);
- }
-
- // light frames
- int light_frame_num;
- stream->read((char*) &light_frame_num, sizeof(int));
- result->light_frames.resize(light_frame_num);
- for (int i = 0; i < light_frame_num; i++)
- {
- result->light_frames[i].Read(stream);
- }
-
- // unknown2
- stream->read(buffer, 4);
-
- // ik frames
- if (stream->peek() != std::ios::traits_type::eof())
- {
- int ik_num;
- stream->read((char*) &ik_num, sizeof(int));
- result->ik_frames.resize(ik_num);
- for (int i = 0; i < ik_num; i++)
- {
- result->ik_frames[i].Read(stream);
- }
- }
-
- if (stream->peek() != std::ios::traits_type::eof())
- {
- std::cerr << "vmd stream has unknown data." << std::endl;
- }
-
- return result;
- }
-
- bool SaveToFile(const std::u16string& /*filename*/)
- {
- // TODO: How to adapt u16string to string?
- /*
- std::ofstream stream(filename.c_str(), std::ios::binary);
- auto result = SaveToStream(&stream);
- stream.close();
- return result;
- */
- return false;
- }
-
- bool SaveToStream(std::ofstream *stream)
- {
- std::string magic = "Vocaloid Motion Data 0002\0";
- magic.resize(30);
-
- // magic and version
- stream->write(magic.c_str(), 30);
-
- // name
- stream->write(model_name.c_str(), 20);
-
- // bone frames
- const int bone_frame_num = static_cast<int>(bone_frames.size());
- stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int));
- for (int i = 0; i < bone_frame_num; i++)
- {
- bone_frames[i].Write(stream);
- }
-
- // face frames
- const int face_frame_num = static_cast<int>(face_frames.size());
- stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int));
- for (int i = 0; i < face_frame_num; i++)
- {
- face_frames[i].Write(stream);
- }
-
- // camera frames
- const int camera_frame_num = static_cast<int>(camera_frames.size());
- stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int));
- for (int i = 0; i < camera_frame_num; i++)
- {
- camera_frames[i].Write(stream);
- }
-
- // light frames
- const int light_frame_num = static_cast<int>(light_frames.size());
- stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int));
- for (int i = 0; i < light_frame_num; i++)
- {
- light_frames[i].Write(stream);
- }
-
- // self shadow datas
- const int self_shadow_num = 0;
- stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int));
-
- // ik frames
- const int ik_num = static_cast<int>(ik_frames.size());
- stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int));
- for (int i = 0; i < ik_num; i++)
- {
- ik_frames[i].Write(stream);
- }
-
- return true;
- }
- };
-}
diff --git a/src/3rdparty/assimp/code/MS3DLoader.cpp b/src/3rdparty/assimp/code/MS3DLoader.cpp
deleted file mode 100644
index 64ec1e076..000000000
--- a/src/3rdparty/assimp/code/MS3DLoader.cpp
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MS3DLoader.cpp
- * @brief Implementation of the Ms3D importer class.
- * Written against http://chumbalum.swissquake.ch/ms3d/ms3dspec.txt
- */
-
-
-#ifndef ASSIMP_BUILD_NO_MS3D_IMPORTER
-
-// internal headers
-#include "MS3DLoader.h"
-#include "StreamReader.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/importerdesc.h>
-#include <map>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Milkshape 3D Importer",
- "",
- "",
- "http://chumbalum.swissquake.ch/",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "ms3d"
-};
-
-// ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
-// (enable old code path, which generates extra nodes per mesh while
-// the newer code uses aiMesh::mName to express the name of the
-// meshes (a.k.a. groups in MS3D))
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-MS3DImporter::MS3DImporter()
- : mScene()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-MS3DImporter::~MS3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool MS3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // first call - simple extension check
- const std::string extension = GetExtension(pFile);
- if (extension == "ms3d") {
- return true;
- }
-
- // second call - check for magic identifiers
- else if (!extension.length() || checkSig) {
- if (!pIOHandler) {
- return true;
- }
- const char* tokens[] = {"MS3D000000"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* MS3DImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ReadColor(StreamReaderLE& stream, aiColor4D& ambient)
-{
- // aiColor4D is packed on gcc, implicit binding to float& fails therefore.
- stream >> (float&)ambient.r >> (float&)ambient.g >> (float&)ambient.b >> (float&)ambient.a;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ReadVector(StreamReaderLE& stream, aiVector3D& pos)
-{
- // See note in ReadColor()
- stream >> (float&)pos.x >> (float&)pos.y >> (float&)pos.z;
-}
-
-// ------------------------------------------------------------------------------------------------
-template<typename T>
-void MS3DImporter :: ReadComments(StreamReaderLE& stream, std::vector<T>& outp)
-{
- uint16_t cnt;
- stream >> cnt;
-
- for(unsigned int i = 0; i < cnt; ++i) {
- uint32_t index, clength;
- stream >> index >> clength;
-
- if(index >= outp.size()) {
- DefaultLogger::get()->warn("MS3D: Invalid index in comment section");
- }
- else if (clength > stream.GetRemainingSize()) {
- throw DeadlyImportError("MS3D: Failure reading comment, length field is out of range");
- }
- else {
- outp[index].comment = std::string(reinterpret_cast<char*>(stream.GetPtr()),clength);
- }
- stream.IncPtr(clength);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T, typename T2, typename T3> bool inrange(const T& in, const T2& lower, const T3& higher)
-{
- return in > lower && in <= higher;
-}
-
-// ------------------------------------------------------------------------------------------------
-void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints,
- std::vector<bool>& hadit,
- aiNode* nd,
- const aiMatrix4x4& absTrafo)
-{
- unsigned int cnt = 0;
- for(size_t i = 0; i < joints.size(); ++i) {
- if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
- ++cnt;
- }
- }
-
- nd->mChildren = new aiNode*[nd->mNumChildren = cnt];
- cnt = 0;
- for(size_t i = 0; i < joints.size(); ++i) {
- if (!hadit[i] && !strcmp(joints[i].parentName,nd->mName.data)) {
- aiNode* ch = nd->mChildren[cnt++] = new aiNode(joints[i].name);
- ch->mParent = nd;
-
- ch->mTransformation = aiMatrix4x4::Translation(joints[i].position,aiMatrix4x4()=aiMatrix4x4())*
- // XXX actually, I don't *know* why we need the inverse here. Probably column vs. row order?
- aiMatrix4x4().FromEulerAnglesXYZ(joints[i].rotation).Transpose();
-
- const aiMatrix4x4 abs = absTrafo*ch->mTransformation;
- for(unsigned int a = 0; a < mScene->mNumMeshes; ++a) {
- aiMesh* const msh = mScene->mMeshes[a];
- for(unsigned int n = 0; n < msh->mNumBones; ++n) {
- aiBone* const bone = msh->mBones[n];
-
- if(bone->mName == ch->mName) {
- bone->mOffsetMatrix = aiMatrix4x4(abs).Inverse();
- }
- }
- }
-
- hadit[i] = true;
- CollectChildJoints(joints,hadit,ch,abs);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd)
-{
- std::vector<bool> hadit(joints.size(),false);
- aiMatrix4x4 trafo;
-
- CollectChildJoints(joints,hadit,nd,trafo);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void MS3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
-
- // CanRead() should have done this already
- char head[10];
- int32_t version;
-
- mScene = pScene;
-
-
- // 1 ------------ read into temporary data structures mirroring the original file
-
- stream.CopyAndAdvance(head,10);
- stream >> version;
- if (strncmp(head,"MS3D000000",10)) {
- throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: "+pFile);
- }
-
- if (version != 4) {
- throw DeadlyImportError("MS3D: Unsupported file format version, 4 was expected");
- }
-
- uint16_t verts;
- stream >> verts;
-
- std::vector<TempVertex> vertices(verts);
- for (unsigned int i = 0; i < verts; ++i) {
- TempVertex& v = vertices[i];
-
- stream.IncPtr(1);
- ReadVector(stream,v.pos);
- v.bone_id[0] = stream.GetI1();
- v.ref_cnt = stream.GetI1();
-
- v.bone_id[1] = v.bone_id[2] = v.bone_id[3] = UINT_MAX;
- v.weights[1] = v.weights[2] = v.weights[3] = 0.f;
- v.weights[0] = 1.f;
- }
-
- uint16_t tris;
- stream >> tris;
-
- std::vector<TempTriangle> triangles(tris);
- for (unsigned int i = 0;i < tris; ++i) {
- TempTriangle& t = triangles[i];
-
- stream.IncPtr(2);
- for (unsigned int i = 0; i < 3; ++i) {
- t.indices[i] = stream.GetI2();
- }
-
- for (unsigned int i = 0; i < 3; ++i) {
- ReadVector(stream,t.normals[i]);
- }
-
- for (unsigned int i = 0; i < 3; ++i) {
- stream >> (float&)(t.uv[i].x); // see note in ReadColor()
- }
- for (unsigned int i = 0; i < 3; ++i) {
- stream >> (float&)(t.uv[i].y);
- }
-
- t.sg = stream.GetI1();
- t.group = stream.GetI1();
- }
-
- uint16_t grp;
- stream >> grp;
-
- bool need_default = false;
- std::vector<TempGroup> groups(grp);
- for (unsigned int i = 0;i < grp; ++i) {
- TempGroup& t = groups[i];
-
- stream.IncPtr(1);
- stream.CopyAndAdvance(t.name,32);
-
- t.name[32] = '\0';
- uint16_t num;
- stream >> num;
-
- t.triangles.resize(num);
- for (unsigned int i = 0; i < num; ++i) {
- t.triangles[i] = stream.GetI2();
- }
- t.mat = stream.GetI1();
- if (t.mat == UINT_MAX) {
- need_default = true;
- }
- }
-
- uint16_t mat;
- stream >> mat;
-
- std::vector<TempMaterial> materials(mat);
- for (unsigned int i = 0;i < mat; ++i) {
- TempMaterial& t = materials[i];
-
- stream.CopyAndAdvance(t.name,32);
- t.name[32] = '\0';
-
- ReadColor(stream,t.ambient);
- ReadColor(stream,t.diffuse);
- ReadColor(stream,t.specular);
- ReadColor(stream,t.emissive);
- stream >> t.shininess >> t.transparency;
-
- stream.IncPtr(1);
-
- stream.CopyAndAdvance(t.texture,128);
- t.texture[128] = '\0';
-
- stream.CopyAndAdvance(t.alphamap,128);
- t.alphamap[128] = '\0';
- }
-
- float animfps, currenttime;
- uint32_t totalframes;
- stream >> animfps >> currenttime >> totalframes;
-
- uint16_t joint;
- stream >> joint;
-
- std::vector<TempJoint> joints(joint);
- for(unsigned int i = 0; i < joint; ++i) {
- TempJoint& j = joints[i];
-
- stream.IncPtr(1);
- stream.CopyAndAdvance(j.name,32);
- j.name[32] = '\0';
-
- stream.CopyAndAdvance(j.parentName,32);
- j.parentName[32] = '\0';
-
- // DefaultLogger::get()->debug(j.name);
- // DefaultLogger::get()->debug(j.parentName);
-
- ReadVector(stream,j.rotation);
- ReadVector(stream,j.position);
-
- j.rotFrames.resize(stream.GetI2());
- j.posFrames.resize(stream.GetI2());
-
- for(unsigned int a = 0; a < j.rotFrames.size(); ++a) {
- TempKeyFrame& kf = j.rotFrames[a];
- stream >> kf.time;
- ReadVector(stream,kf.value);
- }
- for(unsigned int a = 0; a < j.posFrames.size(); ++a) {
- TempKeyFrame& kf = j.posFrames[a];
- stream >> kf.time;
- ReadVector(stream,kf.value);
- }
- }
-
- if(stream.GetRemainingSize() > 4) {
- uint32_t subversion;
- stream >> subversion;
- if (subversion == 1) {
- ReadComments<TempGroup>(stream,groups);
- ReadComments<TempMaterial>(stream,materials);
- ReadComments<TempJoint>(stream,joints);
-
- // model comment - print it for we have such a nice log.
- if (stream.GetI4()) {
- const size_t len = static_cast<size_t>(stream.GetI4());
- if (len > stream.GetRemainingSize()) {
- throw DeadlyImportError("MS3D: Model comment is too long");
- }
-
- const std::string& s = std::string(reinterpret_cast<char*>(stream.GetPtr()),len);
- DefaultLogger::get()->debug("MS3D: Model comment: " + s);
- }
-
- if(stream.GetRemainingSize() > 4 && inrange((stream >> subversion,subversion),1u,3u)) {
- for(unsigned int i = 0; i < verts; ++i) {
- TempVertex& v = vertices[i];
- v.weights[3]=1.f;
- for(unsigned int n = 0; n < 3; v.weights[3]-=v.weights[n++]) {
- v.bone_id[n+1] = stream.GetI1();
- v.weights[n] = static_cast<float>(static_cast<unsigned int>(stream.GetI1()))/255.f;
- }
- stream.IncPtr((subversion-1)<<2u);
- }
-
- // even further extra data is not of interest for us, at least now now.
- }
- }
- }
-
- // 2 ------------ convert to proper aiXX data structures -----------------------------------
-
- if (need_default && materials.size()) {
- DefaultLogger::get()->warn("MS3D: Found group with no material assigned, spawning default material");
- // if one of the groups has no material assigned, but there are other
- // groups with materials, a default material needs to be added (
- // scenepreprocessor adds a default material only if nummat==0).
- materials.push_back(TempMaterial());
- TempMaterial& m = materials.back();
-
- strcpy(m.name,"<MS3D_DefaultMat>");
- m.diffuse = aiColor4D(0.6f,0.6f,0.6f,1.0);
- m.transparency = 1.f;
- m.shininess = 0.f;
-
- // this is because these TempXXX struct's have no c'tors.
- m.texture[0] = m.alphamap[0] = '\0';
-
- for (unsigned int i = 0; i < groups.size(); ++i) {
- TempGroup& g = groups[i];
- if (g.mat == UINT_MAX) {
- g.mat = static_cast<unsigned int>(materials.size()-1);
- }
- }
- }
-
- // convert materials to our generic key-value dict-alike
- if (materials.size()) {
- pScene->mMaterials = new aiMaterial*[materials.size()];
- for (size_t i = 0; i < materials.size(); ++i) {
-
- aiMaterial* mo = new aiMaterial();
- pScene->mMaterials[pScene->mNumMaterials++] = mo;
-
- const TempMaterial& mi = materials[i];
-
- aiString tmp;
- if (0[mi.alphamap]) {
- tmp = aiString(mi.alphamap);
- mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_OPACITY(0));
- }
- if (0[mi.texture]) {
- tmp = aiString(mi.texture);
- mo->AddProperty(&tmp,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- if (0[mi.name]) {
- tmp = aiString(mi.name);
- mo->AddProperty(&tmp,AI_MATKEY_NAME);
- }
-
- mo->AddProperty(&mi.ambient,1,AI_MATKEY_COLOR_AMBIENT);
- mo->AddProperty(&mi.diffuse,1,AI_MATKEY_COLOR_DIFFUSE);
- mo->AddProperty(&mi.specular,1,AI_MATKEY_COLOR_SPECULAR);
- mo->AddProperty(&mi.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
-
- mo->AddProperty(&mi.shininess,1,AI_MATKEY_SHININESS);
- mo->AddProperty(&mi.transparency,1,AI_MATKEY_OPACITY);
-
- const int sm = mi.shininess>0.f?aiShadingMode_Phong:aiShadingMode_Gouraud;
- mo->AddProperty(&sm,1,AI_MATKEY_SHADING_MODEL);
- }
- }
-
- // convert groups to meshes
- if (groups.empty()) {
- throw DeadlyImportError("MS3D: Didn't get any group records, file is malformed");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes=static_cast<unsigned int>(groups.size())]();
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
-
- aiMesh* m = pScene->mMeshes[i] = new aiMesh();
- const TempGroup& g = groups[i];
-
- if (pScene->mNumMaterials && g.mat > pScene->mNumMaterials) {
- throw DeadlyImportError("MS3D: Encountered invalid material index, file is malformed");
- } // no error if no materials at all - scenepreprocessor adds one then
-
- m->mMaterialIndex = g.mat;
- m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- m->mFaces = new aiFace[m->mNumFaces = static_cast<unsigned int>(g.triangles.size())];
- m->mNumVertices = m->mNumFaces*3;
-
- // storage for vertices - verbose format, as requested by the postprocessing pipeline
- m->mVertices = new aiVector3D[m->mNumVertices];
- m->mNormals = new aiVector3D[m->mNumVertices];
- m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
- m->mNumUVComponents[0] = 2;
-
- typedef std::map<unsigned int,unsigned int> BoneSet;
- BoneSet mybones;
-
- for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
- aiFace& f = m->mFaces[i];
- if (g.triangles[i]>triangles.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid triangle index, file is malformed");
- }
-
- TempTriangle& t = triangles[g.triangles[i]];
- f.mIndices = new unsigned int[f.mNumIndices=3];
-
- for (unsigned int i = 0; i < 3; ++i,++n) {
- if (t.indices[i]>vertices.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid vertex index, file is malformed");
- }
-
- const TempVertex& v = vertices[t.indices[i]];
- for(unsigned int a = 0; a < 4; ++a) {
- if (v.bone_id[a] != UINT_MAX) {
- if (v.bone_id[a] >= joints.size()) {
- throw DeadlyImportError("MS3D: Encountered invalid bone index, file is malformed");
- }
- if (mybones.find(v.bone_id[a]) == mybones.end()) {
- mybones[v.bone_id[a]] = 1;
- }
- else ++mybones[v.bone_id[a]];
- }
- }
-
- // collect vertex components
- m->mVertices[n] = v.pos;
-
- m->mNormals[n] = t.normals[i];
- m->mTextureCoords[0][n] = aiVector3D(t.uv[i].x,1.f-t.uv[i].y,0.0);
- f.mIndices[i] = n;
- }
- }
-
- // allocate storage for bones
- if(!mybones.empty()) {
- std::vector<unsigned int> bmap(joints.size());
- m->mBones = new aiBone*[mybones.size()]();
- for(BoneSet::const_iterator it = mybones.begin(); it != mybones.end(); ++it) {
- aiBone* const bn = m->mBones[m->mNumBones] = new aiBone();
- const TempJoint& jnt = joints[(*it).first];
-
- bn->mName.Set(jnt.name);
- bn->mWeights = new aiVertexWeight[(*it).second];
-
- bmap[(*it).first] = m->mNumBones++;
- }
-
- // .. and collect bone weights
- for (unsigned int i = 0,n = 0; i < m->mNumFaces; ++i) {
- TempTriangle& t = triangles[g.triangles[i]];
-
- for (unsigned int i = 0; i < 3; ++i,++n) {
- const TempVertex& v = vertices[t.indices[i]];
- for(unsigned int a = 0; a < 4; ++a) {
- const unsigned int bone = v.bone_id[a];
- if(bone==UINT_MAX){
- continue;
- }
-
- aiBone* const outbone = m->mBones[bmap[bone]];
- aiVertexWeight& outwght = outbone->mWeights[outbone->mNumWeights++];
-
- outwght.mVertexId = n;
- outwght.mWeight = v.weights[a];
- }
- }
- }
- }
- }
-
- // ... add dummy nodes under a single root, each holding a reference to one
- // 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
- rt->mChildren = new aiNode*[rt->mNumChildren=pScene->mNumMeshes+(joints.size()?1:0)]();
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- aiNode* nd = rt->mChildren[i] = new aiNode();
-
- const TempGroup& g = groups[i];
-
- // we need to generate an unique name for all mesh nodes.
- // since we want to keep the group name, a prefix is
- // prepended.
- nd->mName = aiString("<MS3DMesh>_");
- nd->mName.Append(g.name);
- nd->mParent = rt;
-
- nd->mMeshes = new unsigned int[nd->mNumMeshes = 1];
- nd->mMeshes[0] = i;
- }
-#else
- rt->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- rt->mMeshes[rt->mNumMeshes++] = i;
- }
-#endif
-
- // convert animations as well
- if(joints.size()) {
-#ifndef ASSIMP_BUILD_MS3D_ONE_NODE_PER_MESH
- rt->mChildren = new aiNode*[1]();
- rt->mNumChildren = 1;
-
- aiNode* jt = rt->mChildren[0] = new aiNode();
-#else
- aiNode* jt = rt->mChildren[pScene->mNumMeshes] = new aiNode();
-#endif
- jt->mParent = rt;
- CollectChildJoints(joints,jt);
- jt->mName.Set("<MS3DJointRoot>");
-
- pScene->mAnimations = new aiAnimation*[ pScene->mNumAnimations = 1 ];
- aiAnimation* const anim = pScene->mAnimations[0] = new aiAnimation();
-
- anim->mName.Set("<MS3DMasterAnim>");
-
- // carry the fps info to the user by scaling all times with it
- anim->mTicksPerSecond = animfps;
-
- // leave duration at its default, so ScenePreprocessor will fill an appropriate
- // value (the values taken from some MS3D files seem to be too unreliable
- // to pass the validation)
- // anim->mDuration = totalframes/animfps;
-
- anim->mChannels = new aiNodeAnim*[joints.size()]();
- for(std::vector<TempJoint>::const_iterator it = joints.begin(); it != joints.end(); ++it) {
- if ((*it).rotFrames.empty() && (*it).posFrames.empty()) {
- continue;
- }
-
- aiNodeAnim* nd = anim->mChannels[anim->mNumChannels++] = new aiNodeAnim();
- nd->mNodeName.Set((*it).name);
-
- if ((*it).rotFrames.size()) {
- nd->mRotationKeys = new aiQuatKey[(*it).rotFrames.size()];
- for(std::vector<TempKeyFrame>::const_iterator rot = (*it).rotFrames.begin(); rot != (*it).rotFrames.end(); ++rot) {
- aiQuatKey& q = nd->mRotationKeys[nd->mNumRotationKeys++];
-
- q.mTime = (*rot).time*animfps;
-
- // XXX it seems our matrix&quaternion code has faults in its conversion routines --
- // aiQuaternion(x,y,z) seems to besomething different as quat(matrix.fromeuler(x,y,z)).
- q.mValue = aiQuaternion(aiMatrix3x3(aiMatrix4x4().FromEulerAnglesXYZ((*rot).value)*
- aiMatrix4x4().FromEulerAnglesXYZ((*it).rotation)).Transpose());
- }
- }
-
- if ((*it).posFrames.size()) {
- nd->mPositionKeys = new aiVectorKey[(*it).posFrames.size()];
-
- aiQuatKey* qu = nd->mRotationKeys;
- for(std::vector<TempKeyFrame>::const_iterator pos = (*it).posFrames.begin(); pos != (*it).posFrames.end(); ++pos,++qu) {
- aiVectorKey& v = nd->mPositionKeys[nd->mNumPositionKeys++];
-
- v.mTime = (*pos).time*animfps;
- v.mValue = (*it).position + (*pos).value;
- }
- }
- }
- // fixup to pass the validation if not a single animation channel is non-trivial
- if (!anim->mNumChannels) {
- anim->mChannels = NULL;
- }
- }
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/MS3DLoader.h b/src/3rdparty/assimp/code/MS3DLoader.h
deleted file mode 100644
index b4b19b3ad..000000000
--- a/src/3rdparty/assimp/code/MS3DLoader.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MS3DLoader.h
- * @brief Declaration of the MS3D importer class.
- */
-#ifndef AI_MS3DLOADER_H_INCLUDED
-#define AI_MS3DLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "StreamReader.h"
-struct aiNode;
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------------------
-/** Milkshape 3D importer implementation */
-// ----------------------------------------------------------------------------------------------
-class MS3DImporter
- : public BaseImporter
-{
-
-public:
-
- MS3DImporter();
- ~MS3DImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details */
- const aiImporterDesc* GetInfo () const;
-
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-
-private:
-
- struct TempJoint;
- void CollectChildJoints(const std::vector<TempJoint>& joints, std::vector<bool>& hadit, aiNode* nd,const aiMatrix4x4& absTrafo);
- void CollectChildJoints(const std::vector<TempJoint>& joints, aiNode* nd);
-
- template<typename T> void ReadComments(StreamReaderLE& stream, std::vector<T>& outp);
-private:
-
- aiScene* mScene;
-
-private:
-
- struct TempVertex
- {
- aiVector3D pos;
- unsigned int bone_id[4], ref_cnt;
- float weights[4];
- };
-
- struct TempTriangle
- {
- unsigned int indices[3];
- aiVector3D normals[3];
- aiVector2D uv[3];
-
- unsigned int sg, group;
- };
-
- struct TempGroup
- {
- char name[33]; // +0
- std::vector<unsigned int> triangles;
- unsigned int mat; // 0xff is no material
- std::string comment;
- };
-
- struct TempMaterial
- {
- // again, add an extra 0 character to all strings -
- char name[33];
- char texture[129];
- char alphamap[129];
-
- aiColor4D diffuse,specular,ambient,emissive;
- float shininess,transparency;
- std::string comment;
- };
-
- struct TempKeyFrame
- {
- float time;
- aiVector3D value;
- };
-
- struct TempJoint
- {
- char name[33];
- char parentName[33];
- aiVector3D rotation, position;
-
- std::vector<TempKeyFrame> rotFrames;
- std::vector<TempKeyFrame> posFrames;
- std::string comment;
- };
-
- //struct TempModel {
- // std::string comment;
- //};
-};
-
-}
-#endif
diff --git a/src/3rdparty/assimp/code/Macros.h b/src/3rdparty/assimp/code/Macros.h
deleted file mode 100644
index 4a2d07569..000000000
--- a/src/3rdparty/assimp/code/Macros.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
----------------------------------------------------------------------------
-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.
----------------------------------------------------------------------------
-*/
-
-/* Helper macro to set a pointer to NULL in debug builds
- */
-#if (defined ASSIMP_BUILD_DEBUG)
-# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
-#else
-# define AI_DEBUG_INVALIDATE_PTR(x)
-#endif
-
diff --git a/src/3rdparty/assimp/code/MakeVerboseFormat.cpp b/src/3rdparty/assimp/code/MakeVerboseFormat.cpp
deleted file mode 100644
index 720d44519..000000000
--- a/src/3rdparty/assimp/code/MakeVerboseFormat.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step "MakeVerboseFormat"
-*/
-
-
-#include "MakeVerboseFormat.h"
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::MakeVerboseFormatProcess()
-{
- // nothing to do here
-}
-// ------------------------------------------------------------------------------------------------
-MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
-{
- // nothing to do here
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void MakeVerboseFormatProcess::Execute( aiScene* pScene)
-{
- ai_assert(NULL != pScene);
- DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
-
- bool bHas = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if( MakeVerboseFormat( pScene->mMeshes[a]))
- bHas = true;
- }
- if (bHas) DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
- else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
-
- pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
-
-}
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
-{
- ai_assert(NULL != pcMesh);
-
- unsigned int iOldNumVertices = pcMesh->mNumVertices;
- const unsigned int iNumVerts = pcMesh->mNumFaces*3;
-
- aiVector3D* pvPositions = new aiVector3D[ iNumVerts ];
-
- aiVector3D* pvNormals = NULL;
- if (pcMesh->HasNormals())
- {
- pvNormals = new aiVector3D[iNumVerts];
- }
- aiVector3D* pvTangents = NULL, *pvBitangents = NULL;
- if (pcMesh->HasTangentsAndBitangents())
- {
- pvTangents = new aiVector3D[iNumVerts];
- pvBitangents = new aiVector3D[iNumVerts];
- }
-
- aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {0};
- aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {0};
-
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- apvTextureCoords[p++] = new aiVector3D[iNumVerts];
-
- p = 0;
- while (pcMesh->HasVertexColors(p))
- apvColorSets[p++] = new aiColor4D[iNumVerts];
-
- // allocate enough memory to hold output bones and vertex weights ...
- std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i) {
- newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
- }
-
- // iterate through all faces and build a clean list
- unsigned int iIndex = 0;
- for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
- {
- aiFace* pcFace = &pcMesh->mFaces[a];
- for (unsigned int q = 0; q < pcFace->mNumIndices;++q,++iIndex)
- {
- // need to build a clean list of bones, too
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
- {
- for (unsigned int a = 0; a < pcMesh->mBones[i]->mNumWeights;a++)
- {
- const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
- if(pcFace->mIndices[q] == w.mVertexId)
- {
- aiVertexWeight wNew;
- wNew.mVertexId = iIndex;
- wNew.mWeight = w.mWeight;
- newWeights[i].push_back(wNew);
- }
- }
- }
-
- pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
-
- if (pcMesh->HasNormals())
- {
- pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
- }
- if (pcMesh->HasTangentsAndBitangents())
- {
- pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
- pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
- }
-
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
- ++p;
- }
- p = 0;
- while (pcMesh->HasVertexColors(p))
- {
- apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
- ++p;
- }
- pcFace->mIndices[q] = iIndex;
- }
- }
-
-
-
- // build output vertex weights
- for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
- {
- delete [] pcMesh->mBones[i]->mWeights;
- if (!newWeights[i].empty()) {
- pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
- aiVertexWeight *weightToCopy = &( newWeights[i][0] );
- memcpy(pcMesh->mBones[i]->mWeights, weightToCopy,
- sizeof(aiVertexWeight) * newWeights[i].size());
- } else {
- pcMesh->mBones[i]->mWeights = NULL;
- }
- }
- delete[] newWeights;
-
- // delete the old members
- delete[] pcMesh->mVertices;
- pcMesh->mVertices = pvPositions;
-
- p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- delete[] pcMesh->mTextureCoords[p];
- pcMesh->mTextureCoords[p] = apvTextureCoords[p];
- ++p;
- }
- p = 0;
- while (pcMesh->HasVertexColors(p))
- {
- delete[] pcMesh->mColors[p];
- pcMesh->mColors[p] = apvColorSets[p];
- ++p;
- }
- pcMesh->mNumVertices = iNumVerts;
-
- if (pcMesh->HasNormals())
- {
- delete[] pcMesh->mNormals;
- pcMesh->mNormals = pvNormals;
- }
- if (pcMesh->HasTangentsAndBitangents())
- {
- delete[] pcMesh->mTangents;
- pcMesh->mTangents = pvTangents;
- delete[] pcMesh->mBitangents;
- pcMesh->mBitangents = pvBitangents;
- }
- return (pcMesh->mNumVertices != iOldNumVertices);
-}
diff --git a/src/3rdparty/assimp/code/MakeVerboseFormat.h b/src/3rdparty/assimp/code/MakeVerboseFormat.h
deleted file mode 100644
index 9832a3f65..000000000
--- a/src/3rdparty/assimp/code/MakeVerboseFormat.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to bring a given scene
- into the verbose format that is expected by most postprocess steps.
- This is the inverse of the "JoinIdenticalVertices" step. */
-#ifndef AI_MAKEVERBOSEFORMAT_H_INC
-#define AI_MAKEVERBOSEFORMAT_H_INC
-
-#include "BaseProcess.h"
-struct aiMesh;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** MakeVerboseFormatProcess: Class to convert an asset to the verbose
- * format which is expected by most postprocess steps.
- *
- * This is the inverse of what the "JoinIdenticalVertices" step is doing.
- * This step has no official flag (since it wouldn't make sense to run it
- * during import). It is intended for applications intending to modify the
- * returned aiScene. After this step has been executed, they can execute
- * other postprocess steps on the data. The code might also be useful to
- * quickly adapt code that doesn't result in a verbose representation of
- * the scene data.
- * The step has been added because it was required by the viewer, however
- * it has been moved to the main library since others might find it
- * useful, too. */
-class ASSIMP_API_WINONLY MakeVerboseFormatProcess : public BaseProcess
-{
-public:
-
-
- MakeVerboseFormatProcess();
- ~MakeVerboseFormatProcess();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not */
- bool IsActive( unsigned int /*pFlags*/ ) const
- {
- // NOTE: There is no direct flag that corresponds to
- // this postprocess step.
- return false;
- }
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at. */
- void Execute( aiScene* pScene);
-
-
-private:
-
- //! Apply the postprocess step to a given submesh
- bool MakeVerboseFormat (aiMesh* pcMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_KILLNORMALPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/MaterialSystem.cpp b/src/3rdparty/assimp/code/MaterialSystem.cpp
deleted file mode 100644
index 55f1a4ff5..000000000
--- a/src/3rdparty/assimp/code/MaterialSystem.cpp
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MaterialSystem.cpp
- * @brief Implementation of the material system of the library
- */
-
-#include "Hash.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include "MaterialSystem.h"
-#include <assimp/types.h>
-#include <assimp/material.h>
-#include <assimp/DefaultLogger.hpp>
-#include "Macros.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Get a specific property from a material
-aiReturn aiGetMaterialProperty(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- const aiMaterialProperty** pPropOut)
-{
- ai_assert (pMat != NULL);
- ai_assert (pKey != NULL);
- ai_assert (pPropOut != NULL);
-
- /* Just search for a property with exactly this name ..
- * could be improved by hashing, but it's possibly
- * no worth the effort (we're bound to C structures,
- * thus std::map or derivates are not applicable. */
- for ( unsigned int i = 0; i < pMat->mNumProperties; ++i ) {
- aiMaterialProperty* prop = pMat->mProperties[i];
-
- if (prop /* just for safety ... */
- && 0 == strcmp( prop->mKey.data, pKey )
- && (UINT_MAX == type || prop->mSemantic == type) /* UINT_MAX is a wildcard, but this is undocumented :-) */
- && (UINT_MAX == index || prop->mIndex == index))
- {
- *pPropOut = pMat->mProperties[i];
- return AI_SUCCESS;
- }
- }
- *pPropOut = NULL;
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get an array of floating-point values from the material.
-aiReturn aiGetMaterialFloatArray(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- ai_real* pOut,
- unsigned int* pMax)
-{
- ai_assert (pOut != NULL);
- ai_assert (pMat != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index, (const aiMaterialProperty**) &prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- // data is given in floats, convert to ai_real
- unsigned int iWrite = 0;
- if( aiPTI_Float == prop->mType || aiPTI_Buffer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(float);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<ai_real> ( reinterpret_cast<float*>(prop->mData)[a] );
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // data is given in doubles, convert to float
- else if( aiPTI_Double == prop->mType) {
- iWrite = prop->mDataLength / sizeof(double);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<ai_real> ( reinterpret_cast<double*>(prop->mData)[a] );
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // data is given in ints, convert to float
- else if( aiPTI_Integer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(int32_t);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<ai_real> ( reinterpret_cast<int32_t*>(prop->mData)[a] );
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // a string ... read floats separated by spaces
- else {
- if (pMax) {
- iWrite = *pMax;
- }
- // strings are zero-terminated with a 32 bit length prefix, so this is safe
- const char *cur = prop->mData + 4;
- ai_assert( prop->mDataLength >= 5 );
- ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
- for ( unsigned int a = 0; ;++a) {
- cur = fast_atoreal_move<ai_real>(cur,pOut[a]);
- if ( a==iWrite-1 ) {
- break;
- }
- if ( !IsSpace(*cur) ) {
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " is a string; failed to parse a float array out of it.");
- return AI_FAILURE;
- }
- }
-
- if (pMax) {
- *pMax = iWrite;
- }
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get an array if integers from the material
-aiReturn aiGetMaterialIntegerArray(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- int* pOut,
- unsigned int* pMax)
-{
- ai_assert (pOut != NULL);
- ai_assert (pMat != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**) &prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- // data is given in ints, simply copy it
- unsigned int iWrite = 0;
- if( aiPTI_Integer == prop->mType || aiPTI_Buffer == prop->mType) {
- iWrite = prop->mDataLength / sizeof(int32_t);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<int>(reinterpret_cast<int32_t*>(prop->mData)[a]);
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // data is given in floats convert to int
- else if( aiPTI_Float == prop->mType) {
- iWrite = prop->mDataLength / sizeof(float);
- if (pMax) {
- iWrite = std::min(*pMax,iWrite); ;
- }
- for (unsigned int a = 0; a < iWrite;++a) {
- pOut[a] = static_cast<int>(reinterpret_cast<float*>(prop->mData)[a]);
- }
- if (pMax) {
- *pMax = iWrite;
- }
- }
- // it is a string ... no way to read something out of this
- else {
- if (pMax) {
- iWrite = *pMax;
- }
- // strings are zero-terminated with a 32 bit length prefix, so this is safe
- const char *cur = prop->mData+4;
- ai_assert( prop->mDataLength >= 5 );
- ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
- for (unsigned int a = 0; ;++a) {
- pOut[a] = strtol10(cur,&cur);
- if(a==iWrite-1) {
- break;
- }
- if(!IsSpace(*cur)) {
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " is a string; failed to parse an integer array out of it.");
- return AI_FAILURE;
- }
- }
-
- if (pMax) {
- *pMax = iWrite;
- }
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a color (3 or 4 floats) from the material
-aiReturn aiGetMaterialColor(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiColor4D* pOut)
-{
- unsigned int iMax = 4;
- const aiReturn eRet = aiGetMaterialFloatArray(pMat,pKey,type,index,(ai_real*)pOut,&iMax);
-
- // if no alpha channel is defined: set it to 1.0
- if (3 == iMax) {
- pOut->a = 1.0;
- }
-
- return eRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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,(ai_real*)pOut,&iMax);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a string from the material
-aiReturn aiGetMaterialString(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiString* pOut)
-{
- ai_assert (pOut != NULL);
-
- const aiMaterialProperty* prop;
- aiGetMaterialProperty(pMat,pKey,type,index,(const aiMaterialProperty**)&prop);
- if (!prop) {
- return AI_FAILURE;
- }
-
- if( aiPTI_String == prop->mType) {
- ai_assert(prop->mDataLength>=5);
-
- // The string is stored as 32 but length prefix followed by zero-terminated UTF8 data
- pOut->length = static_cast<unsigned int>(*reinterpret_cast<uint32_t*>(prop->mData));
-
- ai_assert( pOut->length+1+4==prop->mDataLength );
- ai_assert( !prop->mData[ prop->mDataLength - 1 ] );
- memcpy(pOut->data,prop->mData+4,pOut->length+1);
- }
- else {
- // TODO - implement lexical cast as well
- DefaultLogger::get()->error("Material property" + std::string(pKey) +
- " was found, but is no string" );
- return AI_FAILURE;
- }
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the number of textures on a particular texture stack
-ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
- C_ENUM aiTextureType type)
-{
- ai_assert (pMat != NULL);
-
- // Textures are always stored with ascending indices (ValidateDS provides a check, so we don't need to do it again)
- unsigned int max = 0;
- for (unsigned int i = 0; i < pMat->mNumProperties;++i) {
- aiMaterialProperty* prop = pMat->mProperties[i];
-
- if ( prop /* just a sanity check ... */
- && 0 == strcmp( prop->mKey.data, _AI_MATKEY_TEXTURE_BASE )
- && prop->mSemantic == type) {
-
- max = std::max(max,prop->mIndex+1);
- }
- }
- return max;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
- aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* _mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- ai_real* blend /*= NULL*/,
- aiTextureOp* op /*= NULL*/,
- aiTextureMapMode* mapmode /*= NULL*/,
- unsigned int* flags /*= NULL*/
- )
-{
- ai_assert(NULL != mat && NULL != path);
-
- // Get the path to the texture
- if (AI_SUCCESS != aiGetMaterialString(mat,AI_MATKEY_TEXTURE(type,index),path)) {
- return AI_FAILURE;
- }
- // Determine mapping type
- aiTextureMapping mapping = aiTextureMapping_UV;
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPING(type,index),(int*)&mapping);
- if (_mapping)
- *_mapping = mapping;
-
- // Get UV index
- if (aiTextureMapping_UV == mapping && uvindex) {
- aiGetMaterialInteger(mat,AI_MATKEY_UVWSRC(type,index),(int*)uvindex);
- }
- // Get blend factor
- if (blend) {
- aiGetMaterialFloat(mat,AI_MATKEY_TEXBLEND(type,index),blend);
- }
- // Get texture operation
- if (op){
- aiGetMaterialInteger(mat,AI_MATKEY_TEXOP(type,index),(int*)op);
- }
- // Get texture mapping modes
- if (mapmode) {
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U(type,index),(int*)&mapmode[0]);
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V(type,index),(int*)&mapmode[1]);
- }
- // Get texture flags
- if (flags){
- aiGetMaterialInteger(mat,AI_MATKEY_TEXFLAGS(type,index),(int*)flags);
- }
- return AI_SUCCESS;
-}
-
-static const unsigned int DefaultNumAllocated = 5;
-
-// ------------------------------------------------------------------------------------------------
-// Construction. Actually the one and only way to get an aiMaterial instance
-aiMaterial::aiMaterial()
-: mProperties( NULL )
-, mNumProperties( 0 )
-, mNumAllocated( DefaultNumAllocated ) {
- // Allocate 5 entries by default
- mProperties = new aiMaterialProperty*[ DefaultNumAllocated ];
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial::~aiMaterial()
-{
- Clear();
-
- delete[] mProperties;
-}
-
-// ------------------------------------------------------------------------------------------------
-void aiMaterial::Clear()
-{
- for (unsigned int i = 0; i < mNumProperties;++i) {
- // delete this entry
- delete mProperties[i];
- AI_DEBUG_INVALIDATE_PTR(mProperties[i]);
- }
- mNumProperties = 0;
-
- // The array remains allocated, we just invalidated its contents
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn aiMaterial::RemoveProperty (const char* pKey,unsigned int type,
- unsigned int index
- )
-{
- ai_assert(NULL != pKey);
-
- for (unsigned int i = 0; i < mNumProperties;++i) {
- aiMaterialProperty* prop = mProperties[i];
-
- if (prop && !strcmp( prop->mKey.data, pKey ) &&
- prop->mSemantic == type && prop->mIndex == index)
- {
- // Delete this entry
- delete mProperties[i];
-
- // collapse the array behind --.
- --mNumProperties;
- for (unsigned int a = i; a < mNumProperties;++a) {
- mProperties[a] = mProperties[a+1];
- }
- return AI_SUCCESS;
- }
- }
-
- return AI_FAILURE;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
- unsigned int pSizeInBytes,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- aiPropertyTypeInfo pType
- )
-{
- ai_assert (pInput != NULL);
- ai_assert (pKey != NULL);
- ai_assert (0 != pSizeInBytes);
-
- if ( 0 == pSizeInBytes ) {
-
- }
- // first search the list whether there is already an entry with this key
- unsigned int iOutIndex = UINT_MAX;
- for (unsigned int i = 0; i < mNumProperties;++i) {
- aiMaterialProperty* prop = mProperties[i];
-
- if (prop /* just for safety */ && !strcmp( prop->mKey.data, pKey ) &&
- prop->mSemantic == type && prop->mIndex == index){
-
- delete mProperties[i];
- iOutIndex = i;
- }
- }
-
- // Allocate a new material property
- aiMaterialProperty* pcNew = new aiMaterialProperty();
-
- // .. and fill it
- pcNew->mType = pType;
- pcNew->mSemantic = type;
- pcNew->mIndex = index;
-
- pcNew->mDataLength = pSizeInBytes;
- pcNew->mData = new char[pSizeInBytes];
- memcpy (pcNew->mData,pInput,pSizeInBytes);
-
- pcNew->mKey.length = ::strlen(pKey);
- ai_assert ( MAXLEN > pcNew->mKey.length);
- strcpy( pcNew->mKey.data, pKey );
-
- if (UINT_MAX != iOutIndex) {
- mProperties[iOutIndex] = pcNew;
- return AI_SUCCESS;
- }
-
- // resize the array ... double the storage allocated
- if (mNumProperties == mNumAllocated) {
- const unsigned int iOld = mNumAllocated;
- mNumAllocated *= 2;
-
- aiMaterialProperty** ppTemp;
- try {
- ppTemp = new aiMaterialProperty*[mNumAllocated];
- } catch (std::bad_alloc&) {
- delete pcNew;
- return AI_OUTOFMEMORY;
- }
-
- // just copy all items over; then replace the old array
- memcpy (ppTemp,mProperties,iOld * sizeof(void*));
-
- delete[] mProperties;
- mProperties = ppTemp;
- }
- // push back ...
- mProperties[mNumProperties++] = pcNew;
- return AI_SUCCESS;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiReturn aiMaterial::AddProperty (const aiString* pInput,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- // We don't want to add the whole buffer .. write a 32 bit length
- // prefix followed by the zero-terminated UTF8 string.
- // (HACK) I don't want to break the ABI now, but we definitely
- // ought to change aiString::mLength to uint32_t one day.
- if (sizeof(size_t) == 8) {
- aiString copy = *pInput;
- uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
- s[1] = static_cast<uint32_t>(pInput->length);
-
- return AddBinaryProperty(s+1,
- static_cast<unsigned int>(pInput->length+1+4),
- pKey,
- type,
- index,
- aiPTI_String);
- }
- ai_assert(sizeof(size_t)==4);
- return AddBinaryProperty(pInput,
- static_cast<unsigned int>(pInput->length+1+4),
- pKey,
- type,
- index,
- aiPTI_String);
-}
-
-// ------------------------------------------------------------------------------------------------
-uint32_t Assimp::ComputeMaterialHash(const aiMaterial* mat, bool includeMatName /*= false*/)
-{
- uint32_t hash = 1503; // magic start value, chosen to be my birthday :-)
- for ( unsigned int i = 0; i < mat->mNumProperties; ++i ) {
- aiMaterialProperty* prop;
-
- // Exclude all properties whose first character is '?' from the hash
- // See doc for aiMaterialProperty.
- if ((prop = mat->mProperties[i]) && (includeMatName || prop->mKey.data[0] != '?')) {
-
- hash = SuperFastHash(prop->mKey.data,(unsigned int)prop->mKey.length,hash);
- hash = SuperFastHash(prop->mData,prop->mDataLength,hash);
-
- // Combine the semantic and the index with the hash
- hash = SuperFastHash((const char*)&prop->mSemantic,sizeof(unsigned int),hash);
- hash = SuperFastHash((const char*)&prop->mIndex,sizeof(unsigned int),hash);
- }
- }
- return hash;
-}
-
-// ------------------------------------------------------------------------------------------------
-void aiMaterial::CopyPropertyList(aiMaterial* pcDest,
- const aiMaterial* pcSrc
- )
-{
- ai_assert(NULL != pcDest);
- ai_assert(NULL != pcSrc);
-
- unsigned int iOldNum = pcDest->mNumProperties;
- pcDest->mNumAllocated += pcSrc->mNumAllocated;
- pcDest->mNumProperties += pcSrc->mNumProperties;
-
- aiMaterialProperty** pcOld = pcDest->mProperties;
- pcDest->mProperties = new aiMaterialProperty*[pcDest->mNumAllocated];
-
- if (iOldNum && pcOld) {
- for (unsigned int i = 0; i < iOldNum;++i) {
- pcDest->mProperties[i] = pcOld[i];
- }
- }
-
- if ( pcOld ) {
- delete[] pcOld;
- }
-
- for (unsigned int i = iOldNum; i< pcDest->mNumProperties;++i) {
- aiMaterialProperty* propSrc = pcSrc->mProperties[i];
-
- // search whether we have already a property with this name -> if yes, overwrite it
- aiMaterialProperty* prop;
- for ( unsigned int q = 0; q < iOldNum; ++q ) {
- prop = pcDest->mProperties[q];
- if (prop /* just for safety */ && prop->mKey == propSrc->mKey && prop->mSemantic == propSrc->mSemantic
- && prop->mIndex == propSrc->mIndex) {
- delete prop;
-
- // collapse the whole array ...
- memmove(&pcDest->mProperties[q],&pcDest->mProperties[q+1],i-q);
- i--;
- pcDest->mNumProperties--;
- }
- }
-
- // Allocate the output property and copy the source property
- prop = pcDest->mProperties[i] = new aiMaterialProperty();
- prop->mKey = propSrc->mKey;
- prop->mDataLength = propSrc->mDataLength;
- prop->mType = propSrc->mType;
- prop->mSemantic = propSrc->mSemantic;
- prop->mIndex = propSrc->mIndex;
-
- prop->mData = new char[propSrc->mDataLength];
- memcpy(prop->mData,propSrc->mData,prop->mDataLength);
- }
-}
diff --git a/src/3rdparty/assimp/code/MaterialSystem.h b/src/3rdparty/assimp/code/MaterialSystem.h
deleted file mode 100644
index b083a5bb8..000000000
--- a/src/3rdparty/assimp/code/MaterialSystem.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MaterialSystem.h
- * Now that #MaterialHelper is gone, this file only contains some
- * internal material utility functions.
- */
-#ifndef AI_MATERIALSYSTEM_H_INC
-#define AI_MATERIALSYSTEM_H_INC
-
-#include <stdint.h>
-
-struct aiMaterial;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------
-/** Computes a hash (hopefully unique) from all material properties
- * The hash value reflects the current property state, so if you add any
- * property and call this method again, the resulting hash value will be
- * different. The hash is not persistent across different builds and platforms.
- *
- * @param includeMatName Set to 'true' to take all properties with
- * '?' as initial character in their name into account.
- * Currently #AI_MATKEY_NAME is the only example.
- * @return 32 Bit jash value for the material
- */
-uint32_t ComputeMaterialHash(const aiMaterial* mat, bool includeMatName = false);
-
-
-} // ! namespace Assimp
-
-#endif //!! AI_MATERIALSYSTEM_H_INC
diff --git a/src/3rdparty/assimp/code/MathFunctions.h b/src/3rdparty/assimp/code/MathFunctions.h
deleted file mode 100644
index cb3b69607..000000000
--- a/src/3rdparty/assimp/code/MathFunctions.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2016, 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 MathFunctions.h
- * @brief Implementation of the math functions (gcd and lcm)
- *
- * Copied from BoostWorkaround/math
- */
-
-namespace Assimp {
-namespace Math {
-
-// TODO: use binary GCD for unsigned integers ....
-template < typename IntegerType >
-IntegerType gcd( IntegerType a, IntegerType b )
-{
- const IntegerType zero = (IntegerType)0;
- while ( true )
- {
- if ( a == zero )
- return b;
- b %= a;
-
- if ( b == zero )
- return a;
- a %= b;
- }
-}
-
-template < typename IntegerType >
-IntegerType lcm( IntegerType a, IntegerType b )
-{
- const IntegerType t = gcd (a,b);
- if (!t)return t;
- return a / t * b;
-}
-
-}
-}
diff --git a/src/3rdparty/assimp/code/MemoryIOWrapper.h b/src/3rdparty/assimp/code/MemoryIOWrapper.h
deleted file mode 100644
index 9bd245337..000000000
--- a/src/3rdparty/assimp/code/MemoryIOWrapper.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 MemoryIOWrapper.h
- * Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
-#ifndef AI_MEMORYIOSTREAM_H_INC
-#define AI_MEMORYIOSTREAM_H_INC
-
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/ai_assert.h>
-#include <stdint.h>
-
-namespace Assimp {
-#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
-#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
-
-// ----------------------------------------------------------------------------------
-/** Implementation of IOStream to read directly from a memory buffer */
-// ----------------------------------------------------------------------------------
-class MemoryIOStream : public IOStream
-{
- //friend class MemoryIOSystem;
-public:
- 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;
- }
- }
-
- // -------------------------------------------------------------------
- // Read from stream
- size_t Read(void* pvBuffer, size_t pSize, size_t pCount) {
- const size_t cnt = std::min(pCount,(length-pos)/pSize),ofs = pSize*cnt;
-
- memcpy(pvBuffer,buffer+pos,ofs);
- pos += ofs;
-
- return cnt;
- }
-
- // -------------------------------------------------------------------
- // Write to stream
- size_t Write(const void* /*pvBuffer*/, size_t /*pSize*/,size_t /*pCount*/) {
- ai_assert(false); // won't be needed
- return 0;
- }
-
- // -------------------------------------------------------------------
- // Seek specific position
- aiReturn Seek(size_t pOffset, aiOrigin pOrigin) {
- if (aiOrigin_SET == pOrigin) {
- if (pOffset >= length) {
- return AI_FAILURE;
- }
- pos = pOffset;
- }
- else if (aiOrigin_END == pOrigin) {
- if (pOffset >= length) {
- return AI_FAILURE;
- }
- pos = length-pOffset;
- }
- else {
- if (pOffset+pos >= length) {
- return AI_FAILURE;
- }
- pos += pOffset;
- }
- return AI_SUCCESS;
- }
-
- // -------------------------------------------------------------------
- // Get current seek position
- size_t Tell() const {
- return pos;
- }
-
- // -------------------------------------------------------------------
- // Get size of file
- size_t FileSize() const {
- return length;
- }
-
- // -------------------------------------------------------------------
- // Flush file contents
- void Flush() {
- ai_assert(false); // won't be needed
- }
-
-private:
- const uint8_t* buffer;
- size_t length,pos;
- bool own;
-};
-
-// ---------------------------------------------------------------------------
-/** Dummy IO system to read from a memory buffer */
-class MemoryIOSystem : public IOSystem
-{
-public:
- /** Constructor. */
- MemoryIOSystem (const uint8_t* buff, size_t len)
- : buffer (buff), length(len) {
- }
-
- /** Destructor. */
- ~MemoryIOSystem() {
- }
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const {
- return !strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH);
- }
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const {
- return '/'; // why not? it doesn't care
- }
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* /*pMode*/ = "rb") {
- if (strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
- return NULL;
- }
- return new MemoryIOStream(buffer,length);
- }
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* pFile) {
- delete pFile;
- }
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* /*one*/, const char* /*second*/) const {
- return false;
- }
-
-private:
- const uint8_t* buffer;
- size_t length;
-};
-} // end namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/NDOLoader.cpp b/src/3rdparty/assimp/code/NDOLoader.cpp
deleted file mode 100644
index 2586bac3e..000000000
--- a/src/3rdparty/assimp/code/NDOLoader.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 NDOLoader.cpp
- * Implementation of the NDO importer class.
- */
-
-
-#ifndef ASSIMP_BUILD_NO_NDO_IMPORTER
-#include "NDOLoader.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include "StreamReader.h"
-#include <map>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Nendo Mesh Importer",
- "",
- "",
- "http://www.izware.com/nendo/index.htm",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "ndo"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-NDOImporter::NDOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-NDOImporter::~NDOImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool NDOImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- const std::string extension = GetExtension(pFile);
-
- if( extension == "ndo")
- return true;
-
- if ((checkSig || !extension.length()) && pIOHandler) {
- const char* tokens[] = {"nendo"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,5);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-const aiImporterDesc* NDOImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void NDOImporter::SetupProperties(const Importer* /*pImp*/)
-{
- // nothing to be done for the moment
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void NDOImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
-
- // first 9 bytes are nendo file format ("nendo 1.n")
- const char* head = (const char*)reader.GetPtr();
- reader.IncPtr(9);
-
- if (strncmp("nendo ",head,6)) {
- throw DeadlyImportError("Not a Nendo file; magic signature missing");
- }
- // check if this is a supported version. if not, continue, too -- users,
- // please don't complain if it doesn't work then ...
- unsigned int file_format = 12;
- if (!strncmp("1.0",head+6,3)) {
- file_format = 10;
- DefaultLogger::get()->info("NDO file format is 1.0");
- }
- else if (!strncmp("1.1",head+6,3)) {
- file_format = 11;
- DefaultLogger::get()->info("NDO file format is 1.1");
- }
- else if (!strncmp("1.2",head+6,3)) {
- file_format = 12;
- DefaultLogger::get()->info("NDO file format is 1.2");
- }
- else {
- DefaultLogger::get()->warn(std::string("Unrecognized nendo file format version, continuing happily ... :") + (head+6));
- }
-
- reader.IncPtr(2); /* skip flags */
- if (file_format >= 12) {
- reader.IncPtr(2);
- }
- unsigned int temp = reader.GetU1();
-
- std::vector<Object> objects(temp); /* buffer to store all the loaded objects in */
-
- // read all objects
- for (unsigned int o = 0; o < objects.size(); ++o) {
-
-// if (file_format < 12) {
- if (!reader.GetI1()) {
- continue; /* skip over empty object */
- }
- // reader.GetI2();
-// }
- Object& obj = objects[o];
-
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- head = (const char*)reader.GetPtr();
- reader.IncPtr(temp + 76); /* skip unknown stuff */
-
- obj.name = std::string(head, temp);
-
- // read edge table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.edges.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.edges.push_back(Edge());
- Edge& edge = obj.edges.back();
-
- for (unsigned int i = 0; i< 8; ++i) {
- edge.edge[i] = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
- edge.hard = file_format >= 11 ? reader.GetU1() : 0;
- for (unsigned int i = 0; i< 8; ++i) {
- edge.color[i] = reader.GetU1();
- }
- }
-
- // read face table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.faces.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.faces.push_back(Face());
- Face& face = obj.faces.back();
-
- face.elem = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- // read vertex table
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- obj.vertices.reserve(temp);
- for (unsigned int e = 0; e < temp; ++e) {
-
- obj.vertices.push_back(Vertex());
- Vertex& v = obj.vertices.back();
-
- v.num = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- v.val.x = reader.GetF4();
- v.val.y = reader.GetF4();
- v.val.z = reader.GetF4();
- }
-
- // read UVs
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- for (unsigned int e = 0; e < temp; ++e) {
- file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- temp = file_format >= 12 ? reader.GetU4() : reader.GetU2();
- for (unsigned int e = 0; e < temp; ++e) {
- file_format >= 12 ? reader.GetU4() : reader.GetU2();
- }
-
- if (reader.GetU1()) {
- const unsigned int x = reader.GetU2(), y = reader.GetU2();
- temp = 0;
- while (temp < x*y) {
- unsigned int repeat = reader.GetU1();
- reader.GetU1();
- reader.GetU1();
- reader.GetU1();
- temp += repeat;
- }
- }
- }
-
- // construct a dummy node graph and add all named objects as child nodes
- aiNode* root = pScene->mRootNode = new aiNode("$NDODummyRoot");
- aiNode** cc = root->mChildren = new aiNode* [ root->mNumChildren = static_cast<unsigned int>( objects.size()) ] ();
- pScene->mMeshes = new aiMesh* [ root->mNumChildren] ();
-
- std::vector<aiVector3D> vertices;
- std::vector<unsigned int> indices;
-
- for(const Object& obj : objects) {
- aiNode* nd = *cc++ = new aiNode(obj.name);
- nd->mParent = root;
-
- // translated from a python dict() - a vector might be sufficient as well
- typedef std::map<unsigned int, unsigned int> FaceTable;
- FaceTable face_table;
-
- unsigned int n = 0;
- for(const Edge& edge : obj.edges) {
-
- face_table[edge.edge[2]] = n;
- face_table[edge.edge[3]] = n;
-
- ++n;
- }
-
- aiMesh* mesh = new aiMesh();
- mesh->mNumFaces=static_cast<unsigned int>(face_table.size());
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- vertices.clear();
- vertices.reserve(4 * face_table.size()); // arbitrarily chosen
- for(FaceTable::value_type& v : face_table) {
- indices.clear();
-
- aiFace& f = *faces++;
-
- const unsigned int key = v.first;
- unsigned int cur_edge = v.second;
- while (1) {
- unsigned int next_edge, next_vert;
- if (key == obj.edges[cur_edge].edge[3]) {
- next_edge = obj.edges[cur_edge].edge[5];
- next_vert = obj.edges[cur_edge].edge[1];
- }
- else {
- next_edge = obj.edges[cur_edge].edge[4];
- next_vert = obj.edges[cur_edge].edge[0];
- }
- indices.push_back( static_cast<unsigned int>(vertices.size()) );
- vertices.push_back(obj.vertices[ next_vert ].val);
-
- cur_edge = next_edge;
- if (cur_edge == v.second) {
- break;
- }
- }
-
- f.mIndices = new unsigned int[f.mNumIndices = static_cast<unsigned int>(indices.size())];
- std::copy(indices.begin(),indices.end(),f.mIndices);
- }
-
- mesh->mVertices = new aiVector3D[mesh->mNumVertices = static_cast<unsigned int>(vertices.size())];
- std::copy(vertices.begin(),vertices.end(),mesh->mVertices);
-
- if (mesh->mNumVertices) {
- pScene->mMeshes[pScene->mNumMeshes] = mesh;
-
- (nd->mMeshes = new unsigned int[nd->mNumMeshes=1])[0]=pScene->mNumMeshes++;
- }else
- delete mesh;
- }
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/NDOLoader.h b/src/3rdparty/assimp/code/NDOLoader.h
deleted file mode 100644
index 4fd315691..000000000
--- a/src/3rdparty/assimp/code/NDOLoader.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2008, 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 NDOLoader.h
- * Declaration of the Nendo importer class.
- */
-#ifndef INCLUDED_AI_NDO_LOADER_H
-#define INCLUDED_AI_NDO_LOADER_H
-
-#include <assimp/vector3.h>
-#include "BaseImporter.h"
-#include <stdint.h>
-#include <string>
-#include <vector>
-
-
-struct aiImporterDesc;
-struct aiScene;
-
-namespace Assimp {
- class IOSystem;
- class Importer;
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load meshes from Nendo.
- *
- * Basing on
- * <blender>/blender/release/scripts/nendo_import.py by Anthony D'Agostino.
-*/
-class NDOImporter : public BaseImporter
-{
-public:
- NDOImporter();
- ~NDOImporter();
-
-
-public:
-
- //! Represents a single edge
- struct Edge
- {
- unsigned int edge[8];
- unsigned int hard;
- uint8_t color[8];
- };
-
- //! Represents a single face
- struct Face
- {
- unsigned int elem;
- };
-
- struct Vertex
- {
- unsigned int num;
- aiVector3D val;
- };
-
- //! Represents a single object
- struct Object
- {
- std::string name;
-
- std::vector<Edge> edges;
- std::vector<Face> faces;
- std::vector<Vertex> vertices;
- };
-
- // -------------------------------------------------------------------
- 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:
-
-}; // end of class NDOImporter
-} // end of namespace Assimp
-#endif // INCLUDED_AI_NDO_LOADER_H
diff --git a/src/3rdparty/assimp/code/NFFLoader.cpp b/src/3rdparty/assimp/code/NFFLoader.cpp
deleted file mode 100644
index a51c500f1..000000000
--- a/src/3rdparty/assimp/code/NFFLoader.cpp
+++ /dev/null
@@ -1,1276 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the STL importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_NFF_IMPORTER
-
-// internal headers
-#include "NFFLoader.h"
-#include "ParsingUtils.h"
-#include "StandardShapes.h"
-#include "qnan.h"
-#include "fast_atof.h"
-#include "RemoveComments.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Neutral File Format Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "enff nff"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-NFFImporter::NFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-NFFImporter::~NFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool NFFImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"nff","enff");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get the list of all supported file extensions
-const aiImporterDesc* NFFImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_FLOAT(f) \
- SkipSpaces(&sz); \
- if (!::IsLineEnd(*sz))sz = fast_atoreal_move<float>(sz, (float&)f);
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_TRIPLE(v) \
- AI_NFF_PARSE_FLOAT(v[0]) \
- AI_NFF_PARSE_FLOAT(v[1]) \
- AI_NFF_PARSE_FLOAT(v[2])
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF_PARSE_SHAPE_INFORMATION() \
- aiVector3D center, radius(1.0f,get_qnan(),get_qnan()); \
- AI_NFF_PARSE_TRIPLE(center); \
- AI_NFF_PARSE_TRIPLE(radius); \
- if (is_qnan(radius.z))radius.z = radius.x; \
- if (is_qnan(radius.y))radius.y = radius.x; \
- currentMesh.radius = radius; \
- currentMesh.center = center;
-
-// ------------------------------------------------------------------------------------------------
-#define AI_NFF2_GET_NEXT_TOKEN() \
- do \
- { \
- if (!GetNextLine(buffer,line)) \
- {DefaultLogger::get()->warn("NFF2: Unexpected EOF, can't read next token");break;} \
- SkipSpaces(line,&sz); \
- } \
- while(IsLineEnd(*sz))
-
-
-// ------------------------------------------------------------------------------------------------
-// Loads the materail table for the NFF2 file format from an external file
-void NFFImporter::LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
- const std::string& path, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( path, "rb"));
-
- // Check whether we can read from the file
- if( !file.get()) {
- DefaultLogger::get()->error("NFF2: Unable to open material library " + path + ".");
- return;
- }
-
- // get the size of the file
- const unsigned int m = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2(m+1);
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // First of all: remove all comments from the file
- CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
-
- // The file should start with the magic sequence "mat"
- if (!TokenMatch(buffer,"mat",3)) {
- DefaultLogger::get()->error("NFF2: Not a valid material library " + path + ".");
- return;
- }
-
- ShadingInfo* curShader = NULL;
-
- // No read the file line per line
- char line[4096];
- const char* sz;
- while (GetNextLine(buffer,line))
- {
- SkipSpaces(line,&sz);
-
- // 'version' defines the version of the file format
- if (TokenMatch(sz,"version",7))
- {
- DefaultLogger::get()->info("NFF (Sense8) material library file format: " + std::string(sz));
- }
- // 'matdef' starts a new material in the file
- else if (TokenMatch(sz,"matdef",6))
- {
- // add a new material to the list
- output.push_back( ShadingInfo() );
- curShader = & output.back();
-
- // parse the name of the material
- }
- else if (!TokenMatch(sz,"valid",5))
- {
- // check whether we have an active material at the moment
- if (!IsLineEnd(*sz))
- {
- if (!curShader)
- {
- DefaultLogger::get()->error(std::string("NFF2 material library: Found element ") +
- sz + "but there is no active material");
- continue;
- }
- }
- else continue;
-
- // now read the material property and determine its type
- aiColor3D c;
- if (TokenMatch(sz,"ambient",7))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->ambient = c;
- }
- else if (TokenMatch(sz,"diffuse",7) || TokenMatch(sz,"ambientdiffuse",14) /* correct? */)
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->diffuse = curShader->ambient = c;
- }
- else if (TokenMatch(sz,"specular",8))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->specular = c;
- }
- else if (TokenMatch(sz,"emission",8))
- {
- AI_NFF_PARSE_TRIPLE(c);
- curShader->emissive = c;
- }
- else if (TokenMatch(sz,"shininess",9))
- {
- AI_NFF_PARSE_FLOAT(curShader->shininess);
- }
- else if (TokenMatch(sz,"opacity",7))
- {
- AI_NFF_PARSE_FLOAT(curShader->opacity);
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void NFFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( !file.get())
- throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // mesh arrays - separate here to make the handling of the pointers below easier.
- std::vector<MeshInfo> meshes;
- std::vector<MeshInfo> meshesWithNormals;
- std::vector<MeshInfo> meshesWithUVCoords;
- std::vector<MeshInfo> meshesLocked;
-
- char line[4096];
- const char* sz;
-
- // camera parameters
- aiVector3D camPos, camUp(0.f,1.f,0.f), camLookAt(0.f,0.f,1.f);
- float angle = 45.f;
- aiVector2D resolution;
-
- bool hasCam = false;
-
- MeshInfo* currentMeshWithNormals = NULL;
- MeshInfo* currentMesh = NULL;
- MeshInfo* currentMeshWithUVCoords = NULL;
-
- ShadingInfo s; // current material info
-
- // degree of tesselation
- unsigned int iTesselation = 4;
-
- // some temporary variables we need to parse the file
- unsigned int sphere = 0,
- cylinder = 0,
- cone = 0,
- numNamed = 0,
- dodecahedron = 0,
- octahedron = 0,
- tetrahedron = 0,
- hexahedron = 0;
-
- // lights imported from the file
- std::vector<Light> lights;
-
- // check whether this is the NFF2 file format
- if (TokenMatch(buffer,"nff",3))
- {
- const float qnan = get_qnan();
- const aiColor4D cQNAN = aiColor4D (qnan,0.f,0.f,1.f);
- const aiVector3D vQNAN = aiVector3D(qnan,0.f,0.f);
-
- // another NFF file format ... just a raw parser has been implemented
- // no support for further details, I don't think it is worth the effort
- // http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/nff/nff2.html
- // http://www.netghost.narod.ru/gff/graphics/summary/sense8.htm
-
- // First of all: remove all comments from the file
- CommentRemover::RemoveLineComments("//",&mBuffer2[0]);
-
- while (GetNextLine(buffer,line))
- {
- SkipSpaces(line,&sz);
- if (TokenMatch(sz,"version",7))
- {
- DefaultLogger::get()->info("NFF (Sense8) file format: " + std::string(sz));
- }
- else if (TokenMatch(sz,"viewpos",7))
- {
- AI_NFF_PARSE_TRIPLE(camPos);
- hasCam = true;
- }
- else if (TokenMatch(sz,"viewdir",7))
- {
- AI_NFF_PARSE_TRIPLE(camLookAt);
- hasCam = true;
- }
- // This starts a new object section
- else if (!IsSpaceOrNewLine(*sz))
- {
- unsigned int subMeshIdx = 0;
-
- // read the name of the object, skip all spaces
- // at the end of it.
- const char* sz3 = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- std::string objectName = std::string(sz3,(unsigned int)(sz-sz3));
-
- const unsigned int objStart = (unsigned int)meshes.size();
-
- // There could be a material table in a separate file
- std::vector<ShadingInfo> materialTable;
- while (true)
- {
- AI_NFF2_GET_NEXT_TOKEN();
-
- // material table - an external file
- if (TokenMatch(sz,"mtable",6))
- {
- SkipSpaces(&sz);
- sz3 = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- const unsigned int diff = (unsigned int)(sz-sz3);
- if (!diff)DefaultLogger::get()->warn("NFF2: Found empty mtable token");
- else
- {
- // The material table has the file extension .mat.
- // If it is not there, we need to append it
- std::string path = std::string(sz3,diff);
- if(std::string::npos == path.find_last_of(".mat"))
- {
- path.append(".mat");
- }
-
- // Now extract the working directory from the path to
- // this file and append the material library filename
- // to it.
- std::string::size_type s;
- if ((std::string::npos == (s = path.find_last_of('\\')) || !s) &&
- (std::string::npos == (s = path.find_last_of('/')) || !s) )
- {
- s = pFile.find_last_of('\\');
- if (std::string::npos == s)s = pFile.find_last_of('/');
- if (std::string::npos != s)
- {
- path = pFile.substr(0,s+1) + path;
- }
- }
- LoadNFF2MaterialTable(materialTable,path,pIOHandler);
- }
- }
- else break;
- }
-
- // read the numbr of vertices
- unsigned int num = ::strtoul10(sz,&sz);
-
- // temporary storage
- std::vector<aiColor4D> tempColors;
- std::vector<aiVector3D> tempPositions,tempTextureCoords,tempNormals;
-
- bool hasNormals = false,hasUVs = false,hasColor = false;
-
- tempPositions.reserve (num);
- tempColors.reserve (num);
- tempNormals.reserve (num);
- tempTextureCoords.reserve (num);
- for (unsigned int i = 0; i < num; ++i)
- {
- AI_NFF2_GET_NEXT_TOKEN();
- aiVector3D v;
- AI_NFF_PARSE_TRIPLE(v);
- tempPositions.push_back(v);
-
- // parse all other attributes in the line
- while (true)
- {
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))break;
-
- // color definition
- if (TokenMatch(sz,"0x",2))
- {
- hasColor = true;
- unsigned int numIdx = ::strtoul16(sz,&sz);
- aiColor4D clr;
- clr.a = 1.f;
-
- // 0xRRGGBB
- clr.r = ((numIdx >> 16u) & 0xff) / 255.f;
- clr.g = ((numIdx >> 8u) & 0xff) / 255.f;
- clr.b = ((numIdx) & 0xff) / 255.f;
- tempColors.push_back(clr);
- }
- // normal vector
- else if (TokenMatch(sz,"norm",4))
- {
- hasNormals = true;
- AI_NFF_PARSE_TRIPLE(v);
- tempNormals.push_back(v);
- }
- // UV coordinate
- else if (TokenMatch(sz,"uv",2))
- {
- hasUVs = true;
- AI_NFF_PARSE_FLOAT(v.x);
- AI_NFF_PARSE_FLOAT(v.y);
- v.z = 0.f;
- tempTextureCoords.push_back(v);
- }
- }
-
- // fill in dummies for all attributes that have not been set
- if (tempNormals.size() != tempPositions.size())
- tempNormals.push_back(vQNAN);
-
- if (tempTextureCoords.size() != tempPositions.size())
- tempTextureCoords.push_back(vQNAN);
-
- if (tempColors.size() != tempPositions.size())
- tempColors.push_back(cQNAN);
- }
-
- AI_NFF2_GET_NEXT_TOKEN();
- if (!num)throw DeadlyImportError("NFF2: There are zero vertices");
- num = ::strtoul10(sz,&sz);
-
- std::vector<unsigned int> tempIdx;
- tempIdx.reserve(10);
- for (unsigned int i = 0; i < num; ++i)
- {
- AI_NFF2_GET_NEXT_TOKEN();
- SkipSpaces(line,&sz);
- unsigned int numIdx = ::strtoul10(sz,&sz);
-
- // read all faces indices
- if (numIdx)
- {
- // mesh.faces.push_back(numIdx);
- // tempIdx.erase(tempIdx.begin(),tempIdx.end());
- tempIdx.resize(numIdx);
-
- for (unsigned int a = 0; a < numIdx;++a)
- {
- SkipSpaces(sz,&sz);
- unsigned int m = ::strtoul10(sz,&sz);
- if (m >= (unsigned int)tempPositions.size())
- {
- DefaultLogger::get()->error("NFF2: Vertex index overflow");
- m= 0;
- }
- // mesh.vertices.push_back (tempPositions[idx]);
- tempIdx[a] = m;
- }
- }
-
- // build a temporary shader object for the face.
- ShadingInfo shader;
- unsigned int matIdx = 0;
-
- // white material color - we have vertex colors
- shader.color = aiColor3D(1.f,1.f,1.f);
- aiColor4D c = aiColor4D(1.f,1.f,1.f,1.f);
- while (true)
- {
- SkipSpaces(sz,&sz);
- if(IsLineEnd(*sz))break;
-
- // per-polygon colors
- if (TokenMatch(sz,"0x",2))
- {
- hasColor = true;
- const char* sz2 = sz;
- numIdx = ::strtoul16(sz,&sz);
- const unsigned int diff = (unsigned int)(sz-sz2);
-
- // 0xRRGGBB
- if (diff > 3)
- {
- c.r = ((numIdx >> 16u) & 0xff) / 255.f;
- c.g = ((numIdx >> 8u) & 0xff) / 255.f;
- c.b = ((numIdx) & 0xff) / 255.f;
- }
- // 0xRGB
- else
- {
- c.r = ((numIdx >> 8u) & 0xf) / 16.f;
- c.g = ((numIdx >> 4u) & 0xf) / 16.f;
- c.b = ((numIdx) & 0xf) / 16.f;
- }
- }
- // TODO - implement texture mapping here
-#if 0
- // mirror vertex texture coordinate?
- else if (TokenMatch(sz,"mirror",6))
- {
- }
- // texture coordinate scaling
- else if (TokenMatch(sz,"scale",5))
- {
- }
- // texture coordinate translation
- else if (TokenMatch(sz,"trans",5))
- {
- }
- // texture coordinate rotation angle
- else if (TokenMatch(sz,"rot",3))
- {
- }
-#endif
-
- // texture file name for this polygon + mapping information
- else if ('_' == sz[0])
- {
- // get mapping information
- switch (sz[1])
- {
- case 'v':
- case 'V':
-
- shader.shaded = false;
- break;
-
- case 't':
- case 'T':
- case 'u':
- case 'U':
-
- DefaultLogger::get()->warn("Unsupported NFF2 texture attribute: trans");
- };
- if (!sz[1] || '_' != sz[2])
- {
- DefaultLogger::get()->warn("NFF2: Expected underscore after texture attributes");
- continue;
- }
- const char* sz2 = sz+3;
- while (!IsSpaceOrNewLine( *sz ))++sz;
- const unsigned int diff = (unsigned int)(sz-sz2);
- if (diff)shader.texFile = std::string(sz2,diff);
- }
-
- // Two-sided material?
- else if (TokenMatch(sz,"both",4))
- {
- shader.twoSided = true;
- }
-
- // Material ID?
- else if (!materialTable.empty() && TokenMatch(sz,"matid",5))
- {
- SkipSpaces(&sz);
- matIdx = ::strtoul10(sz,&sz);
- if (matIdx >= materialTable.size())
- {
- DefaultLogger::get()->error("NFF2: Material index overflow.");
- matIdx = 0;
- }
-
- // now combine our current shader with the shader we
- // read from the material table.
- ShadingInfo& mat = materialTable[matIdx];
- shader.ambient = mat.ambient;
- shader.diffuse = mat.diffuse;
- shader.emissive = mat.emissive;
- shader.opacity = mat.opacity;
- shader.specular = mat.specular;
- shader.shininess = mat.shininess;
- }
- else SkipToken(sz);
- }
-
- // search the list of all shaders we have for this object whether
- // there is an identical one. In this case, we append our mesh
- // data to it.
- MeshInfo* mesh = NULL;
- for (std::vector<MeshInfo>::iterator it = meshes.begin() + objStart, end = meshes.end();
- it != end; ++it)
- {
- if ((*it).shader == shader && (*it).matIndex == matIdx)
- {
- // we have one, we can append our data to it
- mesh = &(*it);
- }
- }
- if (!mesh)
- {
- meshes.push_back(MeshInfo(PatchType_Simple,false));
- mesh = &meshes.back();
- mesh->matIndex = matIdx;
-
- // We need to add a new mesh to the list. We assign
- // an unique name to it to make sure the scene will
- // pass the validation step for the moment.
- // TODO: fix naming of objects in the scenegraph later
- if (objectName.length())
- {
- ::strcpy(mesh->name,objectName.c_str());
- ASSIMP_itoa10(&mesh->name[objectName.length()],30,subMeshIdx++);
- }
-
- // copy the shader to the mesh.
- mesh->shader = shader;
- }
-
- // fill the mesh with data
- if (!tempIdx.empty())
- {
- mesh->faces.push_back((unsigned int)tempIdx.size());
- for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
- it != end;++it)
- {
- unsigned int m = *it;
-
- // copy colors -vertex color specifications override polygon color specifications
- if (hasColor)
- {
- const aiColor4D& clr = tempColors[m];
- mesh->colors.push_back((is_qnan( clr.r ) ? c : clr));
- }
-
- // positions should always be there
- mesh->vertices.push_back (tempPositions[m]);
-
- // copy normal vectors
- if (hasNormals)
- mesh->normals.push_back (tempNormals[m]);
-
- // copy texture coordinates
- if (hasUVs)
- mesh->uvs.push_back (tempTextureCoords[m]);
- }
- }
- }
- if (!num)throw DeadlyImportError("NFF2: There are zero faces");
- }
- }
- camLookAt = camLookAt + camPos;
- }
- else // "Normal" Neutral file format that is quite more common
- {
- while (GetNextLine(buffer,line))
- {
- sz = line;
- if ('p' == line[0] || TokenMatch(sz,"tpp",3))
- {
- MeshInfo* out = NULL;
-
- // 'tpp' - texture polygon patch primitive
- if ('t' == line[0])
- {
- currentMeshWithUVCoords = NULL;
- for (auto &mesh : meshesWithUVCoords)
- {
- if (mesh.shader == s)
- {
- currentMeshWithUVCoords = &mesh;
- break;
- }
- }
-
- if (!currentMeshWithUVCoords)
- {
- meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
- currentMeshWithUVCoords = &meshesWithUVCoords.back();
- currentMeshWithUVCoords->shader = s;
- }
- out = currentMeshWithUVCoords;
- }
- // 'pp' - polygon patch primitive
- else if ('p' == line[1])
- {
- currentMeshWithNormals = NULL;
- for (auto &mesh : meshesWithNormals)
- {
- if (mesh.shader == s)
- {
- currentMeshWithNormals = &mesh;
- break;
- }
- }
-
- if (!currentMeshWithNormals)
- {
- meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
- currentMeshWithNormals = &meshesWithNormals.back();
- currentMeshWithNormals->shader = s;
- }
- sz = &line[2];out = currentMeshWithNormals;
- }
- // 'p' - polygon primitive
- else
- {
- currentMesh = NULL;
- for (auto &mesh : meshes)
- {
- if (mesh.shader == s)
- {
- currentMesh = &mesh;
- break;
- }
- }
-
- if (!currentMesh)
- {
- meshes.push_back(MeshInfo(PatchType_Simple));
- currentMesh = &meshes.back();
- currentMesh->shader = s;
- }
- sz = &line[1];out = currentMesh;
- }
- SkipSpaces(sz,&sz);
- unsigned int m = strtoul10(sz);
-
- // ---- flip the face order
- out->vertices.resize(out->vertices.size()+m);
- if (out != currentMesh)
- {
- out->normals.resize(out->vertices.size());
- }
- if (out == currentMeshWithUVCoords)
- {
- out->uvs.resize(out->vertices.size());
- }
- for (unsigned int n = 0; n < m;++n)
- {
- if(!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected EOF was encountered. Patch definition incomplete");
- continue;
- }
-
- aiVector3D v; sz = &line[0];
- AI_NFF_PARSE_TRIPLE(v);
- out->vertices[out->vertices.size()-n-1] = v;
-
- if (out != currentMesh)
- {
- AI_NFF_PARSE_TRIPLE(v);
- out->normals[out->vertices.size()-n-1] = v;
- }
- if (out == currentMeshWithUVCoords)
- {
- // FIX: in one test file this wraps over multiple lines
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))
- {
- GetNextLine(buffer,line);
- sz = line;
- }
- AI_NFF_PARSE_FLOAT(v.x);
- SkipSpaces(&sz);
- if (IsLineEnd(*sz))
- {
- GetNextLine(buffer,line);
- sz = line;
- }
- AI_NFF_PARSE_FLOAT(v.y);
- v.y = 1.f - v.y;
- out->uvs[out->vertices.size()-n-1] = v;
- }
- }
- out->faces.push_back(m);
- }
- // 'f' - shading information block
- else if (TokenMatch(sz,"f",1))
- {
- float d;
-
- // read the RGB colors
- AI_NFF_PARSE_TRIPLE(s.color);
-
- // read the other properties
- AI_NFF_PARSE_FLOAT(s.diffuse.r);
- AI_NFF_PARSE_FLOAT(s.specular.r);
- AI_NFF_PARSE_FLOAT(d); // skip shininess and transmittance
- AI_NFF_PARSE_FLOAT(d);
- AI_NFF_PARSE_FLOAT(s.refracti);
-
- // NFF2 uses full colors here so we need to use them too
- // although NFF uses simple scaling factors
- s.diffuse.g = s.diffuse.b = s.diffuse.r;
- s.specular.g = s.specular.b = s.specular.r;
-
- // if the next one is NOT a number we assume it is a texture file name
- // this feature is used by some NFF files on the internet and it has
- // been implemented as it can be really useful
- SkipSpaces(&sz);
- if (!IsNumeric(*sz))
- {
- // TODO: Support full file names with spaces and quotation marks ...
- const char* p = sz;
- while (!IsSpaceOrNewLine( *sz ))++sz;
-
- unsigned int diff = (unsigned int)(sz-p);
- if (diff)
- {
- s.texFile = std::string(p,diff);
- }
- }
- else
- {
- AI_NFF_PARSE_FLOAT(s.ambient); // optional
- }
- }
- // 'shader' - other way to specify a texture
- else if (TokenMatch(sz,"shader",6))
- {
- SkipSpaces(&sz);
- const char* old = sz;
- while (!IsSpaceOrNewLine(*sz))++sz;
- s.texFile = std::string(old, (uintptr_t)sz - (uintptr_t)old);
- }
- // 'l' - light source
- else if (TokenMatch(sz,"l",1))
- {
- lights.push_back(Light());
- Light& light = lights.back();
-
- AI_NFF_PARSE_TRIPLE(light.position);
- AI_NFF_PARSE_FLOAT (light.intensity);
- AI_NFF_PARSE_TRIPLE(light.color);
- }
- // 's' - sphere
- else if (TokenMatch(sz,"s",1))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeSphere(iTesselation, currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::ai_snprintf(currentMesh.name,128,"sphere_%i",sphere++);
- }
- // 'dod' - dodecahedron
- else if (TokenMatch(sz,"dod",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeDodecahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::ai_snprintf(currentMesh.name,128,"dodecahedron_%i",dodecahedron++);
- }
-
- // 'oct' - octahedron
- else if (TokenMatch(sz,"oct",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeOctahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::ai_snprintf(currentMesh.name,128,"octahedron_%i",octahedron++);
- }
-
- // 'tet' - tetrahedron
- else if (TokenMatch(sz,"tet",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_SPHERE;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeTetrahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::ai_snprintf(currentMesh.name,128,"tetrahedron_%i",tetrahedron++);
- }
-
- // 'hex' - hexahedron
- else if (TokenMatch(sz,"hex",3))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_BOX;
-
- AI_NFF_PARSE_SHAPE_INFORMATION();
-
- // we don't need scaling or translation here - we do it in the node's transform
- StandardShapes::MakeHexahedron(currentMesh.vertices);
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh
- ::ai_snprintf(currentMesh.name,128,"hexahedron_%i",hexahedron++);
- }
- // 'c' - cone
- else if (TokenMatch(sz,"c",1))
- {
- meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
- MeshInfo& currentMesh = meshesLocked.back();
- currentMesh.shader = s;
- currentMesh.shader.mapping = aiTextureMapping_CYLINDER;
-
- if(!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
- break;
- }
- sz = line;
-
- // read the two center points and the respective radii
- aiVector3D center1, center2; float radius1, radius2;
- AI_NFF_PARSE_TRIPLE(center1);
- AI_NFF_PARSE_FLOAT(radius1);
-
- if(!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
- break;
- }
- sz = line;
-
- AI_NFF_PARSE_TRIPLE(center2);
- AI_NFF_PARSE_FLOAT(radius2);
-
- // compute the center point of the cone/cylinder -
- // it is its local transformation origin
- currentMesh.dir = center2-center1;
- currentMesh.center = center1+currentMesh.dir/(ai_real)2.0;
-
- float f;
- if (( f = currentMesh.dir.Length()) < 10e-3f )
- {
- DefaultLogger::get()->error("NFF: Cone height is close to zero");
- continue;
- }
- currentMesh.dir /= f; // normalize
-
- // generate the cone - it consists of simple triangles
- StandardShapes::MakeCone(f, radius1, radius2,
- integer_pow(4, iTesselation), currentMesh.vertices);
-
- // MakeCone() returns tris
- currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
-
- // generate a name for the mesh. 'cone' if it a cone,
- // 'cylinder' if it is a cylinder. Funny, isn't it?
- if (radius1 != radius2)
- ::ai_snprintf(currentMesh.name,128,"cone_%i",cone++);
- else ::ai_snprintf(currentMesh.name,128,"cylinder_%i",cylinder++);
- }
- // 'tess' - tesselation
- else if (TokenMatch(sz,"tess",4))
- {
- SkipSpaces(&sz);
- iTesselation = strtoul10(sz);
- }
- // 'from' - camera position
- else if (TokenMatch(sz,"from",4))
- {
- AI_NFF_PARSE_TRIPLE(camPos);
- hasCam = true;
- }
- // 'at' - camera look-at vector
- else if (TokenMatch(sz,"at",2))
- {
- AI_NFF_PARSE_TRIPLE(camLookAt);
- hasCam = true;
- }
- // 'up' - camera up vector
- else if (TokenMatch(sz,"up",2))
- {
- AI_NFF_PARSE_TRIPLE(camUp);
- hasCam = true;
- }
- // 'angle' - (half?) camera field of view
- else if (TokenMatch(sz,"angle",5))
- {
- AI_NFF_PARSE_FLOAT(angle);
- hasCam = true;
- }
- // 'resolution' - used to compute the screen aspect
- else if (TokenMatch(sz,"resolution",10))
- {
- AI_NFF_PARSE_FLOAT(resolution.x);
- AI_NFF_PARSE_FLOAT(resolution.y);
- hasCam = true;
- }
- // 'pb' - bezier patch. Not supported yet
- else if (TokenMatch(sz,"pb",2))
- {
- DefaultLogger::get()->error("NFF: Encountered unsupported ID: bezier patch");
- }
- // 'pn' - NURBS. Not supported yet
- else if (TokenMatch(sz,"pn",2) || TokenMatch(sz,"pnn",3))
- {
- DefaultLogger::get()->error("NFF: Encountered unsupported ID: NURBS");
- }
- // '' - comment
- else if ('#' == line[0])
- {
- const char* sz;SkipSpaces(&line[1],&sz);
- if (!IsLineEnd(*sz))DefaultLogger::get()->info(sz);
- }
- }
- }
-
- // copy all arrays into one large
- meshes.reserve (meshes.size()+meshesLocked.size()+meshesWithNormals.size()+meshesWithUVCoords.size());
- meshes.insert (meshes.end(),meshesLocked.begin(),meshesLocked.end());
- meshes.insert (meshes.end(),meshesWithNormals.begin(),meshesWithNormals.end());
- meshes.insert (meshes.end(),meshesWithUVCoords.begin(),meshesWithUVCoords.end());
-
- // now generate output meshes. first find out how many meshes we'll need
- std::vector<MeshInfo>::const_iterator it = meshes.begin(), end = meshes.end();
- for (;it != end;++it)
- {
- if (!(*it).faces.empty())
- {
- ++pScene->mNumMeshes;
- if ((*it).name[0])++numNamed;
- }
- }
-
- // generate a dummy root node - assign all unnamed elements such
- // as polygons and polygon patches to the root node and generate
- // sub nodes for named objects such as spheres and cones.
- aiNode* const root = new aiNode();
- root->mName.Set("<NFF_Root>");
- root->mNumChildren = numNamed + (hasCam ? 1 : 0) + (unsigned int) lights.size();
- root->mNumMeshes = pScene->mNumMeshes-numNamed;
-
- aiNode** ppcChildren = NULL;
- unsigned int* pMeshes = NULL;
- if (root->mNumMeshes)
- pMeshes = root->mMeshes = new unsigned int[root->mNumMeshes];
- if (root->mNumChildren)
- ppcChildren = root->mChildren = new aiNode*[root->mNumChildren];
-
- // generate the camera
- if (hasCam)
- {
- ai_assert(ppcChildren);
- aiNode* nd = new aiNode();
- *ppcChildren = nd;
- nd->mName.Set("<NFF_Camera>");
- nd->mParent = root;
-
- // allocate the camera in the scene
- pScene->mNumCameras = 1;
- pScene->mCameras = new aiCamera*[1];
- aiCamera* c = pScene->mCameras[0] = new aiCamera;
-
- c->mName = nd->mName; // make sure the names are identical
- c->mHorizontalFOV = AI_DEG_TO_RAD( angle );
- c->mLookAt = camLookAt - camPos;
- c->mPosition = camPos;
- c->mUp = camUp;
-
- // If the resolution is not specified in the file, we
- // need to set 1.0 as aspect.
- c->mAspect = (!resolution.y ? 0.f : resolution.x / resolution.y);
- ++ppcChildren;
- }
-
- // generate light sources
- if (!lights.empty())
- {
- ai_assert(ppcChildren);
- pScene->mNumLights = (unsigned int)lights.size();
- pScene->mLights = new aiLight*[pScene->mNumLights];
- for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
- {
- const Light& l = lights[i];
-
- aiNode* nd = new aiNode();
- *ppcChildren = nd;
- nd->mParent = root;
-
- nd->mName.length = ::ai_snprintf(nd->mName.data,1024,"<NFF_Light%u>",i);
-
- // allocate the light in the scene data structure
- aiLight* out = pScene->mLights[i] = new aiLight();
- out->mName = nd->mName; // make sure the names are identical
- out->mType = aiLightSource_POINT;
- out->mColorDiffuse = out->mColorSpecular = l.color * l.intensity;
- out->mPosition = l.position;
- }
- }
-
- if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
- unsigned int m = 0;
- for (it = meshes.begin(); it != end;++it)
- {
- if ((*it).faces.empty())continue;
-
- const MeshInfo& src = *it;
- aiMesh* const mesh = pScene->mMeshes[m] = new aiMesh();
- mesh->mNumVertices = (unsigned int)src.vertices.size();
- mesh->mNumFaces = (unsigned int)src.faces.size();
-
- // Generate sub nodes for named meshes
- if ( src.name[ 0 ] && NULL != ppcChildren ) {
- aiNode* const node = *ppcChildren = new aiNode();
- node->mParent = root;
- node->mNumMeshes = 1;
- node->mMeshes = new unsigned int[1];
- node->mMeshes[0] = m;
- node->mName.Set(src.name);
-
- // setup the transformation matrix of the node
- aiMatrix4x4::FromToMatrix(aiVector3D(0.f,1.f,0.f),
- src.dir,node->mTransformation);
-
- aiMatrix4x4& mat = node->mTransformation;
- mat.a1 *= src.radius.x; mat.b1 *= src.radius.x; mat.c1 *= src.radius.x;
- mat.a2 *= src.radius.y; mat.b2 *= src.radius.y; mat.c2 *= src.radius.y;
- mat.a3 *= src.radius.z; mat.b3 *= src.radius.z; mat.c3 *= src.radius.z;
- mat.a4 = src.center.x;
- mat.b4 = src.center.y;
- mat.c4 = src.center.z;
-
- ++ppcChildren;
- } else {
- *pMeshes++ = m;
- }
-
- // copy vertex positions
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mVertices,&src.vertices[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
-
- // NFF2: there could be vertex colors
- if (!src.colors.empty())
- {
- ai_assert(src.colors.size() == src.vertices.size());
-
- // copy vertex colors
- mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
- ::memcpy(mesh->mColors[0],&src.colors[0],
- sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- if (!src.normals.empty())
- {
- ai_assert(src.normals.size() == src.vertices.size());
-
- // copy normal vectors
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mNormals,&src.normals[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
- }
-
- if (!src.uvs.empty())
- {
- ai_assert(src.uvs.size() == src.vertices.size());
-
- // copy texture coordinates
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- ::memcpy(mesh->mTextureCoords[0],&src.uvs[0],
- sizeof(aiVector3D)*mesh->mNumVertices);
- }
-
- // generate faces
- unsigned int p = 0;
- aiFace* pFace = mesh->mFaces = new aiFace[mesh->mNumFaces];
- for (std::vector<unsigned int>::const_iterator it2 = src.faces.begin(),
- end2 = src.faces.end();
- it2 != end2;++it2,++pFace)
- {
- pFace->mIndices = new unsigned int [ pFace->mNumIndices = *it2 ];
- for (unsigned int o = 0; o < pFace->mNumIndices;++o)
- pFace->mIndices[o] = p++;
- }
-
- // generate a material for the mesh
- aiMaterial* pcMat = (aiMaterial*)(pScene->mMaterials[m] = new aiMaterial());
-
- mesh->mMaterialIndex = m++;
-
- aiString s;
- s.Set(AI_DEFAULT_MATERIAL_NAME);
- pcMat->AddProperty(&s, AI_MATKEY_NAME);
-
- // FIX: Ignore diffuse == 0
- aiColor3D c = src.shader.color * (src.shader.diffuse.r ? src.shader.diffuse : aiColor3D(1.f,1.f,1.f));
- pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
- c = src.shader.color * src.shader.specular;
- pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
-
- // NFF2 - default values for NFF
- pcMat->AddProperty(&src.shader.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
- pcMat->AddProperty(&src.shader.emissive,1,AI_MATKEY_COLOR_EMISSIVE);
- pcMat->AddProperty(&src.shader.opacity, 1,AI_MATKEY_OPACITY);
-
- // setup the first texture layer, if existing
- if (src.shader.texFile.length())
- {
- s.Set(src.shader.texFile);
- pcMat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
-
- if (aiTextureMapping_UV != src.shader.mapping) {
-
- aiVector3D v(0.f,-1.f,0.f);
- pcMat->AddProperty(&v, 1,AI_MATKEY_TEXMAP_AXIS_DIFFUSE(0));
- pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0));
- }
- }
-
- // setup the name of the material
- if (src.shader.name.length())
- {
- s.Set(src.shader.texFile);
- pcMat->AddProperty(&s,AI_MATKEY_NAME);
- }
-
- // setup some more material properties that are specific to NFF2
- int i;
- if (src.shader.twoSided)
- {
- i = 1;
- pcMat->AddProperty(&i,1,AI_MATKEY_TWOSIDED);
- }
- i = (src.shader.shaded ? aiShadingMode_Gouraud : aiShadingMode_NoShading);
- if (src.shader.shininess)
- {
- i = aiShadingMode_Phong;
- pcMat->AddProperty(&src.shader.shininess,1,AI_MATKEY_SHININESS);
- }
- pcMat->AddProperty(&i,1,AI_MATKEY_SHADING_MODEL);
- }
- pScene->mRootNode = root;
-}
-
-#endif // !! ASSIMP_BUILD_NO_NFF_IMPORTER
diff --git a/src/3rdparty/assimp/code/NFFLoader.h b/src/3rdparty/assimp/code/NFFLoader.h
deleted file mode 100644
index 0640d4405..000000000
--- a/src/3rdparty/assimp/code/NFFLoader.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 NFFLoader.h
- * @brief Declaration of the NFF importer class.
- */
-#ifndef AI_NFFLOADER_H_INCLUDED
-#define AI_NFFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include <assimp/material.h>
-#include <vector>
-
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** NFF (Neutral File Format) Importer class.
- *
- * The class implements both Eric Haynes NFF format and Sense8's NFF (NFF2) format.
- * Both are quite different and the loading code is somewhat dirty at
- * the moment. Sense8 should be moved to a separate loader.
-*/
-class NFFImporter : public BaseImporter
-{
-public:
- NFFImporter();
- ~NFFImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-
- // describes face material properties
- struct ShadingInfo
- {
- ShadingInfo()
- : color (0.6f,0.6f,0.6f)
- , diffuse (1.f,1.f,1.f)
- , specular (1.f,1.f,1.f)
- , ambient (0.f,0.f,0.f)
- , emissive (0.f,0.f,0.f)
- , refracti (1.f)
- , twoSided (false) // for NFF2
- , shaded (true) // for NFF2
- , opacity (1.f)
- , shininess (0.f)
- , mapping (aiTextureMapping_UV)
- {}
-
- aiColor3D color,diffuse,specular,ambient,emissive;
- float refracti;
-
- std::string texFile;
-
- // For NFF2
- bool twoSided;
- bool shaded;
- float opacity, shininess;
-
- std::string name;
-
- // texture mapping to be generated for the mesh - uv is the default
- // it means: use UV if there, nothing otherwise. This property is
- // used for locked meshes.
- aiTextureMapping mapping;
-
- // shininess is ignored for the moment
- bool operator == (const ShadingInfo& other) const
- {
- return color == other.color &&
- diffuse == other.diffuse &&
- specular == other.specular &&
- ambient == other.ambient &&
- refracti == other.refracti &&
- texFile == other.texFile &&
- twoSided == other.twoSided &&
- shaded == other.shaded;
-
- // Some properties from NFF2 aren't compared by this operator.
- // Comparing MeshInfo::matIndex should do that.
- }
- };
-
- // describes a NFF light source
- struct Light
- {
- Light()
- : intensity (1.f)
- , color (1.f,1.f,1.f)
- {}
-
- aiVector3D position;
- float intensity;
- aiColor3D color;
- };
-
- enum PatchType
- {
- PatchType_Simple = 0x0,
- PatchType_Normals = 0x1,
- PatchType_UVAndNormals = 0x2
- };
-
- // describes a NFF mesh
- struct MeshInfo
- {
- MeshInfo(PatchType _pType, bool bL = false)
- : pType (_pType)
- , bLocked (bL)
- , radius (1.f,1.f,1.f)
- , dir (0.f,1.f,0.f)
- , matIndex (0)
- {
- name[0] = '\0'; // by default meshes are unnamed
- }
-
- ShadingInfo shader;
- PatchType pType;
- bool bLocked;
-
- // for spheres, cones and cylinders: center point of the object
- aiVector3D center, radius, dir;
-
- char name[128];
-
- std::vector<aiVector3D> vertices, normals, uvs;
- std::vector<unsigned int> faces;
-
- // for NFF2
- std::vector<aiColor4D> colors;
- unsigned int matIndex;
- };
-
-
- // -------------------------------------------------------------------
- /** Loads the material table for the NFF2 file format from an
- * external file.
- *
- * @param output Receives the list of output meshes
- * @param path Path to the file (abs. or rel.)
- * @param pIOHandler IOSystem to be used to open the file
- */
- void LoadNFF2MaterialTable(std::vector<ShadingInfo>& output,
- const std::string& path, IOSystem* pIOHandler);
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_NFFIMPORTER_H_IN
diff --git a/src/3rdparty/assimp/code/OFFLoader.cpp b/src/3rdparty/assimp/code/OFFLoader.cpp
deleted file mode 100644
index 5038176e2..000000000
--- a/src/3rdparty/assimp/code/OFFLoader.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OFFLoader.cpp
- * @brief Implementation of the OFF importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_OFF_IMPORTER
-
-// internal headers
-#include "OFFLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "OFF Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "off"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OFFImporter::OFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OFFImporter::~OFFImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool OFFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "off")
- return true;
- else if (!extension.length() || checkSig)
- {
- if (!pIOHandler)return true;
- const char* tokens[] = {"off"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1,3);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* OFFImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void OFFImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- char line[4096];
- GetNextLine(buffer,line);
- if ('O' == line[0]) {
- GetNextLine(buffer,line); // skip the 'OFF' line
- }
-
- const char* sz = line; SkipSpaces(&sz);
- const unsigned int numVertices = strtoul10(sz,&sz);SkipSpaces(&sz);
- const unsigned int numFaces = strtoul10(sz,&sz);
-
- if (!numVertices) {
- throw DeadlyImportError("OFF: There are no valid vertices");
- }
- if (!numFaces) {
- throw DeadlyImportError("OFF: There are no valid faces");
- }
-
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
-
- aiMesh* mesh = new aiMesh();
- pScene->mMeshes[0] = mesh;
-
- mesh->mNumFaces = numFaces;
- aiFace* faces = new aiFace [mesh->mNumFaces];
- mesh->mFaces = faces;
-
- std::vector<aiVector3D> tempPositions(numVertices);
-
- // now read all vertex lines
- for (unsigned int i = 0; i< numVertices;++i)
- {
- if(!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("OFF: The number of verts in the header is incorrect");
- break;
- }
- aiVector3D& v = tempPositions[i];
-
- sz = line; SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz,(ai_real&)v.x); SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz,(ai_real&)v.y); SkipSpaces(&sz);
- fast_atoreal_move<ai_real>(sz,(ai_real&)v.z);
- }
-
-
- // First find out how many vertices we'll need
- const char* old = buffer;
- for (unsigned int i = 0; i< mesh->mNumFaces;++i)
- {
- if(!GetNextLine(buffer,line))
- {
- DefaultLogger::get()->error("OFF: The number of faces in the header is incorrect");
- break;
- }
- sz = line;SkipSpaces(&sz);
- faces->mNumIndices = strtoul10(sz,&sz);
- if(!(faces->mNumIndices) || faces->mNumIndices > 9)
- {
- DefaultLogger::get()->error("OFF: Faces with zero indices aren't allowed");
- --mesh->mNumFaces;
- continue;
- }
- mesh->mNumVertices += faces->mNumIndices;
- ++faces;
- }
-
- if (!mesh->mNumVertices)
- throw DeadlyImportError("OFF: There are no valid faces");
-
- // allocate storage for the output vertices
- std::vector<aiVector3D> verts;
- verts.reserve(mesh->mNumVertices);
-
- // second: now parse all face indices
- buffer = old;
- faces = mesh->mFaces;
- for (unsigned int i = 0, p = 0; i< mesh->mNumFaces;)
- {
- if(!GetNextLine(buffer,line))break;
-
- unsigned int idx;
- sz = line;SkipSpaces(&sz);
- idx = strtoul10(sz,&sz);
- if(!(idx) || idx > 9)
- continue;
-
- faces->mIndices = new unsigned int [faces->mNumIndices];
- for (unsigned int m = 0; m < faces->mNumIndices;++m)
- {
- SkipSpaces(&sz);
- idx = strtoul10(sz,&sz);
- if ((idx) >= numVertices)
- {
- DefaultLogger::get()->error("OFF: Vertex index is out of range");
- idx = numVertices-1;
- }
- faces->mIndices[m] = p++;
- verts.push_back(tempPositions[idx]);
- }
- ++i;
- ++faces;
- }
-
- if (mesh->mNumVertices != verts.size()) {
- throw DeadlyImportError("OFF: Vertex count mismatch");
- }
- mesh->mVertices = new aiVector3D[verts.size()];
- memcpy(mesh->mVertices, &verts[0], verts.size() * sizeof(aiVector3D));
- // generate the output node graph
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<OFFRoot>");
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int [pScene->mRootNode->mNumMeshes];
- pScene->mRootNode->mMeshes[0] = 0;
-
- // generate a default material
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- aiMaterial* pcMat = new aiMaterial();
-
- aiColor4D clr( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 1.0 ) );
- pcMat->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- pScene->mMaterials[0] = pcMat;
-
- const int twosided =1;
- pcMat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
-}
-
-#endif // !! ASSIMP_BUILD_NO_OFF_IMPORTER
diff --git a/src/3rdparty/assimp/code/OFFLoader.h b/src/3rdparty/assimp/code/OFFLoader.h
deleted file mode 100644
index 29a4927bd..000000000
--- a/src/3rdparty/assimp/code/OFFLoader.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OFFLoader.h
- * @brief Declaration of the OFF importer class.
- */
-#ifndef AI_OFFLOADER_H_INCLUDED
-#define AI_OFFLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the Object File Format (.off)
-*/
-class OFFImporter : public BaseImporter
-{
-public:
- OFFImporter();
- ~OFFImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/src/3rdparty/assimp/code/ObjExporter.cpp b/src/3rdparty/assimp/code/ObjExporter.cpp
deleted file mode 100644
index a8bf9935a..000000000
--- a/src/3rdparty/assimp/code/ObjExporter.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
-
-#include "ObjExporter.h"
-#include "Exceptional.h"
-#include "StringComparison.h"
-#include <assimp/version.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <memory>
-
-using namespace Assimp;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to Wavefront OBJ. Prototyped and registered in Exporter.cpp
-void ExportSceneObj(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
- // invoke the exporter
- ObjExporter exporter(pFile, pScene);
-
- if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write both the main OBJ file and the material script
- {
- std::unique_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);
- }
- {
- std::unique_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);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to Wavefront OBJ without the material file. Prototyped and registered in Exporter.cpp
-void ExportSceneObjNoMtl(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) {
- // invoke the exporter
- ObjExporter exporter(pFile, pScene, true);
-
- if (exporter.mOutput.fail() || exporter.mOutputMat.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write both the main OBJ file and the material script
- {
- std::unique_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);
- }
-
-
-}
-
-} // end of namespace Assimp
-
-static const std::string MaterialExt = ".mtl";
-
-// ------------------------------------------------------------------------------------------------
-ObjExporter::ObjExporter(const char* _filename, const aiScene* pScene, bool noMtl)
-: filename(_filename)
-, pScene(pScene)
-, vp()
-, vn()
-, vt()
-, vc()
-, mVpMap()
-, mVnMap()
-, mVtMap()
-, mVcMap()
-, mMeshes()
-, endl("\n") {
- // 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);
- mOutput.precision(16);
- mOutputMat.imbue(l);
- mOutputMat.precision(16);
-
- WriteGeometryFile(noMtl);
- if (!noMtl)
- WriteMaterialFile();
-}
-
-// ------------------------------------------------------------------------------------------------
-ObjExporter::~ObjExporter() {
-
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string ObjExporter :: GetMaterialLibName()
-{
- // within the Obj file, we use just the relative file name with the path stripped
- const std::string& s = GetMaterialLibFileName();
- std::string::size_type il = s.find_last_of("/\\");
- if (il != std::string::npos) {
- return s.substr(il + 1);
- }
-
- return s;
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string ObjExporter::GetMaterialLibFileName() {
- // Remove existing .obj file extension so that the final material file name will be fileName.mtl and not fileName.obj.mtl
- size_t lastdot = filename.find_last_of('.');
- if (lastdot != std::string::npos)
- return filename.substr(0, lastdot) + MaterialExt;
-
- return filename + MaterialExt;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ObjExporter::WriteHeader(std::ostringstream& out) {
- out << "# File produced by Open Asset Import Library (http://www.assimp.sf.net)" << endl;
- out << "# (assimp v" << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
- << aiGetVersionRevision() << ")" << endl << endl;
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string ObjExporter::GetMaterialName(unsigned int index)
-{
- const aiMaterial* const mat = pScene->mMaterials[index];
- if ( nullptr == mat ) {
- static const std::string EmptyStr;
- return EmptyStr;
- }
-
- aiString s;
- if(AI_SUCCESS == mat->Get(AI_MATKEY_NAME,s)) {
- return std::string(s.data,s.length);
- }
-
- char number[ sizeof(unsigned int) * 3 + 1 ];
- ASSIMP_itoa10(number,index);
- return "$Material_" + std::string(number);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ObjExporter::WriteMaterialFile()
-{
- WriteHeader(mOutputMat);
-
- for(unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
- const aiMaterial* const mat = pScene->mMaterials[i];
-
- int illum = 1;
- mOutputMat << "newmtl " << GetMaterialName(i) << endl;
-
- aiColor4D c;
- if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_DIFFUSE,c)) {
- mOutputMat << "Kd " << c.r << " " << c.g << " " << c.b << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_AMBIENT,c)) {
- mOutputMat << "Ka " << c.r << " " << c.g << " " << c.b << endl;
- }
- 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;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_COLOR_TRANSPARENT,c)) {
- mOutputMat << "Tf " << c.r << " " << c.g << " " << c.b << endl;
- }
-
- ai_real o;
- if(AI_SUCCESS == mat->Get(AI_MATKEY_OPACITY,o)) {
- mOutputMat << "d " << o << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_REFRACTI,o)) {
- mOutputMat << "Ni " << o << endl;
- }
-
- if(AI_SUCCESS == mat->Get(AI_MATKEY_SHININESS,o) && o) {
- mOutputMat << "Ns " << o << endl;
- illum = 2;
- }
-
- mOutputMat << "illum " << illum << endl;
-
- aiString s;
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_DIFFUSE(0),s)) {
- mOutputMat << "map_Kd " << s.data << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_AMBIENT(0),s)) {
- mOutputMat << "map_Ka " << s.data << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SPECULAR(0),s)) {
- mOutputMat << "map_Ks " << s.data << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_SHININESS(0),s)) {
- mOutputMat << "map_Ns " << s.data << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_OPACITY(0),s)) {
- mOutputMat << "map_d " << s.data << endl;
- }
- if(AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_HEIGHT(0),s) || AI_SUCCESS == mat->Get(AI_MATKEY_TEXTURE_NORMALS(0),s)) {
- // implementations seem to vary here, so write both variants
- mOutputMat << "bump " << s.data << endl;
- mOutputMat << "map_bump " << s.data << endl;
- }
-
- mOutputMat << endl;
- }
-}
-
-void ObjExporter::WriteGeometryFile(bool noMtl) {
- WriteHeader(mOutput);
- if (!noMtl)
- mOutput << "mtllib " << GetMaterialLibName() << endl << endl;
-
- // collect mesh geometry
- aiMatrix4x4 mBase;
- AddNode(pScene->mRootNode, mBase);
-
- // write vertex positions with colors, if any
- mVpMap.getVectors( vp );
- mVcMap.getColors( vc );
- if ( vc.empty() ) {
- mOutput << "# " << vp.size() << " vertex positions" << endl;
- for ( const aiVector3D& v : vp ) {
- mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
- }
- } else {
- mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
- size_t colIdx = 0;
- for ( const aiVector3D& v : vp ) {
- if ( colIdx < vc.size() ) {
- mOutput << "v " << v.x << " " << v.y << " " << v.z << " " << vc[ colIdx ].r << " " << vc[ colIdx ].g << " " << vc[ colIdx ].b << endl;
- }
- ++colIdx;
- }
- }
- mOutput << endl;
-
- // write uv coordinates
- mVtMap.getVectors(vt);
- mOutput << "# " << vt.size() << " UV coordinates" << endl;
- for(const aiVector3D& v : vt) {
- mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
- }
- mOutput << endl;
-
- // write vertex normals
- mVnMap.getVectors(vn);
- mOutput << "# " << vn.size() << " vertex normals" << endl;
- for(const aiVector3D& v : vn) {
- mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
- }
- mOutput << endl;
-
- // now write all mesh instances
- for(const MeshInstance& m : mMeshes) {
- mOutput << "# Mesh \'" << m.name << "\' with " << m.faces.size() << " faces" << endl;
- if (!m.name.empty()) {
- mOutput << "g " << m.name << endl;
- }
- if (!noMtl)
- mOutput << "usemtl " << m.matname << endl;
-
- for(const Face& f : m.faces) {
- mOutput << f.kind << ' ';
- for(const FaceVertex& fv : f.indices) {
- mOutput << ' ' << fv.vp;
-
- if (f.kind != 'p') {
- if (fv.vt || f.kind == 'f') {
- mOutput << '/';
- }
- if (fv.vt) {
- mOutput << fv.vt;
- }
- if (f.kind == 'f' && fv.vn) {
- mOutput << '/' << fv.vn;
- }
- }
- }
-
- mOutput << endl;
- }
- mOutput << endl;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec) {
- vecIndexMap::dataType::iterator vertIt = vecMap.find(vec);
- // vertex already exists, so reference it
- if(vertIt != vecMap.end()){
- 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;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-int ObjExporter::colIndexMap::getIndex( const aiColor4D& col ) {
- colIndexMap::dataType::iterator vertIt = colMap.find( col );
- // vertex already exists, so reference it
- if ( vertIt != colMap.end() ) {
- return vertIt->second;
- }
- colMap[ col ] = mNextIndex;
- int ret = mNextIndex;
- mNextIndex++;
-
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void ObjExporter::colIndexMap::getColors( std::vector<aiColor4D> &colors ) {
- colors.resize( colMap.size() );
- for ( colIndexMap::dataType::iterator it = colMap.begin(); it != colMap.end(); ++it ) {
- colors[ it->second - 1 ] = it->first;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ObjExporter::AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat) {
- mMeshes.push_back(MeshInstance());
- MeshInstance& mesh = mMeshes.back();
-
- mesh.name = std::string( name.data, name.length );
- 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];
-
- Face& face = mesh.faces[i];
- switch (f.mNumIndices) {
- case 1:
- face.kind = 'p';
- break;
- case 2:
- face.kind = 'l';
- break;
- default:
- face.kind = 'f';
- }
- face.indices.resize(f.mNumIndices);
-
- for(unsigned int a = 0; a < f.mNumIndices; ++a) {
- const unsigned int idx = f.mIndices[a];
-
- aiVector3D vert = mat * m->mVertices[idx];
- face.indices[a].vp = mVpMap.getIndex(vert);
-
- if (m->mNormals) {
- aiVector3D norm = aiMatrix3x3(mat) * m->mNormals[idx];
- face.indices[a].vn = mVnMap.getIndex(norm);
- } else {
- face.indices[a].vn = 0;
- }
-
- if ( nullptr != m->mColors[ 0 ] ) {
- aiColor4D col4 = m->mColors[ 0 ][ idx ];
- face.indices[ a ].vc = mVcMap.getIndex( col4 );
- } else {
- face.indices[ a ].vc = 0;
- }
-
- if ( m->mTextureCoords[ 0 ] ) {
- face.indices[a].vt = mVtMap.getIndex(m->mTextureCoords[0][idx]);
- } else {
- face.indices[a].vt = 0;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ObjExporter::AddNode(const aiNode* nd, const aiMatrix4x4& mParent)
-{
- const aiMatrix4x4& mAbs = mParent * nd->mTransformation;
-
- for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
- AddMesh(nd->mName, pScene->mMeshes[nd->mMeshes[i]], mAbs);
- }
-
- for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
- AddNode(nd->mChildren[i], mAbs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-
-#endif // ASSIMP_BUILD_NO_OBJ_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/ObjExporter.h b/src/3rdparty/assimp/code/ObjExporter.h
deleted file mode 100644
index 391f8416d..000000000
--- a/src/3rdparty/assimp/code/ObjExporter.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ObjExporter.h
- * Declares the exporter class to write a scene to a Collada file
- */
-#ifndef AI_OBJEXPORTER_H_INC
-#define AI_OBJEXPORTER_H_INC
-
-#include <assimp/types.h>
-#include <sstream>
-#include <vector>
-#include <map>
-
-struct aiScene;
-struct aiNode;
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/** Helper class to export a given scene to an OBJ file. */
-// ------------------------------------------------------------------------------------------------
-class ObjExporter {
-public:
- /// Constructor for a specific scene to export
- ObjExporter(const char* filename, const aiScene* pScene, bool noMtl=false);
- ~ObjExporter();
- std::string GetMaterialLibName();
- std::string GetMaterialLibFileName();
-
- /// public string-streams to write all output into
- std::ostringstream mOutput, mOutputMat;
-
-private:
- // intermediate data structures
- struct FaceVertex {
- FaceVertex()
- : vp()
- , vn()
- , vt()
- , vc() {
- // empty
- }
-
- // one-based, 0 means: 'does not exist'
- unsigned int vp, vn, vt, vc;
- };
-
- struct Face {
- char kind;
- std::vector<FaceVertex> indices;
- };
-
- struct MeshInstance {
- std::string name, matname;
- std::vector<Face> faces;
- };
-
- void WriteHeader(std::ostringstream& out);
- void WriteMaterialFile();
- void WriteGeometryFile(bool noMtl=false);
- std::string GetMaterialName(unsigned int index);
- void AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat);
- void AddNode(const aiNode* nd, const aiMatrix4x4& mParent);
-
-private:
- std::string filename;
- const aiScene* const pScene;
- std::vector<aiVector3D> vp, vn, vt;
- std::vector<aiColor4D> vc;
-
- 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;
- }
- };
-
- struct aiColor4Compare {
- bool operator() ( const aiColor4D& a, const aiColor4D& b ) const {
- if ( a.r < b.r ) return true;
- if ( a.r > b.r ) return false;
- if ( a.g < b.g ) return true;
- if ( a.g > b.g ) return false;
- if ( a.b < b.b ) return true;
- if ( a.b > b.b ) return false;
- if ( a.a < b.a ) return true;
- if ( a.a > b.a ) return false;
- return false;
- }
- };
-
- class vecIndexMap {
- int mNextIndex;
- typedef std::map<aiVector3D, int, aiVectorCompare> dataType;
- dataType vecMap;
-
- public:
- vecIndexMap()
- : mNextIndex(1) {
- // empty
- }
-
- int getIndex(const aiVector3D& vec);
- void getVectors( std::vector<aiVector3D>& vecs );
- };
-
- class colIndexMap {
- int mNextIndex;
- typedef std::map<aiColor4D, int, aiColor4Compare> dataType;
- dataType colMap;
-
- public:
- colIndexMap()
- : mNextIndex( 1 ) {
- // empty
- }
-
- int getIndex( const aiColor4D& col );
- void getColors( std::vector<aiColor4D> &colors );
- };
-
- vecIndexMap mVpMap, mVnMap, mVtMap;
- colIndexMap mVcMap;
- std::vector<MeshInstance> mMeshes;
-
- // this endl() doesn't flush() the stream
- const std::string endl;
-};
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/ObjFileData.h b/src/3rdparty/assimp/code/ObjFileData.h
deleted file mode 100644
index 2658f8a2a..000000000
--- a/src/3rdparty/assimp/code/ObjFileData.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#pragma once
-#ifndef OBJ_FILEDATA_H_INC
-#define OBJ_FILEDATA_H_INC
-
-#include <vector>
-#include <map>
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-
-namespace Assimp {
-namespace ObjFile {
-
-struct Object;
-struct Face;
-struct Material;
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Face
-//! \brief Data structure for a simple obj-face, describes discredit,l.ation and materials
-// ------------------------------------------------------------------------------------------------
-struct Face {
- typedef std::vector<unsigned int> IndexArray;
-
- //! Primitive type
- aiPrimitiveType m_PrimitiveType;
- //! Vertex indices
- IndexArray m_vertices;
- //! Normal indices
- IndexArray m_normals;
- //! Texture coordinates indices
- IndexArray m_texturCoords;
- //! Pointer to assigned material
- Material *m_pMaterial;
-
- //! \brief Default constructor
- Face( aiPrimitiveType pt = aiPrimitiveType_POLYGON)
- : m_PrimitiveType( pt )
- , m_vertices()
- , m_normals()
- , m_texturCoords()
- , m_pMaterial( 0L ) {
- // empty
- }
-
- //! \brief Destructor
- ~Face() {
- // empty
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Object
-//! \brief Stores all objects of an obj-file object definition
-// ------------------------------------------------------------------------------------------------
-struct Object {
- enum ObjectType {
- ObjType,
- GroupType
- };
-
- //! Object name
- std::string m_strObjName;
- //! Transformation matrix, stored in OpenGL format
- aiMatrix4x4 m_Transformation;
- //! All sub-objects referenced by this object
- std::vector<Object*> m_SubObjects;
- /// Assigned meshes
- std::vector<unsigned int> m_Meshes;
-
- //! \brief Default constructor
- Object()
- : m_strObjName("") {
- // empty
- }
-
- //! \brief Destructor
- ~Object() {
- for ( std::vector<Object*>::iterator it = m_SubObjects.begin(); it != m_SubObjects.end(); ++it) {
- delete *it;
- }
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Material
-//! \brief Data structure to store all material specific data
-// ------------------------------------------------------------------------------------------------
-struct Material {
- //! Name of material description
- aiString MaterialName;
-
- //! Texture names
- aiString texture;
- aiString textureSpecular;
- aiString textureAmbient;
- aiString textureEmissive;
- aiString textureBump;
- aiString textureNormal;
- aiString textureReflection[6];
- aiString textureSpecularity;
- aiString textureOpacity;
- aiString textureDisp;
-
- enum TextureType {
- TextureDiffuseType = 0,
- TextureSpecularType,
- TextureAmbientType,
- TextureEmissiveType,
- TextureBumpType,
- TextureNormalType,
- TextureReflectionSphereType,
- TextureReflectionCubeTopType,
- TextureReflectionCubeBottomType,
- TextureReflectionCubeFrontType,
- TextureReflectionCubeBackType,
- TextureReflectionCubeLeftType,
- TextureReflectionCubeRightType,
- TextureSpecularityType,
- TextureOpacityType,
- TextureDispType,
- TextureTypeCount
- };
- bool clamp[TextureTypeCount];
-
- //! Ambient color
- aiColor3D ambient;
- //! Diffuse color
- aiColor3D diffuse;
- //! Specular color
- aiColor3D specular;
- //! Emissive color
- aiColor3D emissive;
- //! Alpha value
- ai_real alpha;
- //! Shineness factor
- ai_real shineness;
- //! Illumination model
- int illumination_model;
- //! Index of refraction
- ai_real ior;
- //! Transparency color
- aiColor3D transparent;
-
- //! Constructor
- Material()
- : diffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) )
- , alpha (ai_real( 1.0 ) )
- , shineness ( ai_real( 0.0) )
- , illumination_model (1)
- , ior ( ai_real( 1.0 ) )
- , transparent( ai_real( 1.0), ai_real (1.0), ai_real(1.0)) {
- // empty
- for (size_t i = 0; i < TextureTypeCount; ++i) {
- clamp[ i ] = false;
- }
- }
-
- // Destructor
- ~Material() {
- // empty
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Mesh
-//! \brief Data structure to store a mesh
-// ------------------------------------------------------------------------------------------------
-struct Mesh {
- static const unsigned int NoMaterial = ~0u;
- /// The name for the mesh
- std::string m_name;
- /// Array with pointer to all stored faces
- std::vector<Face*> m_Faces;
- /// Assigned material
- Material *m_pMaterial;
- /// Number of stored indices.
- unsigned int m_uiNumIndices;
- /// Number of UV
- unsigned int m_uiUVCoordinates[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
- /// Material index.
- unsigned int m_uiMaterialIndex;
- /// True, if normals are stored.
- bool m_hasNormals;
- /// True, if vertex colors are stored.
- bool m_hasVertexColors;
-
- /// Constructor
- explicit Mesh( const std::string &name )
- : m_name( name )
- , m_pMaterial(NULL)
- , m_uiNumIndices(0)
- , m_uiMaterialIndex( NoMaterial )
- , m_hasNormals(false) {
- memset(m_uiUVCoordinates, 0, sizeof( unsigned int ) * AI_MAX_NUMBER_OF_TEXTURECOORDS);
- }
-
- /// Destructor
- ~Mesh() {
- for (std::vector<Face*>::iterator it = m_Faces.begin();
- it != m_Faces.end(); ++it)
- {
- delete *it;
- }
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-//! \struct Model
-//! \brief Data structure to store all obj-specific model datas
-// ------------------------------------------------------------------------------------------------
-struct Model {
- typedef std::map<std::string, std::vector<unsigned int>* > GroupMap;
- typedef std::map<std::string, std::vector<unsigned int>* >::iterator GroupMapIt;
- typedef std::map<std::string, std::vector<unsigned int>* >::const_iterator ConstGroupMapIt;
-
- //! Model name
- std::string m_ModelName;
- //! List ob assigned objects
- std::vector<Object*> m_Objects;
- //! Pointer to current object
- ObjFile::Object *m_pCurrent;
- //! Pointer to current material
- ObjFile::Material *m_pCurrentMaterial;
- //! Pointer to default material
- ObjFile::Material *m_pDefaultMaterial;
- //! Vector with all generated materials
- std::vector<std::string> m_MaterialLib;
- //! Vector with all generated vertices
- std::vector<aiVector3D> m_Vertices;
- //! vector with all generated normals
- std::vector<aiVector3D> m_Normals;
- //! vector with all vertex colors
- std::vector<aiVector3D> m_VertexColors;
- //! Group map
- GroupMap m_Groups;
- //! Group to face id assignment
- std::vector<unsigned int> *m_pGroupFaceIDs;
- //! Active group
- std::string m_strActiveGroup;
- //! Vector with generated texture coordinates
- std::vector<aiVector3D> m_TextureCoord;
- //! Current mesh instance
- Mesh *m_pCurrentMesh;
- //! Vector with stored meshes
- std::vector<Mesh*> m_Meshes;
- //! Material map
- std::map<std::string, Material*> m_MaterialMap;
-
- //! \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 The class destructor
- ~Model() {
- // Clear all stored object instances
- for (std::vector<Object*>::iterator it = m_Objects.begin();
- it != m_Objects.end(); ++it) {
- delete *it;
- }
- m_Objects.clear();
-
- // Clear all stored mesh instances
- for (std::vector<Mesh*>::iterator it = m_Meshes.begin();
- it != m_Meshes.end(); ++it) {
- delete *it;
- }
- m_Meshes.clear();
-
- for(GroupMapIt it = m_Groups.begin(); it != m_Groups.end(); ++it) {
- delete it->second;
- }
- m_Groups.clear();
-
- for ( std::map<std::string, Material*>::iterator it = m_MaterialMap.begin(); it != m_MaterialMap.end(); ++it ) {
- delete it->second;
- }
- }
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace ObjFile
-} // Namespace Assimp
-
-#endif // OBJ_FILEDATA_H_INC
diff --git a/src/3rdparty/assimp/code/ObjFileImporter.cpp b/src/3rdparty/assimp/code/ObjFileImporter.cpp
deleted file mode 100644
index 9f3bdef97..000000000
--- a/src/3rdparty/assimp/code/ObjFileImporter.cpp
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include "ObjFileImporter.h"
-#include "ObjFileParser.h"
-#include "ObjFileData.h"
-#include "IOStreamBuffer.h"
-#include <memory>
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-static const aiImporterDesc desc = {
- "Wavefront Object Importer",
- "",
- "",
- "surfaces not supported",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "obj"
-};
-
-static const unsigned int ObjMinSize = 16;
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-// Default constructor
-ObjFileImporter::ObjFileImporter() :
- m_Buffer(),
- m_pRootObject( NULL ),
- m_strAbsPath( "" )
-{
- DefaultIOSystem io;
- m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-ObjFileImporter::~ObjFileImporter()
-{
- delete m_pRootObject;
- m_pRootObject = NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if file is an obj file.
-bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const
-{
- if(!checkSig) //Check File Extension
- {
- return SimpleExtensionCheck(pFile,"obj");
- }
- else //Check file Header
- {
- static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " };
- return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* ObjFileImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Obj-file import implementation
-void ObjFileImporter::InternReadFile( const std::string &file, aiScene* pScene, IOSystem* pIOHandler) {
- // Read file into memory
- static const std::string mode = "rb";
- std::unique_ptr<IOStream> fileStream( pIOHandler->Open( file, mode));
- if( !fileStream.get() ) {
- throw DeadlyImportError( "Failed to open file " + file + "." );
- }
-
- // Get the file-size and validate it, throwing an exception when fails
- size_t fileSize = fileStream->FileSize();
- if( fileSize < ObjMinSize ) {
- throw DeadlyImportError( "OBJ-file is too small.");
- }
-
- IOStreamBuffer<char> streamedBuffer;
- streamedBuffer.open( fileStream.get() );
-
- // Allocate buffer and read file into it
- //TextFileToBuffer( fileStream.get(),m_Buffer);
-
- // Get the model name
- std::string modelName, folderName;
- std::string::size_type pos = file.find_last_of( "\\/" );
- if ( pos != std::string::npos ) {
- modelName = file.substr(pos+1, file.size() - pos - 1);
- folderName = file.substr( 0, pos );
- if ( !folderName.empty() ) {
- pIOHandler->PushDirectory( folderName );
- }
- } else {
- modelName = file;
- }
-
- // This next stage takes ~ 1/3th of the total readFile task
- // so should amount for 1/3th of the progress
- // only update every 100KB or it'll be too slow
- /*unsigned int progress = 0;
- unsigned int progressCounter = 0;
- const unsigned int updateProgressEveryBytes = 100 * 1024;
- const unsigned int progressTotal = static_cast<unsigned int>(3*m_Buffer.size()/updateProgressEveryBytes);*/
- // process all '\'
- /*std::vector<char> ::iterator iter = m_Buffer.begin();
- while (iter != m_Buffer.end())
- {
- if (*iter == '\\')
- {
- // remove '\'
- iter = m_Buffer.erase(iter);
- // remove next character
- while (*iter == '\r' || *iter == '\n')
- iter = m_Buffer.erase(iter);
- }
- else
- ++iter;
-
- if (++progressCounter >= updateProgressEveryBytes)
- {
- m_progress->UpdateFileRead(++progress, progressTotal);
- progressCounter = 0;
- }
- }*/
-
- // 1/3rd progress
- m_progress->UpdateFileRead(1, 3);
-
- // parse the file into a temporary representation
- ObjFileParser parser( streamedBuffer, modelName, pIOHandler, m_progress, file);
-
- // And create the proper return structures out of it
- CreateDataFromImport(parser.GetModel(), pScene);
-
- streamedBuffer.close();
-
- // Clean up allocated storage for the next import
- m_Buffer.clear();
-
- // Pop directory stack
- if ( pIOHandler->StackSize() > 0 ) {
- pIOHandler->PopDirectory();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Create the data from parsed obj-file
-void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene) {
- if( 0L == pModel ) {
- return;
- }
-
- // Create the root node of the scene
- pScene->mRootNode = new aiNode;
- if ( !pModel->m_ModelName.empty() )
- {
- // Set the name of the scene
- pScene->mRootNode->mName.Set(pModel->m_ModelName);
- }
- else
- {
- // 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 ], pScene->mRootNode, pScene, MeshArray);
- }
-
- // Create mesh pointer buffer for this scene
- if (pScene->mNumMeshes > 0)
- {
- pScene->mMeshes = new aiMesh*[ MeshArray.size() ];
- for (size_t index =0; index < MeshArray.size(); index++)
- {
- pScene->mMeshes[ index ] = MeshArray[ index ];
- }
- }
-
- // Create all materials
- createMaterials( pModel, pScene );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all nodes of the model
-aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject,
- aiNode *pParent, aiScene* pScene,
- std::vector<aiMesh*> &MeshArray )
-{
- ai_assert( NULL != pModel );
- 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();
- aiNode *pNode = new aiNode;
-
- pNode->mName = pObject->m_strObjName;
-
- // If we have a parent node, store it
- if( pParent != NULL ) {
- appendChildToParentNode( pParent, pNode );
- }
-
- for ( size_t i=0; i< pObject->m_Meshes.size(); i++ )
- {
- unsigned int meshId = pObject->m_Meshes[ i ];
- aiMesh *pMesh = createTopology( pModel, pObject, meshId );
- if( pMesh && pMesh->mNumFaces > 0 ) {
- MeshArray.push_back( pMesh );
- }
- }
-
- // Create all nodes from the sub-objects stored in the current object
- if ( !pObject->m_SubObjects.empty() )
- {
- size_t numChilds = pObject->m_SubObjects.size();
- pNode->mNumChildren = static_cast<unsigned int>( numChilds );
- pNode->mChildren = new aiNode*[ numChilds ];
- pNode->mNumMeshes = 1;
- pNode->mMeshes = new unsigned int[ 1 ];
- }
-
- // Set mesh instances into scene- and node-instances
- const size_t meshSizeDiff = MeshArray.size()- oldMeshSize;
- if ( meshSizeDiff > 0 )
- {
- pNode->mMeshes = new unsigned int[ meshSizeDiff ];
- pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff );
- size_t index = 0;
- for (size_t i = oldMeshSize; i < MeshArray.size(); i++)
- {
- pNode->mMeshes[ index ] = pScene->mNumMeshes;
- pScene->mNumMeshes++;
- index++;
- }
- }
-
- return pNode;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Create topology data
-aiMesh *ObjFileImporter::createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData, unsigned int meshIndex ) {
- // Checking preconditions
- ai_assert( NULL != pModel );
-
- if( NULL == pData ) {
- return NULL;
- }
-
- // Create faces
- ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ meshIndex ];
- if( !pObjMesh ) {
- return NULL;
- }
-
- if( pObjMesh->m_Faces.empty() ) {
- return NULL;
- }
-
- aiMesh* pMesh = new aiMesh;
- if( !pObjMesh->m_name.empty() ) {
- pMesh->mName.Set( pObjMesh->m_name );
- }
-
- for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++)
- {
- ObjFile::Face *const inp = pObjMesh->m_Faces[ index ];
- ai_assert( NULL != inp );
-
- if (inp->m_PrimitiveType == aiPrimitiveType_LINE) {
- pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size() - 1);
- pMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- } else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
- pMesh->mNumFaces += static_cast<unsigned int>(inp->m_vertices.size());
- pMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- } else {
- ++pMesh->mNumFaces;
- if (inp->m_vertices.size() > 3) {
- pMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- } else {
- pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- }
- }
- }
-
- unsigned int uiIdxCount( 0u );
- if ( pMesh->mNumFaces > 0 ) {
- pMesh->mFaces = new aiFace[ pMesh->mNumFaces ];
- if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial ) {
- pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex;
- }
-
- unsigned int outIndex( 0 );
-
- // Copy all data from all stored meshes
- 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) {
- for(size_t i = 0; i < inp->m_vertices.size() - 1; ++i) {
- aiFace& f = pMesh->mFaces[ outIndex++ ];
- uiIdxCount += f.mNumIndices = 2;
- f.mIndices = new unsigned int[2];
- }
- continue;
- }
- else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) {
- for(size_t i = 0; i < inp->m_vertices.size(); ++i) {
- aiFace& f = pMesh->mFaces[ outIndex++ ];
- uiIdxCount += f.mNumIndices = 1;
- f.mIndices = new unsigned int[1];
- }
- continue;
- }
-
- aiFace *pFace = &pMesh->mFaces[ outIndex++ ];
- const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_vertices.size();
- uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices;
- if (pFace->mNumIndices > 0) {
- pFace->mIndices = new unsigned int[ uiNumIndices ];
- }
- }
- }
-
- // Create mesh vertices
- createVertexArray(pModel, pData, meshIndex, pMesh, uiIdxCount);
-
- return pMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates a vertex array
-void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
- const ObjFile::Object* pCurrentObject,
- unsigned int uiMeshIndex,
- aiMesh* pMesh,
- unsigned int numIndices) {
- // Checking preconditions
- ai_assert( NULL != pCurrentObject );
-
- // Break, if no faces are stored in object
- if ( pCurrentObject->m_Meshes.empty() )
- return;
-
- // Get current mesh
- ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ];
- if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1 ) {
- return;
- }
-
- // Copy vertices of this mesh instance
- pMesh->mNumVertices = numIndices;
- if (pMesh->mNumVertices == 0) {
- throw DeadlyImportError( "OBJ: no vertices" );
- } else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
- throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
- }
- pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
-
- // Allocate buffer for normal vectors
- if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals )
- pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ];
-
- // Allocate buffer for vertex-color vectors
- if ( !pModel->m_VertexColors.empty() )
- pMesh->mColors[0] = new aiColor4D[ pMesh->mNumVertices ];
-
- // Allocate buffer for texture coordinates
- if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
- {
- pMesh->mNumUVComponents[ 0 ] = 2;
- pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
- }
-
- // Copy vertices, normals and textures into aiMesh instance
- unsigned int newIndex = 0, outIndex = 0;
- for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) {
- // Get source face
- ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ];
-
- // Copy all index arrays
- for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_vertices.size(); vertexIndex++ ) {
- const unsigned int vertex = pSourceFace->m_vertices.at( vertexIndex );
- if ( vertex >= pModel->m_Vertices.size() ) {
- throw DeadlyImportError( "OBJ: vertex index out of range" );
- }
-
- pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ];
-
- // Copy all normals
- if ( !pModel->m_Normals.empty() && vertexIndex < pSourceFace->m_normals.size()) {
- const unsigned int normal = pSourceFace->m_normals.at( vertexIndex );
- if ( normal >= pModel->m_Normals.size() ) {
- throw DeadlyImportError( "OBJ: vertex normal index out of range" );
- }
- pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ];
- }
-
- // Copy all vertex colors
- if ( !pModel->m_VertexColors.empty())
- {
- const aiVector3D color = pModel->m_VertexColors[ vertex ];
- pMesh->mColors[0][ newIndex ] = aiColor4D(color.x, color.y, color.z, 1.0);
- }
-
- // Copy all texture coordinates
- if ( !pModel->m_TextureCoord.empty() && vertexIndex < pSourceFace->m_texturCoords.size())
- {
- const unsigned int tex = pSourceFace->m_texturCoords.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 );
- }
-
- if ( pMesh->mNumVertices <= newIndex ) {
- throw DeadlyImportError("OBJ: bad vertex index");
- }
-
- // Get destination face
- aiFace *pDestFace = &pMesh->mFaces[ outIndex ];
-
- const bool last = ( vertexIndex == pSourceFace->m_vertices.size() - 1 );
- if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) {
- pDestFace->mIndices[ outVertexIndex ] = newIndex;
- outVertexIndex++;
- }
-
- if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) {
- outIndex++;
- outVertexIndex = 0;
- } else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) {
- outVertexIndex = 0;
-
- if(!last)
- outIndex++;
-
- if (vertexIndex) {
- if(!last) {
- pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ];
- if ( !pSourceFace->m_normals.empty() && !pModel->m_Normals.empty()) {
- pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ];
- }
- if ( !pModel->m_TextureCoord.empty() ) {
- for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) {
- pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ];
- }
- }
- ++newIndex;
- }
-
- pDestFace[-1].mIndices[1] = newIndex;
- }
- }
- else if (last) {
- outIndex++;
- }
- ++newIndex;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts all stored meshes
-void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes)
-{
- iNumMeshes = 0;
- if ( rObjects.empty() )
- return;
-
- iNumMeshes += static_cast<unsigned int>( rObjects.size() );
- for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin();
- it != rObjects.end();
- ++it)
- {
- if (!(*it)->m_SubObjects.empty())
- {
- countObjects((*it)->m_SubObjects, iNumMeshes);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add clamp mode property to material if necessary
-void ObjFileImporter::addTextureMappingModeProperty( aiMaterial* mat, aiTextureType type, int clampMode, int index) {
- if ( nullptr == mat ) {
- return;
- }
-
- mat->AddProperty<int>( &clampMode, 1, AI_MATKEY_MAPPINGMODE_U( type, index ) );
- mat->AddProperty<int>( &clampMode, 1, AI_MATKEY_MAPPINGMODE_V( type, index ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the material
-void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene ) {
- if ( NULL == pScene ) {
- return;
- }
-
- const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size();
- pScene->mNumMaterials = 0;
- if ( pModel->m_MaterialLib.empty() ) {
- DefaultLogger::get()->debug("OBJ: no materials specified");
- return;
- }
-
- pScene->mMaterials = new aiMaterial*[ numMaterials ];
- for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ )
- {
- // Store material name
- std::map<std::string, ObjFile::Material*>::const_iterator it;
- it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] );
-
- // No material found, use the default material
- if ( pModel->m_MaterialMap.end() == it )
- continue;
-
- aiMaterial* mat = new aiMaterial;
- ObjFile::Material *pCurrentMaterial = (*it).second;
- mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME );
-
- // convert illumination model
- int sm = 0;
- switch (pCurrentMaterial->illumination_model)
- {
- case 0:
- sm = aiShadingMode_NoShading;
- break;
- case 1:
- sm = aiShadingMode_Gouraud;
- break;
- case 2:
- sm = aiShadingMode_Phong;
- break;
- default:
- sm = aiShadingMode_Gouraud;
- DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)");
- }
-
- mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL);
-
- // Adding material colors
- 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 );
- mat->AddProperty( &pCurrentMaterial->transparent,1,AI_MATKEY_COLOR_TRANSPARENT);
-
- // Adding refraction index
- mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI );
-
- // Adding textures
- const int uvwIndex = 0;
-
- if ( 0 != pCurrentMaterial->texture.length )
- {
- mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_EMISSIVE(0) );
- }
-
- if ( 0 != pCurrentMaterial->textureSpecular.length )
- {
- mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0) );
- if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType])
- {
- addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
- }
- }
-
- if( 0 != pCurrentMaterial->textureReflection[0].length )
- {
- ObjFile::Material::TextureType type = 0 != pCurrentMaterial->textureReflection[1].length ?
- ObjFile::Material::TextureReflectionCubeTopType :
- ObjFile::Material::TextureReflectionSphereType;
-
- unsigned count = type == ObjFile::Material::TextureReflectionSphereType ? 1 : 6;
- for( unsigned i = 0; i < count; i++ )
- {
- mat->AddProperty(&pCurrentMaterial->textureReflection[i], AI_MATKEY_TEXTURE_REFLECTION(i));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_REFLECTION(i) );
-
- if(pCurrentMaterial->clamp[type])
- addTextureMappingModeProperty(mat, aiTextureType_REFLECTION, 1, i);
- }
- }
-
- if ( 0 != pCurrentMaterial->textureDisp.length )
- {
- mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) );
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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));
- mat->AddProperty( &uvwIndex, 1, AI_MATKEY_UVWSRC_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;
- pScene->mNumMaterials++;
- }
-
- // Test number of created materials.
- ai_assert( pScene->mNumMaterials == numMaterials );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Appends this node to the parent node
-void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild)
-{
- // Checking preconditions
- ai_assert( NULL != pParent );
- ai_assert( NULL != pChild );
-
- // Assign parent to child
- pChild->mParent = pParent;
-
- // If already children was assigned to the parent node, store them in a
- std::vector<aiNode*> temp;
- if (pParent->mChildren != NULL)
- {
- ai_assert( 0 != pParent->mNumChildren );
- for (size_t index = 0; index < pParent->mNumChildren; index++)
- {
- temp.push_back(pParent->mChildren [ index ] );
- }
- delete [] pParent->mChildren;
- }
-
- // Copy node instances into parent node
- pParent->mNumChildren++;
- pParent->mChildren = new aiNode*[ pParent->mNumChildren ];
- for (size_t index = 0; index < pParent->mNumChildren-1; index++)
- {
- pParent->mChildren[ index ] = temp [ index ];
- }
- pParent->mChildren[ pParent->mNumChildren-1 ] = pChild;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/src/3rdparty/assimp/code/ObjFileImporter.h b/src/3rdparty/assimp/code/ObjFileImporter.h
deleted file mode 100644
index 302cf951a..000000000
--- a/src/3rdparty/assimp/code/ObjFileImporter.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OBJ_FILE_IMPORTER_H_INC
-#define OBJ_FILE_IMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include <assimp/material.h>
-#include <vector>
-
-struct aiMesh;
-struct aiNode;
-
-namespace Assimp {
-
-namespace ObjFile {
- struct Object;
- struct Model;
-}
-
-// ------------------------------------------------------------------------------------------------
-/// \class ObjFileImporter
-/// \brief Imports a waveform obj file
-// ------------------------------------------------------------------------------------------------
-class ObjFileImporter : public BaseImporter {
-public:
- /// \brief Default constructor
- ObjFileImporter();
-
- /// \brief Destructor
- ~ObjFileImporter();
-
-public:
- /// \brief Returns whether the class can handle the format of the given file.
- /// \remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
- //! \brief Appends the supported extension.
- const aiImporterDesc* GetInfo () const;
-
- //! \brief File import implementation.
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
- //! \brief Create the data from imported content.
- 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,
- aiNode *pParent, aiScene* pScene, std::vector<aiMesh*> &MeshArray);
-
- //! \brief Creates topology data like faces and meshes for the geometry.
- aiMesh *createTopology( const ObjFile::Model* pModel, const ObjFile::Object* pData,
- unsigned int uiMeshIndex );
-
- //! \brief Creates vertices from model.
- void createVertexArray(const ObjFile::Model* pModel, const ObjFile::Object* pCurrentObject,
- unsigned int uiMeshIndex, aiMesh* pMesh, unsigned int numIndices );
-
- //! \brief Object counter helper method.
- void countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes);
-
- //! \brief Material creation.
- void createMaterials(const ObjFile::Model* pModel, aiScene* pScene);
-
- /// @brief Adds special property for the used texture mapping mode of the model.
- void addTextureMappingModeProperty(aiMaterial* mat, aiTextureType type, int clampMode = 1, int index = 0);
-
- //! \brief Appends a child node to a parent node and updates the data structures.
- void appendChildToParentNode(aiNode *pParent, aiNode *pChild);
-
-private:
- //! Data buffer
- std::vector<char> m_Buffer;
- //! Pointer to root object instance
- ObjFile::Object *m_pRootObject;
- //! Absolute pathname of model in file system
- std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp b/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp
deleted file mode 100644
index 6ef655f8a..000000000
--- a/src/3rdparty/assimp/code/ObjFileMtlImporter.cpp
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include <stdlib.h>
-#include "ObjFileMtlImporter.h"
-#include "ObjTools.h"
-#include "ObjFileData.h"
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include <assimp/material.h>
-#include <assimp/DefaultLogger.hpp>
-
-
-namespace Assimp {
-
-// Material specific token (case insensitive compare)
-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 EmissiveTexture1 = "map_emissive";
-static const std::string EmissiveTexture2 = "map_Ke";
-static const std::string BumpTexture1 = "map_bump";
-static const std::string BumpTexture2 = "bump";
-static const std::string NormalTexture = "map_Kn";
-static const std::string ReflectionTexture = "refl";
-static const std::string DisplacementTexture1 = "map_disp";
-static const std::string DisplacementTexture2 = "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,
- const std::string &,
- ObjFile::Model *pModel ) :
- m_DataIt( buffer.begin() ),
- m_DataItEnd( buffer.end() ),
- m_pModel( pModel ),
- m_uiLine( 0 )
-{
- ai_assert( NULL != m_pModel );
- if ( NULL == m_pModel->m_pDefaultMaterial )
- {
- m_pModel->m_pDefaultMaterial = new ObjFile::Material;
- m_pModel->m_pDefaultMaterial->MaterialName.Set( "default" );
- }
- load();
-}
-
-// -------------------------------------------------------------------
-// Destructor
-ObjFileMtlImporter::~ObjFileMtlImporter()
-{
- // empty
-}
-
-// -------------------------------------------------------------------
-// Private copy constructor
-ObjFileMtlImporter::ObjFileMtlImporter(const ObjFileMtlImporter & )
-{
- // empty
-}
-
-// -------------------------------------------------------------------
-// Private copy constructor
-ObjFileMtlImporter &ObjFileMtlImporter::operator = ( const ObjFileMtlImporter & )
-{
- return *this;
-}
-
-// -------------------------------------------------------------------
-// Loads the material description
-void ObjFileMtlImporter::load()
-{
- if ( m_DataIt == m_DataItEnd )
- return;
-
- while ( m_DataIt != m_DataItEnd )
- {
- switch (*m_DataIt)
- {
- case 'k':
- case 'K':
- {
- ++m_DataIt;
- if (*m_DataIt == 'a') // Ambient color
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->ambient );
- }
- else if (*m_DataIt == 'd') // Diffuse color
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->diffuse );
- }
- else if (*m_DataIt == 's')
- {
- ++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;
- case 'T':
- {
- ++m_DataIt;
- if (*m_DataIt == 'f') // Material transmission
- {
- ++m_DataIt;
- getColorRGBA( &m_pModel->m_pCurrentMaterial->transparent);
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
- case 'd':
- {
- if( *(m_DataIt+1) == 'i' && *( m_DataIt + 2 ) == 's' && *( m_DataIt + 3 ) == 'p' ) {
- // A displacement map
- getTexture();
- } else {
- // Alpha value
- ++m_DataIt;
- getFloatValue( m_pModel->m_pCurrentMaterial->alpha );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- }
- break;
-
- case 'N':
- case 'n':
- {
- ++m_DataIt;
- switch(*m_DataIt)
- {
- case 's': // Specular exponent
- ++m_DataIt;
- getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
- break;
- case 'i': // Index Of refraction
- ++m_DataIt;
- getFloatValue(m_pModel->m_pCurrentMaterial->ior);
- break;
- case 'e': // New material
- createMaterial();
- break;
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'm': // Texture
- case 'b': // quick'n'dirty - for 'bump' sections
- case 'r': // quick'n'dirty - for 'refl' sections
- {
- getTexture();
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- case 'i': // Illumination model
- {
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- getIlluminationModel( m_pModel->m_pCurrentMaterial->illumination_model );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
-
- default:
- {
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
- }
- }
-}
-
-// -------------------------------------------------------------------
-// Loads a color definition
-void ObjFileMtlImporter::getColorRGBA( aiColor3D *pColor )
-{
- ai_assert( NULL != pColor );
-
- ai_real r( 0.0 ), g( 0.0 ), b( 0.0 );
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, r );
- pColor->r = r;
-
- // we have to check if color is default 0 with only one token
- if( !IsLineEnd( *m_DataIt ) ) {
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, g );
- m_DataIt = getFloat<DataArrayIt>( m_DataIt, m_DataItEnd, b );
- }
- pColor->g = g;
- pColor->b = b;
-}
-
-// -------------------------------------------------------------------
-// Loads the kind of illumination model.
-void ObjFileMtlImporter::getIlluminationModel( int &illum_model )
-{
- m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
- illum_model = atoi(m_buffer);
-}
-
-// -------------------------------------------------------------------
-// Loads a single float value.
-void ObjFileMtlImporter::getFloatValue( ai_real &value )
-{
- m_DataIt = CopyNextWord<DataArrayIt>( m_DataIt, m_DataItEnd, m_buffer, BUFFERSIZE );
- value = (ai_real) fast_atof(m_buffer);
-}
-
-// -------------------------------------------------------------------
-// Creates a material from loaded data.
-void ObjFileMtlImporter::createMaterial()
-{
- std::string line( "" );
- while( !IsLineEnd( *m_DataIt ) ) {
- line += *m_DataIt;
- ++m_DataIt;
- }
-
- std::vector<std::string> token;
- const unsigned int numToken = tokenize<std::string>( line, token, " \t" );
- std::string name( "" );
- if ( numToken == 1 ) {
- name = AI_DEFAULT_MATERIAL_NAME;
- } else {
- // skip newmtl and all following white spaces
- std::size_t first_ws_pos = line.find_first_of(" \t");
- std::size_t first_non_ws_pos = line.find_first_not_of(" \t", first_ws_pos);
- if (first_non_ws_pos != std::string::npos) {
- name = line.substr(first_non_ws_pos);
- }
- }
-
- name = trim_whitespaces(name);
-
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( name );
- if ( m_pModel->m_MaterialMap.end() == it) {
- // New Material created
- m_pModel->m_pCurrentMaterial = new ObjFile::Material();
- m_pModel->m_pCurrentMaterial->MaterialName.Set( name );
- if (m_pModel->m_pCurrentMesh) {
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex = static_cast<unsigned int>(m_pModel->m_MaterialLib.size() - 1);
- }
- m_pModel->m_MaterialLib.push_back( name );
- m_pModel->m_MaterialMap[ name ] = m_pModel->m_pCurrentMaterial;
- } else {
- // Use older material
- m_pModel->m_pCurrentMaterial = (*it).second;
- }
-}
-
-// -------------------------------------------------------------------
-// Gets a texture name from data.
-void ObjFileMtlImporter::getTexture() {
- aiString *out( NULL );
- int clampIndex = -1;
-
- const char *pPtr( &(*m_DataIt) );
- if ( !ASSIMP_strincmp( pPtr, DiffuseTexture.c_str(), static_cast<unsigned int>(DiffuseTexture.size()) ) ) {
- // Diffuse texture
- out = & m_pModel->m_pCurrentMaterial->texture;
- clampIndex = ObjFile::Material::TextureDiffuseType;
- } else if ( !ASSIMP_strincmp( pPtr,AmbientTexture.c_str(), static_cast<unsigned int>(AmbientTexture.size()) ) ) {
- // Ambient texture
- out = & m_pModel->m_pCurrentMaterial->textureAmbient;
- clampIndex = ObjFile::Material::TextureAmbientType;
- } else if ( !ASSIMP_strincmp( pPtr, SpecularTexture.c_str(), static_cast<unsigned int>(SpecularTexture.size()) ) ) {
- // Specular texture
- out = & m_pModel->m_pCurrentMaterial->textureSpecular;
- clampIndex = ObjFile::Material::TextureSpecularType;
- } else if ( !ASSIMP_strincmp( pPtr, OpacityTexture.c_str(), static_cast<unsigned int>(OpacityTexture.size()) ) ) {
- // Opacity texture
- out = & m_pModel->m_pCurrentMaterial->textureOpacity;
- clampIndex = ObjFile::Material::TextureOpacityType;
- } else if ( !ASSIMP_strincmp( pPtr, EmissiveTexture1.c_str(), static_cast<unsigned int>(EmissiveTexture1.size()) ) ||
- !ASSIMP_strincmp( pPtr, EmissiveTexture2.c_str(), static_cast<unsigned int>(EmissiveTexture2.size()) ) ) {
- // Emissive texture
- out = & m_pModel->m_pCurrentMaterial->textureEmissive;
- clampIndex = ObjFile::Material::TextureEmissiveType;
- } else if ( !ASSIMP_strincmp( pPtr, BumpTexture1.c_str(), static_cast<unsigned int>(BumpTexture1.size()) ) ||
- !ASSIMP_strincmp( pPtr, BumpTexture2.c_str(), static_cast<unsigned int>(BumpTexture2.size()) ) ) {
- // Bump texture
- out = & m_pModel->m_pCurrentMaterial->textureBump;
- clampIndex = ObjFile::Material::TextureBumpType;
- } else if ( !ASSIMP_strincmp( pPtr,NormalTexture.c_str(), static_cast<unsigned int>(NormalTexture.size()) ) ) {
- // Normal map
- out = & m_pModel->m_pCurrentMaterial->textureNormal;
- clampIndex = ObjFile::Material::TextureNormalType;
- } else if( !ASSIMP_strincmp( pPtr, ReflectionTexture.c_str(), static_cast<unsigned int>(ReflectionTexture.size()) ) ) {
- // Reflection texture(s)
- //Do nothing here
- return;
- } else if ( !ASSIMP_strincmp( pPtr, DisplacementTexture1.c_str(), static_cast<unsigned int>(DisplacementTexture1.size()) ) ||
- !ASSIMP_strincmp( pPtr, DisplacementTexture2.c_str(), static_cast<unsigned int>(DisplacementTexture2.size()) ) ) {
- // Displacement texture
- out = &m_pModel->m_pCurrentMaterial->textureDisp;
- clampIndex = ObjFile::Material::TextureDispType;
- } else if ( !ASSIMP_strincmp( pPtr, SpecularityTexture.c_str(), static_cast<unsigned int>(SpecularityTexture.size()) ) ) {
- // Specularity scaling (glossiness)
- out = & m_pModel->m_pCurrentMaterial->textureSpecularity;
- clampIndex = ObjFile::Material::TextureSpecularityType;
- } else {
- DefaultLogger::get()->error("OBJ/MTL: Encountered unknown texture type");
- return;
- }
-
- bool clamp = false;
- getTextureOption(clamp, clampIndex, out);
- m_pModel->m_pCurrentMaterial->clamp[clampIndex] = clamp;
-
- std::string texture;
- m_DataIt = getName<DataArrayIt>( m_DataIt, m_DataItEnd, texture );
- if ( NULL!=out ) {
- out->Set( texture );
- }
-}
-
-/* /////////////////////////////////////////////////////////////////////////////
- * 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, int &clampIndex, aiString *&out) {
- 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(), static_cast<unsigned int>(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, TypeOption.c_str(), static_cast<unsigned int>(TypeOption.size()) ) )
- {
- DataArrayIt it = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
- char value[ 12 ];
- CopyNextWord( it, m_DataItEnd, value, sizeof( value ) / sizeof( *value ) );
- if( !ASSIMP_strincmp( value, "cube_top", 8 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeTopType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
- }
- else if( !ASSIMP_strincmp( value, "cube_bottom", 11 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeBottomType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[1];
- }
- else if( !ASSIMP_strincmp( value, "cube_front", 10 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeFrontType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[2];
- }
- else if( !ASSIMP_strincmp( value, "cube_back", 9 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeBackType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[3];
- }
- else if( !ASSIMP_strincmp( value, "cube_left", 9 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeLeftType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[4];
- }
- else if( !ASSIMP_strincmp( value, "cube_right", 10 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionCubeRightType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[5];
- }
- else if( !ASSIMP_strincmp( value, "sphere", 6 ) )
- {
- clampIndex = ObjFile::Material::TextureReflectionSphereType;
- out = &m_pModel->m_pCurrentMaterial->textureReflection[0];
- }
-
- skipToken = 2;
- }
- else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size()))
- || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size()))
- || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size()))
- || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size()))
- || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))
- || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size())))
- {
- skipToken = 2;
- }
- else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size())))
- {
- skipToken = 3;
- }
- else if ( !ASSIMP_strincmp(pPtr, OffsetOption.c_str(), static_cast<unsigned int>(OffsetOption.size()))
- || !ASSIMP_strincmp(pPtr, ScaleOption.c_str(), static_cast<unsigned int>(ScaleOption.size()))
- || !ASSIMP_strincmp(pPtr, TurbulenceOption.c_str(), static_cast<unsigned int>(TurbulenceOption.size()))
- )
- {
- skipToken = 4;
- }
-
- for (int i = 0; i < skipToken; ++i)
- {
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- }
- }
-}
-
-// -------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/src/3rdparty/assimp/code/ObjFileMtlImporter.h b/src/3rdparty/assimp/code/ObjFileMtlImporter.h
deleted file mode 100644
index c9bcc9a9f..000000000
--- a/src/3rdparty/assimp/code/ObjFileMtlImporter.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OBJFILEMTLIMPORTER_H_INC
-#define OBJFILEMTLIMPORTER_H_INC
-
-#include <vector>
-#include <string>
-#include <assimp/defs.h>
-
-struct aiColor3D;
-struct aiString;
-
-namespace Assimp {
-
-namespace ObjFile {
- struct Model;
- struct Material;
-}
-
-
-/**
- * @class ObjFileMtlImporter
- * @brief Loads the material description from a mtl file.
- */
-class ObjFileMtlImporter
-{
-public:
- static const size_t BUFFERSIZE = 2048;
- typedef std::vector<char> DataArray;
- typedef std::vector<char>::iterator DataArrayIt;
- typedef std::vector<char>::const_iterator ConstDataArrayIt;
-
-public:
- //! \brief Default constructor
- ObjFileMtlImporter( std::vector<char> &buffer, const std::string &strAbsPath,
- ObjFile::Model *pModel );
-
- //! \brief DEstructor
- ~ObjFileMtlImporter();
-
-private:
- /// Copy constructor, empty.
- ObjFileMtlImporter(const ObjFileMtlImporter &rOther);
- /// \brief Assignment operator, returns only a reference of this instance.
- ObjFileMtlImporter &operator = (const ObjFileMtlImporter &rOther);
- /// Load the whole material description
- void load();
- /// Get color data.
- void getColorRGBA( aiColor3D *pColor);
- /// Get illumination model from loaded data
- void getIlluminationModel( int &illum_model );
- /// Gets a float value from data.
- void getFloatValue( ai_real &value );
- /// Creates a new material from loaded data.
- void createMaterial();
- /// Get texture name from loaded data.
- void getTexture();
- void getTextureOption(bool &clamp, int &clampIndex, aiString *&out);
-
-private:
- //! Absolute pathname
- std::string m_strAbsPath;
- //! Data iterator showing to the current position in data buffer
- DataArrayIt m_DataIt;
- //! Data iterator to end of buffer
- DataArrayIt m_DataItEnd;
- //! USed model instance
- ObjFile::Model *m_pModel;
- //! Current line in file
- unsigned int m_uiLine;
- //! Helper buffer
- char m_buffer[BUFFERSIZE];
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // OBJFILEMTLIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/ObjFileParser.cpp b/src/3rdparty/assimp/code/ObjFileParser.cpp
deleted file mode 100644
index d89d52977..000000000
--- a/src/3rdparty/assimp/code/ObjFileParser.cpp
+++ /dev/null
@@ -1,862 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OBJ_IMPORTER
-
-#include "ObjFileParser.h"
-#include "ObjFileMtlImporter.h"
-#include "ObjTools.h"
-#include "ObjFileData.h"
-#include "ParsingUtils.h"
-#include "BaseImporter.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/material.h>
-#include <assimp/Importer.hpp>
-#include <cstdlib>
-
-namespace Assimp {
-
-const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
-
-ObjFileParser::ObjFileParser()
-: m_DataIt()
-, m_DataItEnd()
-, m_pModel( NULL )
-, m_uiLine( 0 )
-, m_pIO( nullptr )
-, m_progress( nullptr )
-, m_originalObjFileName() {
- // empty
-}
-
-ObjFileParser::ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName,
- IOSystem *io, ProgressHandler* progress,
- const std::string &originalObjFileName) :
- m_DataIt(),
- m_DataItEnd(),
- m_pModel(NULL),
- m_uiLine(0),
- m_pIO( io ),
- m_progress(progress),
- m_originalObjFileName(originalObjFileName)
-{
- std::fill_n(m_buffer,Buffersize,0);
-
- // Create the model instance to store all the data
- m_pModel = new ObjFile::Model();
- m_pModel->m_ModelName = modelName;
-
- // 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_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
-
- // Start parsing the file
- parseFile( streamBuffer );
-}
-
-ObjFileParser::~ObjFileParser() {
- delete m_pModel;
- m_pModel = NULL;
-}
-
-void ObjFileParser::setBuffer( std::vector<char> &buffer ) {
- m_DataIt = buffer.begin();
- m_DataItEnd = buffer.end();
-}
-
-ObjFile::Model *ObjFileParser::GetModel() const {
- return m_pModel;
-}
-
-void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
- // only update every 100KB or it'll be too slow
- //const unsigned int updateProgressEveryBytes = 100 * 1024;
- unsigned int progressCounter = 0;
- const unsigned int bytesToProcess = static_cast<unsigned int>(streamBuffer.size());
- const unsigned int progressTotal = 3 * bytesToProcess;
- const unsigned int progressOffset = bytesToProcess;
- unsigned int processed = 0;
- size_t lastFilePos( 0 );
-
- std::vector<char> buffer;
- while ( streamBuffer.getNextDataLine( buffer, '\\' ) ) {
- m_DataIt = buffer.begin();
- m_DataItEnd = buffer.end();
-
- // Handle progress reporting
- const size_t filePos( streamBuffer.getFilePos() );
- if ( lastFilePos < filePos ) {
- processed += static_cast<unsigned int>(filePos);
- lastFilePos = filePos;
- progressCounter++;
- m_progress->UpdateFileRead( progressOffset + processed * 2, progressTotal );
- }
-
- // parse line
- switch (*m_DataIt) {
- case 'v': // Parse a vertex texture coordinate
- {
- ++m_DataIt;
- if (*m_DataIt == ' ' || *m_DataIt == '\t') {
- size_t numComponents = getNumComponentsInDataDefinition();
- if (numComponents == 3) {
- // read in vertex definition
- getVector3(m_pModel->m_Vertices);
- } else if (numComponents == 4) {
- // read in vertex definition (homogeneous coords)
- getHomogeneousVector3(m_pModel->m_Vertices);
- } else if (numComponents == 6) {
- // read vertex and vertex-color
- getTwoVectors3(m_pModel->m_Vertices, m_pModel->m_VertexColors);
- }
- } 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 );
- }
- }
- break;
-
- case 'p': // Parse a face, line or point statement
- case 'l':
- case 'f':
- {
- getFace(*m_DataIt == 'f' ? aiPrimitiveType_POLYGON : (*m_DataIt == 'l'
- ? aiPrimitiveType_LINE : aiPrimitiveType_POINT));
- }
- break;
-
- case '#': // Parse a comment
- {
- getComment();
- }
- break;
-
- case 'u': // Parse a material desc. setter
- {
- std::string name;
-
- getNameNoSpace(m_DataIt, m_DataItEnd, name);
-
- size_t nextSpace = name.find(" ");
- if (nextSpace != std::string::npos)
- name = name.substr(0, nextSpace);
-
- if(name == "usemtl")
- {
- getMaterialDesc();
- }
- }
- break;
-
- case 'm': // Parse a material library or merging group ('mg')
- {
- std::string name;
-
- getNameNoSpace(m_DataIt, m_DataItEnd, name);
-
- size_t nextSpace = name.find(" ");
- if (nextSpace != std::string::npos)
- name = name.substr(0, nextSpace);
-
- if (name == "mg")
- getGroupNumberAndResolution();
- else if(name == "mtllib")
- getMaterialLib();
- else
- goto pf_skip_line;
- }
- break;
-
- case 'g': // Parse group name
- {
- getGroupName();
- }
- break;
-
- case 's': // Parse group number
- {
- getGroupNumber();
- }
- break;
-
- case 'o': // Parse object name
- {
- getObjectName();
- }
- break;
-
- default:
- {
-pf_skip_line:
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- }
- break;
- }
- }
-}
-
-void ObjFileParser::copyNextWord(char *pBuffer, size_t length) {
- size_t index = 0;
- m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
- if ( *m_DataIt == '\\' ) {
- m_DataIt++;
- m_DataIt++;
- m_DataIt = getNextWord<DataArrayIt>( m_DataIt, m_DataItEnd );
- }
- while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
- pBuffer[index] = *m_DataIt;
- index++;
- if( index == length - 1 ) {
- break;
- }
- ++m_DataIt;
- }
-
- ai_assert(index < length);
- pBuffer[index] = '\0';
-}
-
-static bool isDataDefinitionEnd( const char *tmp ) {
- if ( *tmp == '\\' ) {
- tmp++;
- if ( IsLineEnd( *tmp ) ) {
- tmp++;
- return true;
- }
- }
- return false;
-}
-
-size_t ObjFileParser::getNumComponentsInDataDefinition() {
- size_t numComponents( 0 );
- const char* tmp( &m_DataIt[0] );
- bool end_of_definition = false;
- while ( !end_of_definition ) {
- if ( isDataDefinitionEnd( tmp ) ) {
- tmp += 2;
- } else if ( IsLineEnd( *tmp ) ) {
- end_of_definition = true;
- }
- if ( !SkipSpaces( &tmp ) ) {
- break;
- }
- const bool isNum( IsNumeric( *tmp ) );
- SkipToken( tmp );
- if ( isNum ) {
- ++numComponents;
- }
- if ( !SkipSpaces( &tmp ) ) {
- break;
- }
- }
- return numComponents;
-}
-
-void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
- size_t numComponents = getNumComponentsInDataDefinition();
- ai_real x, y, z;
- if( 2 == numComponents ) {
- copyNextWord( m_buffer, Buffersize );
- x = ( ai_real ) fast_atof( m_buffer );
-
- copyNextWord( m_buffer, Buffersize );
- y = ( ai_real ) fast_atof( m_buffer );
- z = 0.0;
- } else if( 3 == numComponents ) {
- copyNextWord( m_buffer, Buffersize );
- x = ( ai_real ) fast_atof( m_buffer );
-
- copyNextWord( m_buffer, Buffersize );
- y = ( ai_real ) fast_atof( m_buffer );
-
- copyNextWord( m_buffer, Buffersize );
- z = ( ai_real ) fast_atof( m_buffer );
- } else {
- throw DeadlyImportError( "OBJ: Invalid number of components" );
- }
- point3d_array.push_back( aiVector3D( x, y, z ) );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {
- ai_real x, y, z;
- copyNextWord(m_buffer, Buffersize);
- x = (ai_real) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, Buffersize);
- y = (ai_real) fast_atof(m_buffer);
-
- copyNextWord( m_buffer, Buffersize );
- z = ( ai_real ) fast_atof( m_buffer );
-
- point3d_array.push_back( aiVector3D( x, y, z ) );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-void ObjFileParser::getHomogeneousVector3( std::vector<aiVector3D> &point3d_array ) {
- ai_real x, y, z, w;
- copyNextWord(m_buffer, Buffersize);
- x = (ai_real) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, Buffersize);
- y = (ai_real) fast_atof(m_buffer);
-
- copyNextWord( m_buffer, Buffersize );
- z = ( ai_real ) fast_atof( m_buffer );
-
- copyNextWord( m_buffer, Buffersize );
- w = ( ai_real ) fast_atof( m_buffer );
-
- ai_assert( w != 0 );
-
- point3d_array.push_back( aiVector3D( x/w, y/w, z/w ) );
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-void ObjFileParser::getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, std::vector<aiVector3D> &point3d_array_b ) {
- ai_real x, y, z;
- copyNextWord(m_buffer, Buffersize);
- x = (ai_real) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, Buffersize);
- y = (ai_real) fast_atof(m_buffer);
-
- copyNextWord( m_buffer, Buffersize );
- z = ( ai_real ) fast_atof( m_buffer );
-
- point3d_array_a.push_back( aiVector3D( x, y, z ) );
-
- copyNextWord(m_buffer, Buffersize);
- x = (ai_real) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, Buffersize);
- y = (ai_real) fast_atof(m_buffer);
-
- copyNextWord( m_buffer, Buffersize );
- z = ( ai_real ) fast_atof( m_buffer );
-
- point3d_array_b.push_back( aiVector3D( x, y, z ) );
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
- ai_real x, y;
- copyNextWord(m_buffer, Buffersize);
- x = (ai_real) fast_atof(m_buffer);
-
- copyNextWord(m_buffer, Buffersize);
- y = (ai_real) fast_atof(m_buffer);
-
- point2d_array.push_back(aiVector2D(x, y));
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-static const std::string DefaultObjName = "defaultobject";
-
-void ObjFileParser::getFace( aiPrimitiveType type ) {
- m_DataIt = getNextToken<DataArrayIt>( m_DataIt, m_DataItEnd );
- if ( m_DataIt == m_DataItEnd || *m_DataIt == '\0' ) {
- return;
- }
-
- ObjFile::Face *face = new ObjFile::Face( type );
- bool hasNormal = false;
-
- const int vSize = static_cast<unsigned int>(m_pModel->m_Vertices.size());
- const int vtSize = static_cast<unsigned int>(m_pModel->m_TextureCoord.size());
- const int vnSize = static_cast<unsigned int>(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;
- while ( m_DataIt != m_DataItEnd ) {
- iStep = 1;
-
- if ( IsLineEnd( *m_DataIt ) ) {
- break;
- }
-
- if ( *m_DataIt =='/' ) {
- if (type == aiPrimitiveType_POINT) {
- DefaultLogger::get()->error("Obj: Separator unexpected in point statement");
- }
- if (iPos == 0) {
- //if there are no texture coordinates in the file, but normals
- if (!vt && vn) {
- iPos = 1;
- iStep++;
- }
- }
- iPos++;
- } else if( IsSpaceOrNewLine( *m_DataIt ) ) {
- iPos = 0;
- } else {
- //OBJ USES 1 Base ARRAYS!!!!
- const int iVal( ::atoi( & ( *m_DataIt ) ) );
-
- // increment iStep position based off of the sign and # of digits
- int tmp = iVal;
- if ( iVal < 0 ) {
- ++iStep;
- }
- while ( ( tmp = tmp / 10 ) != 0 ) {
- ++iStep;
- }
-
- if ( iVal > 0 ) {
- // Store parsed index
- if ( 0 == iPos ) {
- face->m_vertices.push_back( iVal - 1 );
- } else if ( 1 == iPos ) {
- face->m_texturCoords.push_back( iVal - 1 );
- } else if ( 2 == iPos ) {
- face->m_normals.push_back( iVal - 1 );
- hasNormal = true;
- } else {
- reportErrorTokenInFace();
- }
- } else if ( iVal < 0 ) {
- // Store relatively index
- if ( 0 == iPos ) {
- face->m_vertices.push_back( vSize + iVal );
- } else if ( 1 == iPos ) {
- face->m_texturCoords.push_back( vtSize + iVal );
- } else if ( 2 == iPos ) {
- face->m_normals.push_back( vnSize + iVal );
- hasNormal = true;
- } else {
- reportErrorTokenInFace();
- }
- } else {
- //On error, std::atoi will return 0 which is not a valid value
- delete face;
- delete m_pModel;
- m_pModel = nullptr;
- throw DeadlyImportError("OBJ: Invalid face indice");
- }
-
- }
- m_DataIt += iStep;
- }
-
- if ( face->m_vertices.empty() ) {
- DefaultLogger::get()->error("Obj: Ignoring empty face");
- // skip line and clean up
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- delete face;
- return;
- }
-
- // Set active material, if one set
- if( NULL != m_pModel->m_pCurrentMaterial ) {
- face->m_pMaterial = m_pModel->m_pCurrentMaterial;
- } else {
- face->m_pMaterial = m_pModel->m_pDefaultMaterial;
- }
-
- // Create a default object, if nothing is there
- if( NULL == m_pModel->m_pCurrent ) {
- createObject( DefaultObjName );
- }
-
- // Assign face to mesh
- if ( NULL == m_pModel->m_pCurrentMesh ) {
- createMesh( DefaultObjName );
- }
-
- // Store the face
- m_pModel->m_pCurrentMesh->m_Faces.push_back( face );
- m_pModel->m_pCurrentMesh->m_uiNumIndices += (unsigned int) face->m_vertices.size();
- m_pModel->m_pCurrentMesh->m_uiUVCoordinates[ 0 ] += (unsigned int) face->m_texturCoords.size();
- if( !m_pModel->m_pCurrentMesh->m_hasNormals && hasNormal ) {
- m_pModel->m_pCurrentMesh->m_hasNormals = true;
- }
- // Skip the rest of the line
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-void ObjFileParser::getMaterialDesc() {
- // Get next data for material data
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if (m_DataIt == m_DataItEnd) {
- return;
- }
-
- char *pStart = &(*m_DataIt);
- while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
- ++m_DataIt;
- }
-
- // In some cases we should ignore this 'usemtl' command, this variable helps us to do so
- bool skip = false;
-
- // Get name
- std::string strName(pStart, &(*m_DataIt));
- strName = trim_whitespaces(strName);
- if (strName.empty())
- skip = true;
-
- // If the current mesh has the same material, we simply ignore that 'usemtl' command
- // There is no need to create another object or even mesh here
- if ( m_pModel->m_pCurrentMaterial && m_pModel->m_pCurrentMaterial->MaterialName == aiString( strName ) ) {
- skip = true;
- }
-
- if (!skip) {
- // Search for material
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find(strName);
- if (it == m_pModel->m_MaterialMap.end()) {
- // Not found, so we don't know anything about the material except for its name.
- // This may be the case if the material library is missing. We don't want to lose all
- // materials if that happens, so create a new named material instead of discarding it
- // completely.
- DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", creating new material");
- m_pModel->m_pCurrentMaterial = new ObjFile::Material();
- m_pModel->m_pCurrentMaterial->MaterialName.Set(strName);
- m_pModel->m_MaterialLib.push_back(strName);
- m_pModel->m_MaterialMap[strName] = m_pModel->m_pCurrentMaterial;
- } else {
- // Found, using detected material
- m_pModel->m_pCurrentMaterial = (*it).second;
- }
-
- if ( needsNewMesh( strName ) ) {
- createMesh( strName );
- }
-
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex(strName);
- }
-
- // Skip rest of line
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get a comment, values will be skipped
-void ObjFileParser::getComment() {
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Get material library from file.
-void ObjFileParser::getMaterialLib() {
- // Translate tuple
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if( m_DataIt == m_DataItEnd ) {
- return;
- }
-
- char *pStart = &(*m_DataIt);
- while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
- ++m_DataIt;
- }
-
- // Check for existence
- const std::string strMatName(pStart, &(*m_DataIt));
- std::string absName;
-
- // Check if directive is valid.
- if ( 0 == strMatName.length() ) {
- DefaultLogger::get()->warn( "OBJ: no name for material library specified." );
- return;
- }
-
- if ( m_pIO->StackSize() > 0 ) {
- std::string path = m_pIO->CurrentDirectory();
- if ( '/' != *path.rbegin() ) {
- path += '/';
- }
- absName = path + strMatName;
- } else {
- absName = strMatName;
- }
- IOStream *pFile = m_pIO->Open( absName );
-
- if (!pFile ) {
- DefaultLogger::get()->error("OBJ: Unable to locate material file " + strMatName);
- std::string strMatFallbackName = m_originalObjFileName.substr(0, m_originalObjFileName.length() - 3) + "mtl";
- DefaultLogger::get()->info("OBJ: Opening fallback material file " + strMatFallbackName);
- pFile = m_pIO->Open(strMatFallbackName);
- if (!pFile) {
- DefaultLogger::get()->error("OBJ: Unable to locate fallback material file " + strMatFallbackName);
- m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
- return;
- }
- }
-
- // Import material library data from file.
- // Some exporters (e.g. Silo) will happily write out empty
- // material files if the model doesn't use any materials, so we
- // allow that.
- std::vector<char> buffer;
- BaseImporter::TextFileToBuffer( pFile, buffer, BaseImporter::ALLOW_EMPTY );
- m_pIO->Close( pFile );
-
- // Importing the material library
- ObjFileMtlImporter mtlImporter( buffer, strMatName, m_pModel );
-}
-
-// -------------------------------------------------------------------
-// Set a new material definition as the current material.
-void ObjFileParser::getNewMaterial() {
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- m_DataIt = getNextWord<DataArrayIt>(m_DataIt, m_DataItEnd);
- if( m_DataIt == m_DataItEnd ) {
- return;
- }
-
- char *pStart = &(*m_DataIt);
- std::string strMat( pStart, *m_DataIt );
- while( m_DataIt != m_DataItEnd && IsSpaceOrNewLine( *m_DataIt ) ) {
- ++m_DataIt;
- }
- std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strMat );
- if ( it == m_pModel->m_MaterialMap.end() ) {
- // Show a warning, if material was not found
- DefaultLogger::get()->warn("OBJ: Unsupported material requested: " + strMat);
- m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
- } else {
- // Set new material
- if ( needsNewMesh( strMat ) ) {
- createMesh( strMat );
- }
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex = getMaterialIndex( strMat );
- }
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-int ObjFileParser::getMaterialIndex( const std::string &strMaterialName )
-{
- int mat_index = -1;
- if( strMaterialName.empty() ) {
- return mat_index;
- }
- for (size_t index = 0; index < m_pModel->m_MaterialLib.size(); ++index)
- {
- if ( strMaterialName == m_pModel->m_MaterialLib[ index ])
- {
- mat_index = (int)index;
- break;
- }
- }
- return mat_index;
-}
-
-// -------------------------------------------------------------------
-// Getter for a group name.
-void ObjFileParser::getGroupName() {
- std::string groupName;
-
- // here we skip 'g ' from line
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- m_DataIt = getName<DataArrayIt>(m_DataIt, m_DataItEnd, groupName);
- if( isEndOfBuffer( m_DataIt, m_DataItEnd ) ) {
- return;
- }
-
- // Change active group, if necessary
- if ( m_pModel->m_strActiveGroup != groupName ) {
- // Search for already existing entry
- ObjFile::Model::ConstGroupMapIt it = m_pModel->m_Groups.find(groupName);
-
- // We are mapping groups into the object structure
- createObject( groupName );
-
- // New group name, creating a new entry
- if (it == m_pModel->m_Groups.end())
- {
- std::vector<unsigned int> *pFaceIDArray = new std::vector<unsigned int>;
- m_pModel->m_Groups[ groupName ] = pFaceIDArray;
- m_pModel->m_pGroupFaceIDs = (pFaceIDArray);
- }
- else
- {
- m_pModel->m_pGroupFaceIDs = (*it).second;
- }
- m_pModel->m_strActiveGroup = groupName;
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// Not supported
-void ObjFileParser::getGroupNumber()
-{
- // Not used
-
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-
-// -------------------------------------------------------------------
-// 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()
-{
- m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
- if( m_DataIt == m_DataItEnd ) {
- return;
- }
- char *pStart = &(*m_DataIt);
- while( m_DataIt != m_DataItEnd && !IsSpaceOrNewLine( *m_DataIt ) ) {
- ++m_DataIt;
- }
-
- std::string strObjectName(pStart, &(*m_DataIt));
- if (!strObjectName.empty())
- {
- // Reset current object
- m_pModel->m_pCurrent = NULL;
-
- // Search for actual object
- for (std::vector<ObjFile::Object*>::const_iterator it = m_pModel->m_Objects.begin();
- it != m_pModel->m_Objects.end();
- ++it)
- {
- if ((*it)->m_strObjName == strObjectName)
- {
- m_pModel->m_pCurrent = *it;
- break;
- }
- }
-
- // Allocate a new object, if current one was not found before
- if( NULL == m_pModel->m_pCurrent ) {
- createObject( strObjectName );
- }
- }
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
-}
-// -------------------------------------------------------------------
-// Creates a new object instance
-void ObjFileParser::createObject(const std::string &objName)
-{
- ai_assert( NULL != m_pModel );
-
- m_pModel->m_pCurrent = new ObjFile::Object;
- m_pModel->m_pCurrent->m_strObjName = objName;
- m_pModel->m_Objects.push_back( m_pModel->m_pCurrent );
-
- createMesh( objName );
-
- if( m_pModel->m_pCurrentMaterial )
- {
- m_pModel->m_pCurrentMesh->m_uiMaterialIndex =
- getMaterialIndex( m_pModel->m_pCurrentMaterial->MaterialName.data );
- m_pModel->m_pCurrentMesh->m_pMaterial = m_pModel->m_pCurrentMaterial;
- }
-}
-// -------------------------------------------------------------------
-// Creates a new mesh
-void ObjFileParser::createMesh( const std::string &meshName )
-{
- ai_assert( NULL != m_pModel );
- m_pModel->m_pCurrentMesh = new ObjFile::Mesh( meshName );
- m_pModel->m_Meshes.push_back( m_pModel->m_pCurrentMesh );
- unsigned int meshId = static_cast<unsigned int>(m_pModel->m_Meshes.size()-1);
- if ( NULL != m_pModel->m_pCurrent )
- {
- m_pModel->m_pCurrent->m_Meshes.push_back( meshId );
- }
- else
- {
- DefaultLogger::get()->error("OBJ: No object detected to attach a new mesh instance.");
- }
-}
-
-// -------------------------------------------------------------------
-// Returns true, if a new mesh must be created.
-bool ObjFileParser::needsNewMesh( const std::string &materialName )
-{
- // If no mesh data yet
- if(m_pModel->m_pCurrentMesh == 0)
- {
- return true;
- }
- bool newMat = false;
- int matIdx = getMaterialIndex( materialName );
- int curMatIdx = m_pModel->m_pCurrentMesh->m_uiMaterialIndex;
- if ( curMatIdx != int(ObjFile::Mesh::NoMaterial)
- && curMatIdx != matIdx
- // no need create a new mesh if no faces in current
- // lets say 'usemtl' goes straight after 'g'
- && m_pModel->m_pCurrentMesh->m_Faces.size() > 0 )
- {
- // New material -> only one material per mesh, so we need to create a new
- // material
- newMat = true;
- }
- return newMat;
-}
-
-// -------------------------------------------------------------------
-// Shows an error in parsing process.
-void ObjFileParser::reportErrorTokenInFace()
-{
- m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
- DefaultLogger::get()->error("OBJ: Not supported token in face description detected");
-}
-
-// -------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER
diff --git a/src/3rdparty/assimp/code/ObjFileParser.h b/src/3rdparty/assimp/code/ObjFileParser.h
deleted file mode 100644
index fa5b3ca31..000000000
--- a/src/3rdparty/assimp/code/ObjFileParser.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OBJ_FILEPARSER_H_INC
-#define OBJ_FILEPARSER_H_INC
-
-#include <vector>
-#include <string>
-#include <map>
-#include <assimp/vector2.h>
-#include <assimp/vector3.h>
-#include <assimp/mesh.h>
-#include "IOStreamBuffer.h"
-
-namespace Assimp {
-
-namespace ObjFile {
- struct Model;
- struct Object;
- struct Material;
- struct Point3;
- struct Point2;
-}
-
-class ObjFileImporter;
-class IOSystem;
-class ProgressHandler;
-
-/// \class ObjFileParser
-/// \brief Parser for a obj waveform file
-class ASSIMP_API ObjFileParser {
-public:
- static const size_t Buffersize = 4096;
- typedef std::vector<char> DataArray;
- typedef std::vector<char>::iterator DataArrayIt;
- typedef std::vector<char>::const_iterator ConstDataArrayIt;
-
-public:
- /// @brief The default constructor.
- ObjFileParser();
- /// @brief Constructor with data array.
- ObjFileParser( IOStreamBuffer<char> &streamBuffer, const std::string &modelName, IOSystem* io, ProgressHandler* progress, const std::string &originalObjFileName);
- /// @brief Destructor
- ~ObjFileParser();
- /// @brief If you want to load in-core data.
- void setBuffer( std::vector<char> &buffer );
- /// @brief Model getter.
- ObjFile::Model *GetModel() const;
-
-protected:
- /// Parse the loaded file
- void parseFile( IOStreamBuffer<char> &streamBuffer );
- /// 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);
- /// Get the number of components in a line.
- size_t getNumComponentsInDataDefinition();
- /// 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 homogeneous vector as a 3D vector
- void getHomogeneousVector3( std::vector<aiVector3D> &point3d_array );
- /// Stores the following two 3d vectors on the line.
- void getTwoVectors3( std::vector<aiVector3D> &point3d_array_a, std::vector<aiVector3D> &point3d_array_b );
- /// Stores the following 3d vector.
- void getVector2(std::vector<aiVector2D> &point2d_array);
- /// Stores the following face.
- void getFace(aiPrimitiveType type);
- /// 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 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
- void getObjectName();
- /// Creates a new object.
- void createObject( const std::string &strObjectName );
- /// Creates a new mesh.
- void createMesh( const std::string &meshName );
- /// Returns true, if a new mesh instance must be created.
- bool needsNewMesh( const std::string &rMaterialName );
- /// Error report in token
- void reportErrorTokenInFace();
-
-private:
- // Copy and assignment constructor should be private
- // because the class contains pointer to allocated memory
- ObjFileParser(const ObjFileParser& rhs);
- ObjFileParser& operator=(const ObjFileParser& rhs);
-
- /// Default material name
- static const std::string DEFAULT_MATERIAL;
- //! Iterator to current position in buffer
- DataArrayIt m_DataIt;
- //! Iterator to end position of buffer
- DataArrayIt m_DataItEnd;
- //! Pointer to model instance
- ObjFile::Model *m_pModel;
- //! Current line (for debugging)
- unsigned int m_uiLine;
- //! Helper buffer
- char m_buffer[Buffersize];
- /// Pointer to IO system instance.
- IOSystem *m_pIO;
- //! Pointer to progress handler
- ProgressHandler* m_progress;
- /// Path to the current model, name of the obj file where the buffer comes from
- const std::string m_originalObjFileName;
-};
-
-} // Namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/ObjTools.h b/src/3rdparty/assimp/code/ObjTools.h
deleted file mode 100644
index 7236cedc0..000000000
--- a/src/3rdparty/assimp/code/ObjTools.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ObjTools.h
- * @brief Some helpful templates for text parsing
- */
-#ifndef OBJ_TOOLS_H_INC
-#define OBJ_TOOLS_H_INC
-
-#include "fast_atof.h"
-#include "ParsingUtils.h"
-#include <vector>
-
-namespace Assimp {
-
-/** @brief Returns true, if the last entry of the buffer is reached.
- * @param it Iterator of current position.
- * @param end Iterator with end of buffer.
- * @return true, if the end of the buffer is reached.
- */
-template<class char_t>
-inline bool isEndOfBuffer( char_t it, char_t end ) {
- if ( it == end )
- {
- return true;
- }
- else
- {
- --end;
- }
- return ( it == end );
-}
-
-/** @brief Returns next word separated by a space
- * @param pBuffer Pointer to data buffer
- * @param pEnd Pointer to end of buffer
- * @return Pointer to next space
- */
-template<class Char_T>
-inline Char_T getNextWord( Char_T pBuffer, Char_T pEnd )
-{
- while ( !isEndOfBuffer( pBuffer, pEnd ) )
- {
- if ( !IsSpaceOrNewLine( *pBuffer ) || IsLineEnd( *pBuffer ) ) {
- //if ( *pBuffer != '\\' )
- break;
- }
- pBuffer++;
- }
- return pBuffer;
-}
-
-/** @brief Returns pointer a next token
- * @param pBuffer Pointer to data buffer
- * @param pEnd Pointer to end of buffer
- * @return Pointer to next token
- */
-template<class Char_T>
-inline Char_T getNextToken( Char_T pBuffer, Char_T pEnd )
-{
- while ( !isEndOfBuffer( pBuffer, pEnd ) )
- {
- if( IsSpaceOrNewLine( *pBuffer ) )
- break;
- pBuffer++;
- }
- return getNextWord( pBuffer, pEnd );
-}
-
-/** @brief Skips a line
- * @param it Iterator set to current position
- * @param end Iterator set to end of scratch buffer for readout
- * @param uiLine Current line number in format
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t skipLine( char_t it, char_t end, unsigned int &uiLine ) {
- while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it ) ) {
- ++it;
- }
-
- if ( it != end ) {
- ++it;
- ++uiLine;
- }
- // fix .. from time to time there are spaces at the beginning of a material line
- while ( it != end && ( *it == '\t' || *it == ' ' ) ) {
- ++it;
- }
-
- return it;
-}
-
-/** @brief Get a name from the current line. Preserve space in the middle,
- * but trim it at the end.
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param name Separated name
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t getName( char_t it, char_t end, std::string &name )
-{
- name = "";
- if( isEndOfBuffer( it, end ) ) {
- return end;
- }
-
- char *pStart = &( *it );
- while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it )) {
- ++it;
- }
-
- while(IsSpace( *it ) ) {
- --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;
- else
- name = strName;
-
- return it;
-}
-
-/** @brief Get a name from the current line. Do not preserve space
- * in the middle, but trim it at the end.
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param name Separated name
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t getNameNoSpace( char_t it, char_t end, std::string &name )
-{
- name = "";
- if( isEndOfBuffer( it, end ) ) {
- return end;
- }
-
- char *pStart = &( *it );
- while( !isEndOfBuffer( it, end ) && !IsLineEnd( *it )
- && !IsSpaceOrNewLine( *it ) ) {
- ++it;
- }
-
- while( isEndOfBuffer( it, end ) || IsLineEnd( *it )
- || IsSpaceOrNewLine( *it ) ) {
- --it;
- }
- ++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;
- else
- name = strName;
-
- return it;
-}
-
-/** @brief Get next word from given line
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param pBuffer Buffer for next word
- * @param length Buffer length
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t CopyNextWord( char_t it, char_t end, char *pBuffer, size_t length )
-{
- size_t index = 0;
- it = getNextWord<char_t>( it, end );
- while( !IsSpaceOrNewLine( *it ) && !isEndOfBuffer( it, end ) )
- {
- pBuffer[index] = *it ;
- index++;
- if (index == length-1)
- break;
- ++it;
- }
- pBuffer[ index ] = '\0';
- return it;
-}
-
-/** @brief Get next float from given line
- * @param it set to current position
- * @param end set to end of scratch buffer for readout
- * @param value Separated float value.
- * @return Current-iterator with new position
- */
-template<class char_t>
-inline char_t getFloat( char_t it, char_t end, ai_real &value )
-{
- static const size_t BUFFERSIZE = 1024;
- char buffer[ BUFFERSIZE ];
- it = CopyNextWord<char_t>( it, end, buffer, BUFFERSIZE );
- value = (ai_real) fast_atof( buffer );
-
- return it;
-}
-
-/** @brief Will perform a simple tokenize.
- * @param str String to tokenize.
- * @param tokens Array with tokens, will be empty if no token was found.
- * @param delimiters Delimiter for tokenize.
- * @return Number of found token.
- */
-template<class string_type>
-unsigned int tokenize( const string_type& str, std::vector<string_type>& tokens,
- const string_type& delimiters )
-{
- // Skip delimiters at beginning.
- typename string_type::size_type lastPos = str.find_first_not_of( delimiters, 0 );
-
- // Find first "non-delimiter".
- typename string_type::size_type pos = str.find_first_of( delimiters, lastPos );
- while ( string_type::npos != pos || string_type::npos != lastPos )
- {
- // Found a token, add it to the vector.
- string_type tmp = str.substr(lastPos, pos - lastPos);
- if ( !tmp.empty() && ' ' != tmp[ 0 ] )
- tokens.push_back( tmp );
-
- // Skip delimiters. Note the "not_of"
- lastPos = str.find_first_not_of( delimiters, pos );
-
- // Find next "non-delimiter"
- pos = str.find_first_of( delimiters, lastPos );
- }
-
- return static_cast<unsigned int>( tokens.size() );
-}
-
-template <class string_type>
-string_type trim_whitespaces(string_type str)
-{
- while (!str.empty() && IsSpace(str[0])) str.erase(0);
- while (!str.empty() && IsSpace(str[str.length() - 1])) str.erase(str.length() - 1);
- return str;
-}
-
-template<class T>
-bool hasLineEnd( T it, T end ) {
- bool hasLineEnd( false );
- while ( !isEndOfBuffer( it, end ) ) {
- it++;
- if ( IsLineEnd( it ) ) {
- hasLineEnd = true;
- break;
- }
- }
-
- return hasLineEnd;
-}
-
-} // Namespace Assimp
-
-#endif // OBJ_TOOLS_H_INC
diff --git a/src/3rdparty/assimp/code/OgreBinarySerializer.cpp b/src/3rdparty/assimp/code/OgreBinarySerializer.cpp
deleted file mode 100644
index 95aec221f..000000000
--- a/src/3rdparty/assimp/code/OgreBinarySerializer.cpp
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "OgreBinarySerializer.h"
-#include "OgreXmlSerializer.h"
-#include "OgreParsingUtils.h"
-
-#include "TinyFormatter.h"
-#include <assimp/DefaultLogger.hpp>
-
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-// Define as 1 to get verbose logging.
-#define OGRE_BINARY_SERIALIZER_DEBUG 0
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-const std::string MESH_VERSION_1_8 = "[MeshSerializer_v1.8]";
-const std::string SKELETON_VERSION_1_8 = "[Serializer_v1.80]";
-const std::string SKELETON_VERSION_1_1 = "[Serializer_v1.10]";
-
-const unsigned short HEADER_CHUNK_ID = 0x1000;
-
-const long MSTREAM_OVERHEAD_SIZE = sizeof(uint16_t) + sizeof(uint32_t);
-const long MSTREAM_BONE_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_SIZE + sizeof(unsigned short) + (sizeof(float) * 7);
-const long MSTREAM_KEYFRAME_SIZE_WITHOUT_SCALE = MSTREAM_OVERHEAD_SIZE + (sizeof(float) * 8);
-
-template<>
-inline bool OgreBinarySerializer::Read<bool>()
-{
- return (m_reader->GetU1() > 0);
-}
-
-template<>
-inline char OgreBinarySerializer::Read<char>()
-{
- return static_cast<char>(m_reader->GetU1());
-}
-
-template<>
-inline uint8_t OgreBinarySerializer::Read<uint8_t>()
-{
- return m_reader->GetU1();
-}
-
-template<>
-inline uint16_t OgreBinarySerializer::Read<uint16_t>()
-{
- return m_reader->GetU2();
-}
-
-template<>
-inline uint32_t OgreBinarySerializer::Read<uint32_t>()
-{
- return m_reader->GetU4();
-}
-
-template<>
-inline float OgreBinarySerializer::Read<float>()
-{
- return m_reader->GetF4();
-}
-
-void OgreBinarySerializer::ReadBytes(char *dest, size_t numBytes)
-{
- ReadBytes(static_cast<void*>(dest), numBytes);
-}
-
-void OgreBinarySerializer::ReadBytes(uint8_t *dest, size_t numBytes)
-{
- ReadBytes(static_cast<void*>(dest), numBytes);
-}
-
-void OgreBinarySerializer::ReadBytes(void *dest, size_t numBytes)
-{
- m_reader->CopyAndAdvance(dest, numBytes);
-}
-
-uint8_t *OgreBinarySerializer::ReadBytes(size_t numBytes)
-{
- uint8_t *bytes = new uint8_t[numBytes];
- ReadBytes(bytes, numBytes);
- return bytes;
-}
-
-void OgreBinarySerializer::ReadVector(aiVector3D &vec)
-{
- m_reader->CopyAndAdvance(&vec.x, sizeof(float)*3);
-}
-
-void OgreBinarySerializer::ReadQuaternion(aiQuaternion &quat)
-{
- float temp[4];
- m_reader->CopyAndAdvance(temp, sizeof(float)*4);
- quat.x = temp[0];
- quat.y = temp[1];
- quat.z = temp[2];
- quat.w = temp[3];
-}
-
-bool OgreBinarySerializer::AtEnd() const
-{
- return (m_reader->GetRemainingSize() == 0);
-}
-
-std::string OgreBinarySerializer::ReadString(size_t len)
-{
- std::string str;
- str.resize(len);
- ReadBytes(&str[0], len);
- return str;
-}
-
-std::string OgreBinarySerializer::ReadLine()
-{
- std::string str;
- while(!AtEnd())
- {
- char c = Read<char>();
- if (c == '\n')
- break;
- str += c;
- }
- return str;
-}
-
-uint16_t OgreBinarySerializer::ReadHeader(bool readLen)
-{
- uint16_t id = Read<uint16_t>();
- if (readLen)
- m_currentLen = Read<uint32_t>();
-
-#if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
- if (id != HEADER_CHUNK_ID)
- {
- DefaultLogger::get()->debug(Formatter::format() << (assetMode == AM_Mesh
- ? MeshHeaderToString(static_cast<MeshChunkId>(id)) : SkeletonHeaderToString(static_cast<SkeletonChunkId>(id))));
- }
-#endif
-
- return id;
-}
-
-void OgreBinarySerializer::RollbackHeader()
-{
- m_reader->IncPtr(-MSTREAM_OVERHEAD_SIZE);
-}
-
-void OgreBinarySerializer::SkipBytes(size_t numBytes)
-{
-#if (OGRE_BINARY_SERIALIZER_DEBUG == 1)
- DefaultLogger::get()->debug(Formatter::format() << "Skipping " << numBytes << " bytes");
-#endif
-
- m_reader->IncPtr(numBytes);
-}
-
-// Mesh
-
-Mesh *OgreBinarySerializer::ImportMesh(MemoryStreamReader *stream)
-{
- OgreBinarySerializer serializer(stream, OgreBinarySerializer::AM_Mesh);
-
- uint16_t id = serializer.ReadHeader(false);
- if (id != HEADER_CHUNK_ID) {
- throw DeadlyExportError("Invalid Ogre Mesh file header.");
- }
-
- /// @todo Check what we can actually support.
- std::string version = serializer.ReadLine();
- if (version != MESH_VERSION_1_8)
- {
- throw DeadlyExportError(Formatter::format() << "Mesh version " << version << " not supported by this importer. Run OgreMeshUpgrader tool on the file and try again."
- << " Supported versions: " << MESH_VERSION_1_8);
- }
-
- Mesh *mesh = new Mesh();
- while (!serializer.AtEnd())
- {
- id = serializer.ReadHeader();
- switch(id)
- {
- case M_MESH:
- {
- serializer.ReadMesh(mesh);
- break;
- }
- }
- }
- return mesh;
-}
-
-void OgreBinarySerializer::ReadMesh(Mesh *mesh)
-{
- mesh->hasSkeletalAnimations = Read<bool>();
-
- DefaultLogger::get()->debug("Reading Mesh");
- DefaultLogger::get()->debug(Formatter::format() << " - Skeletal animations: " << (mesh->hasSkeletalAnimations ? "true" : "false"));
-
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() &&
- (id == M_GEOMETRY ||
- id == M_SUBMESH ||
- id == M_MESH_SKELETON_LINK ||
- id == M_MESH_BONE_ASSIGNMENT ||
- id == M_MESH_LOD ||
- id == M_MESH_BOUNDS ||
- id == M_SUBMESH_NAME_TABLE ||
- id == M_EDGE_LISTS ||
- id == M_POSES ||
- id == M_ANIMATIONS ||
- id == M_TABLE_EXTREMES))
- {
- switch(id)
- {
- case M_GEOMETRY:
- {
- mesh->sharedVertexData = new VertexData();
- ReadGeometry(mesh->sharedVertexData);
- break;
- }
- case M_SUBMESH:
- {
- ReadSubMesh(mesh);
- break;
- }
- case M_MESH_SKELETON_LINK:
- {
- ReadMeshSkeletonLink(mesh);
- break;
- }
- case M_MESH_BONE_ASSIGNMENT:
- {
- ReadBoneAssignment(mesh->sharedVertexData);
- break;
- }
- case M_MESH_LOD:
- {
- ReadMeshLodInfo(mesh);
- break;
- }
- case M_MESH_BOUNDS:
- {
- ReadMeshBounds(mesh);
- break;
- }
- case M_SUBMESH_NAME_TABLE:
- {
- ReadSubMeshNames(mesh);
- break;
- }
- case M_EDGE_LISTS:
- {
- ReadEdgeList(mesh);
- break;
- }
- case M_POSES:
- {
- ReadPoses(mesh);
- break;
- }
- case M_ANIMATIONS:
- {
- ReadAnimations(mesh);
- break;
- }
- case M_TABLE_EXTREMES:
- {
- ReadMeshExtremes(mesh);
- break;
- }
- }
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-
- NormalizeBoneWeights(mesh->sharedVertexData);
-}
-
-void OgreBinarySerializer::ReadMeshLodInfo(Mesh *mesh)
-{
- // Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped.
- // @todo Put this stuff to scene/mesh custom properties. If manual mesh the app can use the information.
- ReadLine(); // strategy name
- uint16_t numLods = Read<uint16_t>();
- bool manual = Read<bool>();
-
- /// @note Main mesh is considered as LOD 0, start from index 1.
- for (size_t i=1; i<numLods; ++i)
- {
- uint16_t id = ReadHeader();
- if (id != M_MESH_LOD_USAGE) {
- throw DeadlyImportError("M_MESH_LOD does not contain a M_MESH_LOD_USAGE for each LOD level");
- }
-
- m_reader->IncPtr(sizeof(float)); // user value
-
- if (manual)
- {
- id = ReadHeader();
- if (id != M_MESH_LOD_MANUAL) {
- throw DeadlyImportError("Manual M_MESH_LOD_USAGE does not contain M_MESH_LOD_MANUAL");
- }
-
- ReadLine(); // manual mesh name (ref to another mesh)
- }
- else
- {
- for(size_t si=0, silen=mesh->NumSubMeshes(); si<silen; ++si)
- {
- id = ReadHeader();
- if (id != M_MESH_LOD_GENERATED) {
- throw DeadlyImportError("Generated M_MESH_LOD_USAGE does not contain M_MESH_LOD_GENERATED");
- }
-
- uint32_t indexCount = Read<uint32_t>();
- bool is32bit = Read<bool>();
-
- if (indexCount > 0)
- {
- uint32_t len = indexCount * (is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
- m_reader->IncPtr(len);
- }
- }
- }
- }
-}
-
-void OgreBinarySerializer::ReadMeshSkeletonLink(Mesh *mesh)
-{
- mesh->skeletonRef = ReadLine();
-}
-
-void OgreBinarySerializer::ReadMeshBounds(Mesh * /*mesh*/)
-{
- // Skip bounds, not compatible with Assimp.
- // 2x float vec3 + 1x float sphere radius
- SkipBytes(sizeof(float) * 7);
-}
-
-void OgreBinarySerializer::ReadMeshExtremes(Mesh * /*mesh*/)
-{
- // Skip extremes, not compatible with Assimp.
- size_t numBytes = m_currentLen - MSTREAM_OVERHEAD_SIZE;
- SkipBytes(numBytes);
-}
-
-void OgreBinarySerializer::ReadBoneAssignment(VertexData *dest)
-{
- if (!dest) {
- throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
- }
-
- VertexBoneAssignment ba;
- ba.vertexIndex = Read<uint32_t>();
- ba.boneIndex = Read<uint16_t>();
- ba.weight = Read<float>();
-
- dest->boneAssignments.push_back(ba);
-}
-
-void OgreBinarySerializer::ReadSubMesh(Mesh *mesh)
-{
- uint16_t id = 0;
-
- SubMesh *submesh = new SubMesh();
- submesh->materialRef = ReadLine();
- submesh->usesSharedVertexData = Read<bool>();
-
- submesh->indexData->count = Read<uint32_t>();
- submesh->indexData->faceCount = static_cast<uint32_t>(submesh->indexData->count / 3);
- submesh->indexData->is32bit = Read<bool>();
-
- DefaultLogger::get()->debug(Formatter::format() << "Reading SubMesh " << mesh->subMeshes.size());
- DefaultLogger::get()->debug(Formatter::format() << " - Material: '" << submesh->materialRef << "'");
- DefaultLogger::get()->debug(Formatter::format() << " - Uses shared geometry: " << (submesh->usesSharedVertexData ? "true" : "false"));
-
- // Index buffer
- if (submesh->indexData->count > 0)
- {
- uint32_t numBytes = submesh->indexData->count * (submesh->indexData->is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
- uint8_t *indexBuffer = ReadBytes(numBytes);
- submesh->indexData->buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(indexBuffer, numBytes, true));
-
- DefaultLogger::get()->debug(Formatter::format() << " - " << submesh->indexData->faceCount
- << " faces from " << submesh->indexData->count << (submesh->indexData->is32bit ? " 32bit" : " 16bit")
- << " indexes of " << numBytes << " bytes");
- }
-
- // Vertex buffer if not referencing the shared geometry
- if (!submesh->usesSharedVertexData)
- {
- id = ReadHeader();
- if (id != M_GEOMETRY) {
- throw DeadlyImportError("M_SUBMESH does not contain M_GEOMETRY, but shader geometry is set to false");
- }
-
- submesh->vertexData = new VertexData();
- ReadGeometry(submesh->vertexData);
- }
-
- // Bone assignment, submesh operation and texture aliases
- if (!AtEnd())
- {
- id = ReadHeader();
- while (!AtEnd() &&
- (id == M_SUBMESH_OPERATION ||
- id == M_SUBMESH_BONE_ASSIGNMENT ||
- id == M_SUBMESH_TEXTURE_ALIAS))
- {
- switch(id)
- {
- case M_SUBMESH_OPERATION:
- {
- ReadSubMeshOperation(submesh);
- break;
- }
- case M_SUBMESH_BONE_ASSIGNMENT:
- {
- ReadBoneAssignment(submesh->vertexData);
- break;
- }
- case M_SUBMESH_TEXTURE_ALIAS:
- {
- ReadSubMeshTextureAlias(submesh);
- break;
- }
- }
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-
- NormalizeBoneWeights(submesh->vertexData);
-
- submesh->index = static_cast<unsigned int>(mesh->subMeshes.size());
- mesh->subMeshes.push_back(submesh);
-}
-
-void OgreBinarySerializer::NormalizeBoneWeights(VertexData *vertexData) const
-{
- if (!vertexData || vertexData->boneAssignments.empty())
- return;
-
- std::set<uint32_t> influencedVertices;
- for (VertexBoneAssignmentList::const_iterator baIter=vertexData->boneAssignments.begin(), baEnd=vertexData->boneAssignments.end(); baIter != baEnd; ++baIter) {
- influencedVertices.insert(baIter->vertexIndex);
- }
-
- /** Normalize bone weights.
- Some exporters won't care if the sum of all bone weights
- for a single vertex equals 1 or not, so validate here. */
- const float epsilon = 0.05f;
- for (const uint32_t vertexIndex : influencedVertices)
- {
- float sum = 0.0f;
- for (VertexBoneAssignmentList::const_iterator baIter=vertexData->boneAssignments.begin(), baEnd=vertexData->boneAssignments.end(); baIter != baEnd; ++baIter)
- {
- if (baIter->vertexIndex == vertexIndex)
- sum += baIter->weight;
- }
- if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
- {
- for (auto &boneAssign : vertexData->boneAssignments)
- {
- if (boneAssign.vertexIndex == vertexIndex)
- boneAssign.weight /= sum;
- }
- }
- }
-}
-
-void OgreBinarySerializer::ReadSubMeshOperation(SubMesh *submesh)
-{
- submesh->operationType = static_cast<SubMesh::OperationType>(Read<uint16_t>());
-}
-
-void OgreBinarySerializer::ReadSubMeshTextureAlias(SubMesh *submesh)
-{
- submesh->textureAliasName = ReadLine();
- submesh->textureAliasRef = ReadLine();
-}
-
-void OgreBinarySerializer::ReadSubMeshNames(Mesh *mesh)
-{
- uint16_t id = 0;
-
- if (!AtEnd())
- {
- id = ReadHeader();
- while (!AtEnd() && id == M_SUBMESH_NAME_TABLE_ELEMENT)
- {
- uint16_t submeshIndex = Read<uint16_t>();
- SubMesh *submesh = mesh->GetSubMesh(submeshIndex);
- if (!submesh) {
- throw DeadlyImportError(Formatter::format() << "Ogre Mesh does not include submesh " << submeshIndex << " referenced in M_SUBMESH_NAME_TABLE_ELEMENT. Invalid mesh file.");
- }
-
- submesh->name = ReadLine();
- DefaultLogger::get()->debug(Formatter::format() << " - SubMesh " << submesh->index << " name '" << submesh->name << "'");
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadGeometry(VertexData *dest)
-{
- dest->count = Read<uint32_t>();
-
- DefaultLogger::get()->debug(Formatter::format() << " - Reading geometry of " << dest->count << " vertices");
-
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() &&
- (id == M_GEOMETRY_VERTEX_DECLARATION ||
- id == M_GEOMETRY_VERTEX_BUFFER))
- {
- switch(id)
- {
- case M_GEOMETRY_VERTEX_DECLARATION:
- {
- ReadGeometryVertexDeclaration(dest);
- break;
- }
- case M_GEOMETRY_VERTEX_BUFFER:
- {
- ReadGeometryVertexBuffer(dest);
- break;
- }
- }
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadGeometryVertexDeclaration(VertexData *dest)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == M_GEOMETRY_VERTEX_ELEMENT)
- {
- ReadGeometryVertexElement(dest);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadGeometryVertexElement(VertexData *dest)
-{
- VertexElement element;
- element.source = Read<uint16_t>();
- element.type = static_cast<VertexElement::Type>(Read<uint16_t>());
- element.semantic = static_cast<VertexElement::Semantic>(Read<uint16_t>());
- element.offset = Read<uint16_t>();
- element.index = Read<uint16_t>();
-
- DefaultLogger::get()->debug(Formatter::format() << " - Vertex element " << element.SemanticToString() << " of type "
- << element.TypeToString() << " index=" << element.index << " source=" << element.source);
-
- dest->vertexElements.push_back(element);
-}
-
-void OgreBinarySerializer::ReadGeometryVertexBuffer(VertexData *dest)
-{
- uint16_t bindIndex = Read<uint16_t>();
- uint16_t vertexSize = Read<uint16_t>();
-
- uint16_t id = ReadHeader();
- if (id != M_GEOMETRY_VERTEX_BUFFER_DATA)
- throw DeadlyImportError("M_GEOMETRY_VERTEX_BUFFER_DATA not found in M_GEOMETRY_VERTEX_BUFFER");
-
- if (dest->VertexSize(bindIndex) != vertexSize)
- throw DeadlyImportError("Vertex buffer size does not agree with vertex declaration in M_GEOMETRY_VERTEX_BUFFER");
-
- size_t numBytes = dest->count * vertexSize;
- uint8_t *vertexBuffer = ReadBytes(numBytes);
- dest->vertexBindings[bindIndex] = MemoryStreamPtr(new Assimp::MemoryIOStream(vertexBuffer, numBytes, true));
-
- DefaultLogger::get()->debug(Formatter::format() << " - Read vertex buffer for source " << bindIndex << " of " << numBytes << " bytes");
-}
-
-void OgreBinarySerializer::ReadEdgeList(Mesh * /*mesh*/)
-{
- // Assimp does not acknowledge LOD levels as far as I can see it. This info is just skipped.
-
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == M_EDGE_LIST_LOD)
- {
- m_reader->IncPtr(sizeof(uint16_t)); // lod index
- bool manual = Read<bool>();
-
- if (!manual)
- {
- m_reader->IncPtr(sizeof(uint8_t));
- uint32_t numTriangles = Read<uint32_t>();
- uint32_t numEdgeGroups = Read<uint32_t>();
-
- size_t skipBytes = (sizeof(uint32_t) * 8 + sizeof(float) * 4) * numTriangles;
- m_reader->IncPtr(skipBytes);
-
- for (size_t i=0; i<numEdgeGroups; ++i)
- {
- uint16_t id = ReadHeader();
- if (id != M_EDGE_GROUP)
- throw DeadlyImportError("M_EDGE_GROUP not found in M_EDGE_LIST_LOD");
-
- m_reader->IncPtr(sizeof(uint32_t) * 3);
- uint32_t numEdges = Read<uint32_t>();
- for (size_t j=0; j<numEdges; ++j)
- {
- m_reader->IncPtr(sizeof(uint32_t) * 6 + sizeof(uint8_t));
- }
- }
- }
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadPoses(Mesh *mesh)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == M_POSE)
- {
- Pose *pose = new Pose();
- pose->name = ReadLine();
- pose->target = Read<uint16_t>();
- pose->hasNormals = Read<bool>();
-
- ReadPoseVertices(pose);
-
- mesh->poses.push_back(pose);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadPoseVertices(Pose *pose)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == M_POSE_VERTEX)
- {
- Pose::Vertex v;
- v.index = Read<uint32_t>();
- ReadVector(v.offset);
- if (pose->hasNormals)
- ReadVector(v.normal);
-
- pose->vertices[v.index] = v;
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadAnimations(Mesh *mesh)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == M_ANIMATION)
- {
- Animation *anim = new Animation(mesh);
- anim->name = ReadLine();
- anim->length = Read<float>();
-
- ReadAnimation(anim);
-
- mesh->animations.push_back(anim);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadAnimation(Animation *anim)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- if (id == M_ANIMATION_BASEINFO)
- {
- anim->baseName = ReadLine();
- anim->baseTime = Read<float>();
-
- // Advance to first track
- id = ReadHeader();
- }
-
- while (!AtEnd() && id == M_ANIMATION_TRACK)
- {
- VertexAnimationTrack track;
- track.type = static_cast<VertexAnimationTrack::Type>(Read<uint16_t>());
- track.target = Read<uint16_t>();
-
- ReadAnimationKeyFrames(anim, &track);
-
- anim->tracks.push_back(track);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-void OgreBinarySerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track)
-{
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- while (!AtEnd() &&
- (id == M_ANIMATION_MORPH_KEYFRAME ||
- id == M_ANIMATION_POSE_KEYFRAME))
- {
- if (id == M_ANIMATION_MORPH_KEYFRAME)
- {
- MorphKeyFrame kf;
- kf.timePos = Read<float>();
- bool hasNormals = Read<bool>();
-
- size_t vertexCount = anim->AssociatedVertexData(track)->count;
- size_t vertexSize = sizeof(float) * (hasNormals ? 6 : 3);
- size_t numBytes = vertexCount * vertexSize;
-
- uint8_t *morphBuffer = ReadBytes(numBytes);
- kf.buffer = MemoryStreamPtr(new Assimp::MemoryIOStream(morphBuffer, numBytes, true));
-
- track->morphKeyFrames.push_back(kf);
- }
- else if (id == M_ANIMATION_POSE_KEYFRAME)
- {
- PoseKeyFrame kf;
- kf.timePos = Read<float>();
-
- if (!AtEnd())
- {
- id = ReadHeader();
- while (!AtEnd() && id == M_ANIMATION_POSE_REF)
- {
- PoseRef pr;
- pr.index = Read<uint16_t>();
- pr.influence = Read<float>();
- kf.references.push_back(pr);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-
- track->poseKeyFrames.push_back(kf);
- }
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-}
-
-// Skeleton
-
-bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
-{
- if (!mesh || mesh->skeletonRef.empty())
- return false;
-
- // Highly unusual to see in read world cases but support
- // binary mesh referencing a XML skeleton file.
- if (EndsWith(mesh->skeletonRef, ".skeleton.xml", false))
- {
- OgreXmlSerializer::ImportSkeleton(pIOHandler, mesh);
- return false;
- }
-
- MemoryStreamReaderPtr reader = OpenReader(pIOHandler, mesh->skeletonRef);
-
- Skeleton *skeleton = new Skeleton();
- OgreBinarySerializer serializer(reader.get(), OgreBinarySerializer::AM_Skeleton);
- serializer.ReadSkeleton(skeleton);
- mesh->skeleton = skeleton;
- return true;
-}
-
-bool OgreBinarySerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
-{
- if (!mesh || mesh->skeletonRef.empty())
- return false;
-
- MemoryStreamReaderPtr reader = OpenReader(pIOHandler, mesh->skeletonRef);
- if (!reader.get())
- return false;
-
- Skeleton *skeleton = new Skeleton();
- OgreBinarySerializer serializer(reader.get(), OgreBinarySerializer::AM_Skeleton);
- serializer.ReadSkeleton(skeleton);
- mesh->skeleton = skeleton;
- return true;
-}
-
-MemoryStreamReaderPtr OgreBinarySerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
-{
- if (!EndsWith(filename, ".skeleton", false))
- {
- DefaultLogger::get()->error("Imported Mesh is referencing to unsupported '" + filename + "' skeleton file.");
- return MemoryStreamReaderPtr();
- }
-
- if (!pIOHandler->Exists(filename))
- {
- DefaultLogger::get()->error("Failed to find skeleton file '" + filename + "' that is referenced by imported Mesh.");
- return MemoryStreamReaderPtr();
- }
-
- IOStream *f = pIOHandler->Open(filename, "rb");
- if (!f) {
- throw DeadlyImportError("Failed to open skeleton file " + filename);
- }
-
- return MemoryStreamReaderPtr(new MemoryStreamReader(f));
-}
-
-void OgreBinarySerializer::ReadSkeleton(Skeleton *skeleton)
-{
- uint16_t id = ReadHeader(false);
- if (id != HEADER_CHUNK_ID) {
- throw DeadlyExportError("Invalid Ogre Skeleton file header.");
- }
-
- // This deserialization supports both versions of the skeleton spec
- std::string version = ReadLine();
- if (version != SKELETON_VERSION_1_8 && version != SKELETON_VERSION_1_1)
- {
- throw DeadlyExportError(Formatter::format() << "Skeleton version " << version << " not supported by this importer."
- << " Supported versions: " << SKELETON_VERSION_1_8 << " and " << SKELETON_VERSION_1_1);
- }
-
- DefaultLogger::get()->debug("Reading Skeleton");
-
- bool firstBone = true;
- bool firstAnim = true;
-
- while (!AtEnd())
- {
- id = ReadHeader();
- switch(id)
- {
- case SKELETON_BLENDMODE:
- {
- skeleton->blendMode = static_cast<Skeleton::BlendMode>(Read<uint16_t>());
- break;
- }
- case SKELETON_BONE:
- {
- if (firstBone)
- {
- DefaultLogger::get()->debug(" - Bones");
- firstBone = false;
- }
-
- ReadBone(skeleton);
- break;
- }
- case SKELETON_BONE_PARENT:
- {
- ReadBoneParent(skeleton);
- break;
- }
- case SKELETON_ANIMATION:
- {
- if (firstAnim)
- {
- DefaultLogger::get()->debug(" - Animations");
- firstAnim = false;
- }
-
- ReadSkeletonAnimation(skeleton);
- break;
- }
- case SKELETON_ANIMATION_LINK:
- {
- ReadSkeletonAnimationLink(skeleton);
- break;
- }
- }
- }
-
- // Calculate bone matrices for root bones. Recursively calculates their children.
- for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
- {
- Bone *bone = skeleton->bones[i];
- if (!bone->IsParented())
- bone->CalculateWorldMatrixAndDefaultPose(skeleton);
- }
-}
-
-void OgreBinarySerializer::ReadBone(Skeleton *skeleton)
-{
- Bone *bone = new Bone();
- bone->name = ReadLine();
- bone->id = Read<uint16_t>();
-
- // Pos and rot
- ReadVector(bone->position);
- ReadQuaternion(bone->rotation);
-
- // Scale (optional)
- if (m_currentLen > MSTREAM_BONE_SIZE_WITHOUT_SCALE)
- ReadVector(bone->scale);
-
- // Bone indexes need to start from 0 and be contiguous
- if (bone->id != skeleton->bones.size()) {
- throw DeadlyImportError(Formatter::format() << "Ogre Skeleton bone indexes not contiguous. Error at bone index " << bone->id);
- }
-
- DefaultLogger::get()->debug(Formatter::format() << " " << bone->id << " " << bone->name);
-
- skeleton->bones.push_back(bone);
-}
-
-void OgreBinarySerializer::ReadBoneParent(Skeleton *skeleton)
-{
- uint16_t childId = Read<uint16_t>();
- uint16_t parentId = Read<uint16_t>();
-
- Bone *child = skeleton->BoneById(childId);
- Bone *parent = skeleton->BoneById(parentId);
-
- if (child && parent)
- parent->AddChild(child);
- else
- throw DeadlyImportError(Formatter::format() << "Failed to find bones for parenting: Child id " << childId << " for parent id " << parentId);
-}
-
-void OgreBinarySerializer::ReadSkeletonAnimation(Skeleton *skeleton)
-{
- Animation *anim = new Animation(skeleton);
- anim->name = ReadLine();
- anim->length = Read<float>();
-
- if (!AtEnd())
- {
- uint16_t id = ReadHeader();
- if (id == SKELETON_ANIMATION_BASEINFO)
- {
- anim->baseName = ReadLine();
- anim->baseTime = Read<float>();
-
- // Advance to first track
- id = ReadHeader();
- }
-
- while (!AtEnd() && id == SKELETON_ANIMATION_TRACK)
- {
- ReadSkeletonAnimationTrack(skeleton, anim);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
- }
-
- skeleton->animations.push_back(anim);
-
- DefaultLogger::get()->debug(Formatter::format() << " " << anim->name << " (" << anim->length << " sec, " << anim->tracks.size() << " tracks)");
-}
-
-void OgreBinarySerializer::ReadSkeletonAnimationTrack(Skeleton * /*skeleton*/, Animation *dest)
-{
- uint16_t boneId = Read<uint16_t>();
- Bone *bone = dest->parentSkeleton->BoneById(boneId);
- if (!bone) {
- throw DeadlyImportError(Formatter::format() << "Cannot read animation track, target bone " << boneId << " not in target Skeleton");
- }
-
- VertexAnimationTrack track;
- track.type = VertexAnimationTrack::VAT_TRANSFORM;
- track.boneName = bone->name;
-
- uint16_t id = ReadHeader();
- while (!AtEnd() && id == SKELETON_ANIMATION_TRACK_KEYFRAME)
- {
- ReadSkeletonAnimationKeyFrame(&track);
-
- if (!AtEnd())
- id = ReadHeader();
- }
- if (!AtEnd())
- RollbackHeader();
-
- dest->tracks.push_back(track);
-}
-
-void OgreBinarySerializer::ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest)
-{
- TransformKeyFrame keyframe;
- keyframe.timePos = Read<float>();
-
- // Rot and pos
- ReadQuaternion(keyframe.rotation);
- ReadVector(keyframe.position);
-
- // Scale (optional)
- if (m_currentLen > MSTREAM_KEYFRAME_SIZE_WITHOUT_SCALE)
- ReadVector(keyframe.scale);
-
- dest->transformKeyFrames.push_back(keyframe);
-}
-
-void OgreBinarySerializer::ReadSkeletonAnimationLink(Skeleton * /*skeleton*/)
-{
- // Skip bounds, not compatible with Assimp.
- ReadLine(); // skeleton name
- SkipBytes(sizeof(float) * 3); // scale
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/src/3rdparty/assimp/code/OgreBinarySerializer.h b/src/3rdparty/assimp/code/OgreBinarySerializer.h
deleted file mode 100644
index c48e33dd6..000000000
--- a/src/3rdparty/assimp/code/OgreBinarySerializer.h
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OGREBINARYSERIALIZER_H_INC
-#define AI_OGREBINARYSERIALIZER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "OgreStructs.h"
-#include "StreamReader.h"
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-typedef Assimp::StreamReaderLE MemoryStreamReader;
-typedef std::shared_ptr<MemoryStreamReader> MemoryStreamReaderPtr;
-
-class OgreBinarySerializer
-{
-public:
- /// Imports mesh and returns the result.
- /** @note Fatal unrecoverable errors will throw a DeadlyImportError. */
- static Mesh *ImportMesh(MemoryStreamReader *reader);
-
- /// Imports skeleton to @c mesh into Mesh::skeleton.
- /** If mesh does not have a skeleton reference or the skeleton file
- cannot be found it is not a fatal DeadlyImportError.
- @return If skeleton import was successful. */
- static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh);
- static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh);
-
-private:
- enum AssetMode
- {
- AM_Mesh,
- AM_Skeleton
- };
-
- OgreBinarySerializer(MemoryStreamReader *reader, AssetMode mode) :
- m_currentLen(0),
- m_reader(reader),
- assetMode(mode)
- {
- }
-
- static MemoryStreamReaderPtr OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename);
-
- // Header
-
- uint16_t ReadHeader(bool readLen = true);
- void RollbackHeader();
-
- // Mesh
-
- void ReadMesh(Mesh *mesh);
- void ReadMeshLodInfo(Mesh *mesh);
- void ReadMeshSkeletonLink(Mesh *mesh);
- void ReadMeshBounds(Mesh *mesh);
- void ReadMeshExtremes(Mesh *mesh);
-
- void ReadSubMesh(Mesh *mesh);
- void ReadSubMeshNames(Mesh *mesh);
- void ReadSubMeshOperation(SubMesh *submesh);
- void ReadSubMeshTextureAlias(SubMesh *submesh);
-
- void ReadBoneAssignment(VertexData *dest);
-
- void ReadGeometry(VertexData *dest);
- void ReadGeometryVertexDeclaration(VertexData *dest);
- void ReadGeometryVertexElement(VertexData *dest);
- void ReadGeometryVertexBuffer(VertexData *dest);
-
- void ReadEdgeList(Mesh *mesh);
- void ReadPoses(Mesh *mesh);
- void ReadPoseVertices(Pose *pose);
-
- void ReadAnimations(Mesh *mesh);
- void ReadAnimation(Animation *anim);
- void ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *track);
-
- void NormalizeBoneWeights(VertexData *vertexData) const;
-
- // Skeleton
-
- void ReadSkeleton(Skeleton *skeleton);
-
- void ReadBone(Skeleton *skeleton);
- void ReadBoneParent(Skeleton *skeleton);
-
- void ReadSkeletonAnimation(Skeleton *skeleton);
- void ReadSkeletonAnimationTrack(Skeleton *skeleton, Animation *dest);
- void ReadSkeletonAnimationKeyFrame(VertexAnimationTrack *dest);
- void ReadSkeletonAnimationLink(Skeleton *skeleton);
-
- // Reader utils
- bool AtEnd() const;
-
- template<typename T>
- inline T Read();
-
- void ReadBytes(char *dest, size_t numBytes);
- void ReadBytes(uint8_t *dest, size_t numBytes);
- void ReadBytes(void *dest, size_t numBytes);
- uint8_t *ReadBytes(size_t numBytes);
-
- void ReadVector(aiVector3D &vec);
- void ReadQuaternion(aiQuaternion &quat);
-
- std::string ReadString(size_t len);
- std::string ReadLine();
-
- void SkipBytes(size_t numBytes);
-
- uint32_t m_currentLen;
- MemoryStreamReader *m_reader;
-
- AssetMode assetMode;
-};
-
-enum MeshChunkId
-{
- M_HEADER = 0x1000,
- // char* version : Version number check
- M_MESH = 0x3000,
- // bool skeletallyAnimated // important flag which affects h/w buffer policies
- // Optional M_GEOMETRY chunk
- M_SUBMESH = 0x4000,
- // char* materialName
- // bool useSharedVertices
- // unsigned int indexCount
- // bool indexes32Bit
- // unsigned int* faceVertexIndices (indexCount)
- // OR
- // unsigned short* faceVertexIndices (indexCount)
- // M_GEOMETRY chunk (Optional: present only if useSharedVertices = false)
- M_SUBMESH_OPERATION = 0x4010, // optional, trilist assumed if missing
- // unsigned short operationType
- M_SUBMESH_BONE_ASSIGNMENT = 0x4100,
- // Optional bone weights (repeating section)
- // unsigned int vertexIndex;
- // unsigned short boneIndex;
- // float weight;
- // Optional chunk that matches a texture name to an alias
- // a texture alias is sent to the submesh material to use this texture name
- // instead of the one in the texture unit with a matching alias name
- M_SUBMESH_TEXTURE_ALIAS = 0x4200, // Repeating section
- // char* aliasName;
- // char* textureName;
-
- M_GEOMETRY = 0x5000, // NB this chunk is embedded within M_MESH and M_SUBMESH
- // unsigned int vertexCount
- M_GEOMETRY_VERTEX_DECLARATION = 0x5100,
- M_GEOMETRY_VERTEX_ELEMENT = 0x5110, // Repeating section
- // unsigned short source; // buffer bind source
- // unsigned short type; // VertexElementType
- // unsigned short semantic; // VertexElementSemantic
- // unsigned short offset; // start offset in buffer in bytes
- // unsigned short index; // index of the semantic (for colours and texture coords)
- M_GEOMETRY_VERTEX_BUFFER = 0x5200, // Repeating section
- // unsigned short bindIndex; // Index to bind this buffer to
- // unsigned short vertexSize; // Per-vertex size, must agree with declaration at this index
- M_GEOMETRY_VERTEX_BUFFER_DATA = 0x5210,
- // raw buffer data
- M_MESH_SKELETON_LINK = 0x6000,
- // Optional link to skeleton
- // char* skeletonName : name of .skeleton to use
- M_MESH_BONE_ASSIGNMENT = 0x7000,
- // Optional bone weights (repeating section)
- // unsigned int vertexIndex;
- // unsigned short boneIndex;
- // float weight;
- M_MESH_LOD = 0x8000,
- // Optional LOD information
- // string strategyName;
- // unsigned short numLevels;
- // bool manual; (true for manual alternate meshes, false for generated)
- M_MESH_LOD_USAGE = 0x8100,
- // Repeating section, ordered in increasing depth
- // NB LOD 0 (full detail from 0 depth) is omitted
- // LOD value - this is a distance, a pixel count etc, based on strategy
- // float lodValue;
- M_MESH_LOD_MANUAL = 0x8110,
- // Required if M_MESH_LOD section manual = true
- // String manualMeshName;
- M_MESH_LOD_GENERATED = 0x8120,
- // Required if M_MESH_LOD section manual = false
- // Repeating section (1 per submesh)
- // unsigned int indexCount;
- // bool indexes32Bit
- // unsigned short* faceIndexes; (indexCount)
- // OR
- // unsigned int* faceIndexes; (indexCount)
- M_MESH_BOUNDS = 0x9000,
- // float minx, miny, minz
- // float maxx, maxy, maxz
- // float radius
-
- // Added By DrEvil
- // optional chunk that contains a table of submesh indexes and the names of
- // the sub-meshes.
- M_SUBMESH_NAME_TABLE = 0xA000,
- // Subchunks of the name table. Each chunk contains an index & string
- M_SUBMESH_NAME_TABLE_ELEMENT = 0xA100,
- // short index
- // char* name
- // Optional chunk which stores precomputed edge data
- M_EDGE_LISTS = 0xB000,
- // Each LOD has a separate edge list
- M_EDGE_LIST_LOD = 0xB100,
- // unsigned short lodIndex
- // bool isManual // If manual, no edge data here, loaded from manual mesh
- // bool isClosed
- // unsigned long numTriangles
- // unsigned long numEdgeGroups
- // Triangle* triangleList
- // unsigned long indexSet
- // unsigned long vertexSet
- // unsigned long vertIndex[3]
- // unsigned long sharedVertIndex[3]
- // float normal[4]
-
- M_EDGE_GROUP = 0xB110,
- // unsigned long vertexSet
- // unsigned long triStart
- // unsigned long triCount
- // unsigned long numEdges
- // Edge* edgeList
- // unsigned long triIndex[2]
- // unsigned long vertIndex[2]
- // unsigned long sharedVertIndex[2]
- // bool degenerate
- // Optional poses section, referred to by pose keyframes
- M_POSES = 0xC000,
- M_POSE = 0xC100,
- // char* name (may be blank)
- // unsigned short target // 0 for shared geometry,
- // 1+ for submesh index + 1
- // bool includesNormals [1.8+]
- M_POSE_VERTEX = 0xC111,
- // unsigned long vertexIndex
- // float xoffset, yoffset, zoffset
- // float xnormal, ynormal, znormal (optional, 1.8+)
- // Optional vertex animation chunk
- M_ANIMATIONS = 0xD000,
- M_ANIMATION = 0xD100,
- // char* name
- // float length
- M_ANIMATION_BASEINFO = 0xD105,
- // [Optional] base keyframe information (pose animation only)
- // char* baseAnimationName (blank for self)
- // float baseKeyFrameTime
- M_ANIMATION_TRACK = 0xD110,
- // unsigned short type // 1 == morph, 2 == pose
- // unsigned short target // 0 for shared geometry,
- // 1+ for submesh index + 1
- M_ANIMATION_MORPH_KEYFRAME = 0xD111,
- // float time
- // bool includesNormals [1.8+]
- // float x,y,z // repeat by number of vertices in original geometry
- M_ANIMATION_POSE_KEYFRAME = 0xD112,
- // float time
- M_ANIMATION_POSE_REF = 0xD113, // repeat for number of referenced poses
- // unsigned short poseIndex
- // float influence
- // Optional submesh extreme vertex list chink
- M_TABLE_EXTREMES = 0xE000
- // unsigned short submesh_index;
- // float extremes [n_extremes][3];
-};
-
-/*
-static std::string MeshHeaderToString(MeshChunkId id)
-{
- switch(id)
- {
- case M_HEADER: return "HEADER";
- case M_MESH: return "MESH";
- case M_SUBMESH: return "SUBMESH";
- case M_SUBMESH_OPERATION: return "SUBMESH_OPERATION";
- case M_SUBMESH_BONE_ASSIGNMENT: return "SUBMESH_BONE_ASSIGNMENT";
- case M_SUBMESH_TEXTURE_ALIAS: return "SUBMESH_TEXTURE_ALIAS";
- case M_GEOMETRY: return "GEOMETRY";
- case M_GEOMETRY_VERTEX_DECLARATION: return "GEOMETRY_VERTEX_DECLARATION";
- case M_GEOMETRY_VERTEX_ELEMENT: return "GEOMETRY_VERTEX_ELEMENT";
- case M_GEOMETRY_VERTEX_BUFFER: return "GEOMETRY_VERTEX_BUFFER";
- case M_GEOMETRY_VERTEX_BUFFER_DATA: return "GEOMETRY_VERTEX_BUFFER_DATA";
- case M_MESH_SKELETON_LINK: return "MESH_SKELETON_LINK";
- case M_MESH_BONE_ASSIGNMENT: return "MESH_BONE_ASSIGNMENT";
- case M_MESH_LOD: return "MESH_LOD";
- case M_MESH_LOD_USAGE: return "MESH_LOD_USAGE";
- case M_MESH_LOD_MANUAL: return "MESH_LOD_MANUAL";
- case M_MESH_LOD_GENERATED: return "MESH_LOD_GENERATED";
- case M_MESH_BOUNDS: return "MESH_BOUNDS";
- case M_SUBMESH_NAME_TABLE: return "SUBMESH_NAME_TABLE";
- case M_SUBMESH_NAME_TABLE_ELEMENT: return "SUBMESH_NAME_TABLE_ELEMENT";
- case M_EDGE_LISTS: return "EDGE_LISTS";
- case M_EDGE_LIST_LOD: return "EDGE_LIST_LOD";
- case M_EDGE_GROUP: return "EDGE_GROUP";
- case M_POSES: return "POSES";
- case M_POSE: return "POSE";
- case M_POSE_VERTEX: return "POSE_VERTEX";
- case M_ANIMATIONS: return "ANIMATIONS";
- case M_ANIMATION: return "ANIMATION";
- case M_ANIMATION_BASEINFO: return "ANIMATION_BASEINFO";
- case M_ANIMATION_TRACK: return "ANIMATION_TRACK";
- case M_ANIMATION_MORPH_KEYFRAME: return "ANIMATION_MORPH_KEYFRAME";
- case M_ANIMATION_POSE_KEYFRAME: return "ANIMATION_POSE_KEYFRAME";
- case M_ANIMATION_POSE_REF: return "ANIMATION_POSE_REF";
- case M_TABLE_EXTREMES: return "TABLE_EXTREMES";
- }
- return "Unknown_MeshChunkId";
-}
-*/
-
-enum SkeletonChunkId
-{
- SKELETON_HEADER = 0x1000,
- // char* version : Version number check
- SKELETON_BLENDMODE = 0x1010, // optional
- // unsigned short blendmode : SkeletonAnimationBlendMode
- SKELETON_BONE = 0x2000,
- // Repeating section defining each bone in the system.
- // Bones are assigned indexes automatically based on their order of declaration
- // starting with 0.
- // char* name : name of the bone
- // unsigned short handle : handle of the bone, should be contiguous & start at 0
- // Vector3 position : position of this bone relative to parent
- // Quaternion orientation : orientation of this bone relative to parent
- // Vector3 scale : scale of this bone relative to parent
- SKELETON_BONE_PARENT = 0x3000,
- // Record of the parent of a single bone, used to build the node tree
- // Repeating section, listed in Bone Index order, one per Bone
- // unsigned short handle : child bone
- // unsigned short parentHandle : parent bone
- SKELETON_ANIMATION = 0x4000,
- // A single animation for this skeleton
- // char* name : Name of the animation
- // float length : Length of the animation in seconds
- SKELETON_ANIMATION_BASEINFO = 0x4010,
- // [Optional] base keyframe information
- // char* baseAnimationName (blank for self)
- // float baseKeyFrameTime
- SKELETON_ANIMATION_TRACK = 0x4100,
- // A single animation track (relates to a single bone)
- // Repeating section (within SKELETON_ANIMATION)
- // unsigned short boneIndex : Index of bone to apply to
- SKELETON_ANIMATION_TRACK_KEYFRAME = 0x4110,
- // A single keyframe within the track
- // Repeating section
- // float time : The time position (seconds)
- // Quaternion rotate : Rotation to apply at this keyframe
- // Vector3 translate : Translation to apply at this keyframe
- // Vector3 scale : Scale to apply at this keyframe
- SKELETON_ANIMATION_LINK = 0x5000
- // Link to another skeleton, to re-use its animations
- // char* skeletonName : name of skeleton to get animations from
- // float scale : scale to apply to trans/scale keys
-};
-
-/*
-static std::string SkeletonHeaderToString(SkeletonChunkId id)
-{
- switch(id)
- {
- case SKELETON_HEADER: return "HEADER";
- case SKELETON_BLENDMODE: return "BLENDMODE";
- case SKELETON_BONE: return "BONE";
- case SKELETON_BONE_PARENT: return "BONE_PARENT";
- case SKELETON_ANIMATION: return "ANIMATION";
- case SKELETON_ANIMATION_BASEINFO: return "ANIMATION_BASEINFO";
- case SKELETON_ANIMATION_TRACK: return "ANIMATION_TRACK";
- case SKELETON_ANIMATION_TRACK_KEYFRAME: return "ANIMATION_TRACK_KEYFRAME";
- case SKELETON_ANIMATION_LINK: return "ANIMATION_LINK";
- }
- return "Unknown_SkeletonChunkId";
-}
-*/
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
-#endif // AI_OGREBINARYSERIALIZER_H_INC
diff --git a/src/3rdparty/assimp/code/OgreImporter.cpp b/src/3rdparty/assimp/code/OgreImporter.cpp
deleted file mode 100644
index 4dc802574..000000000
--- a/src/3rdparty/assimp/code/OgreImporter.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "OgreImporter.h"
-#include "OgreBinarySerializer.h"
-#include "OgreXmlSerializer.h"
-#include <assimp/Importer.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-static const aiImporterDesc desc = {
- "Ogre3D Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "mesh mesh.xml"
-};
-
-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) {
- return EndsWith(pFile, ".mesh.xml", false) || EndsWith(pFile, ".mesh", false);
- }
-
- if (EndsWith(pFile, ".mesh.xml", false))
- {
- const char* tokens[] = { "<mesh>" };
- return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
- }
- else
- {
- /// @todo Read and validate first header chunk?
- return EndsWith(pFile, ".mesh", false);
- }
-}
-
-void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Assimp::IOSystem *pIOHandler)
-{
- // Open source file
- IOStream *f = pIOHandler->Open(pFile, "rb");
- if (!f) {
- throw DeadlyImportError("Failed to open file " + pFile);
- }
-
- // Binary .mesh import
- if (EndsWith(pFile, ".mesh", false))
- {
- /// @note MemoryStreamReader takes ownership of f.
- MemoryStreamReader reader(f);
-
- // Import mesh
- std::unique_ptr<Mesh> mesh(OgreBinarySerializer::ImportMesh(&reader));
-
- // Import skeleton
- OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh.get());
-
- // Import mesh referenced materials
- ReadMaterials(pFile, pIOHandler, pScene, mesh.get());
-
- // Convert to Assimp
- mesh->ConvertToAssimpScene(pScene);
- }
- // XML .mesh.xml import
- else
- {
- /// @note XmlReader does not take ownership of f, hence the scoped ptr.
- std::unique_ptr<IOStream> scopedFile(f);
- std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(scopedFile.get()));
- std::unique_ptr<XmlReader> reader(irr::io::createIrrXMLReader(xmlStream.get()));
-
- // Import mesh
- std::unique_ptr<MeshXml> mesh(OgreXmlSerializer::ImportMesh(reader.get()));
-
- // Import skeleton
- OgreXmlSerializer::ImportSkeleton(pIOHandler, mesh.get());
-
- // Import mesh referenced materials
- ReadMaterials(pFile, pIOHandler, pScene, mesh.get());
-
- // Convert to Assimp
- mesh->ConvertToAssimpScene(pScene);
- }
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/src/3rdparty/assimp/code/OgreImporter.h b/src/3rdparty/assimp/code/OgreImporter.h
deleted file mode 100644
index 2b3009096..000000000
--- a/src/3rdparty/assimp/code/OgreImporter.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OGREIMPORTER_H_INC
-#define AI_OGREIMPORTER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "BaseImporter.h"
-
-#include "OgreStructs.h"
-#include "OgreParsingUtils.h"
-
-#include <assimp/material.h>
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-/** Importer for Ogre mesh, skeleton and material formats.
- @todo Support vertex colors.
- @todo Support poses/animations from the mesh file.
- Currently only skeleton file animations are supported. */
-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:
- /// Read materials referenced by the @c mesh to @c pScene.
- void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh);
- void ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh);
- void AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &materials);
-
- /// 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;
-
- std::map<aiTextureType, unsigned int> m_textures;
-};
-} // 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
deleted file mode 100644
index 1abca2cf1..000000000
--- a/src/3rdparty/assimp/code/OgreMaterial.cpp
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "OgreImporter.h"
-#include "TinyFormatter.h"
-#include <assimp/material.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include "fast_atof.h"
-
-#include <vector>
-#include <sstream>
-#include <memory>
-
-using namespace std;
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-static const string partComment = "//";
-static const string partBlockStart = "{";
-static const string partBlockEnd = "}";
-
-void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh)
-{
- std::vector<aiMaterial*> materials;
-
- // Create materials that can be found and parsed via the IOSystem.
- for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
- {
- SubMesh *submesh = mesh->GetSubMesh(i);
- if (submesh && !submesh->materialRef.empty())
- {
- aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
- if (material)
- {
- submesh->materialIndex = static_cast<int>(materials.size());
- materials.push_back(material);
- }
- }
- }
-
- AssignMaterials(pScene, materials);
-}
-
-void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh)
-{
- std::vector<aiMaterial*> materials;
-
- // Create materials that can be found and parsed via the IOSystem.
- for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i)
- {
- SubMeshXml *submesh = mesh->GetSubMesh( static_cast<uint16_t>(i));
- if (submesh && !submesh->materialRef.empty())
- {
- aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
- if (material)
- {
- submesh->materialIndex = static_cast<int>(materials.size());
- materials.push_back(material);
- }
- }
- }
-
- AssignMaterials(pScene, materials);
-}
-
-void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &materials)
-{
- pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
- if (pScene->mNumMaterials > 0)
- {
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for(size_t i=0;i<pScene->mNumMaterials; ++i) {
- pScene->mMaterials[i] = materials[i];
- }
- }
-}
-
-aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string &materialName)
-{
- if (materialName.empty()) {
- return 0;
- }
-
- // 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:
-
- import * from abstract_base_passes_depth.material
- import * from abstract_base.material
- import * from mat_shadow_caster.material
- import * from mat_character_singlepass.material
-
- material hero/hair/caster : mat_shadow_caster_skin_areject
- {
- set $diffuse_map "hero_hair_alpha_c.dds"
- }
-
- material hero/hair_alpha : mat_char_cns_singlepass_areject_4weights
- {
- set $diffuse_map "hero_hair_alpha_c.dds"
- set $specular_map "hero_hair_alpha_s.dds"
- set $normal_map "hero_hair_alpha_n.dds"
- set $light_map "black_lightmap.dds"
-
- set $shadow_caster_material "hero/hair/caster"
- }
- */
-
- stringstream ss;
-
- // 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 *materialFile = 0;
- for(size_t i=0; i<potentialFiles.size(); ++i)
- {
- 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)
- {
- DefaultLogger::get()->error(Formatter::format() << "Failed to find source file for material '" << materialName << "'");
- return 0;
- }
-
- std::unique_ptr<IOStream> stream(materialFile);
- if (stream->FileSize() == 0)
- {
- DefaultLogger::get()->warn(Formatter::format() << "Source file for material '" << materialName << "' is empty (size is 0 bytes)");
- return 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 + "'");
-
- aiMaterial *material = new aiMaterial();
- m_textures.clear();
-
- aiString ts(materialName);
- material->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";
-
- while(!ss.eof())
- {
- // Skip commented lines
- if (linePart == partComment)
- {
- NextAfterNewLine(ss, linePart);
- 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)
- {
- 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 techniqueName = SkipLine(ss);
- ReadTechnique(Trim(techniqueName), ss, material);
- }
-
- // Read information 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:
- {
- }
- else if (linePart=="$diffuse")
- {
- }
- 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);
- }
- aiString ts(linePart);
- material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP, 0));
- }
- }
- }
- 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;
- }
-
- DefaultLogger::get()->debug(" technique '" + techniqueName + "'");
-
- const string partPass = "pass";
-
- while(linePart != partBlockEnd)
- {
- ss >> linePart;
-
- // Skip commented lines
- if (linePart == partComment)
- {
- SkipLine(ss);
- continue;
- }
-
- /// @todo Techniques have other attributes than just passes.
- if (linePart == partPass)
- {
- string passName = SkipLine(ss);
- ReadPass(Trim(passName), ss, material);
- }
- }
- return true;
-}
-
-bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material)
-{
- 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 + "'");
-
- const string partAmbient = "ambient";
- const string partDiffuse = "diffuse";
- const string partSpecular = "specular";
- const string partEmissive = "emissive";
- const string partTextureUnit = "texture_unit";
-
- while(linePart != partBlockEnd)
- {
- ss >> linePart;
-
- // Skip commented lines
- if (linePart == partComment)
- {
- SkipLine(ss);
- 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;
- }
-
- 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 >> linePart;
-
- // Skip commented lines
- if (linePart == partComment)
- {
- SkipLine(ss);
- continue;
- }
-
- if (linePart == partTexture)
- {
- ss >> linePart;
- textureRef = linePart;
-
- // User defined Assimp config property to detect texture type from filename.
- if (m_detectTextureTypeFromFilename)
- {
- 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;
- }
- }
- // Detect from texture unit name. This cannot be too broad as
- // authors might give names like "LightSaber" or "NormalNinja".
- else
- {
- string unitNameLower = Ogre::ToLower(textureUnitName);
- if (unitNameLower.find("normalmap") != string::npos)
- {
- textureType = aiTextureType_NORMALS;
- }
- else if (unitNameLower.find("specularmap") != string::npos)
- {
- textureType = aiTextureType_SPECULAR;
- }
- else if (unitNameLower.find("lightmap") != string::npos)
- {
- textureType = aiTextureType_LIGHTMAP;
- }
- else if (unitNameLower.find("displacementmap") != string::npos)
- {
- textureType = aiTextureType_DISPLACEMENT;
- }
- else
- {
- textureType = aiTextureType_DIFFUSE;
- }
- }
- }
- 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;
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/src/3rdparty/assimp/code/OgreParsingUtils.h b/src/3rdparty/assimp/code/OgreParsingUtils.h
deleted file mode 100644
index b0c31e5be..000000000
--- a/src/3rdparty/assimp/code/OgreParsingUtils.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OGREPARSINGUTILS_H_INC
-#define AI_OGREPARSINGUTILS_H_INC
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "ParsingUtils.h"
-#include <functional>
-#include <algorithm>
-#include <stdint.h>
-#include <sstream>
-#include <cctype>
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-/// 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(), [](char c) { return !Assimp::IsSpace<char>(c); }));
- }
- else
- {
- s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
- }
- 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(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(),s.end());
- }
- else
- {
- s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
- }
- return s;
-}
-
-/// Trim from both ends
-static inline std::string &Trim(std::string &s, bool newlines = true)
-{
- return TrimLeft(TrimRight(s, newlines), newlines);
-}
-
-/// 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;
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
-#endif // AI_OGREPARSINGUTILS_H_INC
diff --git a/src/3rdparty/assimp/code/OgreStructs.cpp b/src/3rdparty/assimp/code/OgreStructs.cpp
deleted file mode 100644
index 09597950a..000000000
--- a/src/3rdparty/assimp/code/OgreStructs.cpp
+++ /dev/null
@@ -1,1205 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "OgreStructs.h"
-#include "TinyFormatter.h"
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include "Exceptional.h"
-
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-// VertexElement
-
-VertexElement::VertexElement() :
- index(0),
- source(0),
- offset(0),
- type(VET_FLOAT1),
- semantic(VES_POSITION)
-{
-}
-
-size_t VertexElement::Size() const
-{
- return TypeSize(type);
-}
-
-size_t VertexElement::ComponentCount() const
-{
- return ComponentCount(type);
-}
-
-size_t VertexElement::ComponentCount(Type type)
-{
- switch(type)
- {
- case VET_COLOUR:
- case VET_COLOUR_ABGR:
- case VET_COLOUR_ARGB:
- case VET_FLOAT1:
- case VET_DOUBLE1:
- case VET_SHORT1:
- case VET_USHORT1:
- case VET_INT1:
- case VET_UINT1:
- return 1;
- case VET_FLOAT2:
- case VET_DOUBLE2:
- case VET_SHORT2:
- case VET_USHORT2:
- case VET_INT2:
- case VET_UINT2:
- return 2;
- case VET_FLOAT3:
- case VET_DOUBLE3:
- case VET_SHORT3:
- case VET_USHORT3:
- case VET_INT3:
- case VET_UINT3:
- return 3;
- case VET_FLOAT4:
- case VET_DOUBLE4:
- case VET_SHORT4:
- case VET_USHORT4:
- case VET_INT4:
- case VET_UINT4:
- case VET_UBYTE4:
- return 4;
- }
- return 0;
-}
-
-size_t VertexElement::TypeSize(Type type)
-{
- switch(type)
- {
- case VET_COLOUR:
- case VET_COLOUR_ABGR:
- case VET_COLOUR_ARGB:
- return sizeof(unsigned int);
- case VET_FLOAT1:
- return sizeof(float);
- case VET_FLOAT2:
- return sizeof(float)*2;
- case VET_FLOAT3:
- return sizeof(float)*3;
- case VET_FLOAT4:
- return sizeof(float)*4;
- case VET_DOUBLE1:
- return sizeof(double);
- case VET_DOUBLE2:
- return sizeof(double)*2;
- case VET_DOUBLE3:
- return sizeof(double)*3;
- case VET_DOUBLE4:
- return sizeof(double)*4;
- case VET_SHORT1:
- return sizeof(short);
- case VET_SHORT2:
- return sizeof(short)*2;
- case VET_SHORT3:
- return sizeof(short)*3;
- case VET_SHORT4:
- return sizeof(short)*4;
- case VET_USHORT1:
- return sizeof(unsigned short);
- case VET_USHORT2:
- return sizeof(unsigned short)*2;
- case VET_USHORT3:
- return sizeof(unsigned short)*3;
- case VET_USHORT4:
- return sizeof(unsigned short)*4;
- case VET_INT1:
- return sizeof(int);
- case VET_INT2:
- return sizeof(int)*2;
- case VET_INT3:
- return sizeof(int)*3;
- case VET_INT4:
- return sizeof(int)*4;
- case VET_UINT1:
- return sizeof(unsigned int);
- case VET_UINT2:
- return sizeof(unsigned int)*2;
- case VET_UINT3:
- return sizeof(unsigned int)*3;
- case VET_UINT4:
- return sizeof(unsigned int)*4;
- case VET_UBYTE4:
- return sizeof(unsigned char)*4;
- }
- return 0;
-}
-
-std::string VertexElement::TypeToString()
-{
- return TypeToString(type);
-}
-
-std::string VertexElement::TypeToString(Type type)
-{
- switch(type)
- {
- case VET_COLOUR: return "COLOUR";
- case VET_COLOUR_ABGR: return "COLOUR_ABGR";
- case VET_COLOUR_ARGB: return "COLOUR_ARGB";
- case VET_FLOAT1: return "FLOAT1";
- case VET_FLOAT2: return "FLOAT2";
- case VET_FLOAT3: return "FLOAT3";
- case VET_FLOAT4: return "FLOAT4";
- case VET_DOUBLE1: return "DOUBLE1";
- case VET_DOUBLE2: return "DOUBLE2";
- case VET_DOUBLE3: return "DOUBLE3";
- case VET_DOUBLE4: return "DOUBLE4";
- case VET_SHORT1: return "SHORT1";
- case VET_SHORT2: return "SHORT2";
- case VET_SHORT3: return "SHORT3";
- case VET_SHORT4: return "SHORT4";
- case VET_USHORT1: return "USHORT1";
- case VET_USHORT2: return "USHORT2";
- case VET_USHORT3: return "USHORT3";
- case VET_USHORT4: return "USHORT4";
- case VET_INT1: return "INT1";
- case VET_INT2: return "INT2";
- case VET_INT3: return "INT3";
- case VET_INT4: return "INT4";
- case VET_UINT1: return "UINT1";
- case VET_UINT2: return "UINT2";
- case VET_UINT3: return "UINT3";
- case VET_UINT4: return "UINT4";
- case VET_UBYTE4: return "UBYTE4";
- }
- return "Uknown_VertexElement::Type";
-}
-
-std::string VertexElement::SemanticToString()
-{
- return SemanticToString(semantic);
-}
-
-std::string VertexElement::SemanticToString(Semantic semantic)
-{
- switch(semantic)
- {
- case VES_POSITION: return "POSITION";
- case VES_BLEND_WEIGHTS: return "BLEND_WEIGHTS";
- case VES_BLEND_INDICES: return "BLEND_INDICES";
- case VES_NORMAL: return "NORMAL";
- case VES_DIFFUSE: return "DIFFUSE";
- case VES_SPECULAR: return "SPECULAR";
- case VES_TEXTURE_COORDINATES: return "TEXTURE_COORDINATES";
- case VES_BINORMAL: return "BINORMAL";
- case VES_TANGENT: return "TANGENT";
- }
- return "Uknown_VertexElement::Semantic";
-}
-
-// IVertexData
-
-IVertexData::IVertexData() :
- count(0)
-{
-}
-
-bool IVertexData::HasBoneAssignments() const
-{
- return !boneAssignments.empty();
-}
-
-void IVertexData::AddVertexMapping(uint32_t oldIndex, uint32_t newIndex)
-{
- BoneAssignmentsForVertex(oldIndex, newIndex, boneAssignmentsMap[newIndex]);
- vertexIndexMapping[oldIndex].push_back(newIndex);
-}
-
-void IVertexData::BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIndex, VertexBoneAssignmentList &dest) const
-{
- for (const auto &boneAssign : boneAssignments)
- {
- if (boneAssign.vertexIndex == currentIndex)
- {
- VertexBoneAssignment a = boneAssign;
- a.vertexIndex = newIndex;
- dest.push_back(a);
- }
- }
-}
-
-AssimpVertexBoneWeightList IVertexData::AssimpBoneWeights(size_t vertices)
-{
- AssimpVertexBoneWeightList weights;
- for(size_t vi=0; vi<vertices; ++vi)
- {
- VertexBoneAssignmentList &vertexWeights = boneAssignmentsMap[static_cast<unsigned int>(vi)];
- for (VertexBoneAssignmentList::const_iterator iter=vertexWeights.begin(), end=vertexWeights.end();
- iter!=end; ++iter)
- {
- std::vector<aiVertexWeight> &boneWeights = weights[iter->boneIndex];
- boneWeights.push_back(aiVertexWeight(static_cast<unsigned int>(vi), iter->weight));
- }
- }
- return weights;
-}
-
-std::set<uint16_t> IVertexData::ReferencedBonesByWeights() const
-{
- std::set<uint16_t> referenced;
- for (const auto &boneAssign : boneAssignments)
- {
- referenced.insert(boneAssign.boneIndex);
- }
- return referenced;
-}
-
-// VertexData
-
-VertexData::VertexData()
-{
-}
-
-VertexData::~VertexData()
-{
- Reset();
-}
-
-void VertexData::Reset()
-{
- // Releases shared ptr memory streams.
- vertexBindings.clear();
- vertexElements.clear();
-}
-
-uint32_t VertexData::VertexSize(uint16_t source) const
-{
- uint32_t size = 0;
- for(const auto &element : vertexElements)
- {
- if (element.source == source)
- size += static_cast<uint32_t>(element.Size());
- }
- return size;
-}
-
-MemoryStream *VertexData::VertexBuffer(uint16_t source)
-{
- if (vertexBindings.find(source) != vertexBindings.end())
- return vertexBindings[source].get();
- return 0;
-}
-
-VertexElement *VertexData::GetVertexElement(VertexElement::Semantic semantic, uint16_t index)
-{
- for(auto & element : vertexElements)
- {
- if (element.semantic == semantic && element.index == index)
- return &element;
- }
- return 0;
-}
-
-// VertexDataXml
-
-VertexDataXml::VertexDataXml()
-{
-}
-
-bool VertexDataXml::HasPositions() const
-{
- return !positions.empty();
-}
-
-bool VertexDataXml::HasNormals() const
-{
- return !normals.empty();
-}
-
-bool VertexDataXml::HasTangents() const
-{
- return !tangents.empty();
-}
-
-bool VertexDataXml::HasUvs() const
-{
- return !uvs.empty();
-}
-
-size_t VertexDataXml::NumUvs() const
-{
- return uvs.size();
-}
-
-// IndexData
-
-IndexData::IndexData() :
- count(0),
- faceCount(0),
- is32bit(false)
-{
-}
-
-IndexData::~IndexData()
-{
- Reset();
-}
-
-void IndexData::Reset()
-{
- // Release shared ptr memory stream.
- buffer.reset();
-}
-
-size_t IndexData::IndexSize() const
-{
- return (is32bit ? sizeof(uint32_t) : sizeof(uint16_t));
-}
-
-size_t IndexData::FaceSize() const
-{
- return IndexSize() * 3;
-}
-
-// Mesh
-
-Mesh::Mesh()
- : hasSkeletalAnimations(false)
- , skeleton(NULL)
- , sharedVertexData(NULL)
- , subMeshes()
- , animations()
- , poses()
-{
-}
-
-Mesh::~Mesh()
-{
- Reset();
-}
-
-void Mesh::Reset()
-{
- OGRE_SAFE_DELETE(skeleton)
- OGRE_SAFE_DELETE(sharedVertexData)
-
- for(auto &mesh : subMeshes) {
- OGRE_SAFE_DELETE(mesh)
- }
- subMeshes.clear();
- for(auto &anim : animations) {
- OGRE_SAFE_DELETE(anim)
- }
- animations.clear();
- for(auto &pose : poses) {
- OGRE_SAFE_DELETE(pose)
- }
- poses.clear();
-}
-
-size_t Mesh::NumSubMeshes() const
-{
- return subMeshes.size();
-}
-
-SubMesh *Mesh::GetSubMesh( size_t index ) const
-{
- for ( size_t i = 0; i < subMeshes.size(); ++i ) {
- if ( subMeshes[ i ]->index == index ) {
- return subMeshes[ i ];
- }
- }
- return 0;
-}
-
-void Mesh::ConvertToAssimpScene(aiScene* dest)
-{
- if ( nullptr == dest ) {
- return;
- }
-
- // Setup
- dest->mNumMeshes = static_cast<unsigned int>(NumSubMeshes());
- dest->mMeshes = new aiMesh*[dest->mNumMeshes];
-
- // Create root node
- dest->mRootNode = new aiNode();
- dest->mRootNode->mNumMeshes = dest->mNumMeshes;
- dest->mRootNode->mMeshes = new unsigned int[dest->mRootNode->mNumMeshes];
-
- // Export meshes
- for(size_t i=0; i<dest->mNumMeshes; ++i) {
- dest->mMeshes[i] = subMeshes[i]->ConvertToAssimpMesh(this);
- dest->mRootNode->mMeshes[i] = static_cast<unsigned int>(i);
- }
-
- // Export skeleton
- if (skeleton)
- {
- // Bones
- if (!skeleton->bones.empty())
- {
- BoneList rootBones = skeleton->RootBones();
- dest->mRootNode->mNumChildren = static_cast<unsigned int>(rootBones.size());
- dest->mRootNode->mChildren = new aiNode*[dest->mRootNode->mNumChildren];
-
- for(size_t i=0, len=rootBones.size(); i<len; ++i)
- {
- dest->mRootNode->mChildren[i] = rootBones[i]->ConvertToAssimpNode(skeleton, dest->mRootNode);
- }
- }
-
- // Animations
- if (!skeleton->animations.empty())
- {
- dest->mNumAnimations = static_cast<unsigned int>(skeleton->animations.size());
- dest->mAnimations = new aiAnimation*[dest->mNumAnimations];
-
- for(size_t i=0, len=skeleton->animations.size(); i<len; ++i)
- {
- dest->mAnimations[i] = skeleton->animations[i]->ConvertToAssimpAnimation();
- }
- }
- }
-}
-
-// ISubMesh
-
-ISubMesh::ISubMesh() :
- index(0),
- materialIndex(-1),
- usesSharedVertexData(false),
- operationType(OT_POINT_LIST)
-{
-}
-
-// SubMesh
-
-SubMesh::SubMesh() :
- vertexData(0),
- indexData(new IndexData())
-{
-}
-
-SubMesh::~SubMesh()
-{
- Reset();
-}
-
-void SubMesh::Reset()
-{
- OGRE_SAFE_DELETE(vertexData)
- OGRE_SAFE_DELETE(indexData)
-}
-
-aiMesh *SubMesh::ConvertToAssimpMesh(Mesh *parent)
-{
- if (operationType != OT_TRIANGLE_LIST) {
- throw DeadlyImportError(Formatter::format() << "Only mesh operation type OT_TRIANGLE_LIST is supported. Found " << operationType);
- }
-
- aiMesh *dest = new aiMesh();
- dest->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- if (!name.empty())
- dest->mName = name;
-
- // Material index
- if (materialIndex != -1)
- dest->mMaterialIndex = materialIndex;
-
- // Pick source vertex data from shader geometry or from internal geometry.
- VertexData *src = (!usesSharedVertexData ? vertexData : parent->sharedVertexData);
-
- VertexElement *positionsElement = src->GetVertexElement(VertexElement::VES_POSITION);
- VertexElement *normalsElement = src->GetVertexElement(VertexElement::VES_NORMAL);
- VertexElement *uv1Element = src->GetVertexElement(VertexElement::VES_TEXTURE_COORDINATES, 0);
- VertexElement *uv2Element = src->GetVertexElement(VertexElement::VES_TEXTURE_COORDINATES, 1);
-
- // Sanity checks
- if (!positionsElement) {
- throw DeadlyImportError("Failed to import Ogre VertexElement::VES_POSITION. Mesh does not have vertex positions!");
- } else if (positionsElement->type != VertexElement::VET_FLOAT3) {
- throw DeadlyImportError("Ogre Mesh position vertex element type != VertexElement::VET_FLOAT3. This is not supported.");
- } else if (normalsElement && normalsElement->type != VertexElement::VET_FLOAT3) {
- throw DeadlyImportError("Ogre Mesh normal vertex element type != VertexElement::VET_FLOAT3. This is not supported.");
- }
-
- // Faces
- dest->mNumFaces = indexData->faceCount;
- dest->mFaces = new aiFace[dest->mNumFaces];
-
- // Assimp required unique vertices, we need to convert from Ogres shared indexing.
- size_t uniqueVertexCount = dest->mNumFaces * 3;
- dest->mNumVertices = static_cast<unsigned int>(uniqueVertexCount);
- dest->mVertices = new aiVector3D[dest->mNumVertices];
-
- // Source streams
- MemoryStream *positions = src->VertexBuffer(positionsElement->source);
- MemoryStream *normals = (normalsElement ? src->VertexBuffer(normalsElement->source) : 0);
- MemoryStream *uv1 = (uv1Element ? src->VertexBuffer(uv1Element->source) : 0);
- MemoryStream *uv2 = (uv2Element ? src->VertexBuffer(uv2Element->source) : 0);
-
- // Element size
- const size_t sizePosition = positionsElement->Size();
- const size_t sizeNormal = (normalsElement ? normalsElement->Size() : 0);
- const size_t sizeUv1 = (uv1Element ? uv1Element->Size() : 0);
- const size_t sizeUv2 = (uv2Element ? uv2Element->Size() : 0);
-
- // Vertex width
- const size_t vWidthPosition = src->VertexSize(positionsElement->source);
- const size_t vWidthNormal = (normalsElement ? src->VertexSize(normalsElement->source) : 0);
- const size_t vWidthUv1 = (uv1Element ? src->VertexSize(uv1Element->source) : 0);
- const size_t vWidthUv2 = (uv2Element ? src->VertexSize(uv2Element->source) : 0);
-
- bool boneAssignments = src->HasBoneAssignments();
-
- // Prepare normals
- if (normals)
- dest->mNormals = new aiVector3D[dest->mNumVertices];
-
- // Prepare UVs, ignoring incompatible UVs.
- if (uv1)
- {
- if (uv1Element->type == VertexElement::VET_FLOAT2 || uv1Element->type == VertexElement::VET_FLOAT3)
- {
- dest->mNumUVComponents[0] = static_cast<unsigned int>(uv1Element->ComponentCount());
- dest->mTextureCoords[0] = new aiVector3D[dest->mNumVertices];
- }
- else
- {
- DefaultLogger::get()->warn(Formatter::format() << "Ogre imported UV0 type " << uv1Element->TypeToString() << " is not compatible with Assimp. Ignoring UV.");
- uv1 = 0;
- }
- }
- if (uv2)
- {
- if (uv2Element->type == VertexElement::VET_FLOAT2 || uv2Element->type == VertexElement::VET_FLOAT3)
- {
- dest->mNumUVComponents[1] = static_cast<unsigned int>(uv2Element->ComponentCount());
- dest->mTextureCoords[1] = new aiVector3D[dest->mNumVertices];
- }
- else
- {
- DefaultLogger::get()->warn(Formatter::format() << "Ogre imported UV0 type " << uv2Element->TypeToString() << " is not compatible with Assimp. Ignoring UV.");
- uv2 = 0;
- }
- }
-
- aiVector3D *uv1Dest = (uv1 ? dest->mTextureCoords[0] : 0);
- aiVector3D *uv2Dest = (uv2 ? dest->mTextureCoords[1] : 0);
-
- MemoryStream *faces = indexData->buffer.get();
- for (size_t fi=0, isize=indexData->IndexSize(), fsize=indexData->FaceSize();
- fi<dest->mNumFaces; ++fi)
- {
- // Source Ogre face
- aiFace ogreFace;
- ogreFace.mNumIndices = 3;
- ogreFace.mIndices = new unsigned int[3];
-
- faces->Seek(fi * fsize, aiOrigin_SET);
- if (indexData->is32bit)
- {
- faces->Read(&ogreFace.mIndices[0], isize, 3);
- }
- else
- {
- uint16_t iout = 0;
- for (size_t ii=0; ii<3; ++ii)
- {
- faces->Read(&iout, isize, 1);
- ogreFace.mIndices[ii] = static_cast<unsigned int>(iout);
- }
- }
-
- // Destination Assimp face
- aiFace &face = dest->mFaces[fi];
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[3];
-
- const size_t pos = fi * 3;
- for (size_t v=0; v<3; ++v)
- {
- const size_t newIndex = pos + v;
-
- // Write face index
- face.mIndices[v] = static_cast<unsigned int>(newIndex);
-
- // Ogres vertex index to ref into the source buffers.
- const size_t ogreVertexIndex = ogreFace.mIndices[v];
- src->AddVertexMapping(static_cast<uint32_t>(ogreVertexIndex), static_cast<uint32_t>(newIndex));
-
- // Position
- positions->Seek((vWidthPosition * ogreVertexIndex) + positionsElement->offset, aiOrigin_SET);
- positions->Read(&dest->mVertices[newIndex], sizePosition, 1);
-
- // Normal
- if (normals)
- {
- normals->Seek((vWidthNormal * ogreVertexIndex) + normalsElement->offset, aiOrigin_SET);
- normals->Read(&dest->mNormals[newIndex], sizeNormal, 1);
- }
- // UV0
- if (uv1 && uv1Dest)
- {
- uv1->Seek((vWidthUv1 * ogreVertexIndex) + uv1Element->offset, aiOrigin_SET);
- uv1->Read(&uv1Dest[newIndex], sizeUv1, 1);
- uv1Dest[newIndex].y = (uv1Dest[newIndex].y * -1) + 1; // Flip UV from Ogre to Assimp form
- }
- // UV1
- if (uv2 && uv2Dest)
- {
- uv2->Seek((vWidthUv2 * ogreVertexIndex) + uv2Element->offset, aiOrigin_SET);
- uv2->Read(&uv2Dest[newIndex], sizeUv2, 1);
- uv2Dest[newIndex].y = (uv2Dest[newIndex].y * -1) + 1; // Flip UV from Ogre to Assimp form
- }
- }
- }
-
- // Bones and bone weights
- if (parent->skeleton && boneAssignments)
- {
- AssimpVertexBoneWeightList weights = src->AssimpBoneWeights(dest->mNumVertices);
- std::set<uint16_t> referencedBones = src->ReferencedBonesByWeights();
-
- dest->mNumBones = static_cast<unsigned int>(referencedBones.size());
- dest->mBones = new aiBone*[dest->mNumBones];
-
- size_t assimpBoneIndex = 0;
- for(std::set<uint16_t>::const_iterator rbIter=referencedBones.begin(), rbEnd=referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex)
- {
- Bone *bone = parent->skeleton->BoneById((*rbIter));
- dest->mBones[assimpBoneIndex] = bone->ConvertToAssimpBone(parent->skeleton, weights[bone->id]);
- }
- }
-
- return dest;
-}
-
-// MeshXml
-
-MeshXml::MeshXml() :
- skeleton(0),
- sharedVertexData(0)
-{
-}
-
-MeshXml::~MeshXml()
-{
- Reset();
-}
-
-void MeshXml::Reset()
-{
- OGRE_SAFE_DELETE(skeleton)
- OGRE_SAFE_DELETE(sharedVertexData)
-
- for(auto &mesh : subMeshes) {
- OGRE_SAFE_DELETE(mesh)
- }
- subMeshes.clear();
-}
-
-size_t MeshXml::NumSubMeshes() const
-{
- return subMeshes.size();
-}
-
-SubMeshXml *MeshXml::GetSubMesh(uint16_t index) const
-{
- for(size_t i=0; i<subMeshes.size(); ++i)
- if (subMeshes[i]->index == index)
- return subMeshes[i];
- return 0;
-}
-
-void MeshXml::ConvertToAssimpScene(aiScene* dest)
-{
- // Setup
- dest->mNumMeshes = static_cast<unsigned int>(NumSubMeshes());
- dest->mMeshes = new aiMesh*[dest->mNumMeshes];
-
- // Create root node
- dest->mRootNode = new aiNode();
- dest->mRootNode->mNumMeshes = dest->mNumMeshes;
- dest->mRootNode->mMeshes = new unsigned int[dest->mRootNode->mNumMeshes];
-
- // Export meshes
- for(size_t i=0; i<dest->mNumMeshes; ++i)
- {
- dest->mMeshes[i] = subMeshes[i]->ConvertToAssimpMesh(this);
- dest->mRootNode->mMeshes[i] = static_cast<unsigned int>(i);
- }
-
- // Export skeleton
- if (skeleton)
- {
- // Bones
- if (!skeleton->bones.empty())
- {
- BoneList rootBones = skeleton->RootBones();
- dest->mRootNode->mNumChildren = static_cast<unsigned int>(rootBones.size());
- dest->mRootNode->mChildren = new aiNode*[dest->mRootNode->mNumChildren];
-
- for(size_t i=0, len=rootBones.size(); i<len; ++i)
- {
- dest->mRootNode->mChildren[i] = rootBones[i]->ConvertToAssimpNode(skeleton, dest->mRootNode);
- }
- }
-
- // Animations
- if (!skeleton->animations.empty())
- {
- dest->mNumAnimations = static_cast<unsigned int>(skeleton->animations.size());
- dest->mAnimations = new aiAnimation*[dest->mNumAnimations];
-
- for(size_t i=0, len=skeleton->animations.size(); i<len; ++i)
- {
- dest->mAnimations[i] = skeleton->animations[i]->ConvertToAssimpAnimation();
- }
- }
- }
-}
-
-// SubMeshXml
-
-SubMeshXml::SubMeshXml() :
- indexData(new IndexDataXml()),
- vertexData(0)
-{
-}
-
-SubMeshXml::~SubMeshXml()
-{
- Reset();
-}
-
-void SubMeshXml::Reset()
-{
- OGRE_SAFE_DELETE(indexData)
- OGRE_SAFE_DELETE(vertexData)
-}
-
-aiMesh *SubMeshXml::ConvertToAssimpMesh(MeshXml *parent)
-{
- aiMesh *dest = new aiMesh();
- dest->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- if (!name.empty())
- dest->mName = name;
-
- // Material index
- if (materialIndex != -1)
- dest->mMaterialIndex = materialIndex;
-
- // Faces
- dest->mNumFaces = indexData->faceCount;
- dest->mFaces = new aiFace[dest->mNumFaces];
-
- // Assimp required unique vertices, we need to convert from Ogres shared indexing.
- size_t uniqueVertexCount = dest->mNumFaces * 3;
- dest->mNumVertices = static_cast<unsigned int>(uniqueVertexCount);
- dest->mVertices = new aiVector3D[dest->mNumVertices];
-
- VertexDataXml *src = (!usesSharedVertexData ? vertexData : parent->sharedVertexData);
- bool boneAssignments = src->HasBoneAssignments();
- bool normals = src->HasNormals();
- size_t uvs = src->NumUvs();
-
- // Prepare normals
- if (normals)
- dest->mNormals = new aiVector3D[dest->mNumVertices];
-
- // Prepare UVs
- for(size_t uvi=0; uvi<uvs; ++uvi)
- {
- dest->mNumUVComponents[uvi] = 2;
- dest->mTextureCoords[uvi] = new aiVector3D[dest->mNumVertices];
- }
-
- for (size_t fi=0; fi<dest->mNumFaces; ++fi)
- {
- // Source Ogre face
- aiFace &ogreFace = indexData->faces[fi];
-
- // Destination Assimp face
- aiFace &face = dest->mFaces[fi];
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[3];
-
- const size_t pos = fi * 3;
- for (size_t v=0; v<3; ++v)
- {
- const size_t newIndex = pos + v;
-
- // Write face index
- face.mIndices[v] = static_cast<unsigned int>(newIndex);
-
- // Ogres vertex index to ref into the source buffers.
- const size_t ogreVertexIndex = ogreFace.mIndices[v];
- src->AddVertexMapping(static_cast<uint32_t>(ogreVertexIndex), static_cast<uint32_t>(newIndex));
-
- // Position
- dest->mVertices[newIndex] = src->positions[ogreVertexIndex];
-
- // Normal
- if (normals)
- dest->mNormals[newIndex] = src->normals[ogreVertexIndex];
-
- // UVs
- for(size_t uvi=0; uvi<uvs; ++uvi)
- {
- aiVector3D *uvDest = dest->mTextureCoords[uvi];
- std::vector<aiVector3D> &uvSrc = src->uvs[uvi];
- uvDest[newIndex] = uvSrc[ogreVertexIndex];
- }
- }
- }
-
- // Bones and bone weights
- if (parent->skeleton && boneAssignments)
- {
- AssimpVertexBoneWeightList weights = src->AssimpBoneWeights(dest->mNumVertices);
- std::set<uint16_t> referencedBones = src->ReferencedBonesByWeights();
-
- dest->mNumBones = static_cast<unsigned int>(referencedBones.size());
- dest->mBones = new aiBone*[dest->mNumBones];
-
- size_t assimpBoneIndex = 0;
- for(std::set<uint16_t>::const_iterator rbIter=referencedBones.begin(), rbEnd=referencedBones.end(); rbIter != rbEnd; ++rbIter, ++assimpBoneIndex)
- {
- Bone *bone = parent->skeleton->BoneById((*rbIter));
- dest->mBones[assimpBoneIndex] = bone->ConvertToAssimpBone(parent->skeleton, weights[bone->id]);
- }
- }
-
- return dest;
-}
-
-// Animation
-
-Animation::Animation(Skeleton *parent) :
- parentMesh(NULL),
- parentSkeleton(parent),
- length(0.0f),
- baseTime(-1.0f)
-{
-}
-
-Animation::Animation(Mesh *parent) :
- parentMesh(parent),
- parentSkeleton(0),
- length(0.0f),
- baseTime(-1.0f)
-{
-}
-
-VertexData *Animation::AssociatedVertexData(VertexAnimationTrack *track) const
-{
- if (!parentMesh)
- return 0;
-
- bool sharedGeom = (track->target == 0);
- if (sharedGeom)
- return parentMesh->sharedVertexData;
- else
- return parentMesh->GetSubMesh(track->target-1)->vertexData;
-}
-
-aiAnimation *Animation::ConvertToAssimpAnimation()
-{
- aiAnimation *anim = new aiAnimation();
- anim->mName = name;
- anim->mDuration = static_cast<double>(length);
- anim->mTicksPerSecond = 1.0;
-
- // Tracks
- if (!tracks.empty())
- {
- anim->mNumChannels = static_cast<unsigned int>(tracks.size());
- anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
-
- for(size_t i=0, len=tracks.size(); i<len; ++i)
- {
- anim->mChannels[i] = tracks[i].ConvertToAssimpAnimationNode(parentSkeleton);
- }
- }
- return anim;
-}
-
-// Skeleton
-
-Skeleton::Skeleton() :
- bones(),
- animations(),
- blendMode(ANIMBLEND_AVERAGE)
-{
-}
-
-Skeleton::~Skeleton()
-{
- Reset();
-}
-
-void Skeleton::Reset()
-{
- for(auto &bone : bones) {
- OGRE_SAFE_DELETE(bone)
- }
- bones.clear();
- for(auto &anim : animations) {
- OGRE_SAFE_DELETE(anim)
- }
- animations.clear();
-}
-
-BoneList Skeleton::RootBones() const
-{
- BoneList rootBones;
- for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
- {
- if (!(*iter)->IsParented())
- rootBones.push_back((*iter));
- }
- return rootBones;
-}
-
-size_t Skeleton::NumRootBones() const
-{
- size_t num = 0;
- for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
- {
- if (!(*iter)->IsParented())
- num++;
- }
- return num;
-}
-
-Bone *Skeleton::BoneByName(const std::string &name) const
-{
- for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
- {
- if ((*iter)->name == name)
- return (*iter);
- }
- return 0;
-}
-
-Bone *Skeleton::BoneById(uint16_t id) const
-{
- for(BoneList::const_iterator iter = bones.begin(); iter != bones.end(); ++iter)
- {
- if ((*iter)->id == id)
- return (*iter);
- }
- return 0;
-}
-
-// Bone
-
-Bone::Bone() :
- id(0),
- parent(0),
- parentId(-1),
- scale(1.0f, 1.0f, 1.0f)
-{
-}
-
-bool Bone::IsParented() const
-{
- return (parentId != -1 && parent != 0);
-}
-
-uint16_t Bone::ParentId() const
-{
- return static_cast<uint16_t>(parentId);
-}
-
-void Bone::AddChild(Bone *bone)
-{
- if (!bone)
- return;
- if (bone->IsParented())
- throw DeadlyImportError("Attaching child Bone that is already parented: " + bone->name);
-
- bone->parent = this;
- bone->parentId = id;
- children.push_back(bone->id);
-}
-
-void Bone::CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton)
-{
- if (!IsParented())
- worldMatrix = aiMatrix4x4(scale, rotation, position).Inverse();
- else
- worldMatrix = aiMatrix4x4(scale, rotation, position).Inverse() * parent->worldMatrix;
-
- defaultPose = aiMatrix4x4(scale, rotation, position);
-
- // Recursively for all children now that the parent matrix has been calculated.
- for (auto boneId : children)
- {
- Bone *child = skeleton->BoneById(boneId);
- if (!child) {
- throw DeadlyImportError(Formatter::format() << "CalculateWorldMatrixAndDefaultPose: Failed to find child bone " << boneId << " for parent " << id << " " << name);
- }
- child->CalculateWorldMatrixAndDefaultPose(skeleton);
- }
-}
-
-aiNode *Bone::ConvertToAssimpNode(Skeleton *skeleton, aiNode *parentNode)
-{
- // Bone node
- aiNode* node = new aiNode(name);
- node->mParent = parentNode;
- node->mTransformation = defaultPose;
-
- // Children
- if (!children.empty())
- {
- node->mNumChildren = static_cast<unsigned int>(children.size());
- node->mChildren = new aiNode*[node->mNumChildren];
-
- for(size_t i=0, len=children.size(); i<len; ++i)
- {
- Bone *child = skeleton->BoneById(children[i]);
- if (!child) {
- throw DeadlyImportError(Formatter::format() << "ConvertToAssimpNode: Failed to find child bone " << children[i] << " for parent " << id << " " << name);
- }
- node->mChildren[i] = child->ConvertToAssimpNode(skeleton, node);
- }
- }
- return node;
-}
-
-aiBone *Bone::ConvertToAssimpBone(Skeleton * /*parent*/, const std::vector<aiVertexWeight> &boneWeights)
-{
- aiBone *bone = new aiBone();
- bone->mName = name;
- bone->mOffsetMatrix = worldMatrix;
-
- if (!boneWeights.empty())
- {
- bone->mNumWeights = static_cast<unsigned int>(boneWeights.size());
- bone->mWeights = new aiVertexWeight[boneWeights.size()];
- memcpy(bone->mWeights, &boneWeights[0], boneWeights.size() * sizeof(aiVertexWeight));
- }
-
- return bone;
-}
-
-// VertexAnimationTrack
-
-VertexAnimationTrack::VertexAnimationTrack() :
- type(VAT_NONE),
- target(0)
-{
-}
-
-aiNodeAnim *VertexAnimationTrack::ConvertToAssimpAnimationNode(Skeleton *skeleton)
-{
- if (boneName.empty() || type != VAT_TRANSFORM) {
- throw DeadlyImportError("VertexAnimationTrack::ConvertToAssimpAnimationNode: Cannot convert track that has no target bone name or is not type of VAT_TRANSFORM");
- }
-
- aiNodeAnim *nodeAnim = new aiNodeAnim();
- nodeAnim->mNodeName = boneName;
-
- Bone *bone = skeleton->BoneByName(boneName);
- if (!bone) {
- throw DeadlyImportError("VertexAnimationTrack::ConvertToAssimpAnimationNode: Failed to find bone " + boneName + " from parent Skeleton");
- }
-
- // Keyframes
- size_t numKeyframes = transformKeyFrames.size();
-
- nodeAnim->mPositionKeys = new aiVectorKey[numKeyframes];
- nodeAnim->mRotationKeys = new aiQuatKey[numKeyframes];
- nodeAnim->mScalingKeys = new aiVectorKey[numKeyframes];
- nodeAnim->mNumPositionKeys = static_cast<unsigned int>(numKeyframes);
- nodeAnim->mNumRotationKeys = static_cast<unsigned int>(numKeyframes);
- nodeAnim->mNumScalingKeys = static_cast<unsigned int>(numKeyframes);
-
- for(size_t kfi=0; kfi<numKeyframes; ++kfi)
- {
- TransformKeyFrame &kfSource = transformKeyFrames[kfi];
-
- // Calculate the complete transformation from world space to bone space
- aiVector3D pos; aiQuaternion rot; aiVector3D scale;
-
- aiMatrix4x4 finalTransform = bone->defaultPose * kfSource.Transform();
- finalTransform.Decompose(scale, rot, pos);
-
- double t = static_cast<double>(kfSource.timePos);
- nodeAnim->mPositionKeys[kfi].mTime = t;
- nodeAnim->mRotationKeys[kfi].mTime = t;
- nodeAnim->mScalingKeys[kfi].mTime = t;
-
- nodeAnim->mPositionKeys[kfi].mValue = pos;
- nodeAnim->mRotationKeys[kfi].mValue = rot;
- nodeAnim->mScalingKeys[kfi].mValue = scale;
- }
-
- return nodeAnim;
-}
-
-// TransformKeyFrame
-
-TransformKeyFrame::TransformKeyFrame() :
- timePos(0.0f),
- scale(1.0f, 1.0f, 1.0f)
-{
-}
-
-aiMatrix4x4 TransformKeyFrame::Transform()
-{
- return aiMatrix4x4(scale, rotation, position);
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/src/3rdparty/assimp/code/OgreStructs.h b/src/3rdparty/assimp/code/OgreStructs.h
deleted file mode 100644
index 04383bc4e..000000000
--- a/src/3rdparty/assimp/code/OgreStructs.h
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OGRESTRUCTS_H_INC
-#define AI_OGRESTRUCTS_H_INC
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "MemoryIOWrapper.h"
-#include <memory>
-#include <assimp/mesh.h>
-#include <map>
-#include <vector>
-#include <set>
-
-struct aiNodeAnim;
-struct aiAnimation;
-struct aiNode;
-struct aiMaterial;
-struct aiScene;
-
-/** @note Parts of this implementation, for example enums, deserialization constants and logic
- has been copied directly with minor modifications from the MIT licensed Ogre3D code base.
- See more from https://bitbucket.org/sinbad/ogre. */
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-// Forward decl
-class Mesh;
-class MeshXml;
-class SubMesh;
-class SubMeshXml;
-class Skeleton;
-
-#define OGRE_SAFE_DELETE(p) delete p; p=0;
-
-// Typedefs
-typedef Assimp::MemoryIOStream MemoryStream;
-typedef std::shared_ptr<MemoryStream> MemoryStreamPtr;
-typedef std::map<uint16_t, MemoryStreamPtr> VertexBufferBindings;
-
-// Ogre Vertex Element
-class VertexElement
-{
-public:
- /// Vertex element semantics, used to identify the meaning of vertex buffer contents
- enum Semantic {
- /// Position, 3 reals per vertex
- VES_POSITION = 1,
- /// Blending weights
- VES_BLEND_WEIGHTS = 2,
- /// Blending indices
- VES_BLEND_INDICES = 3,
- /// Normal, 3 reals per vertex
- VES_NORMAL = 4,
- /// Diffuse colours
- VES_DIFFUSE = 5,
- /// Specular colours
- VES_SPECULAR = 6,
- /// Texture coordinates
- VES_TEXTURE_COORDINATES = 7,
- /// Binormal (Y axis if normal is Z)
- VES_BINORMAL = 8,
- /// Tangent (X axis if normal is Z)
- VES_TANGENT = 9,
- /// The number of VertexElementSemantic elements (note - the first value VES_POSITION is 1)
- VES_COUNT = 9
- };
-
- /// Vertex element type, used to identify the base types of the vertex contents
- enum Type
- {
- VET_FLOAT1 = 0,
- VET_FLOAT2 = 1,
- VET_FLOAT3 = 2,
- VET_FLOAT4 = 3,
- /// alias to more specific colour type - use the current rendersystem's colour packing
- VET_COLOUR = 4,
- VET_SHORT1 = 5,
- VET_SHORT2 = 6,
- VET_SHORT3 = 7,
- VET_SHORT4 = 8,
- VET_UBYTE4 = 9,
- /// D3D style compact colour
- VET_COLOUR_ARGB = 10,
- /// GL style compact colour
- VET_COLOUR_ABGR = 11,
- VET_DOUBLE1 = 12,
- VET_DOUBLE2 = 13,
- VET_DOUBLE3 = 14,
- VET_DOUBLE4 = 15,
- VET_USHORT1 = 16,
- VET_USHORT2 = 17,
- VET_USHORT3 = 18,
- VET_USHORT4 = 19,
- VET_INT1 = 20,
- VET_INT2 = 21,
- VET_INT3 = 22,
- VET_INT4 = 23,
- VET_UINT1 = 24,
- VET_UINT2 = 25,
- VET_UINT3 = 26,
- VET_UINT4 = 27
- };
-
- VertexElement();
-
- /// Size of the vertex element in bytes.
- size_t Size() const;
-
- /// Count of components in this element, eg. VET_FLOAT3 return 3.
- size_t ComponentCount() const;
-
- /// Type as string.
- std::string TypeToString();
-
- /// Semantic as string.
- std::string SemanticToString();
-
- static size_t TypeSize(Type type);
- static size_t ComponentCount(Type type);
- static std::string TypeToString(Type type);
- static std::string SemanticToString(Semantic semantic);
-
- uint16_t index;
- uint16_t source;
- uint16_t offset;
- Type type;
- Semantic semantic;
-};
-typedef std::vector<VertexElement> VertexElementList;
-
-/// Ogre Vertex Bone Assignment
-struct VertexBoneAssignment
-{
- uint32_t vertexIndex;
- uint16_t boneIndex;
- float weight;
-};
-typedef std::vector<VertexBoneAssignment> VertexBoneAssignmentList;
-typedef std::map<uint32_t, VertexBoneAssignmentList > VertexBoneAssignmentsMap;
-typedef std::map<uint16_t, std::vector<aiVertexWeight> > AssimpVertexBoneWeightList;
-
-// Ogre Vertex Data interface, inherited by the binary and XML implementations.
-class IVertexData
-{
-public:
- IVertexData();
-
- /// Returns if bone assignments are available.
- bool HasBoneAssignments() const;
-
- /// Add vertex mapping from old to new index.
- void AddVertexMapping(uint32_t oldIndex, uint32_t newIndex);
-
- /// Returns re-mapped bone assignments.
- /** @note Uses mappings added via AddVertexMapping. */
- AssimpVertexBoneWeightList AssimpBoneWeights(size_t vertices);
-
- /// Returns a set of bone indexes that are referenced by bone assignments (weights).
- std::set<uint16_t> ReferencedBonesByWeights() const;
-
- /// Vertex count.
- uint32_t count;
-
- /// Bone assignments.
- VertexBoneAssignmentList boneAssignments;
-
-private:
- void BoneAssignmentsForVertex(uint32_t currentIndex, uint32_t newIndex, VertexBoneAssignmentList &dest) const;
-
- std::map<uint32_t, std::vector<uint32_t> > vertexIndexMapping;
- VertexBoneAssignmentsMap boneAssignmentsMap;
-};
-
-// Ogre Vertex Data
-class VertexData : public IVertexData
-{
-public:
- VertexData();
- ~VertexData();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- /// Get vertex size for @c source.
- uint32_t VertexSize(uint16_t source) const;
-
- /// Get vertex buffer for @c source.
- MemoryStream *VertexBuffer(uint16_t source);
-
- /// Get vertex element for @c semantic for @c index.
- VertexElement *GetVertexElement(VertexElement::Semantic semantic, uint16_t index = 0);
-
- /// Vertex elements.
- VertexElementList vertexElements;
-
- /// Vertex buffers mapped to bind index.
- VertexBufferBindings vertexBindings;
-};
-
-// Ogre Index Data
-class IndexData
-{
-public:
- IndexData();
- ~IndexData();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- /// Index size in bytes.
- size_t IndexSize() const;
-
- /// Face size in bytes.
- size_t FaceSize() const;
-
- /// Index count.
- uint32_t count;
-
- /// Face count.
- uint32_t faceCount;
-
- /// If has 32-bit indexes.
- bool is32bit;
-
- /// Index buffer.
- MemoryStreamPtr buffer;
-};
-
-/// Ogre Pose
-class Pose
-{
-public:
- struct Vertex
- {
- uint32_t index;
- aiVector3D offset;
- aiVector3D normal;
- };
- typedef std::map<uint32_t, Vertex> PoseVertexMap;
-
- Pose() : target(0), hasNormals(false) {}
-
- /// Name.
- std::string name;
-
- /// Target.
- uint16_t target;
-
- /// Does vertices map have normals.
- bool hasNormals;
-
- /// Vertex offset and normals.
- PoseVertexMap vertices;
-};
-typedef std::vector<Pose*> PoseList;
-
-/// Ogre Pose Key Frame Ref
-struct PoseRef
-{
- uint16_t index;
- float influence;
-};
-typedef std::vector<PoseRef> PoseRefList;
-
-/// Ogre Pose Key Frame
-struct PoseKeyFrame
-{
- /// Time position in the animation.
- float timePos;
-
- PoseRefList references;
-};
-typedef std::vector<PoseKeyFrame> PoseKeyFrameList;
-
-/// Ogre Morph Key Frame
-struct MorphKeyFrame
-{
- /// Time position in the animation.
- float timePos;
-
- MemoryStreamPtr buffer;
-};
-typedef std::vector<MorphKeyFrame> MorphKeyFrameList;
-
-/// Ogre animation key frame
-struct TransformKeyFrame
-{
- TransformKeyFrame();
-
- aiMatrix4x4 Transform();
-
- float timePos;
-
- aiQuaternion rotation;
- aiVector3D position;
- aiVector3D scale;
-};
-typedef std::vector<TransformKeyFrame> TransformKeyFrameList;
-
-/// Ogre Animation Track
-struct VertexAnimationTrack
-{
- enum Type
- {
- /// No animation
- VAT_NONE = 0,
- /// Morph animation is made up of many interpolated snapshot keyframes
- VAT_MORPH = 1,
- /// Pose animation is made up of a single delta pose keyframe
- VAT_POSE = 2,
- /// Keyframe that has its on pos, rot and scale for a time position
- VAT_TRANSFORM = 3
- };
-
- VertexAnimationTrack();
-
- /// Convert to Assimp node animation.
- aiNodeAnim *ConvertToAssimpAnimationNode(Skeleton *skeleton);
-
- // Animation type.
- Type type;
-
- /// Vertex data target.
- /** 0 == shared geometry
- >0 == submesh index + 1 */
- uint16_t target;
-
- /// Only valid for VAT_TRANSFORM.
- std::string boneName;
-
- /// Only one of these will contain key frames, depending on the type enum.
- PoseKeyFrameList poseKeyFrames;
- MorphKeyFrameList morphKeyFrames;
- TransformKeyFrameList transformKeyFrames;
-};
-typedef std::vector<VertexAnimationTrack> VertexAnimationTrackList;
-
-/// Ogre Animation
-class Animation
-{
-public:
- explicit Animation(Skeleton *parent);
- explicit Animation(Mesh *parent);
-
- /// Returns the associated vertex data for a track in this animation.
- /** @note Only valid to call when parent Mesh is set. */
- VertexData *AssociatedVertexData(VertexAnimationTrack *track) const;
-
- /// Convert to Assimp animation.
- aiAnimation *ConvertToAssimpAnimation();
-
- /// Parent mesh.
- /** @note Set only when animation is read from a mesh. */
- Mesh *parentMesh;
-
- /// Parent skeleton.
- /** @note Set only when animation is read from a skeleton. */
- Skeleton *parentSkeleton;
-
- /// Animation name.
- std::string name;
-
- /// Base animation name.
- std::string baseName;
-
- /// Length in seconds.
- float length;
-
- /// Base animation key time.
- float baseTime;
-
- /// Animation tracks.
- VertexAnimationTrackList tracks;
-};
-typedef std::vector<Animation*> AnimationList;
-
-/// Ogre Bone
-class Bone
-{
-public:
- Bone();
-
- /// Returns if this bone is parented.
- bool IsParented() const;
-
- /// Parent index as uint16_t. Internally int32_t as -1 means unparented.
- uint16_t ParentId() const;
-
- /// Add child bone.
- void AddChild(Bone *bone);
-
- /// Calculates the world matrix for bone and its children.
- void CalculateWorldMatrixAndDefaultPose(Skeleton *skeleton);
-
- /// Convert to Assimp node (animation nodes).
- aiNode *ConvertToAssimpNode(Skeleton *parent, aiNode *parentNode = 0);
-
- /// Convert to Assimp bone (mesh bones).
- aiBone *ConvertToAssimpBone(Skeleton *parent, const std::vector<aiVertexWeight> &boneWeights);
-
- uint16_t id;
- std::string name;
-
- Bone *parent;
- int32_t parentId;
- std::vector<uint16_t> children;
-
- aiVector3D position;
- aiQuaternion rotation;
- aiVector3D scale;
-
- aiMatrix4x4 worldMatrix;
- aiMatrix4x4 defaultPose;
-};
-typedef std::vector<Bone*> BoneList;
-
-/// Ogre Skeleton
-class Skeleton
-{
-public:
- enum BlendMode
- {
- /// Animations are applied by calculating a weighted average of all animations
- ANIMBLEND_AVERAGE = 0,
- /// Animations are applied by calculating a weighted cumulative total
- ANIMBLEND_CUMULATIVE = 1
- };
-
- Skeleton();
- ~Skeleton();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- /// Returns unparented root bones.
- BoneList RootBones() const;
-
- /// Returns number of unparented root bones.
- size_t NumRootBones() const;
-
- /// Get bone by name.
- Bone *BoneByName(const std::string &name) const;
-
- /// Get bone by id.
- Bone *BoneById(uint16_t id) const;
-
- BoneList bones;
- AnimationList animations;
-
- /// @todo Take blend mode into account, but where?
- BlendMode blendMode;
-};
-
-/// Ogre Sub Mesh interface, inherited by the binary and XML implementations.
-class ISubMesh
-{
-public:
- /// @note Full list of Ogre types, not all of them are supported and exposed to Assimp.
- enum OperationType
- {
- /// A list of points, 1 vertex per point
- OT_POINT_LIST = 1,
- /// A list of lines, 2 vertices per line
- OT_LINE_LIST = 2,
- /// A strip of connected lines, 1 vertex per line plus 1 start vertex
- OT_LINE_STRIP = 3,
- /// A list of triangles, 3 vertices per triangle
- OT_TRIANGLE_LIST = 4,
- /// A strip of triangles, 3 vertices for the first triangle, and 1 per triangle after that
- OT_TRIANGLE_STRIP = 5,
- /// A fan of triangles, 3 vertices for the first triangle, and 1 per triangle after that
- OT_TRIANGLE_FAN = 6
- };
-
- ISubMesh();
-
- /// SubMesh index.
- unsigned int index;
-
- /// SubMesh name.
- std::string name;
-
- /// Material used by this submesh.
- std::string materialRef;
-
- /// Texture alias information.
- std::string textureAliasName;
- std::string textureAliasRef;
-
- /// Assimp scene material index used by this submesh.
- /** -1 if no material or material could not be imported. */
- int materialIndex;
-
- /// If submesh uses shared geometry from parent mesh.
- bool usesSharedVertexData;
-
- /// Operation type.
- OperationType operationType;
-};
-
-/// Ogre SubMesh
-class SubMesh : public ISubMesh
-{
-public:
- SubMesh();
- ~SubMesh();
-
- /// Releases all memory that this data structure owns.
- /** @note Vertex and index data contains shared ptrs
- that are freed automatically. In practice the ref count
- should be 0 after this reset. */
- void Reset();
-
- /// Covert to Assimp mesh.
- aiMesh *ConvertToAssimpMesh(Mesh *parent);
-
- /// Vertex data.
- VertexData *vertexData;
-
- /// Index data.
- IndexData *indexData;
-};
-typedef std::vector<SubMesh*> SubMeshList;
-
-/// Ogre Mesh
-class Mesh
-{
-public:
- /// Constructor.
- Mesh();
-
- /// Destructor.
- ~Mesh();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- /// Returns number of subMeshes.
- size_t NumSubMeshes() const;
-
- /// Returns submesh for @c index.
- SubMesh *GetSubMesh( size_t index) const;
-
- /// Convert mesh to Assimp scene.
- void ConvertToAssimpScene(aiScene* dest);
-
- /// Mesh has skeletal animations.
- bool hasSkeletalAnimations;
-
- /// Skeleton reference.
- std::string skeletonRef;
-
- /// Skeleton.
- Skeleton *skeleton;
-
- /// Vertex data
- VertexData *sharedVertexData;
-
- /// Sub meshes.
- SubMeshList subMeshes;
-
- /// Animations
- AnimationList animations;
-
- /// Poses
- PoseList poses;
-};
-
-/// Ogre XML Vertex Data
-class VertexDataXml : public IVertexData
-{
-public:
- VertexDataXml();
-
- bool HasPositions() const;
- bool HasNormals() const;
- bool HasTangents() const;
- bool HasUvs() const;
- size_t NumUvs() const;
-
- std::vector<aiVector3D> positions;
- std::vector<aiVector3D> normals;
- std::vector<aiVector3D> tangents;
- std::vector<std::vector<aiVector3D> > uvs;
-};
-
-/// Ogre XML Index Data
-class IndexDataXml
-{
-public:
- IndexDataXml() : faceCount(0) {}
-
- /// Face count.
- uint32_t faceCount;
-
- std::vector<aiFace> faces;
-};
-
-/// Ogre XML SubMesh
-class SubMeshXml : public ISubMesh
-{
-public:
- SubMeshXml();
- ~SubMeshXml();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- aiMesh *ConvertToAssimpMesh(MeshXml *parent);
-
- IndexDataXml *indexData;
- VertexDataXml *vertexData;
-};
-typedef std::vector<SubMeshXml*> SubMeshXmlList;
-
-/// Ogre XML Mesh
-class MeshXml
-{
-public:
- MeshXml();
- ~MeshXml();
-
- /// Releases all memory that this data structure owns.
- void Reset();
-
- /// Returns number of subMeshes.
- size_t NumSubMeshes() const;
-
- /// Returns submesh for @c index.
- SubMeshXml *GetSubMesh(uint16_t index) const;
-
- /// Convert mesh to Assimp scene.
- void ConvertToAssimpScene(aiScene* dest);
-
- /// Skeleton reference.
- std::string skeletonRef;
-
- /// Skeleton.
- Skeleton *skeleton;
-
- /// Vertex data
- VertexDataXml *sharedVertexData;
-
- /// Sub meshes.
- SubMeshXmlList subMeshes;
-};
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
-#endif // AI_OGRESTRUCTS_H_INC
diff --git a/src/3rdparty/assimp/code/OgreXmlSerializer.cpp b/src/3rdparty/assimp/code/OgreXmlSerializer.cpp
deleted file mode 100644
index b5d20cdf6..000000000
--- a/src/3rdparty/assimp/code/OgreXmlSerializer.cpp
+++ /dev/null
@@ -1,1005 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "OgreXmlSerializer.h"
-#include "OgreBinarySerializer.h"
-#include "OgreParsingUtils.h"
-
-#include "TinyFormatter.h"
-#include <assimp/DefaultLogger.hpp>
-#include <memory>
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-// Define as 1 to get verbose logging.
-#define OGRE_XML_SERIALIZER_DEBUG 0
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN 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<>
-int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const std::string &name) const
-{
- if (HasAttribute(name.c_str()))
- {
- return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name.c_str()));
- }
- else
- {
- ThrowAttibuteError(m_reader, name);
- return 0;
- }
-}
-
-template<>
-uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const std::string &name) const
-{
- if (HasAttribute(name.c_str()))
- {
- /** @note This is hackish. But we are never expecting unsigned values that go outside the
- int32_t range. Just monitor for negative numbers and kill the import. */
- int32_t temp = ReadAttribute<int32_t>(name);
- if (temp >= 0)
- {
- return static_cast<uint32_t>(temp);
- }
- else
- {
- ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
- }
- }
- else
- {
- ThrowAttibuteError(m_reader, name);
- }
- return 0;
-}
-
-template<>
-uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const std::string &name) const
-{
- if (HasAttribute(name.c_str()))
- {
- return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
- }
- else
- {
- ThrowAttibuteError(m_reader, name);
- }
- return 0;
-}
-
-template<>
-float OgreXmlSerializer::ReadAttribute<float>(const std::string &name) const
-{
- if (HasAttribute(name.c_str()))
- {
- return m_reader->getAttributeValueAsFloat(name.c_str());
- }
- else
- {
- ThrowAttibuteError(m_reader, name);
- return 0;
- }
-}
-
-template<>
-std::string OgreXmlSerializer::ReadAttribute<std::string>(const std::string &name) const
-{
- const char* value = m_reader->getAttributeValue(name.c_str());
- if (value)
- {
- return std::string(value);
- }
- else
- {
- ThrowAttibuteError(m_reader, name);
- return "";
- }
-}
-
-template<>
-bool OgreXmlSerializer::ReadAttribute<bool>(const std::string &name) const
-{
- std::string value = Ogre::ToLower(ReadAttribute<std::string>(name));
- if (ASSIMP_stricmp(value, "true") == 0)
- {
- return true;
- }
- else if (ASSIMP_stricmp(value, "false") == 0)
- {
- return false;
- }
- else
- {
- ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
- return false;
- }
-}
-
-bool OgreXmlSerializer::HasAttribute(const std::string &name) const
-{
- return (m_reader->getAttributeValue(name.c_str()) != 0);
-}
-
-std::string &OgreXmlSerializer::NextNode()
-{
- do
- {
- if (!m_reader->read())
- {
- m_currentNodeName = "";
- return m_currentNodeName;
- }
- }
- while(m_reader->getNodeType() != irr::io::EXN_ELEMENT);
-
- CurrentNodeName(true);
-#if (OGRE_XML_SERIALIZER_DEBUG == 1)
- DefaultLogger::get()->debug("<" + m_currentNodeName + ">");
-#endif
- return m_currentNodeName;
-}
-
-bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const
-{
- return (ASSIMP_stricmp(m_currentNodeName, name) == 0);
-}
-
-std::string OgreXmlSerializer::CurrentNodeName(bool forceRead)
-{
- if (forceRead)
- m_currentNodeName = std::string(m_reader->getNodeName());
- return m_currentNodeName;
-}
-
-std::string &OgreXmlSerializer::SkipCurrentNode()
-{
-#if (OGRE_XML_SERIALIZER_DEBUG == 1)
- DefaultLogger::get()->debug("Skipping node <" + m_currentNodeName + ">");
-#endif
-
- for(;;)
- {
- if (!m_reader->read())
- {
- m_currentNodeName = "";
- return m_currentNodeName;
- }
- if (m_reader->getNodeType() != irr::io::EXN_ELEMENT_END)
- continue;
- else if (std::string(m_reader->getNodeName()) == m_currentNodeName)
- break;
- }
- return NextNode();
-}
-
-// Mesh XML constants
-
-// <mesh>
-const std::string nnMesh = "mesh";
-const std::string nnSharedGeometry = "sharedgeometry";
-const std::string nnSubMeshes = "submeshes";
-const std::string nnSubMesh = "submesh";
-const std::string nnSubMeshNames = "submeshnames";
-const std::string nnSkeletonLink = "skeletonlink";
-const std::string nnLOD = "levelofdetail";
-const std::string nnExtremes = "extremes";
-const std::string nnPoses = "poses";
-const std::string nnAnimations = "animations";
-
-// <submesh>
-const std::string nnFaces = "faces";
-const std::string nnFace = "face";
-const std::string nnGeometry = "geometry";
-const std::string nnTextures = "textures";
-
-// <mesh/submesh>
-const std::string nnBoneAssignments = "boneassignments";
-
-// <sharedgeometry/geometry>
-const std::string nnVertexBuffer = "vertexbuffer";
-
-// <vertexbuffer>
-const std::string nnVertex = "vertex";
-const std::string nnPosition = "position";
-const std::string nnNormal = "normal";
-const std::string nnTangent = "tangent";
-const std::string nnBinormal = "binormal";
-const std::string nnTexCoord = "texcoord";
-const std::string nnColorDiffuse = "colour_diffuse";
-const std::string nnColorSpecular = "colour_specular";
-
-// <boneassignments>
-const std::string nnVertexBoneAssignment = "vertexboneassignment";
-
-// Skeleton XML constants
-
-// <skeleton>
-const std::string nnSkeleton = "skeleton";
-const std::string nnBones = "bones";
-const std::string nnBoneHierarchy = "bonehierarchy";
-const std::string nnAnimationLinks = "animationlinks";
-
-// <bones>
-const std::string nnBone = "bone";
-const std::string nnRotation = "rotation";
-const std::string nnAxis = "axis";
-const std::string nnScale = "scale";
-
-// <bonehierarchy>
-const std::string nnBoneParent = "boneparent";
-
-// <animations>
-const std::string nnAnimation = "animation";
-const std::string nnTracks = "tracks";
-
-// <tracks>
-const std::string nnTrack = "track";
-const std::string nnKeyFrames = "keyframes";
-const std::string nnKeyFrame = "keyframe";
-const std::string nnTranslate = "translate";
-const std::string nnRotate = "rotate";
-
-// Common XML constants
-
-const std::string anX = "x";
-const std::string anY = "y";
-const std::string anZ = "z";
-
-// Mesh
-
-MeshXml *OgreXmlSerializer::ImportMesh(XmlReader *reader)
-{
- OgreXmlSerializer serializer(reader);
-
- MeshXml *mesh = new MeshXml();
- serializer.ReadMesh(mesh);
- return mesh;
-}
-
-void OgreXmlSerializer::ReadMesh(MeshXml *mesh)
-{
- if (NextNode() != nnMesh) {
- throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <mesh>");
- }
-
- DefaultLogger::get()->debug("Reading Mesh");
-
- NextNode();
-
- // Root level nodes
- while(m_currentNodeName == nnSharedGeometry ||
- m_currentNodeName == nnSubMeshes ||
- m_currentNodeName == nnSkeletonLink ||
- m_currentNodeName == nnBoneAssignments ||
- m_currentNodeName == nnLOD ||
- m_currentNodeName == nnSubMeshNames ||
- m_currentNodeName == nnExtremes ||
- m_currentNodeName == nnPoses ||
- m_currentNodeName == nnAnimations)
- {
- if (m_currentNodeName == nnSharedGeometry)
- {
- mesh->sharedVertexData = new VertexDataXml();
- ReadGeometry(mesh->sharedVertexData);
- }
- else if (m_currentNodeName == nnSubMeshes)
- {
- NextNode();
- while(m_currentNodeName == nnSubMesh) {
- ReadSubMesh(mesh);
- }
- }
- else if (m_currentNodeName == nnBoneAssignments)
- {
- ReadBoneAssignments(mesh->sharedVertexData);
- }
- else if (m_currentNodeName == nnSkeletonLink)
- {
- mesh->skeletonRef = ReadAttribute<std::string>("name");
- DefaultLogger::get()->debug("Read skeleton link " + mesh->skeletonRef);
- NextNode();
- }
- // Assimp incompatible/ignored nodes
- else
- SkipCurrentNode();
- }
-}
-
-void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
-{
- dest->count = ReadAttribute<uint32_t>("vertexcount");
- DefaultLogger::get()->debug(Formatter::format() << " - Reading geometry of " << dest->count << " vertices");
-
- NextNode();
- while(m_currentNodeName == nnVertexBuffer) {
- ReadGeometryVertexBuffer(dest);
- }
-}
-
-void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
-{
- bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions"));
- bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
- bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
- uint32_t uvs = (HasAttribute("texture_coords") ? ReadAttribute<uint32_t>("texture_coords") : 0);
-
- // Not having positions is a error only if a previous vertex buffer did not have them.
- if (!positions && !dest->HasPositions()) {
- throw DeadlyImportError("Vertex buffer does not contain positions!");
- }
-
- if (positions)
- {
- DefaultLogger::get()->debug(" - Contains positions");
- dest->positions.reserve(dest->count);
- }
- if (normals)
- {
- DefaultLogger::get()->debug(" - Contains normals");
- dest->normals.reserve(dest->count);
- }
- if (tangents)
- {
- DefaultLogger::get()->debug(" - Contains tangents");
- dest->tangents.reserve(dest->count);
- }
- if (uvs > 0)
- {
- DefaultLogger::get()->debug(Formatter::format() << " - Contains " << uvs << " texture coords");
- dest->uvs.resize(uvs);
- for(size_t i=0, len=dest->uvs.size(); i<len; ++i) {
- dest->uvs[i].reserve(dest->count);
- }
- }
-
- bool warnBinormal = true;
- bool warnColorDiffuse = true;
- bool warnColorSpecular = true;
-
- NextNode();
-
- while(m_currentNodeName == nnVertex ||
- m_currentNodeName == nnPosition ||
- m_currentNodeName == nnNormal ||
- m_currentNodeName == nnTangent ||
- m_currentNodeName == nnBinormal ||
- m_currentNodeName == nnTexCoord ||
- m_currentNodeName == nnColorDiffuse ||
- m_currentNodeName == nnColorSpecular)
- {
- if (m_currentNodeName == nnVertex) {
- NextNode();
- }
-
- /// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
-
- if (positions && m_currentNodeName == nnPosition)
- {
- aiVector3D pos;
- pos.x = ReadAttribute<float>(anX);
- pos.y = ReadAttribute<float>(anY);
- pos.z = ReadAttribute<float>(anZ);
- dest->positions.push_back(pos);
- }
- else if (normals && m_currentNodeName == nnNormal)
- {
- aiVector3D normal;
- normal.x = ReadAttribute<float>(anX);
- normal.y = ReadAttribute<float>(anY);
- normal.z = ReadAttribute<float>(anZ);
- dest->normals.push_back(normal);
- }
- else if (tangents && m_currentNodeName == nnTangent)
- {
- aiVector3D tangent;
- tangent.x = ReadAttribute<float>(anX);
- tangent.y = ReadAttribute<float>(anY);
- tangent.z = ReadAttribute<float>(anZ);
- dest->tangents.push_back(tangent);
- }
- else if (uvs > 0 && m_currentNodeName == nnTexCoord)
- {
- for(auto &uvs : dest->uvs)
- {
- if (m_currentNodeName != nnTexCoord) {
- throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
- }
-
- aiVector3D uv;
- uv.x = ReadAttribute<float>("u");
- uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
- uvs.push_back(uv);
-
- NextNode();
- }
- // Continue main loop as above already read next node
- continue;
- }
- else
- {
- /// @todo Remove this stuff once implemented. We only want to log warnings once per element.
- bool warn = true;
- if (m_currentNodeName == nnBinormal)
- {
- if (warnBinormal)
- {
- warnBinormal = false;
- }
- else
- {
- warn = false;
- }
- }
- else if (m_currentNodeName == nnColorDiffuse)
- {
- if (warnColorDiffuse)
- {
- warnColorDiffuse = false;
- }
- else
- {
- warn = false;
- }
- }
- else if (m_currentNodeName == nnColorSpecular)
- {
- if (warnColorSpecular)
- {
- warnColorSpecular = false;
- }
- else
- {
- warn = false;
- }
- }
- if (warn) {
- DefaultLogger::get()->warn("Vertex buffer attribute read not implemented for element: " + m_currentNodeName);
- }
- }
-
- // Advance
- NextNode();
- }
-
- // Sanity checks
- if (dest->positions.size() != dest->count) {
- throw DeadlyImportError(Formatter::format() << "Read only " << dest->positions.size() << " positions when should have read " << dest->count);
- }
- if (normals && dest->normals.size() != dest->count) {
- throw DeadlyImportError(Formatter::format() << "Read only " << dest->normals.size() << " normals when should have read " << dest->count);
- }
- if (tangents && dest->tangents.size() != dest->count) {
- throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
- }
- for(unsigned int i=0; i<dest->uvs.size(); ++i)
- {
- if (dest->uvs[i].size() != dest->count) {
- throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
- << " uvs for uv index " << i << " when should have read " << dest->count);
- }
- }
-}
-
-void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
-{
- static const std::string anMaterial = "material";
- static const std::string anUseSharedVertices = "usesharedvertices";
- static const std::string anCount = "count";
- static const std::string anV1 = "v1";
- static const std::string anV2 = "v2";
- static const std::string anV3 = "v3";
- static const std::string anV4 = "v4";
-
- SubMeshXml* submesh = new SubMeshXml();
-
- if (HasAttribute(anMaterial)) {
- submesh->materialRef = ReadAttribute<std::string>(anMaterial);
- }
- if (HasAttribute(anUseSharedVertices)) {
- submesh->usesSharedVertexData = ReadAttribute<bool>(anUseSharedVertices);
- }
-
- DefaultLogger::get()->debug(Formatter::format() << "Reading SubMesh " << mesh->subMeshes.size());
- DefaultLogger::get()->debug(Formatter::format() << " - Material: '" << submesh->materialRef << "'");
- DefaultLogger::get()->debug(Formatter::format() << " - Uses shared geometry: " << (submesh->usesSharedVertexData ? "true" : "false"));
-
- // TODO: maybe we have always 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
- /// @todo Fix above comment with better read logic below
-
- bool quadWarned = false;
-
- NextNode();
- while(m_currentNodeName == nnFaces ||
- m_currentNodeName == nnGeometry ||
- m_currentNodeName == nnTextures ||
- m_currentNodeName == nnBoneAssignments)
- {
- if (m_currentNodeName == nnFaces)
- {
- submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
- submesh->indexData->faces.reserve(submesh->indexData->faceCount);
-
- NextNode();
- while(m_currentNodeName == nnFace)
- {
- aiFace face;
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[3];
- face.mIndices[0] = ReadAttribute<uint32_t>(anV1);
- face.mIndices[1] = ReadAttribute<uint32_t>(anV2);
- face.mIndices[2] = ReadAttribute<uint32_t>(anV3);
-
- /// @todo Support quads if Ogre even supports them in XML (I'm not sure but I doubt it)
- if (!quadWarned && HasAttribute(anV4)) {
- DefaultLogger::get()->warn("Submesh <face> has quads with <v4>, only triangles are supported at the moment!");
- quadWarned = true;
- }
-
- submesh->indexData->faces.push_back(face);
-
- // Advance
- NextNode();
- }
-
- if (submesh->indexData->faces.size() == submesh->indexData->faceCount)
- {
- DefaultLogger::get()->debug(Formatter::format() << " - Faces " << submesh->indexData->faceCount);
- }
- else
- {
- throw DeadlyImportError(Formatter::format() << "Read only " << submesh->indexData->faces.size() << " faces when should have read " << submesh->indexData->faceCount);
- }
- }
- else if (m_currentNodeName == nnGeometry)
- {
- if (submesh->usesSharedVertexData) {
- throw DeadlyImportError("Found <geometry> in <submesh> when use shared geometry is true. Invalid mesh file.");
- }
-
- submesh->vertexData = new VertexDataXml();
- ReadGeometry(submesh->vertexData);
- }
- else if (m_currentNodeName == nnBoneAssignments)
- {
- ReadBoneAssignments(submesh->vertexData);
- }
- // Assimp incompatible/ignored nodes
- else
- SkipCurrentNode();
- }
-
- submesh->index = static_cast<unsigned int>(mesh->subMeshes.size());
- mesh->subMeshes.push_back(submesh);
-}
-
-void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
-{
- if (!dest) {
- throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
- }
-
- static const std::string anVertexIndex = "vertexindex";
- static const std::string anBoneIndex = "boneindex";
- static const std::string anWeight = "weight";
-
- std::set<uint32_t> influencedVertices;
-
- NextNode();
- while(m_currentNodeName == nnVertexBoneAssignment)
- {
- VertexBoneAssignment ba;
- ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
- ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
- ba.weight = ReadAttribute<float>(anWeight);
-
- dest->boneAssignments.push_back(ba);
- influencedVertices.insert(ba.vertexIndex);
-
- NextNode();
- }
-
- /** Normalize bone weights.
- Some exporters won't care if the sum of all bone weights
- for a single vertex equals 1 or not, so validate here. */
- const float epsilon = 0.05f;
- for (const uint32_t vertexIndex : influencedVertices)
- {
- float sum = 0.0f;
- for (VertexBoneAssignmentList::const_iterator baIter=dest->boneAssignments.begin(), baEnd=dest->boneAssignments.end(); baIter != baEnd; ++baIter)
- {
- if (baIter->vertexIndex == vertexIndex)
- sum += baIter->weight;
- }
- if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
- {
- for (auto &boneAssign : dest->boneAssignments)
- {
- if (boneAssign.vertexIndex == vertexIndex)
- boneAssign.weight /= sum;
- }
- }
- }
-
- DefaultLogger::get()->debug(Formatter::format() << " - " << dest->boneAssignments.size() << " bone assignments");
-}
-
-// Skeleton
-
-bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
-{
- if (!mesh || mesh->skeletonRef.empty())
- return false;
-
- // Highly unusual to see in read world cases but support
- // XML mesh referencing a binary skeleton file.
- if (EndsWith(mesh->skeletonRef, ".skeleton", false))
- {
- if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh))
- return true;
-
- /** Last fallback if .skeleton failed to be read. Try reading from
- .skeleton.xml even if the XML file referenced a binary skeleton.
- @note This logic was in the previous version and I don't want to break
- old code that might depends on it. */
- mesh->skeletonRef = mesh->skeletonRef + ".xml";
- }
-
- XmlReaderPtr reader = OpenReader(pIOHandler, mesh->skeletonRef);
- if (!reader.get())
- return false;
-
- Skeleton *skeleton = new Skeleton();
- OgreXmlSerializer serializer(reader.get());
- serializer.ReadSkeleton(skeleton);
- mesh->skeleton = skeleton;
- return true;
-}
-
-bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
-{
- if (!mesh || mesh->skeletonRef.empty())
- return false;
-
- XmlReaderPtr reader = OpenReader(pIOHandler, mesh->skeletonRef);
- if (!reader.get())
- return false;
-
- Skeleton *skeleton = new Skeleton();
- OgreXmlSerializer serializer(reader.get());
- serializer.ReadSkeleton(skeleton);
- mesh->skeleton = skeleton;
- return true;
-}
-
-XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
-{
- if (!EndsWith(filename, ".skeleton.xml", false))
- {
- DefaultLogger::get()->error("Imported Mesh is referencing to unsupported '" + filename + "' skeleton file.");
- return XmlReaderPtr();
- }
-
- if (!pIOHandler->Exists(filename))
- {
- DefaultLogger::get()->error("Failed to find skeleton file '" + filename + "' that is referenced by imported Mesh.");
- return XmlReaderPtr();
- }
-
- std::unique_ptr<IOStream> file(pIOHandler->Open(filename));
- if (!file.get()) {
- throw DeadlyImportError("Failed to open skeleton file " + filename);
- }
-
- std::unique_ptr<CIrrXML_IOStreamReader> stream(new CIrrXML_IOStreamReader(file.get()));
- XmlReaderPtr reader = XmlReaderPtr(irr::io::createIrrXMLReader(stream.get()));
- if (!reader.get()) {
- throw DeadlyImportError("Failed to create XML reader for skeleton file " + filename);
- }
- return reader;
-}
-
-void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
-{
- if (NextNode() != nnSkeleton) {
- throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>");
- }
-
- DefaultLogger::get()->debug("Reading Skeleton");
-
- // Optional blend mode from root node
- if (HasAttribute("blendmode")) {
- skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative"
- ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
- }
-
- NextNode();
-
- // Root level nodes
- while(m_currentNodeName == nnBones ||
- m_currentNodeName == nnBoneHierarchy ||
- m_currentNodeName == nnAnimations ||
- m_currentNodeName == nnAnimationLinks)
- {
- if (m_currentNodeName == nnBones)
- ReadBones(skeleton);
- else if (m_currentNodeName == nnBoneHierarchy)
- ReadBoneHierarchy(skeleton);
- else if (m_currentNodeName == nnAnimations)
- ReadAnimations(skeleton);
- else
- SkipCurrentNode();
- }
-}
-
-void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
-{
- if (skeleton->bones.empty()) {
- throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones");
- }
-
- DefaultLogger::get()->debug(" - Animations");
-
- NextNode();
- while(m_currentNodeName == nnAnimation)
- {
- Animation *anim = new Animation(skeleton);
- anim->name = ReadAttribute<std::string>("name");
- anim->length = ReadAttribute<float>("length");
-
- if (NextNode() != nnTracks) {
- throw DeadlyImportError(Formatter::format() << "No <tracks> found in <animation> " << anim->name);
- }
-
- ReadAnimationTracks(anim);
- skeleton->animations.push_back(anim);
-
- DefaultLogger::get()->debug(Formatter::format() << " " << anim->name << " (" << anim->length << " sec, " << anim->tracks.size() << " tracks)");
- }
-}
-
-void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
-{
- NextNode();
- while(m_currentNodeName == nnTrack)
- {
- VertexAnimationTrack track;
- track.type = VertexAnimationTrack::VAT_TRANSFORM;
- track.boneName = ReadAttribute<std::string>("bone");
-
- if (NextNode() != nnKeyFrames) {
- throw DeadlyImportError(Formatter::format() << "No <keyframes> found in <track> " << dest->name);
- }
-
- ReadAnimationKeyFrames(dest, &track);
-
- dest->tracks.push_back(track);
- }
-}
-
-void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest)
-{
- const aiVector3D zeroVec(0.f, 0.f, 0.f);
-
- NextNode();
- while(m_currentNodeName == nnKeyFrame)
- {
- TransformKeyFrame keyframe;
- keyframe.timePos = ReadAttribute<float>("time");
-
- NextNode();
- while(m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale)
- {
- if (m_currentNodeName == nnTranslate)
- {
- keyframe.position.x = ReadAttribute<float>(anX);
- keyframe.position.y = ReadAttribute<float>(anY);
- keyframe.position.z = ReadAttribute<float>(anZ);
- }
- else if (m_currentNodeName == nnRotate)
- {
- float angle = ReadAttribute<float>("angle");
-
- if (NextNode() != nnAxis) {
- throw DeadlyImportError("No axis specified for keyframe rotation in animation " + anim->name);
- }
-
- aiVector3D axis;
- axis.x = ReadAttribute<float>(anX);
- axis.y = ReadAttribute<float>(anY);
- axis.z = ReadAttribute<float>(anZ);
- if (axis.Equal(zeroVec))
- {
- axis.x = 1.0f;
- if (angle != 0) {
- DefaultLogger::get()->warn("Found invalid a key frame with a zero rotation axis in animation: " + anim->name);
- }
- }
- keyframe.rotation = aiQuaternion(axis, angle);
- }
- else if (m_currentNodeName == nnScale)
- {
- keyframe.scale.x = ReadAttribute<float>(anX);
- keyframe.scale.y = ReadAttribute<float>(anY);
- keyframe.scale.z = ReadAttribute<float>(anZ);
- }
-
- NextNode();
- }
-
- dest->transformKeyFrames.push_back(keyframe);
- }
-}
-
-void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
-{
- if (skeleton->bones.empty()) {
- throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones");
- }
-
- while(NextNode() == nnBoneParent)
- {
- const std::string name = ReadAttribute<std::string>("bone");
- const std::string parentName = ReadAttribute<std::string>("parent");
-
- Bone *bone = skeleton->BoneByName(name);
- Bone *parent = skeleton->BoneByName(parentName);
-
- if (bone && parent)
- parent->AddChild(bone);
- else
- throw DeadlyImportError("Failed to find bones for parenting: Child " + name + " for parent " + parentName);
- }
-
- // Calculate bone matrices for root bones. Recursively calculates their children.
- for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
- {
- Bone *bone = skeleton->bones[i];
- if (!bone->IsParented())
- bone->CalculateWorldMatrixAndDefaultPose(skeleton);
- }
-}
-
-bool BoneCompare(Bone *a, Bone *b)
-{
- return (a->id < b->id);
-}
-
-void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
-{
- DefaultLogger::get()->debug(" - Bones");
-
- NextNode();
- while(m_currentNodeName == nnBone)
- {
- Bone *bone = new Bone();
- bone->id = ReadAttribute<uint16_t>("id");
- bone->name = ReadAttribute<std::string>("name");
-
- NextNode();
- while(m_currentNodeName == nnPosition ||
- m_currentNodeName == nnRotation ||
- m_currentNodeName == nnScale)
- {
- if (m_currentNodeName == nnPosition)
- {
- bone->position.x = ReadAttribute<float>(anX);
- bone->position.y = ReadAttribute<float>(anY);
- bone->position.z = ReadAttribute<float>(anZ);
- }
- else if (m_currentNodeName == nnRotation)
- {
- float angle = ReadAttribute<float>("angle");
-
- if (NextNode() != nnAxis) {
- throw DeadlyImportError(Formatter::format() << "No axis specified for bone rotation in bone " << bone->id);
- }
-
- aiVector3D axis;
- axis.x = ReadAttribute<float>(anX);
- axis.y = ReadAttribute<float>(anY);
- axis.z = ReadAttribute<float>(anZ);
-
- bone->rotation = aiQuaternion(axis, angle);
- }
- else if (m_currentNodeName == nnScale)
- {
- /// @todo Implement taking scale into account in matrix/pose calculations!
- if (HasAttribute("factor"))
- {
- float factor = ReadAttribute<float>("factor");
- bone->scale.Set(factor, factor, factor);
- }
- else
- {
- if (HasAttribute(anX))
- bone->scale.x = ReadAttribute<float>(anX);
- if (HasAttribute(anY))
- bone->scale.y = ReadAttribute<float>(anY);
- if (HasAttribute(anZ))
- bone->scale.z = ReadAttribute<float>(anZ);
- }
- }
-
- NextNode();
- }
-
- skeleton->bones.push_back(bone);
- }
-
- // Order bones by Id
- std::sort(skeleton->bones.begin(), skeleton->bones.end(), BoneCompare);
-
- // 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=skeleton->bones.size(); i<len; ++i)
- {
- Bone *b = skeleton->bones[i];
- DefaultLogger::get()->debug(Formatter::format() << " " << b->id << " " << b->name);
-
- if (b->id != static_cast<uint16_t>(i)) {
- throw DeadlyImportError(Formatter::format() << "Bone ids are not in sequence starting from 0. Missing index " << i);
- }
- }
-}
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
diff --git a/src/3rdparty/assimp/code/OgreXmlSerializer.h b/src/3rdparty/assimp/code/OgreXmlSerializer.h
deleted file mode 100644
index 01b9a7b23..000000000
--- a/src/3rdparty/assimp/code/OgreXmlSerializer.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OGREXMLSERIALIZER_H_INC
-#define AI_OGREXMLSERIALIZER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
-
-#include "OgreStructs.h"
-#include "irrXMLWrapper.h"
-
-namespace Assimp
-{
-namespace Ogre
-{
-
-typedef irr::io::IrrXMLReader XmlReader;
-typedef std::shared_ptr<XmlReader> XmlReaderPtr;
-
-class OgreXmlSerializer
-{
-public:
- /// Imports mesh and returns the result.
- /** @note Fatal unrecoverable errors will throw a DeadlyImportError. */
- static MeshXml *ImportMesh(XmlReader *reader);
-
- /// Imports skeleton to @c mesh.
- /** If mesh does not have a skeleton reference or the skeleton file
- cannot be found it is not a fatal DeadlyImportError.
- @return If skeleton import was successful. */
- static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh);
- static bool ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh);
-
-private:
- explicit OgreXmlSerializer(XmlReader *reader) :
- m_reader(reader)
- {
- }
-
- static XmlReaderPtr OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename);
-
- // Mesh
- void ReadMesh(MeshXml *mesh);
- void ReadSubMesh(MeshXml *mesh);
-
- void ReadGeometry(VertexDataXml *dest);
- void ReadGeometryVertexBuffer(VertexDataXml *dest);
-
- void ReadBoneAssignments(VertexDataXml *dest);
-
- // Skeleton
- void ReadSkeleton(Skeleton *skeleton);
-
- void ReadBones(Skeleton *skeleton);
- void ReadBoneHierarchy(Skeleton *skeleton);
-
- void ReadAnimations(Skeleton *skeleton);
- void ReadAnimationTracks(Animation *dest);
- void ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest);
-
- template<typename T>
- T ReadAttribute(const std::string &name) const;
- bool HasAttribute(const std::string &name) const;
-
- std::string &NextNode();
- std::string &SkipCurrentNode();
-
- bool CurrentNodeNameEquals(const std::string &name) const;
- std::string CurrentNodeName(bool forceRead = false);
-
- XmlReader *m_reader;
- std::string m_currentNodeName;
-};
-
-} // Ogre
-} // Assimp
-
-#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
-#endif // AI_OGREXMLSERIALIZER_H_INC
diff --git a/src/3rdparty/assimp/code/OpenGEXExporter.cpp b/src/3rdparty/assimp/code/OpenGEXExporter.cpp
deleted file mode 100644
index 0f2b1c35b..000000000
--- a/src/3rdparty/assimp/code/OpenGEXExporter.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#include "OpenGEXExporter.h"
-
-namespace Assimp {
-namespace OpenGEX {
-
-#ifndef ASSIMP_BUILD_NO_OPENGEX_EXPORTER
-
-OpenGEXExporter::OpenGEXExporter() {
-}
-
-OpenGEXExporter::~OpenGEXExporter() {
-}
-
-bool OpenGEXExporter::exportScene( const char * /*filename*/, const aiScene* /*pScene*/ ) {
- return true;
-}
-
-#endif // ASSIMP_BUILD_NO_OPENGEX_EXPORTER
-
-} // Namespace OpenGEX
-} // Namespace Assimp
diff --git a/src/3rdparty/assimp/code/OpenGEXExporter.h b/src/3rdparty/assimp/code/OpenGEXExporter.h
deleted file mode 100644
index 9df9d853e..000000000
--- a/src/3rdparty/assimp/code/OpenGEXExporter.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OPENGEX_EXPORTER_H
-#define AI_OPENGEX_EXPORTER_H
-
-#include <assimp/types.h>
-
-#ifndef ASSIMP_BUILD_NO_OPENGEX_EXPORTER
-
-namespace Assimp {
-
-struct aiScene;
-
-namespace OpenGEX {
-
-class OpenGEXExporter {
-public:
- OpenGEXExporter();
- ~OpenGEXExporter();
- bool exportScene( const char *filename, const aiScene* pScene );
-};
-
-} // Namespace OpenGEX
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_OPENGEX_EXPORTER
-
-#endif // AI_OPENGEX_EXPORTER_H
-
diff --git a/src/3rdparty/assimp/code/OpenGEXImporter.cpp b/src/3rdparty/assimp/code/OpenGEXImporter.cpp
deleted file mode 100644
index 025356c1d..000000000
--- a/src/3rdparty/assimp/code/OpenGEXImporter.cpp
+++ /dev/null
@@ -1,1303 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-
-#include "OpenGEXImporter.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/DefaultLogger.hpp>
-#include "MakeVerboseFormat.h"
-#include "StringComparison.h"
-
-#include <openddlparser/OpenDDLParser.h>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-#include <assimp/importerdesc.h>
-
-#include <vector>
-
-static const aiImporterDesc desc = {
- "Open Game Engine Exchange",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "ogex"
-};
-
-namespace Grammar {
- static const std::string MetricType = "Metric";
- static const std::string Metric_DistanceType = "distance";
- static const std::string Metric_AngleType = "angle";
- static const std::string Metric_TimeType = "time";
- static const std::string Metric_UpType = "up";
- static const std::string NameType = "Name";
- static const std::string ObjectRefType = "ObjectRef";
- static const std::string MaterialRefType = "MaterialRef";
- static const std::string MetricKeyType = "key";
- static const std::string GeometryNodeType = "GeometryNode";
- static const std::string CameraNodeType = "CameraNode";
- static const std::string LightNodeType = "LightNode";
- static const std::string GeometryObjectType = "GeometryObject";
- static const std::string CameraObjectType = "CameraObject";
- static const std::string LightObjectType = "LightObject";
- static const std::string TransformType = "Transform";
- static const std::string MeshType = "Mesh";
- static const std::string VertexArrayType = "VertexArray";
- static const std::string IndexArrayType = "IndexArray";
- static const std::string MaterialType = "Material";
- static const std::string ColorType = "Color";
- static const std::string ParamType = "Param";
- static const std::string TextureType = "Texture";
- static const std::string AttenType = "Atten";
-
- static const std::string DiffuseColorToken = "diffuse";
- static const std::string SpecularColorToken = "specular";
- static const std::string EmissionColorToken = "emission";
-
- static const std::string DiffuseTextureToken = "diffuse";
- static const std::string DiffuseSpecularTextureToken = "specular";
- static const std::string SpecularPowerTextureToken = "specular_power";
- static const std::string EmissionTextureToken = "emission";
- static const std::string OpacyTextureToken = "opacity";
- static const std::string TransparencyTextureToken = "transparency";
- static const std::string NormalTextureToken = "normal";
-
- enum TokenType {
- NoneType = -1,
- MetricToken,
- NameToken,
- ObjectRefToken,
- MaterialRefToken,
- MetricKeyToken,
- GeometryNodeToken,
- CameraNodeToken,
- LightNodeToken,
- GeometryObjectToken,
- CameraObjectToken,
- LightObjectToken,
- TransformToken,
- MeshToken,
- VertexArrayToken,
- IndexArrayToken,
- MaterialToken,
- ColorToken,
- ParamToken,
- TextureToken,
- AttenToken
- };
-
- static const std::string ValidMetricToken[ 4 ] = {
- Metric_DistanceType,
- Metric_AngleType,
- Metric_TimeType,
- Metric_UpType
- };
-
- static int isValidMetricType( const char *token ) {
- if( nullptr == token ) {
- return false;
- }
-
- int idx( -1 );
- for( size_t i = 0; i < 4; i++ ) {
- if( ValidMetricToken[ i ] == token ) {
- idx = (int) i;
- break;
- }
- }
-
- return idx;
- }
-
- static TokenType matchTokenType( const char *tokenType ) {
- if( MetricType == tokenType ) {
- return MetricToken;
- } else if( NameType == tokenType ) {
- return NameToken;
- } else if( ObjectRefType == tokenType ) {
- return ObjectRefToken;
- } else if( MaterialRefType == tokenType ) {
- return MaterialRefToken;
- } else if( MetricKeyType == tokenType ) {
- return MetricKeyToken;
- } else if ( GeometryNodeType == tokenType ) {
- return GeometryNodeToken;
- } else if ( CameraNodeType == tokenType ) {
- return CameraNodeToken;
- } else if ( LightNodeType == tokenType ) {
- return LightNodeToken;
- } else if ( GeometryObjectType == tokenType ) {
- return GeometryObjectToken;
- } else if ( CameraObjectType == tokenType ) {
- return CameraObjectToken;
- } else if ( LightObjectType == tokenType ) {
- return LightObjectToken;
- } else if( TransformType == tokenType ) {
- return TransformToken;
- } else if( MeshType == tokenType ) {
- return MeshToken;
- } else if( VertexArrayType == tokenType ) {
- return VertexArrayToken;
- } else if( IndexArrayType == tokenType ) {
- return IndexArrayToken;
- } else if( MaterialType == tokenType ) {
- return MaterialToken;
- } else if ( ColorType == tokenType ) {
- return ColorToken;
- } else if ( ParamType == tokenType ) {
- return ParamToken;
- } else if( TextureType == tokenType ) {
- return TextureToken;
- } else if ( AttenType == tokenType ) {
- return AttenToken;
- }
-
- return NoneType;
- }
-} // Namespace Grammar
-
-namespace Assimp {
-namespace OpenGEX {
-
-USE_ODDLPARSER_NS
-
-//------------------------------------------------------------------------------------------------
-static void propId2StdString( Property *prop, std::string &name, std::string &key ) {
- name = key = "";
- if ( nullptr == prop ) {
- return;
- }
-
- if ( nullptr != prop->m_key ) {
- name = prop->m_key->m_buffer;
- if ( Value::ddl_string == prop->m_value->m_type ) {
- key = prop->m_value->getString();
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::VertexContainer::VertexContainer()
-: m_numVerts( 0 )
-, m_vertices( nullptr )
-, m_numColors( 0 )
-, m_colors( nullptr )
-, m_numNormals( 0 )
-, m_normals( nullptr )
-, m_numUVComps()
-, m_textureCoords() {
- // empty
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::VertexContainer::~VertexContainer() {
- delete[] m_vertices;
- delete[] m_colors;
- delete[] m_normals;
-
- for(auto &texcoords : m_textureCoords) {
- delete [] texcoords;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::RefInfo::RefInfo( aiNode *node, Type type, std::vector<std::string> &names )
-: m_node( node )
-, m_type( type )
-, m_Names( names ) {
- // empty
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::RefInfo::~RefInfo() {
- // empty
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::OpenGEXImporter()
-: m_root( nullptr )
-, m_nodeChildMap()
-, m_meshCache()
-, m_mesh2refMap()
-, m_material2refMap()
-, m_ctx( nullptr )
-, m_metrics()
-, m_currentNode( nullptr )
-, m_currentVertices()
-, m_currentMesh( nullptr )
-, m_currentMaterial( nullptr )
-, m_currentLight( nullptr )
-, m_currentCamera( nullptr )
-, m_tokenType( Grammar::NoneType )
-, m_materialCache()
-, m_cameraCache()
-, m_lightCache()
-, m_nodeStack()
-, m_unresolvedRefStack() {
- // empty
-}
-
-//------------------------------------------------------------------------------------------------
-OpenGEXImporter::~OpenGEXImporter() {
- m_ctx = nullptr;
-}
-
-//------------------------------------------------------------------------------------------------
-bool OpenGEXImporter::CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const {
- bool canRead( false );
- if( !checkSig ) {
- canRead = SimpleExtensionCheck( file, "ogex" );
- } else {
- static const char *token[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
- canRead = BaseImporter::SearchFileHeaderForToken( pIOHandler, file, token, 4 );
- }
-
- return canRead;
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) {
- // open source file
- IOStream *file = pIOHandler->Open( filename, "rb" );
- if( !file ) {
- throw DeadlyImportError( "Failed to open file " + filename );
- }
-
- std::vector<char> buffer;
- TextFileToBuffer( file, buffer );
- pIOHandler->Close( file );
-
- OpenDDLParser myParser;
- myParser.setBuffer( &buffer[ 0 ], buffer.size() );
- bool success( myParser.parse() );
- if( success ) {
- m_ctx = myParser.getContext();
- pScene->mRootNode = new aiNode;
- pScene->mRootNode->mName.Set( filename );
- handleNodes( m_ctx->m_root, pScene );
- }
-
- copyMeshes( pScene );
- copyCameras( pScene );
- copyLights( pScene );
- copyMaterials( pScene );
- resolveReferences();
- createNodeTree( pScene );
-}
-
-//------------------------------------------------------------------------------------------------
-const aiImporterDesc *OpenGEXImporter::GetInfo() const {
- return &desc;
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::SetupProperties( const Importer *pImp ) {
- if( nullptr == pImp ) {
- return;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleNodes( DDLNode *node, aiScene *pScene ) {
- if( nullptr == node ) {
- return;
- }
-
- DDLNode::DllNodeList childs = node->getChildNodeList();
- for( DDLNode::DllNodeList::iterator it = childs.begin(); it != childs.end(); ++it ) {
- Grammar::TokenType tokenType( Grammar::matchTokenType( ( *it )->getType().c_str() ) );
- switch( tokenType ) {
- case Grammar::MetricToken:
- handleMetricNode( *it, pScene );
- break;
-
- case Grammar::NameToken:
- handleNameNode( *it, pScene );
- break;
-
- case Grammar::ObjectRefToken:
- handleObjectRefNode( *it, pScene );
- break;
-
- case Grammar::MaterialRefToken:
- handleMaterialRefNode( *it, pScene );
- break;
-
- case Grammar::MetricKeyToken:
- break;
-
- case Grammar::GeometryNodeToken:
- handleGeometryNode( *it, pScene );
- break;
-
- case Grammar::CameraNodeToken:
- handleCameraNode( *it, pScene );
- break;
-
- case Grammar::LightNodeToken:
- handleLightNode( *it, pScene );
- break;
-
- case Grammar::GeometryObjectToken:
- handleGeometryObject( *it, pScene );
- break;
-
- case Grammar::CameraObjectToken:
- handleCameraObject( *it, pScene );
- break;
-
- case Grammar::LightObjectToken:
- handleLightObject( *it, pScene );
- break;
-
- case Grammar::TransformToken:
- handleTransformNode( *it, pScene );
- break;
-
- case Grammar::MeshToken:
- handleMeshNode( *it, pScene );
- break;
-
- case Grammar::VertexArrayToken:
- handleVertexArrayNode( *it, pScene );
- break;
-
- case Grammar::IndexArrayToken:
- handleIndexArrayNode( *it, pScene );
- break;
-
- case Grammar::MaterialToken:
- handleMaterialNode( *it, pScene );
- break;
-
- case Grammar::ColorToken:
- handleColorNode( *it, pScene );
- break;
-
- case Grammar::ParamToken:
- handleParamNode( *it, pScene );
- break;
-
- case Grammar::TextureToken:
- handleTextureNode( *it, pScene );
- break;
-
- default:
- break;
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMetricNode( DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == node || nullptr == m_ctx ) {
- return;
- }
-
- if( m_ctx->m_root != node->getParent() ) {
- return;
- }
-
- Property *prop( node->getProperties() );
- while( nullptr != prop ) {
- if( nullptr != prop->m_key ) {
- if( Value::ddl_string == prop->m_value->m_type ) {
- std::string valName( ( char* ) prop->m_value->m_data );
- int type( Grammar::isValidMetricType( valName.c_str() ) );
- if( Grammar::NoneType != type ) {
- Value *val( node->getValue() );
- if( nullptr != val ) {
- if( Value::ddl_float == val->m_type ) {
- m_metrics[ type ].m_floatValue = val->getFloat();
- } else if( Value::ddl_int32 == val->m_type ) {
- m_metrics[ type ].m_intValue = val->getInt32();
- } else if( Value::ddl_string == val->m_type ) {
- m_metrics[type].m_stringValue = std::string( val->getString() );
- } else {
- throw DeadlyImportError( "OpenGEX: invalid data type for Metric node." );
- }
- }
- }
- }
- }
- prop = prop->m_next;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleNameNode( DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == m_currentNode ) {
- throw DeadlyImportError( "No current node for name." );
- return;
- }
-
- Value *val( node->getValue() );
- if( nullptr != val ) {
- if( Value::ddl_string != val->m_type ) {
- throw DeadlyImportError( "OpenGEX: invalid data type for value in node name." );
- return;
- }
-
- const std::string name( val->getString() );
- if( m_tokenType == Grammar::GeometryNodeToken || m_tokenType == Grammar::LightNodeToken
- || m_tokenType == Grammar::CameraNodeToken ) {
- m_currentNode->mName.Set( name.c_str() );
- } else if( m_tokenType == Grammar::MaterialToken ) {
- aiString aiName;
- aiName.Set( name );
- m_currentMaterial->AddProperty( &aiName, AI_MATKEY_NAME );
- m_material2refMap[ name ] = m_materialCache.size() - 1;
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-static void getRefNames( DDLNode *node, std::vector<std::string> &names ) {
- ai_assert( nullptr != node );
-
- Reference *ref = node->getReferences();
- if( nullptr != ref ) {
- for( size_t i = 0; i < ref->m_numRefs; i++ ) {
- Name *currentName( ref->m_referencedName[ i ] );
- if( nullptr != currentName && nullptr != currentName->m_id ) {
- const std::string name( currentName->m_id->m_buffer );
- if( !name.empty() ) {
- names.push_back( name );
- }
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleObjectRefNode( DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == m_currentNode ) {
- throw DeadlyImportError( "No parent node for name." );
- return;
- }
-
- std::vector<std::string> objRefNames;
- getRefNames( node, objRefNames );
-
- // when we are dealing with a geometry node prepare the mesh cache
- if ( m_tokenType == Grammar::GeometryNodeToken ) {
- m_currentNode->mNumMeshes = static_cast<unsigned int>(objRefNames.size());
- m_currentNode->mMeshes = new unsigned int[ objRefNames.size() ];
- if ( !objRefNames.empty() ) {
- m_unresolvedRefStack.push_back( std::unique_ptr<RefInfo>( new RefInfo( m_currentNode, RefInfo::MeshRef, objRefNames ) ) );
- }
- } else if ( m_tokenType == Grammar::LightNodeToken ) {
- // TODO!
- } else if ( m_tokenType == Grammar::CameraNodeToken ) {
- // TODO!
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == m_currentNode ) {
- throw DeadlyImportError( "No parent node for name." );
- return;
- }
-
- std::vector<std::string> matRefNames;
- getRefNames( node, matRefNames );
- if( !matRefNames.empty() ) {
- m_unresolvedRefStack.push_back( std::unique_ptr<RefInfo>( new RefInfo( m_currentNode, RefInfo::MaterialRef, matRefNames ) ) );
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleGeometryNode( DDLNode *node, aiScene *pScene ) {
- aiNode *newNode = new aiNode;
- pushNode( newNode, pScene );
- m_tokenType = Grammar::GeometryNodeToken;
- m_currentNode = newNode;
- handleNodes( node, pScene );
-
- popNode();
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleCameraNode( DDLNode *node, aiScene *pScene ) {
- aiCamera *camera( new aiCamera );
- m_cameraCache.push_back( camera );
- m_currentCamera = camera;
-
- aiNode *newNode = new aiNode;
- pushNode( newNode, pScene );
- m_tokenType = Grammar::CameraNodeToken;
- m_currentNode = newNode;
-
- handleNodes( node, pScene );
-
- popNode();
-
- m_currentCamera->mName.Set( newNode->mName.C_Str() );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleLightNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
- aiLight *light( new aiLight );
- m_lightCache.push_back( light );
- m_currentLight = light;
-
- aiNode *newNode = new aiNode;
- m_tokenType = Grammar::LightNodeToken;
- m_currentNode = newNode;
- pushNode( newNode, pScene );
-
- handleNodes( node, pScene );
-
- popNode();
-
- m_currentLight->mName.Set( newNode->mName.C_Str() );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleGeometryObject( DDLNode *node, aiScene *pScene ) {
- // parameters will be parsed normally in the tree, so just go for it
- handleNodes( node, pScene );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleCameraObject( ODDLParser::DDLNode *node, aiScene *pScene ) {
- // parameters will be parsed normally in the tree, so just go for it
-
- handleNodes( node, pScene );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleLightObject( ODDLParser::DDLNode *node, aiScene *pScene ) {
- aiLight *light( new aiLight );
- m_lightCache.push_back( light );
- std::string objName = node->getName();
- if ( !objName.empty() ) {
- light->mName.Set( objName );
- }
- m_currentLight = light;
-
- Property *prop( node->findPropertyByName( "type" ) );
- if ( nullptr != prop ) {
- if ( nullptr != prop->m_value ) {
- std::string typeStr( prop->m_value->getString() );
- if ( "point" == typeStr ) {
- m_currentLight->mType = aiLightSource_POINT;
- } else if ( "spot" == typeStr ) {
- m_currentLight->mType = aiLightSource_SPOT;
- } else if ( "infinite" == typeStr ) {
- m_currentLight->mType = aiLightSource_DIRECTIONAL;
- }
- }
- }
-
- // parameters will be parsed normally in the tree, so just go for it
- handleNodes( node, pScene );
-}
-
-//------------------------------------------------------------------------------------------------
-static void setMatrix( aiNode *node, DataArrayList *transformData ) {
- ai_assert( nullptr != node );
- ai_assert( nullptr != transformData );
-
- float m[ 16 ];
- size_t i( 1 );
- Value *next( transformData->m_dataList->m_next );
- m[ 0 ] = transformData->m_dataList->getFloat();
- while( next != nullptr ) {
- m[ i ] = next->getFloat();
- next = next->m_next;
- i++;
- }
-
- ai_assert(i == 16);
-
- node->mTransformation.a1 = m[ 0 ];
- node->mTransformation.a2 = m[ 4 ];
- node->mTransformation.a3 = m[ 8 ];
- node->mTransformation.a4 = m[ 12 ];
-
- node->mTransformation.b1 = m[ 1 ];
- node->mTransformation.b2 = m[ 5 ];
- node->mTransformation.b3 = m[ 9 ];
- node->mTransformation.b4 = m[ 13 ];
-
- node->mTransformation.c1 = m[ 2 ];
- node->mTransformation.c2 = m[ 6 ];
- node->mTransformation.c3 = m[ 10 ];
- node->mTransformation.c4 = m[ 14 ];
-
- node->mTransformation.d1 = m[ 3 ];
- node->mTransformation.d2 = m[ 7 ];
- node->mTransformation.d3 = m[ 11 ];
- node->mTransformation.d4 = m[ 15 ];
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleTransformNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == m_currentNode ) {
- throw DeadlyImportError( "No parent node for name." );
- return;
- }
-
- DataArrayList *transformData( node->getDataArrayList() );
- if( nullptr != transformData ) {
- if( transformData->m_numItems != 16 ) {
- throw DeadlyImportError( "Invalid number of data for transform matrix." );
- return;
- }
- setMatrix( m_currentNode, transformData );
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
- m_currentMesh = new aiMesh;
- const size_t meshidx( m_meshCache.size() );
- m_meshCache.push_back( m_currentMesh );
-
- Property *prop = node->getProperties();
- if( nullptr != prop ) {
- std::string propName, propKey;
- propId2StdString( prop, propName, propKey );
- if( "primitive" == propName ) {
- if ( "points" == propKey ) {
- m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- } else if ( "lines" == propKey ) {
- m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- } else if( "triangles" == propKey ) {
- m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- } else if ( "quads" == propKey ) {
- m_currentMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- } else {
- DefaultLogger::get()->warn( propKey + " is not supported primitive type." );
- }
- }
- }
-
- handleNodes( node, pScene );
-
- DDLNode *parent( node->getParent() );
- if( nullptr != parent ) {
- const std::string &name = parent->getName();
- m_mesh2refMap[ name ] = meshidx;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-enum MeshAttribute {
- None,
- Position,
- Color,
- Normal,
- TexCoord
-};
-
-//------------------------------------------------------------------------------------------------
-static MeshAttribute getAttributeByName( const char *attribName ) {
- ai_assert( nullptr != attribName );
-
- if ( 0 == strncmp( "position", attribName, strlen( "position" ) ) ) {
- return Position;
- } else if ( 0 == strncmp( "color", attribName, strlen( "color" ) ) ) {
- return Color;
- } else if( 0 == strncmp( "normal", attribName, strlen( "normal" ) ) ) {
- return Normal;
- } else if( 0 == strncmp( "texcoord", attribName, strlen( "texcoord" ) ) ) {
- return TexCoord;
- }
-
- return None;
-}
-
-//------------------------------------------------------------------------------------------------
-static void fillVector3( aiVector3D *vec3, Value *vals ) {
- ai_assert( nullptr != vec3 );
- ai_assert( nullptr != vals );
-
- float x( 0.0f ), y( 0.0f ), z( 0.0f );
- Value *next( vals );
- x = next->getFloat();
- next = next->m_next;
- y = next->getFloat();
- next = next->m_next;
- if( nullptr != next ) {
- z = next->getFloat();
- }
-
- vec3->Set( x, y, z );
-}
-
-//------------------------------------------------------------------------------------------------
-static void fillColor4( aiColor4D *col4, Value *vals ) {
- ai_assert( nullptr != col4 );
- ai_assert( nullptr != vals );
-
- Value *next( vals );
- col4->r = next->getFloat();
- next = next->m_next;
- col4->g = next->getFloat();
- next = next->m_next;
- col4->b = next->getFloat();
- next = next->m_next;
- col4->a = next->getFloat();
-}
-
-//------------------------------------------------------------------------------------------------
-static size_t countDataArrayListItems( DataArrayList *vaList ) {
- size_t numItems( 0 );
- if( nullptr == vaList ) {
- return numItems;
- }
-
- DataArrayList *next( vaList );
- while( nullptr != next ) {
- if( nullptr != vaList->m_dataList ) {
- numItems++;
- }
- next = next->m_next;
- }
-
- return numItems;
-}
-
-//------------------------------------------------------------------------------------------------
-static void copyVectorArray( size_t numItems, DataArrayList *vaList, aiVector3D *vectorArray ) {
- for( size_t i = 0; i < numItems; i++ ) {
- Value *next( vaList->m_dataList );
- fillVector3( &vectorArray[ i ], next );
- vaList = vaList->m_next;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-static void copyColor4DArray( size_t numItems, DataArrayList *vaList, aiColor4D *colArray ) {
- for ( size_t i = 0; i < numItems; i++ ) {
- Value *next( vaList->m_dataList );
- fillColor4( &colArray[ i ], next );
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == node ) {
- throw DeadlyImportError( "No parent node for name." );
- return;
- }
-
- Property *prop( node->getProperties() );
- if( nullptr != prop ) {
- std::string propName, propKey;
- propId2StdString( prop, propName, propKey );
- MeshAttribute attribType( getAttributeByName( propKey.c_str() ) );
- if( None == attribType ) {
- return;
- }
-
- DataArrayList *vaList = node->getDataArrayList();
- if( nullptr == vaList ) {
- return;
- }
-
- const size_t numItems( countDataArrayListItems( vaList ) );
-
- if( Position == attribType ) {
- m_currentVertices.m_numVerts = numItems;
- m_currentVertices.m_vertices = new aiVector3D[ numItems ];
- copyVectorArray( numItems, vaList, m_currentVertices.m_vertices );
- } else if ( Color == attribType ) {
- m_currentVertices.m_numColors = numItems;
- m_currentVertices.m_colors = new aiColor4D[ numItems ];
- copyColor4DArray( numItems, vaList, m_currentVertices.m_colors );
- } else if( Normal == attribType ) {
- m_currentVertices.m_numNormals = numItems;
- m_currentVertices.m_normals = new aiVector3D[ numItems ];
- copyVectorArray( numItems, vaList, m_currentVertices.m_normals );
- } else if( TexCoord == attribType ) {
- m_currentVertices.m_numUVComps[ 0 ] = numItems;
- m_currentVertices.m_textureCoords[ 0 ] = new aiVector3D[ numItems ];
- copyVectorArray( numItems, vaList, m_currentVertices.m_textureCoords[ 0 ] );
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == node ) {
- throw DeadlyImportError( "No parent node for name." );
- return;
- }
-
- if( nullptr == m_currentMesh ) {
- throw DeadlyImportError( "No current mesh for index data found." );
- return;
- }
-
- DataArrayList *vaList = node->getDataArrayList();
- if( nullptr == vaList ) {
- return;
- }
-
- const size_t numItems( countDataArrayListItems( vaList ) );
- m_currentMesh->mNumFaces = static_cast<unsigned int>(numItems);
- m_currentMesh->mFaces = new aiFace[ numItems ];
- m_currentMesh->mNumVertices = static_cast<unsigned int>(numItems * 3);
- m_currentMesh->mVertices = new aiVector3D[ m_currentMesh->mNumVertices ];
- bool hasColors( false );
- if ( m_currentVertices.m_numColors > 0 ) {
- m_currentMesh->mColors[0] = new aiColor4D[ m_currentVertices.m_numColors ];
- hasColors = true;
- }
- bool hasNormalCoords( false );
- if ( m_currentVertices.m_numNormals > 0 ) {
- m_currentMesh->mNormals = new aiVector3D[ m_currentMesh->mNumVertices ];
- hasNormalCoords = true;
- }
- bool hasTexCoords( false );
- if ( m_currentVertices.m_numUVComps[ 0 ] > 0 ) {
- m_currentMesh->mTextureCoords[ 0 ] = new aiVector3D[ m_currentMesh->mNumVertices ];
- hasTexCoords = true;
- }
-
- unsigned int index( 0 );
- for( size_t i = 0; i < m_currentMesh->mNumFaces; i++ ) {
- aiFace &current( m_currentMesh->mFaces[ i ] );
- current.mNumIndices = 3;
- current.mIndices = new unsigned int[ current.mNumIndices ];
- Value *next( vaList->m_dataList );
- for( size_t indices = 0; indices < current.mNumIndices; indices++ ) {
- const int idx( next->getUnsignedInt32() );
- ai_assert( static_cast<size_t>( idx ) <= m_currentVertices.m_numVerts );
- ai_assert( index < m_currentMesh->mNumVertices );
- aiVector3D &pos = ( m_currentVertices.m_vertices[ idx ] );
- m_currentMesh->mVertices[ index ].Set( pos.x, pos.y, pos.z );
- if ( hasColors ) {
- aiColor4D &col = m_currentVertices.m_colors[ idx ];
- m_currentMesh->mColors[ 0 ][ index ] = col;
- }
- if ( hasNormalCoords ) {
- aiVector3D &normal = ( m_currentVertices.m_normals[ idx ] );
- m_currentMesh->mNormals[ index ].Set( normal.x, normal.y, normal.z );
- }
- if ( hasTexCoords ) {
- aiVector3D &tex = ( m_currentVertices.m_textureCoords[ 0 ][ idx ] );
- m_currentMesh->mTextureCoords[ 0 ][ index ].Set( tex.x, tex.y, tex.z );
- }
- current.mIndices[ indices ] = index;
- index++;
-
- next = next->m_next;
- }
- vaList = vaList->m_next;
- }
-}
-
-//------------------------------------------------------------------------------------------------
-static void getColorRGB3( aiColor3D *pColor, DataArrayList *colList ) {
- if( nullptr == pColor || nullptr == colList ) {
- return;
- }
-
- ai_assert( 3 == colList->m_numItems );
- Value *val( colList->m_dataList );
- pColor->r = val->getFloat();
- val = val->getNext();
- pColor->g = val->getFloat();
- val = val->getNext();
- pColor->b = val->getFloat();
-}
-
-//------------------------------------------------------------------------------------------------
-static void getColorRGB4( aiColor4D *pColor, DataArrayList *colList ) {
- if ( nullptr == pColor || nullptr == colList ) {
- return;
- }
-
- ai_assert( 4 == colList->m_numItems );
- Value *val( colList->m_dataList );
- pColor->r = val->getFloat();
- val = val->getNext();
- pColor->g = val->getFloat();
- val = val->getNext();
- pColor->b = val->getFloat();
- val = val->getNext();
- pColor->a = val->getFloat();
-}
-
-//------------------------------------------------------------------------------------------------
-enum ColorType {
- NoneColor = 0,
- DiffuseColor,
- SpecularColor,
- EmissionColor,
- LightColor
-};
-
-//------------------------------------------------------------------------------------------------
-static ColorType getColorType( Text *id ) {
- if ( nullptr == id ) {
- return NoneColor;
- }
-
- if( *id == Grammar::DiffuseColorToken ) {
- return DiffuseColor;
- } else if( *id == Grammar::SpecularColorToken ) {
- return SpecularColor;
- } else if( *id == Grammar::EmissionColorToken ) {
- return EmissionColor;
- } else if ( *id == "light" ) {
- return LightColor;
- }
-
- return NoneColor;
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene ) {
- m_currentMaterial = new aiMaterial;
- m_materialCache.push_back( m_currentMaterial );
- m_tokenType = Grammar::MaterialToken;
- handleNodes( node, pScene );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleColorNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == node ) {
- return;
- }
-
- Property *prop = node->findPropertyByName( "attrib" );
- if( nullptr != prop ) {
- if( nullptr != prop->m_value ) {
- DataArrayList *colList( node->getDataArrayList() );
- if( nullptr == colList ) {
- return;
- }
- aiColor3D col;
- if ( 3 == colList->m_numItems ) {
- aiColor3D col3;
- getColorRGB3( &col3, colList );
- col = col3;
- } else {
- aiColor4D col4;
- getColorRGB4( &col4, colList );
- col.r = col4.r;
- col.g = col4.g;
- col.b = col4.b;
- }
- const ColorType colType( getColorType( prop->m_key ) );
- if( DiffuseColor == colType ) {
- m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_DIFFUSE );
- } else if( SpecularColor == colType ) {
- m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_SPECULAR );
- } else if( EmissionColor == colType ) {
- m_currentMaterial->AddProperty( &col, 1, AI_MATKEY_COLOR_EMISSIVE );
- } else if ( LightColor == colType ) {
- m_currentLight->mColorDiffuse = col;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleTextureNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if( nullptr == node ) {
- return;
- }
-
- Property *prop = node->findPropertyByName( "attrib" );
- if( nullptr != prop ) {
- if( nullptr != prop->m_value ) {
- Value *val( node->getValue() );
- if( nullptr != val ) {
- aiString tex;
- tex.Set( val->getString() );
- if( prop->m_value->getString() == Grammar::DiffuseTextureToken ) {
- m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
- } else if( prop->m_value->getString() == Grammar::SpecularPowerTextureToken ) {
- m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR( 0 ) );
- } else if( prop->m_value->getString() == Grammar::EmissionTextureToken ) {
- m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE( 0 ) );
- } else if( prop->m_value->getString() == Grammar::OpacyTextureToken ) {
- m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_OPACITY( 0 ) );
- } else if( prop->m_value->getString() == Grammar::TransparencyTextureToken ) {
- // ToDo!
- // m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
- } else if( prop->m_value->getString() == Grammar::NormalTextureToken ) {
- m_currentMaterial->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS( 0 ) );
- } else {
- ai_assert( false );
- }
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleParamNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if ( nullptr == node ) {
- return;
- }
-
- Property *prop = node->findPropertyByName( "attrib" );
- if ( nullptr == prop ) {
- return;
- }
-
- if ( nullptr != prop->m_value ) {
- Value *val( node->getValue() );
- if ( nullptr == val ) {
- return;
- }
- const float floatVal( val->getFloat() );
- if ( prop->m_value != nullptr ) {
- if ( 0 == ASSIMP_strincmp( "fov", prop->m_value->getString(), 3 ) ) {
- m_currentCamera->mHorizontalFOV = floatVal;
- } else if ( 0 == ASSIMP_strincmp( "near", prop->m_value->getString(), 3 ) ) {
- m_currentCamera->mClipPlaneNear = floatVal;
- } else if ( 0 == ASSIMP_strincmp( "far", prop->m_value->getString(), 3 ) ) {
- m_currentCamera->mClipPlaneFar = floatVal;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::handleAttenNode( ODDLParser::DDLNode *node, aiScene * /*pScene*/ ) {
- if ( nullptr == node ) {
- return;
- }
-
- Property *prop = node->findPropertyByName( "curve" );
- if ( nullptr != prop ) {
- if ( nullptr != prop->m_value ) {
- Value *val( node->getValue() );
- const float floatVal( val->getFloat() );
- if ( 0 == strncmp( "scale", prop->m_value->getString(), strlen( "scale" ) ) ) {
- m_currentLight->mAttenuationQuadratic = floatVal;
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::copyMeshes( aiScene *pScene ) {
- ai_assert( nullptr != pScene );
-
- if( m_meshCache.empty() ) {
- return;
- }
-
- pScene->mNumMeshes = static_cast<unsigned int>(m_meshCache.size());
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
- std::copy( m_meshCache.begin(), m_meshCache.end(), pScene->mMeshes );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::copyCameras( aiScene *pScene ) {
- ai_assert( nullptr != pScene );
-
- if ( m_cameraCache.empty() ) {
- return;
- }
-
- pScene->mNumCameras = static_cast<unsigned int>(m_cameraCache.size());
- pScene->mCameras = new aiCamera*[ pScene->mNumCameras ];
- std::copy( m_cameraCache.begin(), m_cameraCache.end(), pScene->mCameras );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::copyLights( aiScene *pScene ) {
- ai_assert( nullptr != pScene );
-
- if ( m_lightCache.empty() ) {
- return;
- }
-
- pScene->mNumLights = static_cast<unsigned int>(m_lightCache.size());
- pScene->mLights = new aiLight*[ pScene->mNumLights ];
- std::copy( m_lightCache.begin(), m_lightCache.end(), pScene->mLights );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::copyMaterials( aiScene *pScene ) {
- ai_assert( nullptr != pScene );
-
- if ( m_materialCache.empty() ) {
- return;
- }
-
- pScene->mNumMaterials = static_cast<unsigned int>(m_materialCache.size());
- pScene->mMaterials = new aiMaterial*[ pScene->mNumMaterials ];
- std::copy( m_materialCache.begin(), m_materialCache.end(), pScene->mMaterials );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::resolveReferences() {
- if( m_unresolvedRefStack.empty() ) {
- return;
- }
-
- RefInfo *currentRefInfo( nullptr );
- for( auto it = m_unresolvedRefStack.begin(); it != m_unresolvedRefStack.end(); ++it ) {
- currentRefInfo = it->get();
- if( nullptr != currentRefInfo ) {
- aiNode *node( currentRefInfo->m_node );
- if( RefInfo::MeshRef == currentRefInfo->m_type ) {
- for( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
- const std::string &name( currentRefInfo->m_Names[ i ] );
- ReferenceMap::const_iterator it( m_mesh2refMap.find( name ) );
- if( m_mesh2refMap.end() != it ) {
- unsigned int meshIdx = static_cast<unsigned int>(m_mesh2refMap[ name ]);
- node->mMeshes[ i ] = meshIdx;
- }
- }
- } else if( RefInfo::MaterialRef == currentRefInfo->m_type ) {
- for ( size_t i = 0; i < currentRefInfo->m_Names.size(); ++i ) {
- const std::string name( currentRefInfo->m_Names[ i ] );
- ReferenceMap::const_iterator it( m_material2refMap.find( name ) );
- if ( m_material2refMap.end() != it ) {
- if ( nullptr != m_currentMesh ) {
- unsigned int matIdx = static_cast< unsigned int >( m_material2refMap[ name ] );
- if ( m_currentMesh->mMaterialIndex != 0 ) {
- DefaultLogger::get()->warn( "Override of material reference in current mesh by material reference." );
- }
- m_currentMesh->mMaterialIndex = matIdx;
- } else {
- DefaultLogger::get()->warn( "Cannot resolve material reference, because no current mesh is there." );
-
- }
- }
- }
- } else {
- throw DeadlyImportError( "Unknown reference info to resolve." );
- }
- }
- }
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::createNodeTree( aiScene *pScene ) {
- if( nullptr == m_root ) {
- return;
- }
-
- if( m_root->m_children.empty() ) {
- return;
- }
-
- pScene->mRootNode->mNumChildren = static_cast<unsigned int>(m_root->m_children.size());
- pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
- std::copy( m_root->m_children.begin(), m_root->m_children.end(), pScene->mRootNode->mChildren );
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::pushNode( aiNode *node, aiScene *pScene ) {
- ai_assert( nullptr != pScene );
-
- if ( nullptr == node ) {
- return;
- }
-
- ChildInfo *info( nullptr );
- if( m_nodeStack.empty() ) {
- node->mParent = pScene->mRootNode;
- NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
- if( m_nodeChildMap.end() == it ) {
- info = new ChildInfo;
- m_root = info;
- m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
- } else {
- info = it->second.get();
- }
- info->m_children.push_back( node );
- } else {
- aiNode *parent( m_nodeStack.back() );
- ai_assert( nullptr != parent );
- node->mParent = parent;
- NodeChildMap::iterator it( m_nodeChildMap.find( node->mParent ) );
- if( m_nodeChildMap.end() == it ) {
- info = new ChildInfo;
- m_nodeChildMap[ node->mParent ] = std::unique_ptr<ChildInfo>(info);
- } else {
- info = it->second.get();
- }
- info->m_children.push_back( node );
- }
- m_nodeStack.push_back( node );
-}
-
-//------------------------------------------------------------------------------------------------
-aiNode *OpenGEXImporter::popNode() {
- if( m_nodeStack.empty() ) {
- return nullptr;
- }
-
- aiNode *node( top() );
- m_nodeStack.pop_back();
-
- return node;
-}
-
-//------------------------------------------------------------------------------------------------
-aiNode *OpenGEXImporter::top() const {
- if( m_nodeStack.empty() ) {
- return nullptr;
- }
-
- return m_nodeStack.back();
-}
-
-//------------------------------------------------------------------------------------------------
-void OpenGEXImporter::clearNodeStack() {
- m_nodeStack.clear();
-}
-
-//------------------------------------------------------------------------------------------------
-
-} // Namespace OpenGEX
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
diff --git a/src/3rdparty/assimp/code/OpenGEXImporter.h b/src/3rdparty/assimp/code/OpenGEXImporter.h
deleted file mode 100644
index c0cde579c..000000000
--- a/src/3rdparty/assimp/code/OpenGEXImporter.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OPENGEX_IMPORTER_H
-#define AI_OPENGEX_IMPORTER_H
-
-#ifndef ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-
-#include "BaseImporter.h"
-#include <assimp/mesh.h>
-
-#include <vector>
-#include <list>
-#include <map>
-#include <memory>
-
-namespace ODDLParser {
- class DDLNode;
- struct Context;
-}
-
-struct aiNode;
-struct aiMaterial;
-struct aiCamera;
-struct aiLight;
-
-namespace Assimp {
-namespace OpenGEX {
-
-struct MetricInfo {
- enum Type {
- Distance = 0,
- Angle,
- Time,
- Up,
- Max
- };
-
- std::string m_stringValue;
- float m_floatValue;
- int m_intValue;
-
- MetricInfo()
- : m_stringValue( "" )
- , m_floatValue( 0.0f )
- , m_intValue( -1 ) {
- // empty
- }
-};
-
-/** @brief This class is used to implement the OpenGEX importer
- *
- * See http://opengex.org/OpenGEX.pdf for spec.
- */
-class OpenGEXImporter : public BaseImporter {
-public:
- /// The class constructor.
- OpenGEXImporter();
-
- /// The class destructor.
- virtual ~OpenGEXImporter();
-
- /// BaseImporter override.
- virtual bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const;
-
- /// BaseImporter override.
- virtual void InternReadFile( const std::string &file, aiScene *pScene, IOSystem *pIOHandler );
-
- /// BaseImporter override.
- virtual const aiImporterDesc *GetInfo() const;
-
- /// BaseImporter override.
- virtual void SetupProperties( const Importer *pImp );
-
-protected:
- void handleNodes( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleMetricNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleNameNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleObjectRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleMaterialRefNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleGeometryNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleCameraNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleLightNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleGeometryObject( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleCameraObject( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleLightObject( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleTransformNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleMeshNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleVertexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleIndexArrayNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleMaterialNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleColorNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleTextureNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleParamNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void handleAttenNode( ODDLParser::DDLNode *node, aiScene *pScene );
- void copyMeshes( aiScene *pScene );
- void copyCameras( aiScene *pScene );
- void copyLights( aiScene *pScene );
- void copyMaterials( aiScene *pScene );
- void resolveReferences();
- void pushNode( aiNode *node, aiScene *pScene );
- aiNode *popNode();
- aiNode *top() const;
- void clearNodeStack();
- void createNodeTree( aiScene *pScene );
-
-private:
- struct VertexContainer {
- size_t m_numVerts;
- aiVector3D *m_vertices;
- size_t m_numColors;
- aiColor4D *m_colors;
- size_t m_numNormals;
- aiVector3D *m_normals;
- size_t m_numUVComps[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
- aiVector3D *m_textureCoords[ AI_MAX_NUMBER_OF_TEXTURECOORDS ];
-
- VertexContainer();
- ~VertexContainer();
-
- VertexContainer( const VertexContainer & ) = delete;
- VertexContainer &operator = ( const VertexContainer & ) = delete;
- };
-
- struct RefInfo {
- enum Type {
- MeshRef,
- MaterialRef
- };
-
- aiNode *m_node;
- Type m_type;
- std::vector<std::string> m_Names;
-
- RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
- ~RefInfo();
-
- RefInfo( const RefInfo & ) = delete;
- RefInfo &operator = ( const RefInfo & ) = delete;
- };
-
- struct ChildInfo {
- typedef std::list<aiNode*> NodeList;
- std::list<aiNode*> m_children;
- };
- ChildInfo *m_root;
- typedef std::map<aiNode*, std::unique_ptr<ChildInfo> > NodeChildMap;
- NodeChildMap m_nodeChildMap;
-
- std::vector<aiMesh*> m_meshCache;
- typedef std::map<std::string, size_t> ReferenceMap;
- std::map<std::string, size_t> m_mesh2refMap;
- std::map<std::string, size_t> m_material2refMap;
-
- ODDLParser::Context *m_ctx;
- MetricInfo m_metrics[ MetricInfo::Max ];
- aiNode *m_currentNode;
- VertexContainer m_currentVertices;
- aiMesh *m_currentMesh;
- aiMaterial *m_currentMaterial;
- aiLight *m_currentLight;
- aiCamera *m_currentCamera;
- int m_tokenType;
- std::vector<aiMaterial*> m_materialCache;
- std::vector<aiCamera*> m_cameraCache;
- std::vector<aiLight*> m_lightCache;
- std::vector<aiNode*> m_nodeStack;
- std::vector<std::unique_ptr<RefInfo> > m_unresolvedRefStack;
-};
-
-} // Namespace OpenGEX
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_OPENGEX_IMPORTER
-
-#endif // AI_OPENGEX_IMPORTER_H
diff --git a/src/3rdparty/assimp/code/OpenGEXStructs.h b/src/3rdparty/assimp/code/OpenGEXStructs.h
deleted file mode 100644
index 6144a10c5..000000000
--- a/src/3rdparty/assimp/code/OpenGEXStructs.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_OPENGEXSTRUCTS_H_INC
-#define AI_OPENGEXSTRUCTS_H_INC
-
-#include <string>
-#include <map>
-
-namespace Assimp {
-namespace OpenGEX {
-
-struct Skin;
-struct Object;
-struct LightObject;
-struct CameraObject;
-struct Material;
-struct BoneNode;
-struct BoneCountArray;
-struct BoneIndexArray;
-struct BoneWeightArray;
-
-struct Metric {
- float m_distance;
- float m_angle;
- float m_time;
- float m_up;
-};
-
-struct VertexArray {
- std::string arrayAttrib;
- unsigned int morphIndex;
-};
-
-struct IndexArray {
- unsigned int materialIndex;
- unsigned int restartIndex;
- std::string frontFace;
-};
-
-struct Mesh {
- unsigned int meshLevel;
- std::string meshPrimitive;
- Skin *skinStructure;
-};
-
-struct Node {
- std::string nodeName;
-};
-
-struct GeometryNode {
- bool visibleFlag[ 2 ];
- bool shadowFlag[ 2 ];
- bool motionBlurFlag[ 2 ];
-};
-
-struct LightNode {
- bool shadowFlag[ 2 ];
- const LightObject *lightObjectStructure;
-};
-
-struct CameraNode {
- const CameraObject *cameraObjectStructure;
-};
-
-struct GeometryObject {
- Object *object;
- bool visibleFlag;
- bool shadowFlag;
- bool motionBlurFlag;
- std::map<std::string, Mesh*> meshMap;
-};
-
-struct LightObject {
- Object *object;
- std::string typeString;
- bool shadowFlag;
-};
-
-struct CameraObject {
- float focalLength;
- float nearDepth;
- float farDepth;
-};
-
-struct Matrix {
- bool objectFlag;
-};
-
-struct Transform {
- Matrix *matrix;
- int transformCount;
- const float *transformArray;
-};
-
-struct Translation {
- std::string translationKind;
-};
-
-struct Rotation {
- std::string rotationKind;
-};
-
-struct Scale {
- std::string scaleKind;
-};
-
-struct Name {
- std::string name;
-};
-
-struct ObjectRef {
- Object *targetStructure;
-};
-
-struct MaterialRef {
- unsigned int materialIndex;
- const Material *targetStructure;
-};
-
-struct BoneRefArray {
- int boneCount;
- const BoneNode **boneNodeArray;
-};
-
-struct BoneCount {
- int vertexCount;
- const unsigned short *boneCountArray;
- unsigned short *arrayStorage;
-};
-
-struct BoneIndex {
- int boneIndexCount;
- const unsigned short *boneIndexArray;
- unsigned short *arrayStorage;
-};
-
-struct BoneWeight {
- int boneWeightCount;
- const float *boneWeightArray;
-};
-
-struct Skeleton {
- const BoneRefArray *boneRefArrayStructure;
- const Transform *transformStructure;
-};
-
-struct Skin {
- const Skeleton *skeletonStructure;
- const BoneCountArray *boneCountArrayStructure;
- const BoneIndexArray *boneIndexArrayStructure;
- const BoneWeightArray *boneWeightArrayStructure;
-};
-
-struct Material {
- bool twoSidedFlag;
- const char *materialName;
-};
-
-struct Attrib {
- std::string attribString;
-};
-
-struct Param {
- float param;
-};
-
-struct Color {
- float color[ 4 ];
-};
-
-struct Texture {
- std::string textureName;
- unsigned int texcoordIndex;
-};
-
-struct Atten {
- std::string attenKind;
- std::string curveType;
-
- float beginParam;
- float endParam;
-
- float scaleParam;
- float offsetParam;
-
- float constantParam;
- float linearParam;
- float quadraticParam;
-
- float powerParam;
-};
-
-struct Key {
- std::string keyKind;
- bool scalarFlag;
-};
-
-struct Curve {
- std::string curveType;
- const Key *keyValueStructure;
- const Key *keyControlStructure[ 2 ];
- const Key *keyTensionStructure;
- const Key *keyContinuityStructure;
- const Key *keyBiasStructure;
-};
-
-struct Animation {
- int clipIndex;
- bool beginFlag;
- bool endFlag;
- float beginTime;
- float endTime;
-};
-
-struct OpenGexDataDescription {
- float distanceScale;
- float angleScale;
- float timeScale;
- int upDirection;
-};
-
-} // Namespace OpenGEX
-} // Namespace Assimp
-
-#endif // AI_OPENGEXSTRUCTS_H_INC
diff --git a/src/3rdparty/assimp/code/OptimizeGraph.cpp b/src/3rdparty/assimp/code/OptimizeGraph.cpp
deleted file mode 100644
index 11a6fcf65..000000000
--- a/src/3rdparty/assimp/code/OptimizeGraph.cpp
+++ /dev/null
@@ -1,362 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OptimizeGraph.cpp
- * @brief Implementation of the aiProcess_OptimizGraph step
- */
-
-
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-
-#include "OptimizeGraph.h"
-#include "ProcessHelper.h"
-#include <assimp/SceneCombiner.h>
-#include "Exceptional.h"
-#include <stdio.h>
-
-using namespace Assimp;
-
-#define AI_RESERVED_NODE_NAME "$Reserved_And_Evil"
-
-/* AI_OG_USE_HASHING enables the use of hashing to speed-up std::set lookups.
- * The unhashed variant should be faster, except for *very* large data sets
- */
-#ifdef AI_OG_USE_HASHING
- // Use our standard hashing function to compute the hash
-# define AI_OG_GETKEY(str) SuperFastHash(str.data,str.length)
-#else
- // Otherwise hope that std::string will utilize a static buffer
- // for shorter node names. This would avoid endless heap copying.
-# define AI_OG_GETKEY(str) std::string(str.data)
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OptimizeGraphProcess::OptimizeGraphProcess()
- : mScene()
- , nodes_in()
- , nodes_out()
- , count_merged()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeGraphProcess::~OptimizeGraphProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool OptimizeGraphProcess::IsActive( unsigned int pFlags) const
-{
- return (0 != (pFlags & aiProcess_OptimizeGraph));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the postprocessing step
-void OptimizeGraphProcess::SetupProperties(const Importer* pImp)
-{
- // Get value of AI_CONFIG_PP_OG_EXCLUDE_LIST
- std::string tmp = pImp->GetPropertyString(AI_CONFIG_PP_OG_EXCLUDE_LIST,"");
- AddLockedNodeList(tmp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collect new children
-void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes)
-{
- nodes_in += nd->mNumChildren;
-
- // Process children
- std::list<aiNode*> child_nodes;
- for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
-
- CollectNewChildren(nd->mChildren[i],child_nodes);
- nd->mChildren[i] = NULL;
- }
-
- // Check whether we need this node; if not we can replace it by our own children (warn, danger of incest).
- if (locked.find(AI_OG_GETKEY(nd->mName)) == locked.end() ) {
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) {
-
- if (locked.find(AI_OG_GETKEY((*it)->mName)) == locked.end()) {
- (*it)->mTransformation = nd->mTransformation * (*it)->mTransformation;
- nodes.push_back(*it);
-
- it = child_nodes.erase(it);
- continue;
- }
- ++it;
- }
-
- if (nd->mNumMeshes || !child_nodes.empty()) {
- nodes.push_back(nd);
- }
- else {
- delete nd; /* bye, node */
- return;
- }
- }
- else {
-
- // Retain our current position in the hierarchy
- nodes.push_back(nd);
-
- // Now check for possible optimizations in our list of child nodes. join as many as possible
- aiNode* join_master = NULL;
- aiMatrix4x4 inv;
-
- const LockedSetType::const_iterator end = locked.end();
-
- std::list<aiNode*> join;
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end();) {
- aiNode* child = *it;
- if (child->mNumChildren == 0 && locked.find(AI_OG_GETKEY(child->mName)) == end) {
-
- // There may be no instanced meshes
- unsigned int n = 0;
- for (; n < child->mNumMeshes;++n) {
- if (meshes[child->mMeshes[n]] > 1) {
- break;
- }
- }
- if (n == child->mNumMeshes) {
-
- if (!join_master) {
- join_master = child;
- inv = join_master->mTransformation;
- inv.Inverse();
- }
- else {
-
- child->mTransformation = inv * child->mTransformation ;
-
- join.push_back(child);
- it = child_nodes.erase(it);
- continue;
- }
- }
- }
- ++it;
- }
- if (join_master && !join.empty()) {
- join_master->mName.length = ::ai_snprintf(join_master->mName.data, MAXLEN, "$MergedNode_%i",count_merged++);
-
- unsigned int out_meshes = 0;
- for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
- out_meshes += (*it)->mNumMeshes;
- }
-
- // copy all mesh references in one array
- if (out_meshes) {
- unsigned int* meshes = new unsigned int[out_meshes+join_master->mNumMeshes], *tmp = meshes;
- for (unsigned int n = 0; n < join_master->mNumMeshes;++n) {
- *tmp++ = join_master->mMeshes[n];
- }
-
- for (std::list<aiNode*>::iterator it = join.begin(); it != join.end(); ++it) {
- for (unsigned int n = 0; n < (*it)->mNumMeshes; ++n) {
-
- *tmp = (*it)->mMeshes[n];
- aiMesh* mesh = mScene->mMeshes[*tmp++];
-
- // manually move the mesh into the right coordinate system
- const aiMatrix3x3 IT = aiMatrix3x3( (*it)->mTransformation ).Inverse().Transpose();
- for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
-
- mesh->mVertices[a] *= (*it)->mTransformation;
-
- if (mesh->HasNormals())
- mesh->mNormals[a] *= IT;
-
- if (mesh->HasTangentsAndBitangents()) {
- mesh->mTangents[a] *= IT;
- mesh->mBitangents[a] *= IT;
- }
- }
- }
- delete *it; // bye, node
- }
- delete[] join_master->mMeshes;
- join_master->mMeshes = meshes;
- join_master->mNumMeshes += out_meshes;
- }
- }
- }
- // reassign children if something changed
- if (child_nodes.empty() || child_nodes.size() > nd->mNumChildren) {
-
- delete[] nd->mChildren;
-
- if (!child_nodes.empty())
- nd->mChildren = new aiNode*[child_nodes.size()];
- else nd->mChildren = NULL;
- }
-
- nd->mNumChildren = static_cast<unsigned int>(child_nodes.size());
-
- if (nd->mChildren) {
- aiNode** tmp = nd->mChildren;
- for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
- aiNode* node = *tmp++ = *it;
- node->mParent = nd;
- }
- }
-
- nodes_out += static_cast<unsigned int>(child_nodes.size());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Execute the postprocessing step on the given scene
-void OptimizeGraphProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("OptimizeGraphProcess begin");
- nodes_in = nodes_out = count_merged = 0;
- mScene = pScene;
-
- meshes.resize(pScene->mNumMeshes,0);
- FindInstancedMeshes(pScene->mRootNode);
-
- // build a blacklist of identifiers. If the name of a node matches one of these, we won't touch it
- locked.clear();
- for (std::list<std::string>::const_iterator it = locked_nodes.begin(); it != locked_nodes.end(); ++it) {
-#ifdef AI_OG_USE_HASHING
- locked.insert(SuperFastHash((*it).c_str()));
-#else
- locked.insert(*it);
-#endif
- }
-
- for (unsigned int i = 0; i < pScene->mNumAnimations; ++i) {
- for (unsigned int a = 0; a < pScene->mAnimations[i]->mNumChannels; ++a) {
-
- aiNodeAnim* anim = pScene->mAnimations[i]->mChannels[a];
- locked.insert(AI_OG_GETKEY(anim->mNodeName));
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- for (unsigned int a = 0; a < pScene->mMeshes[i]->mNumBones; ++a) {
-
- aiBone* bone = pScene->mMeshes[i]->mBones[a];
- locked.insert(AI_OG_GETKEY(bone->mName));
-
- // HACK: Meshes referencing bones may not be transformed; we need to look them.
- // The easiest way to do this is to increase their reference counters ...
- meshes[i] += 2;
- }
- }
-
- for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {
- aiCamera* cam = pScene->mCameras[i];
- locked.insert(AI_OG_GETKEY(cam->mName));
- }
-
- for (unsigned int i = 0; i < pScene->mNumLights; ++i) {
- aiLight* lgh = pScene->mLights[i];
- locked.insert(AI_OG_GETKEY(lgh->mName));
- }
-
- // Insert a dummy master node and make it read-only
- aiNode* dummy_root = new aiNode(AI_RESERVED_NODE_NAME);
- locked.insert(AI_OG_GETKEY(dummy_root->mName));
-
- const aiString prev = pScene->mRootNode->mName;
- pScene->mRootNode->mParent = dummy_root;
-
- dummy_root->mChildren = new aiNode*[dummy_root->mNumChildren = 1];
- dummy_root->mChildren[0] = pScene->mRootNode;
-
- // Do our recursive processing of scenegraph nodes. For each node collect
- // a fully new list of children and allow their children to place themselves
- // on the same hierarchy layer as their parents.
- std::list<aiNode*> nodes;
- CollectNewChildren (dummy_root,nodes);
-
- ai_assert(nodes.size() == 1);
-
- if (dummy_root->mNumChildren == 0) {
- pScene->mRootNode = NULL;
- throw DeadlyImportError("After optimizing the scene graph, no data remains");
- }
-
- if (dummy_root->mNumChildren > 1) {
- pScene->mRootNode = dummy_root;
-
- // Keep the dummy node but assign the name of the old root node to it
- pScene->mRootNode->mName = prev;
- }
- else {
-
- // Remove the dummy root node again.
- pScene->mRootNode = dummy_root->mChildren[0];
-
- dummy_root->mChildren[0] = NULL;
- delete dummy_root;
- }
-
- pScene->mRootNode->mParent = NULL;
- if (!DefaultLogger::isNullLogger()) {
- if ( nodes_in != nodes_out) {
-
- char buf[512];
- ::ai_snprintf(buf,512,"OptimizeGraphProcess finished; Input nodes: %u, Output nodes: %u",nodes_in,nodes_out);
- DefaultLogger::get()->info(buf);
- }
- else DefaultLogger::get()->debug("OptimizeGraphProcess finished");
- }
- meshes.clear();
- locked.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Buidl a LUT of all instanced meshes
-void OptimizeGraphProcess::FindInstancedMeshes (aiNode* pNode)
-{
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
- ++meshes[pNode->mMeshes[i]];
- }
-
- for (unsigned int i = 0; i < pNode->mNumChildren; ++i)
- FindInstancedMeshes(pNode->mChildren[i]);
-}
-
-#endif // !! ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
diff --git a/src/3rdparty/assimp/code/OptimizeGraph.h b/src/3rdparty/assimp/code/OptimizeGraph.h
deleted file mode 100644
index 22d53afff..000000000
--- a/src/3rdparty/assimp/code/OptimizeGraph.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OptimizeGraph.h
- * @brief Declares a post processing step to optimize the scenegraph
- */
-#ifndef AI_OPTIMIZEGRAPHPROCESS_H_INC
-#define AI_OPTIMIZEGRAPHPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include "ProcessHelper.h"
-#include <assimp/types.h>
-#include <set>
-
-struct aiMesh;
-class OptimizeGraphProcessTest;
-namespace Assimp {
-
-// -----------------------------------------------------------------------------
-/** @brief Postprocessing step to optimize the scenegraph
- *
- * The implementation tries to merge nodes, even if they use different
- * transformations. Animations are preserved.
- *
- * @see aiProcess_OptimizeGraph for a detailed description of the
- * algorithm being applied.
- */
-class OptimizeGraphProcess : public BaseProcess
-{
-public:
-
- OptimizeGraphProcess();
- ~OptimizeGraphProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Add a list of node names to be locked and not modified.
- * @param in List of nodes. See #AI_CONFIG_PP_OG_EXCLUDE_LIST for
- * format explanations.
- */
- inline void AddLockedNodeList(std::string& in)
- {
- ConvertListToStrings (in,locked_nodes);
- }
-
- // -------------------------------------------------------------------
- /** @brief Add another node to be locked and not modified.
- * @param name Name to be locked
- */
- inline void AddLockedNode(std::string& name)
- {
- locked_nodes.push_back(name);
- }
-
- // -------------------------------------------------------------------
- /** @brief Rmeove a node from the list of locked nodes.
- * @param name Name to be unlocked
- */
- inline void RemoveLockedNode(std::string& name)
- {
- locked_nodes.remove(name);
- }
-
-protected:
-
- void CollectNewChildren(aiNode* nd, std::list<aiNode*>& nodes);
- void FindInstancedMeshes (aiNode* pNode);
-
-private:
-
-#ifdef AI_OG_USE_HASHING
- typedef std::set<unsigned int> LockedSetType;
-#else
- typedef std::set<std::string> LockedSetType;
-#endif
-
-
- //! Scene we're working with
- aiScene* mScene;
-
- //! List of locked names. Stored is the hash of the name
- LockedSetType locked;
-
- //! List of nodes to be locked in addition to those with animations, lights or cameras assigned.
- std::list<std::string> locked_nodes;
-
- //! Node counters for logging purposes
- unsigned int nodes_in,nodes_out, count_merged;
-
- //! Reference counters for meshes
- std::vector<unsigned int> meshes;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_OPTIMIZEGRAPHPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/OptimizeMeshes.cpp b/src/3rdparty/assimp/code/OptimizeMeshes.cpp
deleted file mode 100644
index f8183fc75..000000000
--- a/src/3rdparty/assimp/code/OptimizeMeshes.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OptimizeMeshes.cpp
- * @brief Implementation of the aiProcess_OptimizeMeshes step
- */
-
-
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-
-
-#include "OptimizeMeshes.h"
-#include "ProcessHelper.h"
-#include <assimp/SceneCombiner.h>
-#include "Exceptional.h"
-
-using namespace Assimp;
-
-static const unsigned int NotSet = 0xffffffff;
-static const unsigned int DeadBeef = 0xdeadbeef;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-OptimizeMeshesProcess::OptimizeMeshesProcess()
- : mScene()
- , pts(false)
- , max_verts( NotSet )
- , max_faces( NotSet ) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-OptimizeMeshesProcess::~OptimizeMeshesProcess() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool OptimizeMeshesProcess::IsActive( unsigned int pFlags) const
-{
- // Our behaviour needs to be different if the SortByPType or SplitLargeMeshes
- // steps are active. Thus we need to query their flags here and store the
- // information, although we're breaking const-correctness.
- // That's a serious design flaw, consider redesign.
- if( 0 != (pFlags & aiProcess_OptimizeMeshes) ) {
- pts = (0 != (pFlags & aiProcess_SortByPType));
- max_verts = ( 0 != ( pFlags & aiProcess_SplitLargeMeshes ) ) ? DeadBeef : max_verts;
- return true;
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties for the post-processing step
-void OptimizeMeshesProcess::SetupProperties(const Importer* pImp)
-{
- if( max_verts == DeadBeef /* magic hack */ ) {
- max_faces = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
- max_verts = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Execute step
-void OptimizeMeshesProcess::Execute( aiScene* pScene)
-{
- const unsigned int num_old = pScene->mNumMeshes;
- if (num_old <= 1) {
- DefaultLogger::get()->debug("Skipping OptimizeMeshesProcess");
- return;
- }
-
- DefaultLogger::get()->debug("OptimizeMeshesProcess begin");
- mScene = pScene;
-
- // need to clear persistent members from previous runs
- merge_list.resize( 0 );
- output.resize( 0 );
-
- // ensure we have the right sizes
- merge_list.reserve(pScene->mNumMeshes);
- output.reserve(pScene->mNumMeshes);
-
- // Prepare lookup tables
- meshes.resize(pScene->mNumMeshes);
- FindInstancedMeshes(pScene->mRootNode);
- if( max_verts == DeadBeef ) /* undo the magic hack */
- max_verts = NotSet;
-
- // ... instanced meshes are immediately processed and added to the output list
- for (unsigned int i = 0, n = 0; i < pScene->mNumMeshes;++i) {
- meshes[i].vertex_format = GetMeshVFormatUnique(pScene->mMeshes[i]);
-
- if (meshes[i].instance_cnt > 1 && meshes[i].output_id == NotSet ) {
- meshes[i].output_id = n++;
- output.push_back(mScene->mMeshes[i]);
- }
- }
-
- // and process all nodes in the scenegraph recursively
- ProcessNode(pScene->mRootNode);
- if (!output.size()) {
- throw DeadlyImportError("OptimizeMeshes: No meshes remaining; there's definitely something wrong");
- }
-
- meshes.resize( 0 );
- ai_assert(output.size() <= num_old);
-
- mScene->mNumMeshes = static_cast<unsigned int>(output.size());
- std::copy(output.begin(),output.end(),mScene->mMeshes);
-
- if (output.size() != num_old) {
- char tmp[512];
- ::ai_snprintf(tmp,512,"OptimizeMeshesProcess finished. Input meshes: %u, Output meshes: %u",num_old,pScene->mNumMeshes);
- DefaultLogger::get()->info(tmp);
- } else {
- DefaultLogger::get()->debug( "OptimizeMeshesProcess finished" );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Process meshes for a single node
-void OptimizeMeshesProcess::ProcessNode( aiNode* pNode)
-{
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i) {
- unsigned int& im = pNode->mMeshes[i];
-
- if (meshes[im].instance_cnt > 1) {
- im = meshes[im].output_id;
- }
- else {
- merge_list.resize( 0 );
- unsigned int verts = 0, faces = 0;
-
- // Find meshes to merge with us
- for (unsigned int a = i+1; a < pNode->mNumMeshes;++a) {
- unsigned int am = pNode->mMeshes[a];
- if (meshes[am].instance_cnt == 1 && CanJoin(im,am,verts,faces)) {
-
- merge_list.push_back(mScene->mMeshes[am]);
- verts += mScene->mMeshes[am]->mNumVertices;
- faces += mScene->mMeshes[am]->mNumFaces;
-
- pNode->mMeshes[a] = pNode->mMeshes[pNode->mNumMeshes - 1];
- --pNode->mNumMeshes;
- --a;
- }
- }
-
- // and merge all meshes which we found, replace the old ones
- if (!merge_list.empty()) {
- merge_list.push_back(mScene->mMeshes[im]);
-
- aiMesh* out;
- SceneCombiner::MergeMeshes(&out,0,merge_list.begin(),merge_list.end());
- output.push_back(out);
- } else {
- output.push_back(mScene->mMeshes[im]);
- }
- im = static_cast<unsigned int>(output.size()-1);
- }
- }
-
-
- for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) {
- ProcessNode( pNode->mChildren[ i ] );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Check whether two meshes can be joined
-bool OptimizeMeshesProcess::CanJoin ( unsigned int a, unsigned int b, unsigned int verts, unsigned int faces )
-{
- if (meshes[a].vertex_format != meshes[b].vertex_format)
- return false;
-
- aiMesh* ma = mScene->mMeshes[a], *mb = mScene->mMeshes[b];
-
- if ((NotSet != max_verts && verts+mb->mNumVertices > max_verts) ||
- (NotSet != max_faces && faces+mb->mNumFaces > max_faces)) {
- return false;
- }
-
- // Never merge unskinned meshes with skinned meshes
- if (ma->mMaterialIndex != mb->mMaterialIndex || ma->HasBones() != mb->HasBones())
- return false;
-
- // Never merge meshes with different kinds of primitives if SortByPType did already
- // do its work. We would destroy everything again ...
- if (pts && ma->mPrimitiveTypes != mb->mPrimitiveTypes)
- return false;
-
- // If both meshes are skinned, check whether we have many bones defined in both meshes.
- // If yes, we can join them.
- if (ma->HasBones()) {
- // TODO
- return false;
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a LUT of all instanced meshes
-void OptimizeMeshesProcess::FindInstancedMeshes (aiNode* pNode)
-{
- for( unsigned int i = 0; i < pNode->mNumMeshes; ++i ) {
- ++meshes[ pNode->mMeshes[ i ] ].instance_cnt;
- }
-
- for( unsigned int i = 0; i < pNode->mNumChildren; ++i ) {
- FindInstancedMeshes( pNode->mChildren[ i ] );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-
-#endif // !! ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
diff --git a/src/3rdparty/assimp/code/OptimizeMeshes.h b/src/3rdparty/assimp/code/OptimizeMeshes.h
deleted file mode 100644
index bcefe9247..000000000
--- a/src/3rdparty/assimp/code/OptimizeMeshes.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 OptimizeMeshes.h
- * @brief Declares a post processing step to join meshes, if possible
- */
-#ifndef AI_OPTIMIZEMESHESPROCESS_H_INC
-#define AI_OPTIMIZEMESHESPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/types.h>
-#include <vector>
-
-struct aiMesh;
-struct aiNode;
-class OptimizeMeshesProcessTest;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @brief Postprocessing step to optimize mesh usage
- *
- * The implementation looks for meshes that could be joined and joins them.
- * Usually this will reduce the number of drawcalls.
- *
- * @note Instanced meshes are currently not processed.
- */
-class OptimizeMeshesProcess : public BaseProcess
-{
-public:
-
- OptimizeMeshesProcess();
- ~OptimizeMeshesProcess();
-
-
- /** @brief Internal utility to store additional mesh info
- */
- struct MeshInfo
- {
- MeshInfo()
- : instance_cnt (0)
- , vertex_format (0)
- , output_id (0xffffffff)
- {}
-
- //! Number of times this mesh is referenced
- unsigned int instance_cnt;
-
- //! Vertex format id
- unsigned int vertex_format;
-
- //! Output ID
- unsigned int output_id;
- };
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Specify whether you want meshes with different
- * primitive types to be merged as well.
- *
- * IsActive() sets this property automatically to true if the
- * aiProcess_SortByPType flag is found.
- */
- void EnablePrimitiveTypeSorting(bool enable) {
- pts = enable;
- }
-
- // Getter
- bool IsPrimitiveTypeSortingEnabled () const {
- return pts;
- }
-
-
- // -------------------------------------------------------------------
- /** @brief Specify a maximum size of a single output mesh.
- *
- * If a single input mesh already exceeds this limit, it won't
- * be split.
- * @param verts Maximum number of vertices per mesh
- * @param faces Maximum number of faces per mesh
- */
- void SetPreferredMeshSizeLimit (unsigned int verts, unsigned int faces)
- {
- max_verts = verts;
- max_faces = faces;
- }
-
-
-protected:
-
- // -------------------------------------------------------------------
- /** @brief Do the actual optimization on all meshes of this node
- * @param pNode Node we're working with
- */
- void ProcessNode( aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** @brief Returns true if b can be joined with a
- *
- * @param verts Number of output verts up to now
- * @param faces Number of output faces up to now
- */
- bool CanJoin ( unsigned int a, unsigned int b,
- unsigned int verts, unsigned int faces );
-
- // -------------------------------------------------------------------
- /** @brief Find instanced meshes, for the moment we're excluding
- * them from all optimizations
- */
- void FindInstancedMeshes (aiNode* pNode);
-
-private:
-
- //! Scene we're working with
- aiScene* mScene;
-
- //! Per mesh info
- std::vector<MeshInfo> meshes;
-
- //! Output meshes
- std::vector<aiMesh*> output;
-
- //! @see EnablePrimitiveTypeSorting
- mutable bool pts;
-
- //! @see SetPreferredMeshSizeLimit
- mutable unsigned int max_verts,max_faces;
-
- //! Temporary storage
- std::vector<aiMesh*> merge_list;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_CALCTANGENTSPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/ParsingUtils.h b/src/3rdparty/assimp/code/ParsingUtils.h
deleted file mode 100644
index 7da664374..000000000
--- a/src/3rdparty/assimp/code/ParsingUtils.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ParsingUtils.h
- * @brief Defines helper functions for text parsing
- */
-#ifndef AI_PARSING_UTILS_H_INC
-#define AI_PARSING_UTILS_H_INC
-
-#include "StringComparison.h"
-#include "StringUtils.h"
-#include <assimp/defs.h>
-
-namespace Assimp {
-
-// NOTE: the functions below are mostly intended as replacement for
-// std::upper, std::lower, std::isupper, std::islower, std::isspace.
-// we don't bother of locales. We don't want them. We want reliable
-// (i.e. identical) results across all locales.
-
-// The functions below accept any character type, but know only
-// about ASCII. However, UTF-32 is the only safe ASCII superset to
-// use since it doesn't have multi-byte sequences.
-
-static const unsigned int BufferSize = 4096;
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE char_t ToLower( char_t in)
-{
- return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in+0x20) : in;
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE char_t ToUpper( char_t in) {
- return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in-0x20) : in;
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsUpper( char_t in)
-{
- return (in >= (char_t)'A' && in <= (char_t)'Z');
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsLower( char_t in)
-{
- return (in >= (char_t)'a' && in <= (char_t)'z');
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsSpace( char_t in)
-{
- return (in == (char_t)' ' || in == (char_t)'\t');
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsLineEnd( char_t in)
-{
- return (in==(char_t)'\r'||in==(char_t)'\n'||in==(char_t)'\0'||in==(char_t)'\f');
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsSpaceOrNewLine( char_t in)
-{
- return IsSpace<char_t>(in) || IsLineEnd<char_t>(in);
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipSpaces( const char_t* in, const char_t** out)
-{
- while( *in == ( char_t )' ' || *in == ( char_t )'\t' ) {
- ++in;
- }
- *out = in;
- return !IsLineEnd<char_t>(*in);
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipSpaces( const char_t** inout)
-{
- return SkipSpaces<char_t>(*inout,inout);
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-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;
- }
-
- // files are opened in binary mode. Ergo there are both NL and CR
- while( *in == ( char_t )'\r' || *in == ( char_t )'\n' ) {
- ++in;
- }
- *out = in;
- return *in != (char_t)'\0';
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipLine( const char_t** inout)
-{
- return SkipLine<char_t>(*inout,inout);
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-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;
- }
- *out = in;
- return *in != '\0';
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool SkipSpacesAndLineEnd( const char_t** inout)
-{
- return SkipSpacesAndLineEnd<char_t>(*inout,inout);
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool GetNextLine( const char_t*& buffer, char_t out[ BufferSize ] )
-{
- if( ( char_t )'\0' == *buffer ) {
- return false;
- }
-
- char* _out = out;
- char* const end = _out + BufferSize;
- while( !IsLineEnd( *buffer ) && _out < end ) {
- *_out++ = *buffer++;
- }
- *_out = (char_t)'\0';
-
- while( IsLineEnd( *buffer ) && '\0' != *buffer ) {
- ++buffer;
- }
-
- return true;
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool IsNumeric( char_t in)
-{
- return ( in >= '0' && in <= '9' ) || '-' == in || '+' == in;
-}
-
-// ---------------------------------------------------------------------------------
-template <class char_t>
-AI_FORCE_INLINE bool TokenMatch(char_t*& in, const char* token, unsigned int len)
-{
- if (!::strncmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
- if (in[len] != '\0') {
- in += len+1;
- } else {
- // If EOF after the token make sure we don't go past end of buffer
- in += len;
- }
- return true;
- }
-
- return false;
-}
-// ---------------------------------------------------------------------------------
-/** @brief Case-ignoring version of TokenMatch
- * @param in Input
- * @param token Token to check for
- * @param len Number of characters to check
- */
-AI_FORCE_INLINE bool TokenMatchI(const char*& in, const char* token, unsigned int len)
-{
- if (!ASSIMP_strincmp(token,in,len) && IsSpaceOrNewLine(in[len])) {
- in += len+1;
- return true;
- }
- return false;
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE void SkipToken(const char*& in)
-{
- SkipSpaces(&in);
- while (!IsSpaceOrNewLine(*in))++in;
-}
-// ---------------------------------------------------------------------------------
-AI_FORCE_INLINE std::string GetNextToken(const char*& in)
-{
- SkipSpacesAndLineEnd(&in);
- const char* cur = in;
- while (!IsSpaceOrNewLine(*in))++in;
- return std::string(cur,(size_t)(in-cur));
-}
-
-// ---------------------------------------------------------------------------------
-
-} // ! namespace Assimp
-
-#endif // ! AI_PARSING_UTILS_H_INC
diff --git a/src/3rdparty/assimp/code/PlyExporter.cpp b/src/3rdparty/assimp/code/PlyExporter.cpp
deleted file mode 100644
index b20c2b328..000000000
--- a/src/3rdparty/assimp/code/PlyExporter.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-
-
-#if !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_PLY_EXPORTER)
-
-#include "PlyExporter.h"
-#include <memory>
-#include <cmath>
-#include "Exceptional.h"
-#include <assimp/scene.h>
-#include <assimp/version.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include "qnan.h"
-
-
-//using namespace Assimp;
-namespace Assimp {
-
-// make sure type_of returns consistent output across different platforms
-// also consider using: typeid(VAR).name()
-template <typename T> const char* type_of(T&) { return "unknown"; }
-template<> const char* type_of(float&) { return "float"; }
-template<> const char* type_of(double&) { return "double"; }
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to PLY. Prototyped and registered in Exporter.cpp
-void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- // invoke the exporter
- PlyExporter exporter(pFile, pScene);
-
- if (exporter.mOutput.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write the file.
- std::unique_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);
-}
-
-void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- // invoke the exporter
- PlyExporter exporter(pFile, pScene, true);
-
- // we're still here - export successfully completed. Write the file.
- std::unique_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb"));
- 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);
-}
-
-#define PLY_EXPORT_HAS_NORMALS 0x1
-#define PLY_EXPORT_HAS_TANGENTS_BITANGENTS 0x2
-#define PLY_EXPORT_HAS_TEXCOORDS 0x4
-#define PLY_EXPORT_HAS_COLORS (PLY_EXPORT_HAS_TEXCOORDS << AI_MAX_NUMBER_OF_TEXTURECOORDS)
-
-// ------------------------------------------------------------------------------------------------
-PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool binary)
-: filename(_filename)
-, endl("\n")
-{
- // 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);
- mOutput.precision(16);
-
- unsigned int faces = 0u, vertices = 0u, components = 0u;
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- const aiMesh& m = *pScene->mMeshes[i];
- faces += m.mNumFaces;
- vertices += m.mNumVertices;
-
- if (m.HasNormals()) {
- components |= PLY_EXPORT_HAS_NORMALS;
- }
- if (m.HasTangentsAndBitangents()) {
- components |= PLY_EXPORT_HAS_TANGENTS_BITANGENTS;
- }
- for (unsigned int t = 0; m.HasTextureCoords(t); ++t) {
- components |= PLY_EXPORT_HAS_TEXCOORDS << t;
- }
- for (unsigned int t = 0; m.HasVertexColors(t); ++t) {
- components |= PLY_EXPORT_HAS_COLORS << t;
- }
- }
-
- mOutput << "ply" << endl;
- if (binary) {
-#if (defined AI_BUILD_BIG_ENDIAN)
- mOutput << "format binary_big_endian 1.0" << endl;
-#else
- mOutput << "format binary_little_endian 1.0" << endl;
-#endif
- }
- else {
- mOutput << "format ascii 1.0" << endl;
- }
- mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v"
- << aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
- << aiGetVersionRevision() << ")" << endl;
-
- // TODO: probably want to check here rather than just assume something
- // definitely not good to always write float even if we might have double precision
-
- ai_real tmp = 0.0;
- const char * typeName = type_of(tmp);
-
- mOutput << "element vertex " << vertices << endl;
- mOutput << "property " << typeName << " x" << endl;
- mOutput << "property " << typeName << " y" << endl;
- mOutput << "property " << typeName << " z" << endl;
-
- if(components & PLY_EXPORT_HAS_NORMALS) {
- mOutput << "property " << typeName << " nx" << endl;
- mOutput << "property " << typeName << " ny" << endl;
- mOutput << "property " << typeName << " nz" << endl;
- }
-
- // write texcoords first, just in case an importer does not support tangents
- // bitangents and just skips over the rest of the line upon encountering
- // unknown fields (Ply leaves pretty much every vertex component open,
- // but in reality most importers only know about vertex positions, normals
- // and texture coordinates).
- for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
- if (!c) {
- mOutput << "property " << typeName << " s" << endl;
- mOutput << "property " << typeName << " t" << endl;
- }
- else {
- mOutput << "property " << typeName << " s" << c << endl;
- mOutput << "property " << typeName << " t" << c << endl;
- }
- }
-
- for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
- if (!c) {
- mOutput << "property " << typeName << " r" << endl;
- mOutput << "property " << typeName << " g" << endl;
- mOutput << "property " << typeName << " b" << endl;
- mOutput << "property " << typeName << " a" << endl;
- }
- else {
- mOutput << "property " << typeName << " r" << c << endl;
- mOutput << "property " << typeName << " g" << c << endl;
- mOutput << "property " << typeName << " b" << c << endl;
- mOutput << "property " << typeName << " a" << c << endl;
- }
- }
-
- if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
- mOutput << "property " << typeName << " tx" << endl;
- mOutput << "property " << typeName << " ty" << endl;
- mOutput << "property " << typeName << " tz" << endl;
- mOutput << "property " << typeName << " bx" << endl;
- mOutput << "property " << typeName << " by" << endl;
- mOutput << "property " << typeName << " bz" << endl;
- }
-
- mOutput << "element face " << faces << endl;
-
- // uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices.
- // For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well.
- // Obviously, using uchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case?
- mOutput << "property list uchar int vertex_index" << endl;
-
- mOutput << "end_header" << endl;
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- if (binary) {
- WriteMeshVertsBinary(pScene->mMeshes[i], components);
- }
- else {
- WriteMeshVerts(pScene->mMeshes[i], components);
- }
- }
- for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) {
- if (binary) {
- WriteMeshIndicesBinary(pScene->mMeshes[i], ofs);
- }
- else {
- WriteMeshIndices(pScene->mMeshes[i], ofs);
- }
- ofs += pScene->mMeshes[i]->mNumVertices;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-PlyExporter::~PlyExporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
-{
- static const ai_real inf = std::numeric_limits<ai_real>::infinity();
-
- // If a component (for instance normal vectors) is present in at least one mesh in the scene,
- // then default values are written for meshes that do not contain this component.
- for (unsigned int i = 0; i < m->mNumVertices; ++i) {
- mOutput <<
- m->mVertices[i].x << " " <<
- m->mVertices[i].y << " " <<
- m->mVertices[i].z
- ;
- if(components & PLY_EXPORT_HAS_NORMALS) {
- if (m->HasNormals() && is_not_qnan(m->mNormals[i].x) && std::fabs(m->mNormals[i].x) != inf) {
- mOutput <<
- " " << m->mNormals[i].x <<
- " " << m->mNormals[i].y <<
- " " << m->mNormals[i].z;
- }
- else {
- mOutput << " 0.0 0.0 0.0";
- }
- }
-
- for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
- if (m->HasTextureCoords(c)) {
- mOutput <<
- " " << m->mTextureCoords[c][i].x <<
- " " << m->mTextureCoords[c][i].y;
- }
- else {
- mOutput << " -1.0 -1.0";
- }
- }
-
- for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
- if (m->HasVertexColors(c)) {
- mOutput <<
- " " << m->mColors[c][i].r <<
- " " << m->mColors[c][i].g <<
- " " << m->mColors[c][i].b <<
- " " << m->mColors[c][i].a;
- }
- else {
- mOutput << " -1.0 -1.0 -1.0 -1.0";
- }
- }
-
- if(components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
- if (m->HasTangentsAndBitangents()) {
- mOutput <<
- " " << m->mTangents[i].x <<
- " " << m->mTangents[i].y <<
- " " << m->mTangents[i].z <<
- " " << m->mBitangents[i].x <<
- " " << m->mBitangents[i].y <<
- " " << m->mBitangents[i].z
- ;
- }
- else {
- mOutput << " 0.0 0.0 0.0 0.0 0.0 0.0";
- }
- }
-
- mOutput << endl;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
-{
- // If a component (for instance normal vectors) is present in at least one mesh in the scene,
- // then default values are written for meshes that do not contain this component.
- aiVector3D defaultNormal(0, 0, 0);
- aiVector2D defaultUV(-1, -1);
- aiColor4D defaultColor(-1, -1, -1, -1);
- for (unsigned int i = 0; i < m->mNumVertices; ++i) {
- mOutput.write(reinterpret_cast<const char*>(&m->mVertices[i].x), 12);
- if (components & PLY_EXPORT_HAS_NORMALS) {
- if (m->HasNormals()) {
- mOutput.write(reinterpret_cast<const char*>(&m->mNormals[i].x), 12);
- }
- else {
- mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
- }
- }
-
- for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
- if (m->HasTextureCoords(c)) {
- mOutput.write(reinterpret_cast<const char*>(&m->mTextureCoords[c][i].x), 8);
- }
- else {
- mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 8);
- }
- }
-
- for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
- if (m->HasVertexColors(c)) {
- mOutput.write(reinterpret_cast<const char*>(&m->mColors[c][i].r), 16);
- }
- else {
- mOutput.write(reinterpret_cast<const char*>(&defaultColor.r), 16);
- }
- }
-
- if (components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
- if (m->HasTangentsAndBitangents()) {
- mOutput.write(reinterpret_cast<const char*>(&m->mTangents[i].x), 12);
- mOutput.write(reinterpret_cast<const char*>(&m->mBitangents[i].x), 12);
- }
- else {
- mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
- mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset)
-{
- for (unsigned int i = 0; i < m->mNumFaces; ++i) {
- const aiFace& f = m->mFaces[i];
- mOutput << f.mNumIndices << " ";
- for(unsigned int c = 0; c < f.mNumIndices; ++c) {
- mOutput << (f.mIndices[c] + offset) << (c == f.mNumIndices-1 ? endl : " ");
- }
- }
-}
-
-// Generic method in case we want to use different data types for the indices or make this configurable.
-template<typename NumIndicesType, typename IndexType>
-void WriteMeshIndicesBinary_Generic(const aiMesh* m, unsigned int offset, std::ostringstream& output)
-{
- for (unsigned int i = 0; i < m->mNumFaces; ++i) {
- const aiFace& f = m->mFaces[i];
- NumIndicesType numIndices = static_cast<NumIndicesType>(f.mNumIndices);
- output.write(reinterpret_cast<const char*>(&numIndices), sizeof(NumIndicesType));
- for (unsigned int c = 0; c < f.mNumIndices; ++c) {
- IndexType index = f.mIndices[c] + offset;
- output.write(reinterpret_cast<const char*>(&index), sizeof(IndexType));
- }
- }
-}
-
-void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset)
-{
- WriteMeshIndicesBinary_Generic<unsigned char, int>(m, offset, mOutput);
-}
-
-} // end of namespace Assimp
-
-#endif // !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_PLY_EXPORTER)
diff --git a/src/3rdparty/assimp/code/PlyExporter.h b/src/3rdparty/assimp/code/PlyExporter.h
deleted file mode 100644
index d1d4eafbb..000000000
--- a/src/3rdparty/assimp/code/PlyExporter.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PlyExporter.h
- * Declares the exporter class to write a scene to a Polygon Library (ply)
- */
-#ifndef AI_PLYEXPORTER_H_INC
-#define AI_PLYEXPORTER_H_INC
-
-#include <sstream>
-
-struct aiScene;
-struct aiNode;
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/** Helper class to export a given scene to a Stanford Ply file. */
-// ------------------------------------------------------------------------------------------------
-class PlyExporter {
-public:
- /// The class constructor for a specific scene to export
- PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
- /// The class destructor, empty.
- ~PlyExporter();
-
-public:
- /// public string-streams to write all output into:
- std::ostringstream mOutput;
-
-private:
- void WriteMeshVerts(const aiMesh* m, unsigned int components);
- void WriteMeshIndices(const aiMesh* m, unsigned int ofs);
- void WriteMeshVertsBinary(const aiMesh* m, unsigned int components);
- void WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset);
-
-private:
- const std::string filename; // tHE FILENAME
- const std::string endl; // obviously, this endl() doesn't flush() the stream
-
-private:
- PlyExporter( const PlyExporter & );
- PlyExporter &operator = ( const PlyExporter & );
-};
-
-} // Namespace Assimp
-
-#endif // AI_PLYEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/PlyLoader.cpp b/src/3rdparty/assimp/code/PlyLoader.cpp
deleted file mode 100644
index c6e862bf1..000000000
--- a/src/3rdparty/assimp/code/PlyLoader.cpp
+++ /dev/null
@@ -1,1014 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PlyLoader.cpp
- * @brief Implementation of the PLY importer class
- */
-
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-
-// internal headers
-#include "PlyLoader.h"
-#include "IOStreamBuffer.h"
-#include "Macros.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Stanford Polygon Library (PLY) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "ply"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Internal stuff
-namespace
-{
- // ------------------------------------------------------------------------------------------------
- // Checks that property index is within range
- template <class T>
- const T &GetProperty(const std::vector<T> &props, int idx)
- {
- if (static_cast<size_t>(idx) >= props.size()) {
- throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
- }
-
- return props[idx];
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-PLYImporter::PLYImporter()
- : mBuffer()
- , pcDOM()
- , mGeneratedMesh(NULL){
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-PLYImporter::~PLYImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool PLYImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "ply")
- return true;
- else if (!extension.length() || checkSig)
- {
- if (!pIOHandler)return true;
- const char* tokens[] = { "ply" };
- return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* PLYImporter::GetInfo() const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-static bool isBigEndian(const char* szMe) {
- ai_assert(NULL != szMe);
-
- // binary_little_endian
- // binary_big_endian
- bool isBigEndian(false);
-#if (defined AI_BUILD_BIG_ENDIAN)
- if ( 'l' == *szMe || 'L' == *szMe ) {
- isBigEndian = true;
- }
-#else
- if ('b' == *szMe || 'B' == *szMe) {
- isBigEndian = true;
- }
-#endif // ! AI_BUILD_BIG_ENDIAN
-
- return isBigEndian;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void PLYImporter::InternReadFile(const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- static const std::string mode = "rb";
- std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
- if (!fileStream.get()) {
- throw DeadlyImportError("Failed to open file " + pFile + ".");
- }
-
- // Get the file-size
- size_t fileSize = fileStream->FileSize();
- if ( 0 == fileSize ) {
- throw DeadlyImportError("File " + pFile + " is empty.");
- }
-
- IOStreamBuffer<char> streamedBuffer(1024 * 1024);
- streamedBuffer.open(fileStream.get());
-
- // the beginning of the file must be PLY - magic, magic
- std::vector<char> headerCheck;
- streamedBuffer.getNextLine(headerCheck);
-
- if ((headerCheck.size() < 3) ||
- (headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
- (headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
- (headerCheck[2] != 'Y' && headerCheck[2] != 'y') )
- {
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
- }
-
- std::vector<char> mBuffer2;
- streamedBuffer.getNextLine(mBuffer2);
- mBuffer = (unsigned char*)&mBuffer2[0];
-
- char* szMe = (char*)&this->mBuffer[0];
- SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
-
- // determine the format of the file data and construct the aimesh
- PLY::DOM sPlyDom;
- this->pcDOM = &sPlyDom;
-
- if (TokenMatch(szMe, "format", 6)) {
- if (TokenMatch(szMe, "ascii", 5)) {
- SkipLine(szMe, (const char**)&szMe);
- if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this))
- {
- if (mGeneratedMesh != NULL)
- delete(mGeneratedMesh);
-
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#1)");
- }
- }
- else if (!::strncmp(szMe, "binary_", 7))
- {
- szMe += 7;
- const bool bIsBE(isBigEndian(szMe));
-
- // skip the line, parse the rest of the header and build the DOM
- if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE))
- {
- if (mGeneratedMesh != NULL)
- delete(mGeneratedMesh);
-
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
- }
- }
- else
- {
- if (mGeneratedMesh != NULL)
- delete(mGeneratedMesh);
-
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Unknown file format");
- }
- }
- else
- {
- AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
- if (mGeneratedMesh != NULL)
- delete(mGeneratedMesh);
-
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Missing format specification");
- }
-
- //free the file buffer
- streamedBuffer.close();
-
- if (mGeneratedMesh == NULL)
- {
- throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
- }
-
- // if no face list is existing we assume that the vertex
- // list is containing a list of points
- bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
- if (pointsOnly)
- {
- if (mGeneratedMesh->mNumVertices < 3)
- {
- if (mGeneratedMesh != NULL)
- delete(mGeneratedMesh);
-
- streamedBuffer.close();
- throw DeadlyImportError("Invalid .ply file: Not enough "
- "vertices to build a proper face list. ");
- }
-
- const unsigned int iNum = (unsigned int)mGeneratedMesh->mNumVertices / 3;
- mGeneratedMesh->mNumFaces = iNum;
- mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
-
- for (unsigned int i = 0; i < iNum; ++i)
- {
- mGeneratedMesh->mFaces[i].mNumIndices = 3;
- mGeneratedMesh->mFaces[i].mIndices = new unsigned int[3];
- mGeneratedMesh->mFaces[i].mIndices[0] = (i * 3);
- mGeneratedMesh->mFaces[i].mIndices[1] = (i * 3) + 1;
- mGeneratedMesh->mFaces[i].mIndices[2] = (i * 3) + 2;
- }
- }
-
- // now load a list of all materials
- std::vector<aiMaterial*> avMaterials;
- std::string defaultTexture;
- LoadMaterial(&avMaterials, defaultTexture, pointsOnly);
-
- // now generate the output scene object. Fill the material list
- pScene->mNumMaterials = (unsigned int)avMaterials.size();
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
- pScene->mMaterials[i] = avMaterials[i];
- }
-
- // fill the mesh list
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMeshes[0] = mGeneratedMesh;
-
- // generate a simple node structure
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
-
- for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes; ++i) {
- pScene->mRootNode->mMeshes[i] = i;
- }
-}
-
-void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
- ai_assert(NULL != pcElement);
- ai_assert(NULL != instElement);
-
- ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
-
- ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
-
- unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
- PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char };
-
- unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
- PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
-
- // now check whether which normal components are available
- unsigned int _a( 0 ), cnt( 0 );
- for ( std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- a != pcElement->alProperties.end(); ++a, ++_a) {
- if ((*a).bIsList) {
- continue;
- }
-
- // Positions
- if (PLY::EST_XCoord == (*a).Semantic) {
- ++cnt;
- aiPositions[0] = _a;
- aiTypes[0] = (*a).eType;
- } else if (PLY::EST_YCoord == (*a).Semantic) {
- ++cnt;
- aiPositions[1] = _a;
- aiTypes[1] = (*a).eType;
- } else if (PLY::EST_ZCoord == (*a).Semantic) {
- ++cnt;
- aiPositions[2] = _a;
- aiTypes[2] = (*a).eType;
- } else if (PLY::EST_XNormal == (*a).Semantic) {
- // Normals
- ++cnt;
- aiNormal[0] = _a;
- aiNormalTypes[0] = (*a).eType;
- } else if (PLY::EST_YNormal == (*a).Semantic) {
- ++cnt;
- aiNormal[1] = _a;
- aiNormalTypes[1] = (*a).eType;
- } else if (PLY::EST_ZNormal == (*a).Semantic) {
- ++cnt;
- aiNormal[2] = _a;
- aiNormalTypes[2] = (*a).eType;
- } else if (PLY::EST_Red == (*a).Semantic) {
- // Colors
- ++cnt;
- aiColors[0] = _a;
- aiColorsTypes[0] = (*a).eType;
- } else if (PLY::EST_Green == (*a).Semantic) {
- ++cnt;
- aiColors[1] = _a;
- aiColorsTypes[1] = (*a).eType;
- } else if (PLY::EST_Blue == (*a).Semantic) {
- ++cnt;
- aiColors[2] = _a;
- aiColorsTypes[2] = (*a).eType;
- } else if (PLY::EST_Alpha == (*a).Semantic) {
- ++cnt;
- aiColors[3] = _a;
- aiColorsTypes[3] = (*a).eType;
- } else if (PLY::EST_UTextureCoord == (*a).Semantic) {
- // Texture coordinates
- ++cnt;
- aiTexcoord[0] = _a;
- aiTexcoordTypes[0] = (*a).eType;
- } else if (PLY::EST_VTextureCoord == (*a).Semantic) {
- ++cnt;
- aiTexcoord[1] = _a;
- aiTexcoordTypes[1] = (*a).eType;
- }
- }
-
- // check whether we have a valid source for the vertex data
- if (0 != cnt) {
- // Position
- aiVector3D vOut;
- if (0xFFFFFFFF != aiPositions[0]) {
- vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
- }
-
- if (0xFFFFFFFF != aiPositions[1]) {
- vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
- }
-
- if (0xFFFFFFFF != aiPositions[2]) {
- vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
- }
-
- // Normals
- aiVector3D nOut;
- bool haveNormal = false;
- if (0xFFFFFFFF != aiNormal[0]) {
- nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
- haveNormal = true;
- }
-
- if (0xFFFFFFFF != aiNormal[1]) {
- nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
- haveNormal = true;
- }
-
- if (0xFFFFFFFF != aiNormal[2]) {
- nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
- haveNormal = true;
- }
-
- //Colors
- aiColor4D cOut;
- bool haveColor = false;
- if (0xFFFFFFFF != aiColors[0]) {
- cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
- aiColors[0]).avList.front(), aiColorsTypes[0]);
- haveColor = true;
- }
-
- if (0xFFFFFFFF != aiColors[1]) {
- cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
- aiColors[1]).avList.front(), aiColorsTypes[1]);
- haveColor = true;
- }
-
- if (0xFFFFFFFF != aiColors[2]) {
- cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
- aiColors[2]).avList.front(), aiColorsTypes[2]);
- haveColor = true;
- }
-
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiColors[3]) {
- cOut.a = 1.0;
- } else {
- cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
- aiColors[3]).avList.front(), aiColorsTypes[3]);
-
- haveColor = true;
- }
-
- //Texture coordinates
- aiVector3D tOut;
- tOut.z = 0;
- bool haveTextureCoords = false;
- if (0xFFFFFFFF != aiTexcoord[0]) {
- tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
- haveTextureCoords = true;
- }
-
- if (0xFFFFFFFF != aiTexcoord[1]) {
- tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
- GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
- haveTextureCoords = true;
- }
-
- //create aiMesh if needed
- if ( nullptr == mGeneratedMesh ) {
- mGeneratedMesh = new aiMesh();
- mGeneratedMesh->mMaterialIndex = 0;
- }
-
- if (nullptr == mGeneratedMesh->mVertices) {
- mGeneratedMesh->mNumVertices = pcElement->NumOccur;
- mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
- }
-
- mGeneratedMesh->mVertices[pos] = vOut;
-
- if (haveNormal) {
- if (nullptr == mGeneratedMesh->mNormals)
- mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
- mGeneratedMesh->mNormals[pos] = nOut;
- }
-
- if (haveColor) {
- if (nullptr == mGeneratedMesh->mColors[0])
- mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
- mGeneratedMesh->mColors[0][pos] = cOut;
- }
-
- if (haveTextureCoords) {
- if (nullptr == mGeneratedMesh->mTextureCoords[0]) {
- mGeneratedMesh->mNumUVComponents[0] = 2;
- mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
- }
- mGeneratedMesh->mTextureCoords[0][pos] = tOut;
- }
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Convert a color component to [0...1]
-ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val,
- PLY::EDataType eType)
-{
- switch (eType)
- {
- case EDT_Float:
- return val.fFloat;
- case EDT_Double:
- return (ai_real)val.fDouble;
-
- case EDT_UChar:
- return (ai_real)val.iUInt / (ai_real)0xFF;
- case EDT_Char:
- return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
- case EDT_UShort:
- return (ai_real)val.iUInt / (ai_real)0xFFFF;
- case EDT_Short:
- return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
- case EDT_UInt:
- return (ai_real)val.iUInt / (ai_real)0xFFFF;
- case EDT_Int:
- return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
- default:;
- };
- return 0.0f;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Try to extract proper faces from the PLY DOM
-void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
-{
- ai_assert(NULL != pcElement);
- ai_assert(NULL != instElement);
-
- if (mGeneratedMesh == NULL)
- throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
-
- bool bOne = false;
-
- // index of the vertex index list
- unsigned int iProperty = 0xFFFFFFFF;
- PLY::EDataType eType = EDT_Char;
- bool bIsTriStrip = false;
-
- // index of the material index property
- //unsigned int iMaterialIndex = 0xFFFFFFFF;
- //PLY::EDataType eType2 = EDT_Char;
-
- // texture coordinates
- unsigned int iTextureCoord = 0xFFFFFFFF;
- PLY::EDataType eType3 = EDT_Char;
-
- // face = unique number of vertex indices
- if (PLY::EEST_Face == pcElement->eSemantic)
- {
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- a != pcElement->alProperties.end(); ++a, ++_a)
- {
- if (PLY::EST_VertexIndex == (*a).Semantic)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)
- continue;
-
- iProperty = _a;
- bOne = true;
- eType = (*a).eType;
- }
- /*else if (PLY::EST_MaterialIndex == (*a).Semantic)
- {
- if ((*a).bIsList)
- continue;
- iMaterialIndex = _a;
- bOne = true;
- eType2 = (*a).eType;
- }*/
- else if (PLY::EST_TextureCoordinates == (*a).Semantic)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)
- continue;
- iTextureCoord = _a;
- bOne = true;
- eType3 = (*a).eType;
- }
- }
- }
- // triangle strip
- // TODO: triangle strip and material index support???
- else if (PLY::EEST_TriStrip == pcElement->eSemantic)
- {
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- a != pcElement->alProperties.end(); ++a, ++_a)
- {
- // must be a dynamic list!
- if (!(*a).bIsList)
- continue;
- iProperty = _a;
- bOne = true;
- bIsTriStrip = true;
- eType = (*a).eType;
- break;
- }
- }
-
- // check whether we have at least one per-face information set
- if (bOne)
- {
- if (mGeneratedMesh->mFaces == NULL)
- {
- mGeneratedMesh->mNumFaces = pcElement->NumOccur;
- mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
- }
-
- if (!bIsTriStrip)
- {
- // parse the list of vertex indices
- if (0xFFFFFFFF != iProperty)
- {
- const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
- mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
- mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
-
- std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
- GetProperty(instElement->alProperties, iProperty).avList.begin();
-
- for (unsigned int a = 0; a < iNum; ++a, ++p)
- {
- mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
- }
- }
-
- // parse the material index
- // cannot be handled without processing the whole file first
- /*if (0xFFFFFFFF != iMaterialIndex)
- {
- mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
- GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
- }*/
-
- if (0xFFFFFFFF != iTextureCoord)
- {
- const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
-
- //should be 6 coords
- std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
- GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
-
- if ((iNum / 3) == 2) // X Y coord
- {
- for (unsigned int a = 0; a < iNum; ++a, ++p)
- {
- unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
- if (vindex < mGeneratedMesh->mNumVertices)
- {
- if (mGeneratedMesh->mTextureCoords[0] == NULL)
- {
- mGeneratedMesh->mNumUVComponents[0] = 2;
- mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
- }
-
- if (a % 2 == 0)
- mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
- else
- mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
-
- mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
- }
- }
- }
- }
- }
- else // triangle strips
- {
- // normally we have only one triangle strip instance where
- // a value of -1 indicates a restart of the strip
- bool flip = false;
- const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
- //pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
-
- int aiTable[2] = { -1, -1 };
- for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
- const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
-
- if (-1 == p) {
- // restart the strip ...
- aiTable[0] = aiTable[1] = -1;
- flip = false;
- continue;
- }
- if (-1 == aiTable[0]) {
- aiTable[0] = p;
- continue;
- }
- if (-1 == aiTable[1]) {
- aiTable[1] = p;
- continue;
- }
-
- if (mGeneratedMesh->mFaces == NULL)
- {
- mGeneratedMesh->mNumFaces = pcElement->NumOccur;
- mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
- }
-
- mGeneratedMesh->mFaces[pos].mNumIndices = 3;
- mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
- mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
- mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
- mGeneratedMesh->mFaces[pos].mIndices[2] = p;
-
- if ((flip = !flip)) {
- std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
- }
-
- aiTable[0] = aiTable[1];
- aiTable[1] = p;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a RGBA color in [0...1] range
-void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avList,
- unsigned int aiPositions[4],
- PLY::EDataType aiTypes[4],
- aiColor4D* clrOut)
-{
- ai_assert(NULL != clrOut);
-
- if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
- else
- {
- clrOut->r = NormalizeColorValue(GetProperty(avList,
- aiPositions[0]).avList.front(), aiTypes[0]);
- }
-
- if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
- else
- {
- clrOut->g = NormalizeColorValue(GetProperty(avList,
- aiPositions[1]).avList.front(), aiTypes[1]);
- }
-
- if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
- else
- {
- clrOut->b = NormalizeColorValue(GetProperty(avList,
- aiPositions[2]).avList.front(), aiTypes[2]);
- }
-
- // assume 1.0 for the alpha channel ifit is not set
- if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
- else
- {
- clrOut->a = NormalizeColorValue(GetProperty(avList,
- aiPositions[3]).avList.front(), aiTypes[3]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Extract a material from the PLY DOM
-void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly)
-{
- ai_assert(NULL != pvOut);
-
- // diffuse[4], specular[4], ambient[4]
- // rgba order
- unsigned int aaiPositions[3][4] = {
-
- { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
- { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
- { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
- };
-
- PLY::EDataType aaiTypes[3][4] = {
- { EDT_Char, EDT_Char, EDT_Char, EDT_Char },
- { EDT_Char, EDT_Char, EDT_Char, EDT_Char },
- { EDT_Char, EDT_Char, EDT_Char, EDT_Char }
- };
- PLY::ElementInstanceList* pcList = NULL;
-
- unsigned int iPhong = 0xFFFFFFFF;
- PLY::EDataType ePhong = EDT_Char;
-
- unsigned int iOpacity = 0xFFFFFFFF;
- PLY::EDataType eOpacity = EDT_Char;
-
- // search in the DOM for a vertex entry
- unsigned int _i = 0;
- for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
- i != this->pcDOM->alElements.end(); ++i, ++_i)
- {
- if (PLY::EEST_Material == (*i).eSemantic)
- {
- pcList = &this->pcDOM->alElementData[_i];
-
- // now check whether which coordinate sets are available
- unsigned int _a = 0;
- for (std::vector<PLY::Property>::const_iterator
- a = (*i).alProperties.begin();
- a != (*i).alProperties.end(); ++a, ++_a)
- {
- if ((*a).bIsList)continue;
-
- // pohng specularity -----------------------------------
- if (PLY::EST_PhongPower == (*a).Semantic)
- {
- iPhong = _a;
- ePhong = (*a).eType;
- }
-
- // general opacity -----------------------------------
- if (PLY::EST_Opacity == (*a).Semantic)
- {
- iOpacity = _a;
- eOpacity = (*a).eType;
- }
-
- // diffuse color channels -----------------------------------
- if (PLY::EST_DiffuseRed == (*a).Semantic)
- {
- aaiPositions[0][0] = _a;
- aaiTypes[0][0] = (*a).eType;
- }
- else if (PLY::EST_DiffuseGreen == (*a).Semantic)
- {
- aaiPositions[0][1] = _a;
- aaiTypes[0][1] = (*a).eType;
- }
- else if (PLY::EST_DiffuseBlue == (*a).Semantic)
- {
- aaiPositions[0][2] = _a;
- aaiTypes[0][2] = (*a).eType;
- }
- else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
- {
- aaiPositions[0][3] = _a;
- aaiTypes[0][3] = (*a).eType;
- }
- // specular color channels -----------------------------------
- else if (PLY::EST_SpecularRed == (*a).Semantic)
- {
- aaiPositions[1][0] = _a;
- aaiTypes[1][0] = (*a).eType;
- }
- else if (PLY::EST_SpecularGreen == (*a).Semantic)
- {
- aaiPositions[1][1] = _a;
- aaiTypes[1][1] = (*a).eType;
- }
- else if (PLY::EST_SpecularBlue == (*a).Semantic)
- {
- aaiPositions[1][2] = _a;
- aaiTypes[1][2] = (*a).eType;
- }
- else if (PLY::EST_SpecularAlpha == (*a).Semantic)
- {
- aaiPositions[1][3] = _a;
- aaiTypes[1][3] = (*a).eType;
- }
- // ambient color channels -----------------------------------
- else if (PLY::EST_AmbientRed == (*a).Semantic)
- {
- aaiPositions[2][0] = _a;
- aaiTypes[2][0] = (*a).eType;
- }
- else if (PLY::EST_AmbientGreen == (*a).Semantic)
- {
- aaiPositions[2][1] = _a;
- aaiTypes[2][1] = (*a).eType;
- }
- else if (PLY::EST_AmbientBlue == (*a).Semantic)
- {
- aaiPositions[2][2] = _a;
- aaiTypes[2][2] = (*a).eType;
- }
- else if (PLY::EST_AmbientAlpha == (*a).Semantic)
- {
- aaiPositions[2][3] = _a;
- aaiTypes[2][3] = (*a).eType;
- }
- }
- break;
- }
- else if (PLY::EEST_TextureFile == (*i).eSemantic)
- {
- defaultTexture = (*i).szName;
- }
- }
- // check whether we have a valid source for the material data
- if (NULL != pcList) {
- for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) {
- aiColor4D clrOut;
- aiMaterial* pcHelper = new aiMaterial();
-
- // build the diffuse material color
- GetMaterialColor((*i).alProperties, aaiPositions[0], aaiTypes[0], &clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_DIFFUSE);
-
- // build the specular material color
- GetMaterialColor((*i).alProperties, aaiPositions[1], aaiTypes[1], &clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_SPECULAR);
-
- // build the ambient material color
- GetMaterialColor((*i).alProperties, aaiPositions[2], aaiTypes[2], &clrOut);
- pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_AMBIENT);
-
- // handle phong power and shading mode
- int iMode = (int)aiShadingMode_Gouraud;
- if (0xFFFFFFFF != iPhong) {
- ai_real fSpec = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), ePhong);
-
- // if shininess is 0 (and the pow() calculation would therefore always
- // become 1, not depending on the angle), use gouraud lighting
- if (fSpec) {
- // scale this with 15 ... hopefully this is correct
- fSpec *= 15;
- pcHelper->AddProperty<ai_real>(&fSpec, 1, AI_MATKEY_SHININESS);
-
- iMode = (int)aiShadingMode_Phong;
- }
- }
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- // handle opacity
- if (0xFFFFFFFF != iOpacity) {
- ai_real fOpacity = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), eOpacity);
- pcHelper->AddProperty<ai_real>(&fOpacity, 1, AI_MATKEY_OPACITY);
- }
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
-
- //default texture
- if (!defaultTexture.empty())
- {
- const aiString name(defaultTexture.c_str());
- pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
- }
-
- if (!pointsOnly)
- {
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
- }
-
- //set to wireframe, so when using this material info we can switch to points rendering
- if (pointsOnly)
- {
- const int wireframe = 1;
- pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- // add the newly created material instance to the list
- pvOut->push_back(pcHelper);
- }
- }
- else
- {
- // generate a default material
- aiMaterial* pcHelper = new aiMaterial();
-
- // fill in a default material
- int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- //generate white material most 3D engine just multiply ambient / diffuse color with actual ambient / light color
- aiColor3D clr;
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 1.0f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
-
- // The face order is absolutely undefined for PLY, so we have to
- // use two-sided rendering to be sure it's ok.
- if (!pointsOnly)
- {
- const int two_sided = 1;
- pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
- }
-
- //default texture
- if (!defaultTexture.empty())
- {
- const aiString name(defaultTexture.c_str());
- pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
- }
-
- //set to wireframe, so when using this material info we can switch to points rendering
- if (pointsOnly)
- {
- const int wireframe = 1;
- pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
- }
-
- pvOut->push_back(pcHelper);
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/src/3rdparty/assimp/code/PlyLoader.h b/src/3rdparty/assimp/code/PlyLoader.h
deleted file mode 100644
index eb64a9036..000000000
--- a/src/3rdparty/assimp/code/PlyLoader.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PLYLoader.h
- * @brief Declaration of the .ply importer class.
- */
-#ifndef AI_PLYLOADER_H_INCLUDED
-#define AI_PLYLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include "PlyParser.h"
-#include <vector>
-
-struct aiNode;
-struct aiMaterial;
-struct aiMesh;
-
-namespace Assimp {
-
-
-using namespace PLY;
-
-// ---------------------------------------------------------------------------
-/** Importer class to load the stanford PLY file format
-*/
-class PLYImporter : public BaseImporter
-{
-public:
- PLYImporter();
- ~PLYImporter();
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Extract a vertex from the DOM
- */
- void LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
-
- // -------------------------------------------------------------------
- /** Extract a face from the DOM
- */
- void LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
- // -------------------------------------------------------------------
- /** Extract a material list from the DOM
- */
- void LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly);
-
- // -------------------------------------------------------------------
- /** Static helper to parse a color from four single channels in
- */
- static void GetMaterialColor(
- const std::vector<PLY::PropertyInstance>& avList,
- unsigned int aiPositions[4],
- PLY::EDataType aiTypes[4],
- aiColor4D* clrOut);
-
- // -------------------------------------------------------------------
- /** Static helper to parse a color channel value. The input value
- * is normalized to 0-1.
- */
- static ai_real NormalizeColorValue (
- PLY::PropertyInstance::ValueUnion val,
- PLY::EDataType eType);
-
- /** Buffer to hold the loaded file */
- unsigned char* mBuffer;
-
- /** Document object model representation extracted from the file */
- PLY::DOM* pcDOM;
-
- /** Mesh generated by loader */
- aiMesh* mGeneratedMesh;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/PlyParser.cpp b/src/3rdparty/assimp/code/PlyParser.cpp
deleted file mode 100644
index 6321821d2..000000000
--- a/src/3rdparty/assimp/code/PlyParser.cpp
+++ /dev/null
@@ -1,1121 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the PLY parser class */
-
-
-#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
-
-#include "fast_atof.h"
-#include <assimp/DefaultLogger.hpp>
-#include "ByteSwapper.h"
-#include "PlyLoader.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-PLY::EDataType PLY::Property::ParseDataType(std::vector<char> &buffer) {
- ai_assert(!buffer.empty());
-
- PLY::EDataType eOut = PLY::EDT_INVALID;
-
- if (PLY::DOM::TokenMatch(buffer, "char", 4) ||
- PLY::DOM::TokenMatch(buffer, "int8", 4))
- {
- eOut = PLY::EDT_Char;
- }
- else if (PLY::DOM::TokenMatch(buffer, "uchar", 5) ||
- PLY::DOM::TokenMatch(buffer, "uint8", 5))
- {
- eOut = PLY::EDT_UChar;
- }
- else if (PLY::DOM::TokenMatch(buffer, "short", 5) ||
- PLY::DOM::TokenMatch(buffer, "int16", 5))
- {
- eOut = PLY::EDT_Short;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ushort", 6) ||
- PLY::DOM::TokenMatch(buffer, "uint16", 6))
- {
- eOut = PLY::EDT_UShort;
- }
- else if (PLY::DOM::TokenMatch(buffer, "int32", 5) || PLY::DOM::TokenMatch(buffer, "int", 3))
- {
- eOut = PLY::EDT_Int;
- }
- else if (PLY::DOM::TokenMatch(buffer, "uint32", 6) || PLY::DOM::TokenMatch(buffer, "uint", 4))
- {
- eOut = PLY::EDT_UInt;
- }
- else if (PLY::DOM::TokenMatch(buffer, "float", 5) || PLY::DOM::TokenMatch(buffer, "float32", 7))
- {
- eOut = PLY::EDT_Float;
- }
- else if (PLY::DOM::TokenMatch(buffer, "double64", 8) || PLY::DOM::TokenMatch(buffer, "double", 6) ||
- PLY::DOM::TokenMatch(buffer, "float64", 7))
- {
- eOut = PLY::EDT_Double;
- }
- if (PLY::EDT_INVALID == eOut)
- {
- DefaultLogger::get()->info("Found unknown data type in PLY file. This is OK");
- }
-
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::ESemantic PLY::Property::ParseSemantic(std::vector<char> &buffer) {
- ai_assert(!buffer.empty());
-
- PLY::ESemantic eOut = PLY::EST_INVALID;
- if (PLY::DOM::TokenMatch(buffer, "red", 3)) {
- eOut = PLY::EST_Red;
- }
- else if (PLY::DOM::TokenMatch(buffer, "green", 5)) {
- eOut = PLY::EST_Green;
- }
- else if (PLY::DOM::TokenMatch(buffer, "blue", 4)) {
- eOut = PLY::EST_Blue;
- }
- else if (PLY::DOM::TokenMatch(buffer, "alpha", 5)) {
- eOut = PLY::EST_Alpha;
- }
- else if (PLY::DOM::TokenMatch(buffer, "vertex_index", 12) || PLY::DOM::TokenMatch(buffer, "vertex_indices", 14)) {
- eOut = PLY::EST_VertexIndex;
- }
- else if (PLY::DOM::TokenMatch(buffer, "texcoord", 8)) // Manage uv coords on faces
- {
- eOut = PLY::EST_TextureCoordinates;
- }
- else if (PLY::DOM::TokenMatch(buffer, "material_index", 14))
- {
- eOut = PLY::EST_MaterialIndex;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ambient_red", 11))
- {
- eOut = PLY::EST_AmbientRed;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ambient_green", 13))
- {
- eOut = PLY::EST_AmbientGreen;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ambient_blue", 12))
- {
- eOut = PLY::EST_AmbientBlue;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ambient_alpha", 13))
- {
- eOut = PLY::EST_AmbientAlpha;
- }
- else if (PLY::DOM::TokenMatch(buffer, "diffuse_red", 11))
- {
- eOut = PLY::EST_DiffuseRed;
- }
- else if (PLY::DOM::TokenMatch(buffer, "diffuse_green", 13))
- {
- eOut = PLY::EST_DiffuseGreen;
- }
- else if (PLY::DOM::TokenMatch(buffer, "diffuse_blue", 12))
- {
- eOut = PLY::EST_DiffuseBlue;
- }
- else if (PLY::DOM::TokenMatch(buffer, "diffuse_alpha", 13))
- {
- eOut = PLY::EST_DiffuseAlpha;
- }
- else if (PLY::DOM::TokenMatch(buffer, "specular_red", 12))
- {
- eOut = PLY::EST_SpecularRed;
- }
- else if (PLY::DOM::TokenMatch(buffer, "specular_green", 14))
- {
- eOut = PLY::EST_SpecularGreen;
- }
- else if (PLY::DOM::TokenMatch(buffer, "specular_blue", 13))
- {
- eOut = PLY::EST_SpecularBlue;
- }
- else if (PLY::DOM::TokenMatch(buffer, "specular_alpha", 14))
- {
- eOut = PLY::EST_SpecularAlpha;
- }
- else if (PLY::DOM::TokenMatch(buffer, "opacity", 7))
- {
- eOut = PLY::EST_Opacity;
- }
- else if (PLY::DOM::TokenMatch(buffer, "specular_power", 14))
- {
- eOut = PLY::EST_PhongPower;
- }
- else if (PLY::DOM::TokenMatch(buffer, "r", 1))
- {
- eOut = PLY::EST_Red;
- }
- else if (PLY::DOM::TokenMatch(buffer, "g", 1))
- {
- eOut = PLY::EST_Green;
- }
- else if (PLY::DOM::TokenMatch(buffer, "b", 1))
- {
- eOut = PLY::EST_Blue;
- }
-
- // NOTE: Blender3D exports texture coordinates as s,t tuples
- else if (PLY::DOM::TokenMatch(buffer, "u", 1) || PLY::DOM::TokenMatch(buffer, "s", 1) || PLY::DOM::TokenMatch(buffer, "tx", 2) || PLY::DOM::TokenMatch(buffer, "texture_u", 9))
- {
- eOut = PLY::EST_UTextureCoord;
- }
- else if (PLY::DOM::TokenMatch(buffer, "v", 1) || PLY::DOM::TokenMatch(buffer, "t", 1) || PLY::DOM::TokenMatch(buffer, "ty", 2) || PLY::DOM::TokenMatch(buffer, "texture_v", 9))
- {
- eOut = PLY::EST_VTextureCoord;
- }
- else if (PLY::DOM::TokenMatch(buffer, "x", 1))
- {
- eOut = PLY::EST_XCoord;
- }
- else if (PLY::DOM::TokenMatch(buffer, "y", 1)) {
- eOut = PLY::EST_YCoord;
- }
- else if (PLY::DOM::TokenMatch(buffer, "z", 1)) {
- eOut = PLY::EST_ZCoord;
- }
- else if (PLY::DOM::TokenMatch(buffer, "nx", 2)) {
- eOut = PLY::EST_XNormal;
- }
- else if (PLY::DOM::TokenMatch(buffer, "ny", 2)) {
- eOut = PLY::EST_YNormal;
- }
- else if (PLY::DOM::TokenMatch(buffer, "nz", 2)) {
- eOut = PLY::EST_ZNormal;
- }
- else {
- DefaultLogger::get()->info("Found unknown property semantic in file. This is ok");
- PLY::DOM::SkipLine(buffer);
- }
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::Property::ParseProperty(std::vector<char> &buffer, PLY::Property* pOut)
-{
- ai_assert(!buffer.empty());
-
- // Forms supported:
- // "property float x"
- // "property list uchar int vertex_index"
-
- // skip leading spaces
- if (!PLY::DOM::SkipSpaces(buffer)) {
- return false;
- }
-
- // skip the "property" string at the beginning
- if (!PLY::DOM::TokenMatch(buffer, "property", 8))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!PLY::DOM::SkipSpaces(buffer)) {
- return false;
- }
- if (PLY::DOM::TokenMatch(buffer, "list", 4))
- {
- pOut->bIsList = true;
-
- // seems to be a list.
- if (EDT_INVALID == (pOut->eFirstType = PLY::Property::ParseDataType(buffer)))
- {
- // unable to parse list size data type
- PLY::DOM::SkipLine(buffer);
- return false;
- }
- if (!PLY::DOM::SkipSpaces(buffer))return false;
- if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer)))
- {
- // unable to parse list data type
- PLY::DOM::SkipLine(buffer);
- return false;
- }
- }
- else
- {
- if (EDT_INVALID == (pOut->eType = PLY::Property::ParseDataType(buffer)))
- {
- // unable to parse data type. Skip the property
- PLY::DOM::SkipLine(buffer);
- return false;
- }
- }
-
- if (!PLY::DOM::SkipSpaces(buffer))
- return false;
-
- pOut->Semantic = PLY::Property::ParseSemantic(buffer);
-
- if (PLY::EST_INVALID == pOut->Semantic)
- {
- DefaultLogger::get()->info("Found unknown semantic in PLY file. This is OK");
- std::string(&buffer[0], &buffer[0] + strlen(&buffer[0]));
- }
-
- PLY::DOM::SkipSpacesAndLineEnd(buffer);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::EElementSemantic PLY::Element::ParseSemantic(std::vector<char> &buffer)
-{
- ai_assert(!buffer.empty());
-
- PLY::EElementSemantic eOut = PLY::EEST_INVALID;
- if (PLY::DOM::TokenMatch(buffer, "vertex", 6))
- {
- eOut = PLY::EEST_Vertex;
- }
- else if (PLY::DOM::TokenMatch(buffer, "face", 4))
- {
- eOut = PLY::EEST_Face;
- }
- else if (PLY::DOM::TokenMatch(buffer, "tristrips", 9))
- {
- eOut = PLY::EEST_TriStrip;
- }
-#if 0
- // TODO: maybe implement this?
- else if (PLY::DOM::TokenMatch(buffer,"range_grid",10))
- {
- eOut = PLY::EEST_Face;
- }
-#endif
- else if (PLY::DOM::TokenMatch(buffer, "edge", 4))
- {
- eOut = PLY::EEST_Edge;
- }
- else if (PLY::DOM::TokenMatch(buffer, "material", 8))
- {
- eOut = PLY::EEST_Material;
- }
- else if (PLY::DOM::TokenMatch(buffer, "TextureFile", 11))
- {
- eOut = PLY::EEST_TextureFile;
- }
-
- return eOut;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::Element::ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLY::Element* pOut)
-{
- ai_assert(NULL != pOut);
- // Example format: "element vertex 8"
-
- // skip leading spaces
- if (!PLY::DOM::SkipSpaces(buffer))
- {
- return false;
- }
-
- // skip the "element" string at the beginning
- if (!PLY::DOM::TokenMatch(buffer, "element", 7) && !PLY::DOM::TokenMatch(buffer, "comment", 7))
- {
- // seems not to be a valid property entry
- return false;
- }
- // get next word
- if (!PLY::DOM::SkipSpaces(buffer))
- return false;
-
- // parse the semantic of the element
- pOut->eSemantic = PLY::Element::ParseSemantic(buffer);
- if (PLY::EEST_INVALID == pOut->eSemantic)
- {
- // if the exact semantic can't be determined, just store
- // the original string identifier
- pOut->szName = std::string(&buffer[0], &buffer[0] + strlen(&buffer[0]));
- }
-
- if (!PLY::DOM::SkipSpaces(buffer))
- return false;
-
- if (PLY::EEST_TextureFile == pOut->eSemantic)
- {
- char* endPos = &buffer[0] + (strlen(&buffer[0]) - 1);
- pOut->szName = std::string(&buffer[0], endPos);
-
- // go to the next line
- PLY::DOM::SkipSpacesAndLineEnd(buffer);
-
- return true;
- }
-
- //parse the number of occurrences of this element
- const char* pCur = (char*)&buffer[0];
- pOut->NumOccur = strtoul10(pCur, &pCur);
-
- // go to the next line
- PLY::DOM::SkipSpacesAndLineEnd(buffer);
-
- // now parse all properties of the element
- while (true)
- {
- streamBuffer.getNextLine(buffer);
- pCur = (char*)&buffer[0];
-
- // skip all comments
- PLY::DOM::SkipComments(buffer);
-
- PLY::Property prop;
- if (!PLY::Property::ParseProperty(buffer, &prop))
- break;
-
- pOut->alProperties.push_back(prop);
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::SkipSpaces(std::vector<char> &buffer)
-{
- const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
- bool ret = false;
- if (pCur)
- {
- const char* szCur = pCur;
- ret = Assimp::SkipSpaces(pCur, &pCur);
-
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- buffer.erase(buffer.begin(), buffer.begin() + iDiff);
- return ret;
- }
-
- return ret;
-}
-
-bool PLY::DOM::SkipLine(std::vector<char> &buffer)
-{
- const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
- bool ret = false;
- if (pCur)
- {
- const char* szCur = pCur;
- ret = Assimp::SkipLine(pCur, &pCur);
-
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- buffer.erase(buffer.begin(), buffer.begin() + iDiff);
- return ret;
- }
-
- return ret;
-}
-
-bool PLY::DOM::TokenMatch(std::vector<char> &buffer, const char* token, unsigned int len)
-{
- const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
- bool ret = false;
- if (pCur)
- {
- const char* szCur = pCur;
- ret = Assimp::TokenMatch(pCur, token, len);
-
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- buffer.erase(buffer.begin(), buffer.begin() + iDiff);
- return ret;
- }
-
- return ret;
-}
-
-bool PLY::DOM::SkipSpacesAndLineEnd(std::vector<char> &buffer)
-{
- const char* pCur = buffer.empty() ? NULL : (char*)&buffer[0];
- bool ret = false;
- if (pCur)
- {
- const char* szCur = pCur;
- ret = Assimp::SkipSpacesAndLineEnd(pCur, &pCur);
-
- uintptr_t iDiff = (uintptr_t)pCur - (uintptr_t)szCur;
- buffer.erase(buffer.begin(), buffer.begin() + iDiff);
- return ret;
- }
-
- return ret;
-}
-
-bool PLY::DOM::SkipComments(std::vector<char> &buffer)
-{
- ai_assert(!buffer.empty());
-
- std::vector<char> nbuffer = buffer;
- // skip spaces
- if (!SkipSpaces(nbuffer)) {
- return false;
- }
-
- if (TokenMatch(nbuffer, "comment", 7))
- {
- if (!SkipSpaces(nbuffer))
- SkipLine(nbuffer);
-
- if (!TokenMatch(nbuffer, "TextureFile", 11))
- {
- SkipLine(nbuffer);
- buffer = nbuffer;
- return true;
- }
-
- return true;
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool isBinary) {
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() begin");
-
- // parse all elements
- while (!buffer.empty())
- {
- // skip all comments
- PLY::DOM::SkipComments(buffer);
-
- PLY::Element out;
- if (PLY::Element::ParseElement(streamBuffer, buffer, &out))
- {
- // add the element to the list of elements
- alElements.push_back(out);
- }
- else if (TokenMatch(buffer, "end_header", 10))
- {
- // we have reached the end of the header
- break;
- }
- else
- {
- // ignore unknown header elements
- streamBuffer.getNextLine(buffer);
- }
- }
-
- if (!isBinary) // it would occur an error, if binary data start with values as space or line end.
- SkipSpacesAndLineEnd(buffer);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseHeader() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter* loader)
-{
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() begin");
- alElementData.resize(alElements.size());
-
- std::vector<PLY::Element>::const_iterator i = alElements.begin();
- std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
-
- // parse all element instances
- //construct vertices and faces
- for (; i != alElements.end(); ++i, ++a)
- {
- if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip)
- {
- PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), NULL, loader);
- }
- else
- {
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceList(streamBuffer, buffer, &(*i), &(*a), NULL);
- }
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceLists() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur,
- unsigned int &bufferSize,
- PLYImporter* loader,
- bool p_bBE)
-{
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() begin");
- alElementData.resize(alElements.size());
-
- std::vector<PLY::Element>::const_iterator i = alElements.begin();
- std::vector<PLY::ElementInstanceList>::iterator a = alElementData.begin();
-
- // parse all element instances
- for (; i != alElements.end(); ++i, ++a)
- {
- if ((*i).eSemantic == EEST_Vertex || (*i).eSemantic == EEST_Face || (*i).eSemantic == EEST_TriStrip)
- {
- PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), NULL, loader, p_bBE);
- }
- else
- {
- (*a).alInstances.resize((*i).NumOccur);
- PLY::ElementInstanceList::ParseInstanceListBinary(streamBuffer, buffer, pCur, bufferSize, &(*i), &(*a), NULL, p_bBE);
- }
- }
-
- DefaultLogger::get()->debug("PLY::DOM::ParseElementInstanceListsBinary() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE)
-{
- ai_assert(NULL != p_pcOut);
- ai_assert(NULL != loader);
-
- std::vector<char> buffer;
- streamBuffer.getNextLine(buffer);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() begin");
-
- if (!p_pcOut->ParseHeader(streamBuffer, buffer, true))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
-
- streamBuffer.getNextBlock(buffer);
- unsigned int bufferSize = static_cast<unsigned int>(buffer.size());
- const char* pCur = (char*)&buffer[0];
- if (!p_pcOut->ParseElementInstanceListsBinary(streamBuffer, buffer, pCur, bufferSize, loader, p_bBE))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstanceBinary() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::DOM::ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader)
-{
- ai_assert(NULL != p_pcOut);
- ai_assert(NULL != loader);
-
- std::vector<char> buffer;
- streamBuffer.getNextLine(buffer);
-
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() begin");
-
- if (!p_pcOut->ParseHeader(streamBuffer, buffer, false))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
-
- //get next line after header
- streamBuffer.getNextLine(buffer);
- if (!p_pcOut->ParseElementInstanceLists(streamBuffer, buffer, loader))
- {
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() failure");
- return false;
- }
- DefaultLogger::get()->debug("PLY::DOM::ParseInstance() succeeded");
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceList(
- IOStreamBuffer<char> &streamBuffer,
- std::vector<char> &buffer,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut,
- PLYImporter* loader)
-{
- ai_assert(NULL != pcElement);
-
- // parse all elements
- if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
- {
- // if the element has an unknown semantic we can skip all lines
- // However, there could be comments
- for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
- {
- PLY::DOM::SkipComments(buffer);
- PLY::DOM::SkipLine(buffer);
- streamBuffer.getNextLine(buffer);
- }
- }
- else
- {
- const char* pCur = (const char*)&buffer[0];
- // be sure to have enough storage
- for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
- {
- if (p_pcOut)
- PLY::ElementInstance::ParseInstance(pCur, pcElement, &p_pcOut->alInstances[i]);
- else
- {
- ElementInstance elt;
- PLY::ElementInstance::ParseInstance(pCur, pcElement, &elt);
-
- // Create vertex or face
- if (pcElement->eSemantic == EEST_Vertex)
- {
- //call loader instance from here
- loader->LoadVertex(pcElement, &elt, i);
- }
- else if (pcElement->eSemantic == EEST_Face)
- {
- //call loader instance from here
- loader->LoadFace(pcElement, &elt, i);
- }
- else if (pcElement->eSemantic == EEST_TriStrip)
- {
- //call loader instance from here
- loader->LoadFace(pcElement, &elt, i);
- }
- }
-
- streamBuffer.getNextLine(buffer);
- pCur = (buffer.empty()) ? NULL : (const char*)&buffer[0];
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstanceList::ParseInstanceListBinary(
- IOStreamBuffer<char> &streamBuffer,
- std::vector<char> &buffer,
- const char* &pCur,
- unsigned int &bufferSize,
- const PLY::Element* pcElement,
- PLY::ElementInstanceList* p_pcOut,
- PLYImporter* loader,
- bool p_bBE /* = false */)
-{
- ai_assert(NULL != pcElement);
-
- // we can add special handling code for unknown element semantics since
- // we can't skip it as a whole block (we don't know its exact size
- // due to the fact that lists could be contained in the property list
- // of the unknown element)
- for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
- {
- if (p_pcOut)
- PLY::ElementInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, pcElement, &p_pcOut->alInstances[i], p_bBE);
- else
- {
- ElementInstance elt;
- PLY::ElementInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, pcElement, &elt, p_bBE);
-
- // Create vertex or face
- if (pcElement->eSemantic == EEST_Vertex)
- {
- //call loader instance from here
- loader->LoadVertex(pcElement, &elt, i);
- }
- else if (pcElement->eSemantic == EEST_Face)
- {
- //call loader instance from here
- loader->LoadFace(pcElement, &elt, i);
- }
- else if (pcElement->eSemantic == EEST_TriStrip)
- {
- //call loader instance from here
- loader->LoadFace(pcElement, &elt, i);
- }
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstance(const char* &pCur,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut)
-{
- ai_assert(NULL != pcElement);
- ai_assert(NULL != p_pcOut);
-
- // allocate enough storage
- p_pcOut->alProperties.resize(pcElement->alProperties.size());
-
- std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
- std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- for (; i != p_pcOut->alProperties.end(); ++i, ++a)
- {
- if (!(PLY::PropertyInstance::ParseInstance(pCur, &(*a), &(*i))))
- {
- DefaultLogger::get()->warn("Unable to parse property instance. "
- "Skipping this element instance");
-
- PLY::PropertyInstance::ValueUnion v = PLY::PropertyInstance::DefaultValue((*a).eType);
- (*i).avList.push_back(v);
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::ElementInstance::ParseInstanceBinary(
- IOStreamBuffer<char> &streamBuffer,
- std::vector<char> &buffer,
- const char* &pCur,
- unsigned int &bufferSize,
- const PLY::Element* pcElement,
- PLY::ElementInstance* p_pcOut,
- bool p_bBE /* = false */)
-{
- ai_assert(NULL != pcElement);
- ai_assert(NULL != p_pcOut);
-
- // allocate enough storage
- p_pcOut->alProperties.resize(pcElement->alProperties.size());
-
- std::vector<PLY::PropertyInstance>::iterator i = p_pcOut->alProperties.begin();
- std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
- for (; i != p_pcOut->alProperties.end(); ++i, ++a)
- {
- if (!(PLY::PropertyInstance::ParseInstanceBinary(streamBuffer, buffer, pCur, bufferSize, &(*a), &(*i), p_bBE)))
- {
- DefaultLogger::get()->warn("Unable to parse binary property instance. "
- "Skipping this element instance");
-
- (*i).avList.push_back(PLY::PropertyInstance::DefaultValue((*a).eType));
- }
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseInstance(const char* &pCur,
- const PLY::Property* prop, PLY::PropertyInstance* p_pcOut)
-{
- ai_assert(NULL != prop);
- ai_assert(NULL != p_pcOut);
-
- // skip spaces at the beginning
- if (!SkipSpaces(&pCur))
- {
- return false;
- }
-
- if (prop->bIsList)
- {
- // parse the number of elements in the list
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValue(pCur, prop->eFirstType, &v);
-
- // convert to unsigned int
- unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v, prop->eFirstType);
-
- // parse all list elements
- p_pcOut->avList.resize(iNum);
- for (unsigned int i = 0; i < iNum; ++i)
- {
- if (!SkipSpaces(&pCur))
- return false;
-
- PLY::PropertyInstance::ParseValue(pCur, prop->eType, &p_pcOut->avList[i]);
- }
- }
- else
- {
- // parse the property
- PLY::PropertyInstance::ValueUnion v;
-
- PLY::PropertyInstance::ParseValue(pCur, prop->eType, &v);
- p_pcOut->avList.push_back(v);
- }
- SkipSpacesAndLineEnd(&pCur);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur,
- unsigned int &bufferSize,
- const PLY::Property* prop,
- PLY::PropertyInstance* p_pcOut,
- bool p_bBE)
-{
- ai_assert(NULL != prop);
- ai_assert(NULL != p_pcOut);
-
- // parse all elements
- if (prop->bIsList)
- {
- // parse the number of elements in the list
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eFirstType, &v, p_bBE);
-
- // convert to unsigned int
- unsigned int iNum = PLY::PropertyInstance::ConvertTo<unsigned int>(v, prop->eFirstType);
-
- // parse all list elements
- p_pcOut->avList.resize(iNum);
- for (unsigned int i = 0; i < iNum; ++i)
- {
- PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eType, &p_pcOut->avList[i], p_bBE);
- }
- }
- else
- {
- // parse the property
- PLY::PropertyInstance::ValueUnion v;
- PLY::PropertyInstance::ParseValueBinary(streamBuffer, buffer, pCur, bufferSize, prop->eType, &v, p_bBE);
- p_pcOut->avList.push_back(v);
- }
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-PLY::PropertyInstance::ValueUnion PLY::PropertyInstance::DefaultValue(PLY::EDataType eType)
-{
- PLY::PropertyInstance::ValueUnion out;
-
- switch (eType)
- {
- case EDT_Float:
- out.fFloat = 0.f;
- return out;
-
- case EDT_Double:
- out.fDouble = 0.;
- return out;
-
- default:;
- };
- out.iUInt = 0;
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseValue(const char* &pCur,
- PLY::EDataType eType,
- PLY::PropertyInstance::ValueUnion* out)
-{
- ai_assert(NULL != pCur);
- ai_assert(NULL != out);
-
- //calc element size
- bool ret = true;
- switch (eType)
- {
- case EDT_UInt:
- case EDT_UShort:
- case EDT_UChar:
-
- out->iUInt = (uint32_t)strtoul10(pCur, &pCur);
- break;
-
- case EDT_Int:
- case EDT_Short:
- case EDT_Char:
-
- out->iInt = (int32_t)strtol10(pCur, &pCur);
- break;
-
- case EDT_Float:
- // technically this should cast to float, but people tend to use float descriptors for double data
- // this is the best way to not risk losing precision on import and it doesn't hurt to do this
- ai_real f;
- pCur = fast_atoreal_move<ai_real>(pCur, f);
- out->fFloat = (ai_real)f;
- break;
-
- case EDT_Double:
- double d;
- pCur = fast_atoreal_move<double>(pCur, d);
- out->fDouble = (double)d;
- break;
-
- case EDT_INVALID:
- default:
- ret = false;
- break;
- }
-
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool PLY::PropertyInstance::ParseValueBinary(IOStreamBuffer<char> &streamBuffer,
- std::vector<char> &buffer,
- const char* &pCur,
- unsigned int &bufferSize,
- PLY::EDataType eType,
- PLY::PropertyInstance::ValueUnion* out,
- bool p_bBE)
-{
- ai_assert(NULL != out);
-
- //calc element size
- unsigned int lsize = 0;
- switch (eType)
- {
- case EDT_Char:
- case EDT_UChar:
- lsize = 1;
- break;
-
- case EDT_UShort:
- case EDT_Short:
- lsize = 2;
- break;
-
- case EDT_UInt:
- case EDT_Int:
- case EDT_Float:
- lsize = 4;
- break;
-
- case EDT_Double:
- lsize = 8;
- break;
-
- case EDT_INVALID:
- default:
- break;
- }
-
- //read the next file block if needed
- if (bufferSize < lsize)
- {
- std::vector<char> nbuffer;
- if (streamBuffer.getNextBlock(nbuffer))
- {
- //concat buffer contents
- buffer = std::vector<char>(buffer.end() - bufferSize, buffer.end());
- buffer.insert(buffer.end(), nbuffer.begin(), nbuffer.end());
- nbuffer.clear();
- bufferSize = static_cast<unsigned int>(buffer.size());
- pCur = (char*)&buffer[0];
- }
- else
- {
- throw DeadlyImportError("Invalid .ply file: File corrupted");
- }
- }
-
- bool ret = true;
- switch (eType)
- {
- case EDT_UInt:
- out->iUInt = (uint32_t)*((uint32_t*)pCur);
- pCur += 4;
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap((int32_t*)&out->iUInt);
- break;
-
- case EDT_UShort:
- {
- uint16_t i = *((uint16_t*)pCur);
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap(&i);
- out->iUInt = (uint32_t)i;
- pCur += 2;
- break;
- }
-
- case EDT_UChar:
- {
- out->iUInt = (uint32_t)(*((uint8_t*)pCur));
- pCur++;
- break;
- }
-
- case EDT_Int:
- out->iInt = *((int32_t*)pCur);
- pCur += 4;
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap(&out->iInt);
- break;
-
- case EDT_Short:
- {
- int16_t i = *((int16_t*)pCur);
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap(&i);
- out->iInt = (int32_t)i;
- pCur += 2;
- break;
- }
-
- case EDT_Char:
- out->iInt = (int32_t)*((int8_t*)pCur);
- pCur++;
- break;
-
- case EDT_Float:
- {
- out->fFloat = *((float*)pCur);
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap((int32_t*)&out->fFloat);
- pCur += 4;
- break;
- }
- case EDT_Double:
- {
- out->fDouble = *((double*)pCur);
-
- // Swap endianness
- if (p_bBE)ByteSwap::Swap((int64_t*)&out->fDouble);
- pCur += 8;
- break;
- }
- default:
- ret = false;
- }
-
- bufferSize -= lsize;
-
- return ret;
-}
-
-#endif // !! ASSIMP_BUILD_NO_PLY_IMPORTER
diff --git a/src/3rdparty/assimp/code/PlyParser.h b/src/3rdparty/assimp/code/PlyParser.h
deleted file mode 100644
index b17b07341..000000000
--- a/src/3rdparty/assimp/code/PlyParser.h
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the helper data structures for importing PLY files */
-#ifndef AI_PLYFILEHELPER_H_INC
-#define AI_PLYFILEHELPER_H_INC
-
-
-#include "ParsingUtils.h"
-#include "IOStreamBuffer.h"
-#include <vector>
-
-namespace Assimp
-{
-
-//pre-declaration
-class PLYImporter;
-
-// http://local.wasp.uwa.edu.au/~pbourke/dataformats/ply/
-// http://w3.impa.br/~lvelho/outgoing/sossai/old/ViHAP_D4.4.2_PLY_format_v1.1.pdf
-// http://www.okino.com/conv/exp_ply.htm
-namespace PLY
-{
-
-// ---------------------------------------------------------------------------------
-/*
-name type number of bytes
----------------------------------------
-char character 1
-uchar unsigned character 1
-short short integer 2
-ushort unsigned short integer 2
-int integer 4
-uint unsigned integer 4
-float single-precision float 4
-double double-precision float 8
-
-int8
-int16
-uint8 ... forms are also used
-*/
-enum EDataType
-{
- EDT_Char = 0x0u,
- EDT_UChar,
- EDT_Short,
- EDT_UShort,
- EDT_Int,
- EDT_UInt,
- EDT_Float,
- EDT_Double,
-
- // Marks invalid entries
- EDT_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Specifies semantics for PLY element properties
- *
- * Semantics define the usage of a property, e.g. x coordinate
-*/
-enum ESemantic
-{
- //! vertex position x coordinate
- EST_XCoord = 0x0u,
- //! vertex position x coordinate
- EST_YCoord,
- //! vertex position x coordinate
- EST_ZCoord,
-
- //! vertex normal x coordinate
- EST_XNormal,
- //! vertex normal y coordinate
- EST_YNormal,
- //! vertex normal z coordinate
- EST_ZNormal,
-
- //! u texture coordinate
- EST_UTextureCoord,
- //! v texture coordinate
- EST_VTextureCoord,
-
- //! vertex colors, red channel
- EST_Red,
- //! vertex colors, green channel
- EST_Green,
- //! vertex colors, blue channel
- EST_Blue,
- //! vertex colors, alpha channel
- EST_Alpha,
-
- //! vertex index list
- EST_VertexIndex,
-
- //! texture index
- EST_TextureIndex,
-
- //! texture coordinates (stored as element of a face)
- EST_TextureCoordinates,
-
- //! material index
- EST_MaterialIndex,
-
- //! ambient color, red channel
- EST_AmbientRed,
- //! ambient color, green channel
- EST_AmbientGreen,
- //! ambient color, blue channel
- EST_AmbientBlue,
- //! ambient color, alpha channel
- EST_AmbientAlpha,
-
- //! diffuse color, red channel
- EST_DiffuseRed,
- //! diffuse color, green channel
- EST_DiffuseGreen,
- //! diffuse color, blue channel
- EST_DiffuseBlue,
- //! diffuse color, alpha channel
- EST_DiffuseAlpha,
-
- //! specular color, red channel
- EST_SpecularRed,
- //! specular color, green channel
- EST_SpecularGreen,
- //! specular color, blue channel
- EST_SpecularBlue,
- //! specular color, alpha channel
- EST_SpecularAlpha,
-
- //! specular power for phong shading
- EST_PhongPower,
-
- //! opacity between 0 and 1
- EST_Opacity,
-
- //! Marks invalid entries
- EST_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Specifies semantics for PLY elements
- *
- * Semantics define the usage of an element, e.g. vertex or material
-*/
-enum EElementSemantic
-{
- //! The element is a vertex
- EEST_Vertex = 0x0u,
-
- //! The element is a face description (index table)
- EEST_Face,
-
- //! The element is a tristrip description (index table)
- EEST_TriStrip,
-
- //! The element is an edge description (ignored)
- EEST_Edge,
-
- //! The element is a material description
- EEST_Material,
-
- //! texture path
- EEST_TextureFile,
-
- //! Marks invalid entries
- EEST_INVALID
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Helper class for a property in a PLY file.
- *
- * This can e.g. be a part of the vertex declaration
- */
-class Property
-{
-public:
-
- //! Default constructor
- Property()
- : eType (EDT_Int),
- Semantic(),
- bIsList(false),
- eFirstType(EDT_UChar)
- {}
-
- //! Data type of the property
- EDataType eType;
-
- //! Semantical meaning of the property
- ESemantic Semantic;
-
- //! Of the semantic of the property could not be parsed:
- //! Contains the semantic specified in the file
- std::string szName;
-
- //! Specifies whether the data type is a list where
- //! the first element specifies the size of the list
- bool bIsList;
- EDataType eFirstType;
-
- // -------------------------------------------------------------------
- //! Parse a property from a string. The end of the
- //! string is either '\n', '\r' or '\0'. Return value is false
- //! if the input string is NOT a valid property (E.g. does
- //! not start with the "property" keyword)
- static bool ParseProperty(std::vector<char> &buffer, Property* pOut);
-
- // -------------------------------------------------------------------
- //! Parse a data type from a string
- static EDataType ParseDataType(std::vector<char> &buffer);
-
- // -------------------------------------------------------------------
- //! Parse a semantic from a string
- static ESemantic ParseSemantic(std::vector<char> &buffer);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Helper class for an element in a PLY file.
- *
- * This can e.g. be the vertex declaration. Elements contain a
- * well-defined number of properties.
- */
-class Element
-{
-public:
-
- //! Default constructor
- Element()
- : eSemantic (EEST_INVALID)
- , NumOccur(0)
- {}
-
- //! List of properties assigned to the element
- //! std::vector to support operator[]
- std::vector<Property> alProperties;
-
- //! Semantic of the element
- EElementSemantic eSemantic;
-
- //! Of the semantic of the element could not be parsed:
- //! Contains the semantic specified in the file
- std::string szName;
-
- //! How many times will the element occur?
- unsigned int NumOccur;
-
-
- // -------------------------------------------------------------------
- //! Parse an element from a string.
- //! The function will parse all properties contained in the
- //! element, too.
- static bool ParseElement(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, Element* pOut);
-
- // -------------------------------------------------------------------
- //! Parse a semantic from a string
- static EElementSemantic ParseSemantic(std::vector<char> &buffer);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Instance of a property in a PLY file
- */
-class PropertyInstance
-{
-public:
-
- //! Default constructor
- PropertyInstance ()
- {}
-
- union ValueUnion
- {
-
- //! uInt32 representation of the property. All
- // uint types are automatically converted to uint32
- uint32_t iUInt;
-
- //! Int32 representation of the property. All
- // int types are automatically converted to int32
- int32_t iInt;
-
- //! Float32 representation of the property
- float fFloat;
-
- //! Float64 representation of the property
- double fDouble;
-
- };
-
- // -------------------------------------------------------------------
- //! List of all values parsed. Contains only one value
- // for non-list properties
- std::vector<ValueUnion> avList;
-
- // -------------------------------------------------------------------
- //! Parse a property instance
- static bool ParseInstance(const char* &pCur,
- const Property* prop, PropertyInstance* p_pcOut);
-
- // -------------------------------------------------------------------
- //! Parse a property instance in binary format
- static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur, unsigned int &bufferSize, const Property* prop, PropertyInstance* p_pcOut, bool p_bBE);
-
- // -------------------------------------------------------------------
- //! Get the default value for a given data type
- static ValueUnion DefaultValue(EDataType eType);
-
- // -------------------------------------------------------------------
- //! Parse a value
- static bool ParseValue(const char* &pCur, EDataType eType, ValueUnion* out);
-
- // -------------------------------------------------------------------
- //! Parse a binary value
- static bool ParseValueBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur, unsigned int &bufferSize, EDataType eType, ValueUnion* out, bool p_bBE);
-
- // -------------------------------------------------------------------
- //! Convert a property value to a given type TYPE
- template <typename TYPE>
- static TYPE ConvertTo(ValueUnion v, EDataType eType);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Class for an element instance in a PLY file
- */
-class ElementInstance
-{
-public:
-
- //! Default constructor
- ElementInstance ()
- {}
-
- //! List of all parsed properties
- std::vector< PropertyInstance > alProperties;
-
- // -------------------------------------------------------------------
- //! Parse an element instance
- static bool ParseInstance(const char* &pCur,
- const Element* pcElement, ElementInstance* p_pcOut);
-
- // -------------------------------------------------------------------
- //! Parse a binary element instance
- static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstance* p_pcOut, bool p_bBE);
-};
-
-// ---------------------------------------------------------------------------------
-/** \brief Class for an element instance list in a PLY file
- */
-class ElementInstanceList
-{
-public:
-
- //! Default constructor
- ElementInstanceList ()
- {}
-
- //! List of all element instances
- std::vector< ElementInstance > alInstances;
-
- // -------------------------------------------------------------------
- //! Parse an element instance list
- static bool ParseInstanceList(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader);
-
- // -------------------------------------------------------------------
- //! Parse a binary element instance list
- static bool ParseInstanceListBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer,
- const char* &pCur, unsigned int &bufferSize, const Element* pcElement, ElementInstanceList* p_pcOut, PLYImporter* loader, bool p_bBE);
-};
-// ---------------------------------------------------------------------------------
-/** \brief Class to represent the document object model of an ASCII or binary
- * (both little and big-endian) PLY file
- */
-class DOM
-{
-public:
-
- //! Default constructor
- DOM()
- {}
-
-
- //! Contains all elements of the file format
- std::vector<Element> alElements;
- //! Contains the real data of each element's instance list
- std::vector<ElementInstanceList> alElementData;
-
- //! Parse the DOM for a PLY file. The input string is assumed
- //! to be terminated with zero
- static bool ParseInstance(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader);
- static bool ParseInstanceBinary(IOStreamBuffer<char> &streamBuffer, DOM* p_pcOut, PLYImporter* loader, bool p_bBE);
-
- //! Skip all comment lines after this
- static bool SkipComments(std::vector<char> &buffer);
-
- static bool SkipSpaces(std::vector<char> &buffer);
-
- static bool SkipLine(std::vector<char> &buffer);
-
- static bool TokenMatch(std::vector<char> &buffer, const char* token, unsigned int len);
-
- static bool SkipSpacesAndLineEnd(std::vector<char> &buffer);
-
-private:
-
- // -------------------------------------------------------------------
- //! Handle the file header and read all element descriptions
- bool ParseHeader(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, bool p_bBE);
-
- // -------------------------------------------------------------------
- //! Read in all element instance lists
- bool ParseElementInstanceLists(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, PLYImporter* loader);
-
- // -------------------------------------------------------------------
- //! Read in all element instance lists for a binary file format
- bool ParseElementInstanceListsBinary(IOStreamBuffer<char> &streamBuffer, std::vector<char> &buffer, const char* &pCur, unsigned int &bufferSize, PLYImporter* loader, bool p_bBE);
-};
-
-// ---------------------------------------------------------------------------------
-template <typename TYPE>
-inline TYPE PLY::PropertyInstance::ConvertTo(
- PLY::PropertyInstance::ValueUnion v, PLY::EDataType eType)
-{
- switch (eType)
- {
- case EDT_Float:
- return (TYPE)v.fFloat;
- case EDT_Double:
- return (TYPE)v.fDouble;
-
- case EDT_UInt:
- case EDT_UShort:
- case EDT_UChar:
- return (TYPE)v.iUInt;
-
- case EDT_Int:
- case EDT_Short:
- case EDT_Char:
- return (TYPE)v.iInt;
- default: ;
- };
- return (TYPE)0;
-}
-
-} // Namespace PLY
-} // Namespace AssImp
-
-#endif // !! include guard
diff --git a/src/3rdparty/assimp/code/PolyTools.h b/src/3rdparty/assimp/code/PolyTools.h
deleted file mode 100644
index 1089327ae..000000000
--- a/src/3rdparty/assimp/code/PolyTools.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PolyTools.h, various utilities for our dealings with arbitrary polygons */
-
-#ifndef AI_POLYTOOLS_H_INCLUDED
-#define AI_POLYTOOLS_H_INCLUDED
-
-#include <assimp/material.h>
-#include <assimp/ai_assert.h>
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-/** Compute the signed area of a triangle.
- * The function accepts an unconstrained template parameter for use with
- * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
-template <typename T>
-inline double GetArea2D(const T& v1, const T& v2, const T& v3)
-{
- return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y));
-}
-
-// -------------------------------------------------------------------------------
-/** Test if a given point p2 is on the left side of the line formed by p0-p1.
- * The function accepts an unconstrained template parameter for use with
- * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
-template <typename T>
-inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
-{
- return GetArea2D(p0,p2,p1) > 0;
-}
-
-// -------------------------------------------------------------------------------
-/** Test if a given point is inside a given triangle in R2.
- * The function accepts an unconstrained template parameter for use with
- * both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
-template <typename T>
-inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp)
-{
- // Point in triangle test using baryzentric coordinates
- const aiVector2D v0 = p1 - p0;
- const aiVector2D v1 = p2 - p0;
- const aiVector2D v2 = pp - p0;
-
- double dot00 = v0 * v0;
- double dot01 = v0 * v1;
- double dot02 = v0 * v2;
- double dot11 = v1 * v1;
- double dot12 = v1 * v2;
-
- const double invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
- dot11 = (dot11 * dot02 - dot01 * dot12) * invDenom;
- dot00 = (dot00 * dot12 - dot01 * dot02) * invDenom;
-
- return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
-}
-
-
-// -------------------------------------------------------------------------------
-/** Check whether the winding order of a given polygon is counter-clockwise.
- * The function accepts an unconstrained template parameter, but is intended
- * to be used only with aiVector2D and aiVector3D (z axis is ignored, only
- * x and y are taken into account).
- * @note Code taken from http://cgm.cs.mcgill.ca/~godfried/teaching/cg-projects/97/Ian/applet1.html and translated to C++
- */
-template <typename T>
-inline bool IsCCW(T* in, size_t npoints) {
- double aa, bb, cc, b, c, theta;
- double convex_turn;
- double convex_sum = 0;
-
- ai_assert(npoints >= 3);
-
- for (size_t i = 0; i < npoints - 2; i++) {
- aa = ((in[i+2].x - in[i].x) * (in[i+2].x - in[i].x)) +
- ((-in[i+2].y + in[i].y) * (-in[i+2].y + in[i].y));
-
- bb = ((in[i+1].x - in[i].x) * (in[i+1].x - in[i].x)) +
- ((-in[i+1].y + in[i].y) * (-in[i+1].y + in[i].y));
-
- cc = ((in[i+2].x - in[i+1].x) *
- (in[i+2].x - in[i+1].x)) +
- ((-in[i+2].y + in[i+1].y) *
- (-in[i+2].y + in[i+1].y));
-
- b = std::sqrt(bb);
- c = std::sqrt(cc);
- theta = std::acos((bb + cc - aa) / (2 * b * c));
-
- if (OnLeftSideOfLine2D(in[i],in[i+2],in[i+1])) {
- // if (convex(in[i].x, in[i].y,
- // in[i+1].x, in[i+1].y,
- // in[i+2].x, in[i+2].y)) {
- convex_turn = AI_MATH_PI_F - theta;
- convex_sum += convex_turn;
- }
- else {
- convex_sum -= AI_MATH_PI_F - theta;
- }
- }
- aa = ((in[1].x - in[npoints-2].x) *
- (in[1].x - in[npoints-2].x)) +
- ((-in[1].y + in[npoints-2].y) *
- (-in[1].y + in[npoints-2].y));
-
- bb = ((in[0].x - in[npoints-2].x) *
- (in[0].x - in[npoints-2].x)) +
- ((-in[0].y + in[npoints-2].y) *
- (-in[0].y + in[npoints-2].y));
-
- cc = ((in[1].x - in[0].x) * (in[1].x - in[0].x)) +
- ((-in[1].y + in[0].y) * (-in[1].y + in[0].y));
-
- b = std::sqrt(bb);
- c = std::sqrt(cc);
- theta = std::acos((bb + cc - aa) / (2 * b * c));
-
- //if (convex(in[npoints-2].x, in[npoints-2].y,
- // in[0].x, in[0].y,
- // in[1].x, in[1].y)) {
- if (OnLeftSideOfLine2D(in[npoints-2],in[1],in[0])) {
- convex_turn = AI_MATH_PI_F - theta;
- convex_sum += convex_turn;
- }
- else {
- convex_sum -= AI_MATH_PI_F - theta;
- }
-
- return convex_sum >= (2 * AI_MATH_PI_F);
-}
-
-
-// -------------------------------------------------------------------------------
-/** Compute the normal of an arbitrary polygon in R3.
- *
- * The code is based on Newell's formula, that is a polygons normal is the ratio
- * of its area when projected onto the three coordinate axes.
- *
- * @param out Receives the output normal
- * @param num Number of input vertices
- * @param x X data source. x[ofs_x*n] is the n'th element.
- * @param y Y data source. y[ofs_y*n] is the y'th element
- * @param z Z data source. z[ofs_z*n] is the z'th element
- *
- * @note The data arrays must have storage for at least num+2 elements. Using
- * this method is much faster than the 'other' NewellNormal()
- */
-template <int ofs_x, int ofs_y, int ofs_z, typename TReal>
-inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z)
-{
- // Duplicate the first two vertices at the end
- x[(num+0)*ofs_x] = x[0];
- x[(num+1)*ofs_x] = x[ofs_x];
-
- y[(num+0)*ofs_y] = y[0];
- y[(num+1)*ofs_y] = y[ofs_y];
-
- z[(num+0)*ofs_z] = z[0];
- z[(num+1)*ofs_z] = z[ofs_z];
-
- TReal sum_xy = 0.0, sum_yz = 0.0, sum_zx = 0.0;
-
- TReal *xptr = x +ofs_x, *xlow = x, *xhigh = x + ofs_x*2;
- TReal *yptr = y +ofs_y, *ylow = y, *yhigh = y + ofs_y*2;
- TReal *zptr = z +ofs_z, *zlow = z, *zhigh = z + ofs_z*2;
-
- for (int tmp=0; tmp < num; tmp++) {
- sum_xy += (*xptr) * ( (*yhigh) - (*ylow) );
- sum_yz += (*yptr) * ( (*zhigh) - (*zlow) );
- sum_zx += (*zptr) * ( (*xhigh) - (*xlow) );
-
- xptr += ofs_x;
- xlow += ofs_x;
- xhigh += ofs_x;
-
- yptr += ofs_y;
- ylow += ofs_y;
- yhigh += ofs_y;
-
- zptr += ofs_z;
- zlow += ofs_z;
- zhigh += ofs_z;
- }
- out = aiVector3t<TReal>(sum_yz,sum_zx,sum_xy);
-}
-
-} // ! Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/PostStepRegistry.cpp b/src/3rdparty/assimp/code/PostStepRegistry.cpp
deleted file mode 100644
index c80c373e5..000000000
--- a/src/3rdparty/assimp/code/PostStepRegistry.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ImporterRegistry.cpp
-
-Central registry for all postprocessing steps available. Do not edit this file
-directly (unless you are adding new steps), instead use the
-corresponding preprocessor flag to selectively disable steps.
-*/
-
-#include "ProcessHelper.h"
-
-#ifndef ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS
-# include "CalcTangentsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_JOINVERTICES_PROCESS
-# include "JoinVerticesProcess.h"
-#endif
-#if !(defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS && defined ASSIMP_BUILD_NO_FLIPUVS_PROCESS && defined ASSIMP_BUILD_NO_FLIPWINDINGORDER_PROCESS)
-# include "ConvertToLHProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-# include "TriangulateProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS
-# include "GenFaceNormalsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS
-# include "GenVertexNormalsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_REMOVEVC_PROCESS
-# include "RemoveVCProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS
-# include "SplitLargeMeshes.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS
-# include "PretransformVertices.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS
-# include "LimitBoneWeightsProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
-# include "ValidateDataStructure.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS
-# include "ImproveCacheLocality.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FIXINFACINGNORMALS_PROCESS
-# include "FixNormalsStep.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS
-# include "RemoveRedundantMaterials.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS
-# include "FindInvalidDataProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS
-# include "FindDegenerates.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS
-# include "SortByPTypeProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
-# include "ComputeUVMappingProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
-# include "TextureTransform.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS
-# include "FindInstancesProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEMESHES_PROCESS
-# include "OptimizeMeshes.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS
-# include "OptimizeGraph.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS
-# include "SplitByBoneCountProcess.h"
-#endif
-#ifndef ASSIMP_BUILD_NO_DEBONE_PROCESS
-# include "DeboneProcess.h"
-#endif
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
-{
- // ----------------------------------------------------------------------------
- // Add an instance of each post processing step here in the order
- // of sequence it is executed. Steps that are added here are not
- // 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
-#if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
- out.push_back( new RemoveRedundantMatsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS)
- out.push_back( new FindInstancesProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
- out.push_back( new OptimizeGraphProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_FINDDEGENERATES_PROCESS)
- out.push_back( new FindDegeneratesProcess());
-#endif
-#ifndef ASSIMP_BUILD_NO_GENUVCOORDS_PROCESS
- out.push_back( new ComputeUVMappingProcess());
-#endif
-#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
- out.push_back( new TextureTransformStep());
-#endif
-#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
- out.push_back( new PretransformVertices());
-#endif
-#if (!defined ASSIMP_BUILD_NO_TRIANGULATE_PROCESS)
- out.push_back( new TriangulateProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SORTBYPTYPE_PROCESS)
- out.push_back( new SortByPTypeProcess());
-#endif
-#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
-#if (!defined ASSIMP_BUILD_NO_SPLITBYBONECOUNT_PROCESS)
- out.push_back( new SplitByBoneCountProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
- out.push_back( new SplitLargeMeshesProcess_Triangle());
-#endif
-#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
- out.push_back( new GenFaceNormalsProcess());
-#endif
-
- // .........................................................................
- // DON'T change the order of these five ..
- // XXX this is actually a design weakness that dates back to the time
- // when Importer would maintain the postprocessing step list exclusively.
- // Now that others access it too, we need a better solution.
- out.push_back( new ComputeSpatialSortProcess());
- // .........................................................................
-
-#if (!defined ASSIMP_BUILD_NO_GENVERTEXNORMALS_PROCESS)
- out.push_back( new GenVertexNormalsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_CALCTANGENTS_PROCESS)
- out.push_back( new CalcTangentsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_JOINVERTICES_PROCESS)
- out.push_back( new JoinVerticesProcess());
-#endif
-
- // .........................................................................
- out.push_back( new DestroySpatialSortProcess());
- // .........................................................................
-
-#if (!defined ASSIMP_BUILD_NO_SPLITLARGEMESHES_PROCESS)
- out.push_back( new SplitLargeMeshesProcess_Vertex());
-#endif
-#if (!defined ASSIMP_BUILD_NO_DEBONE_PROCESS)
- out.push_back( new DeboneProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_LIMITBONEWEIGHTS_PROCESS)
- out.push_back( new LimitBoneWeightsProcess());
-#endif
-#if (!defined ASSIMP_BUILD_NO_IMPROVECACHELOCALITY_PROCESS)
- out.push_back( new ImproveCacheLocalityProcess());
-#endif
-}
-
-}
diff --git a/src/3rdparty/assimp/code/PretransformVertices.cpp b/src/3rdparty/assimp/code/PretransformVertices.cpp
deleted file mode 100644
index 0751c4556..000000000
--- a/src/3rdparty/assimp/code/PretransformVertices.cpp
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PretransformVertices.cpp
- * @brief Implementation of the "PretransformVertices" post processing step
-*/
-
-
-#include "PretransformVertices.h"
-#include "ProcessHelper.h"
-#include <assimp/SceneCombiner.h>
-#include "Exceptional.h"
-
-using namespace Assimp;
-
-// some array offsets
-#define AI_PTVS_VERTEX 0x0
-#define AI_PTVS_FACE 0x1
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-PretransformVertices::PretransformVertices()
-: configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation()
-{
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-PretransformVertices::~PretransformVertices()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool PretransformVertices::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_PreTransformVertices) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import configuration
-void PretransformVertices::SetupProperties(const Importer* pImp)
-{
- // 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());
-}
-
-// ------------------------------------------------------------------------------------------------
-// Count the number of nodes
-unsigned int PretransformVertices::CountNodes( aiNode* pcNode )
-{
- unsigned int iRet = 1;
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
- {
- iRet += CountNodes(pcNode->mChildren[i]);
- }
- return iRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a bitwise combination identifying the vertex format of a mesh
-unsigned int PretransformVertices::GetMeshVFormat( aiMesh* pcMesh )
-{
- // the vertex format is stored in aiMesh::mBones for later retrieval.
- // there isn't a good reason to compute it a few hundred times
- // from scratch. The pointer is unused as animations are lost
- // during PretransformVertices.
- if (pcMesh->mBones)
- return (unsigned int)(uint64_t)pcMesh->mBones;
-
-
- const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
-
- // store the value for later use
- pcMesh->mBones = (aiBone**)(uint64_t)iRet;
- return iRet;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Count the number of vertices in the whole scene and a given
-// material index
-void PretransformVertices::CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
- unsigned int iVFormat, unsigned int* piFaces, unsigned int* piVertices)
-{
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
- if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
- {
- *piVertices += pcMesh->mNumVertices;
- *piFaces += pcMesh->mNumFaces;
- }
- }
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i)
- {
- CountVerticesAndFaces(pcScene,pcNode->mChildren[i],iMat,
- iVFormat,piFaces,piVertices);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Collect vertex/face data
-void PretransformVertices::CollectData( aiScene* pcScene, aiNode* pcNode, unsigned int iMat,
- unsigned int iVFormat, aiMesh* pcMeshOut,
- unsigned int aiCurrent[2], unsigned int* num_refs)
-{
- // No need to multiply if there's no transformation
- const bool identity = pcNode->mTransformation.IsIdentity();
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ pcNode->mMeshes[i] ];
- if (iMat == pcMesh->mMaterialIndex && iVFormat == GetMeshVFormat(pcMesh))
- {
- // Decrement mesh reference counter
- unsigned int& num_ref = num_refs[pcNode->mMeshes[i]];
- ai_assert(0 != num_ref);
- --num_ref;
- // Save the name of the last mesh
- if (num_ref==0)
- {
- pcMeshOut->mName = pcMesh->mName;
- }
-
- if (identity) {
- // copy positions without modifying them
- ::memcpy(pcMeshOut->mVertices + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mVertices,
- pcMesh->mNumVertices * sizeof(aiVector3D));
-
- if (iVFormat & 0x2) {
- // copy normals without modifying them
- ::memcpy(pcMeshOut->mNormals + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mNormals,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- }
- if (iVFormat & 0x4)
- {
- // copy tangents without modifying them
- ::memcpy(pcMeshOut->mTangents + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mTangents,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- // copy bitangents without modifying them
- ::memcpy(pcMeshOut->mBitangents + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mBitangents,
- pcMesh->mNumVertices * sizeof(aiVector3D));
- }
- }
- else
- {
- // copy positions, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mVertices[aiCurrent[AI_PTVS_VERTEX]+n] = pcNode->mTransformation * pcMesh->mVertices[n];
- }
- aiMatrix4x4 mWorldIT = pcNode->mTransformation;
- mWorldIT.Inverse().Transpose();
-
- // TODO: implement Inverse() for aiMatrix3x3
- aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
-
- if (iVFormat & 0x2)
- {
- // copy normals, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mNormals[aiCurrent[AI_PTVS_VERTEX]+n] =
- (m * pcMesh->mNormals[n]).Normalize();
- }
- }
- if (iVFormat & 0x4)
- {
- // copy tangents and bitangents, transform them to worldspace
- for (unsigned int n = 0; n < pcMesh->mNumVertices;++n) {
- pcMeshOut->mTangents [aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mTangents[n]).Normalize();
- pcMeshOut->mBitangents[aiCurrent[AI_PTVS_VERTEX]+n] = (m * pcMesh->mBitangents[n]).Normalize();
- }
- }
- }
- unsigned int p = 0;
- while (iVFormat & (0x100 << p))
- {
- // copy texture coordinates
- memcpy(pcMeshOut->mTextureCoords[p] + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mTextureCoords[p],
- pcMesh->mNumVertices * sizeof(aiVector3D));
- ++p;
- }
- p = 0;
- while (iVFormat & (0x1000000 << p))
- {
- // copy vertex colors
- memcpy(pcMeshOut->mColors[p] + aiCurrent[AI_PTVS_VERTEX],
- pcMesh->mColors[p],
- pcMesh->mNumVertices * sizeof(aiColor4D));
- ++p;
- }
- // now we need to copy all faces. since we will delete the source mesh afterwards,
- // we don't need to reallocate the array of indices except if this mesh is
- // referenced multiple times.
- for (unsigned int planck = 0;planck < pcMesh->mNumFaces;++planck)
- {
- aiFace& f_src = pcMesh->mFaces[planck];
- aiFace& f_dst = pcMeshOut->mFaces[aiCurrent[AI_PTVS_FACE]+planck];
-
- const unsigned int num_idx = f_src.mNumIndices;
-
- f_dst.mNumIndices = num_idx;
-
- unsigned int* pi;
- if (!num_ref) { /* if last time the mesh is referenced -> no reallocation */
- pi = f_dst.mIndices = f_src.mIndices;
-
- // offset all vertex indices
- for (unsigned int hahn = 0; hahn < num_idx;++hahn){
- pi[hahn] += aiCurrent[AI_PTVS_VERTEX];
- }
- }
- else {
- pi = f_dst.mIndices = new unsigned int[num_idx];
-
- // copy and offset all vertex indices
- for (unsigned int hahn = 0; hahn < num_idx;++hahn){
- pi[hahn] = f_src.mIndices[hahn] + aiCurrent[AI_PTVS_VERTEX];
- }
- }
-
- // Update the mPrimitiveTypes member of the mesh
- switch (pcMesh->mFaces[planck].mNumIndices)
- {
- case 0x1:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 0x2:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 0x3:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMeshOut->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- };
- }
- aiCurrent[AI_PTVS_VERTEX] += pcMesh->mNumVertices;
- aiCurrent[AI_PTVS_FACE] += pcMesh->mNumFaces;
- }
- }
-
- // append all children of us
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
- CollectData(pcScene,pcNode->mChildren[i],iMat,
- iVFormat,pcMeshOut,aiCurrent,num_refs);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all vertex formats that occur for a given material index
-// The output list contains duplicate elements
-void PretransformVertices::GetVFormatList( aiScene* pcScene, unsigned int iMat,
- std::list<unsigned int>& aiOut)
-{
- for (unsigned int i = 0; i < pcScene->mNumMeshes;++i)
- {
- aiMesh* pcMesh = pcScene->mMeshes[ i ];
- if (iMat == pcMesh->mMaterialIndex) {
- aiOut.push_back(GetMeshVFormat(pcMesh));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Compute the absolute transformation matrices of each node
-void PretransformVertices::ComputeAbsoluteTransform( aiNode* pcNode )
-{
- if (pcNode->mParent) {
- pcNode->mTransformation = pcNode->mParent->mTransformation*pcNode->mTransformation;
- }
-
- for (unsigned int i = 0;i < pcNode->mNumChildren;++i) {
- ComputeAbsoluteTransform(pcNode->mChildren[i]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Apply the node transformation to a mesh
-void PretransformVertices::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)
-{
- // Check whether we need to transform the coordinates at all
- if (!mat.IsIdentity()) {
-
- if (mesh->HasPositions()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mVertices[i] = mat * mesh->mVertices[i];
- }
- }
- if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
- aiMatrix4x4 mWorldIT = mat;
- mWorldIT.Inverse().Transpose();
-
- // TODO: implement Inverse() for aiMatrix3x3
- aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
-
- if (mesh->HasNormals()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
- }
- }
- if (mesh->HasTangentsAndBitangents()) {
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
- mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Simple routine to build meshes in worldspace, no further optimization
-void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
- unsigned int numIn, aiNode* node)
-{
- // NOTE:
- // aiMesh::mNumBones store original source mesh, or UINT_MAX if not a copy
- // aiMesh::mBones store reference to abs. transform we multiplied with
-
- // process meshes
- for (unsigned int i = 0; i < node->mNumMeshes;++i) {
- aiMesh* mesh = in[node->mMeshes[i]];
-
- // check whether we can operate on this mesh
- if (!mesh->mBones || *reinterpret_cast<aiMatrix4x4*>(mesh->mBones) == node->mTransformation) {
- // yes, we can.
- mesh->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
- mesh->mNumBones = UINT_MAX;
- }
- else {
-
- // try to find us in the list of newly created meshes
- for (unsigned int n = 0; n < out.size(); ++n) {
- aiMesh* ctz = out[n];
- if (ctz->mNumBones == node->mMeshes[i] && *reinterpret_cast<aiMatrix4x4*>(ctz->mBones) == node->mTransformation) {
-
- // ok, use this one. Update node mesh index
- node->mMeshes[i] = numIn + n;
- }
- }
- if (node->mMeshes[i] < numIn) {
- // Worst case. Need to operate on a full copy of the mesh
- DefaultLogger::get()->info("PretransformVertices: Copying mesh due to mismatching transforms");
- aiMesh* ntz;
-
- const unsigned int tmp = mesh->mNumBones; //
- mesh->mNumBones = 0;
- SceneCombiner::Copy(&ntz,mesh);
- mesh->mNumBones = tmp;
-
- ntz->mNumBones = node->mMeshes[i];
- ntz->mBones = reinterpret_cast<aiBone**> (&node->mTransformation);
-
- out.push_back(ntz);
-
- node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1);
- }
- }
- }
-
- // call children
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- BuildWCSMeshes(out,in,numIn,node->mChildren[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Reset transformation matrices to identity
-void PretransformVertices::MakeIdentityTransform(aiNode* nd)
-{
- nd->mTransformation = aiMatrix4x4();
-
- // call children
- for (unsigned int i = 0; i < nd->mNumChildren;++i)
- MakeIdentityTransform(nd->mChildren[i]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build reference counters for all meshes
-void PretransformVertices::BuildMeshRefCountArray(aiNode* nd, unsigned int * refs)
-{
- for (unsigned int i = 0; i< nd->mNumMeshes;++i)
- refs[nd->mMeshes[i]]++;
-
- // call children
- for (unsigned int i = 0; i < nd->mNumChildren;++i)
- BuildMeshRefCountArray(nd->mChildren[i],refs);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void PretransformVertices::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("PretransformVerticesProcess begin");
-
- // Return immediately if we have no meshes
- if (!pScene->mNumMeshes)
- return;
-
- const unsigned int iOldMeshes = pScene->mNumMeshes;
- 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);
-
- // Delete aiMesh::mBones for all meshes. The bones are
- // removed during this step and we need the pointer as
- // temporary storage
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- aiMesh* mesh = pScene->mMeshes[i];
-
- for (unsigned int a = 0; a < mesh->mNumBones;++a)
- delete mesh->mBones[a];
-
- delete[] mesh->mBones;
- mesh->mBones = NULL;
- }
-
- // now build a list of output meshes
- std::vector<aiMesh*> apcOutMeshes;
-
- // Keep scene hierarchy? It's an easy job in this case ...
- // we go on and transform all meshes, if one is referenced by nodes
- // with different absolute transformations a depth copy of the mesh
- // is required.
- if( configKeepHierarchy ) {
-
- // Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
- BuildWCSMeshes(apcOutMeshes,pScene->mMeshes,pScene->mNumMeshes, pScene->mRootNode);
-
- // ... if new meshes have been generated, append them to the end of the scene
- if (apcOutMeshes.size() > 0) {
- aiMesh** npp = new aiMesh*[pScene->mNumMeshes + apcOutMeshes.size()];
-
- memcpy(npp,pScene->mMeshes,sizeof(aiMesh*)*pScene->mNumMeshes);
- memcpy(npp+pScene->mNumMeshes,&apcOutMeshes[0],sizeof(aiMesh*)*apcOutMeshes.size());
-
- pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size());
- delete[] pScene->mMeshes; pScene->mMeshes = npp;
- }
-
- // now iterate through all meshes and transform them to worldspace
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
- ApplyTransform(pScene->mMeshes[i],*reinterpret_cast<aiMatrix4x4*>( pScene->mMeshes[i]->mBones ));
-
- // prevent improper destruction
- pScene->mMeshes[i]->mBones = NULL;
- pScene->mMeshes[i]->mNumBones = 0;
- }
- }
- else {
-
- apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
- std::list<unsigned int> aiVFormats;
-
- std::vector<unsigned int> s(pScene->mNumMeshes,0);
- BuildMeshRefCountArray(pScene->mRootNode,&s[0]);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- // get the list of all vertex formats for this material
- aiVFormats.clear();
- GetVFormatList(pScene,i,aiVFormats);
- aiVFormats.sort();
- aiVFormats.unique();
- for (std::list<unsigned int>::const_iterator j = aiVFormats.begin();j != aiVFormats.end();++j) {
- unsigned int iVertices = 0;
- unsigned int iFaces = 0;
- CountVerticesAndFaces(pScene,pScene->mRootNode,i,*j,&iFaces,&iVertices);
- if (0 != iFaces && 0 != iVertices)
- {
- apcOutMeshes.push_back(new aiMesh());
- aiMesh* pcMesh = apcOutMeshes.back();
- pcMesh->mNumFaces = iFaces;
- pcMesh->mNumVertices = iVertices;
- pcMesh->mFaces = new aiFace[iFaces];
- pcMesh->mVertices = new aiVector3D[iVertices];
- pcMesh->mMaterialIndex = i;
- if ((*j) & 0x2)pcMesh->mNormals = new aiVector3D[iVertices];
- if ((*j) & 0x4)
- {
- pcMesh->mTangents = new aiVector3D[iVertices];
- pcMesh->mBitangents = new aiVector3D[iVertices];
- }
- iFaces = 0;
- while ((*j) & (0x100 << iFaces))
- {
- pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
- if ((*j) & (0x10000 << iFaces))pcMesh->mNumUVComponents[iFaces] = 3;
- else pcMesh->mNumUVComponents[iFaces] = 2;
- iFaces++;
- }
- iFaces = 0;
- while ((*j) & (0x1000000 << iFaces))
- pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
-
- // fill the mesh ...
- unsigned int aiTemp[2] = {0,0};
- CollectData(pScene,pScene->mRootNode,i,*j,pcMesh,aiTemp,&s[0]);
- }
- }
- }
-
- // If no meshes are referenced in the node graph it is possible that we get no output meshes.
- if (apcOutMeshes.empty()) {
- throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
- }
- else
- {
- // now delete all meshes in the scene and build a new mesh list
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiMesh* mesh = pScene->mMeshes[i];
- mesh->mNumBones = 0;
- mesh->mBones = NULL;
-
- // we're reusing the face index arrays. avoid destruction
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
- mesh->mFaces[a].mNumIndices = 0;
- mesh->mFaces[a].mIndices = NULL;
- }
-
- delete mesh;
-
- // Invalidate the contents of the old mesh array. We will most
- // likely have less output meshes now, so the last entries of
- // the mesh array are not overridden. We set them to NULL to
- // make sure the developer gets notified when his application
- // attempts to access these fields ...
- mesh = NULL;
- }
-
- // It is impossible that we have more output meshes than
- // input meshes, so we can easily reuse the old mesh array
- pScene->mNumMeshes = (unsigned int)apcOutMeshes.size();
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- pScene->mMeshes[i] = apcOutMeshes[i];
- }
- }
- }
-
- // remove all animations from the scene
- for (unsigned int i = 0; i < pScene->mNumAnimations;++i)
- delete pScene->mAnimations[i];
- delete[] pScene->mAnimations;
-
- pScene->mAnimations = NULL;
- pScene->mNumAnimations = 0;
-
- // --- we need to keep all cameras and lights
- for (unsigned int i = 0; i < pScene->mNumCameras;++i)
- {
- aiCamera* cam = pScene->mCameras[i];
- const aiNode* nd = pScene->mRootNode->FindNode(cam->mName);
- ai_assert(NULL != nd);
-
- // multiply all properties of the camera with the absolute
- // transformation of the corresponding node
- cam->mPosition = nd->mTransformation * cam->mPosition;
- cam->mLookAt = aiMatrix3x3( nd->mTransformation ) * cam->mLookAt;
- cam->mUp = aiMatrix3x3( nd->mTransformation ) * cam->mUp;
- }
-
- for (unsigned int i = 0; i < pScene->mNumLights;++i)
- {
- aiLight* l = pScene->mLights[i];
- const aiNode* nd = pScene->mRootNode->FindNode(l->mName);
- ai_assert(NULL != nd);
-
- // multiply all properties of the camera with the absolute
- // transformation of the corresponding node
- l->mPosition = nd->mTransformation * l->mPosition;
- l->mDirection = aiMatrix3x3( nd->mTransformation ) * l->mDirection;
- l->mUp = aiMatrix3x3( nd->mTransformation ) * l->mUp;
- }
-
- if( !configKeepHierarchy ) {
-
- // now delete all nodes in the scene and build a new
- // flat node graph with a root node and some level 1 children
- aiNode* newRoot = new aiNode();
- newRoot->mName = pScene->mRootNode->mName;
- delete pScene->mRootNode;
- pScene->mRootNode = newRoot;
-
- if (1 == pScene->mNumMeshes && !pScene->mNumLights && !pScene->mNumCameras)
- {
- pScene->mRootNode->mNumMeshes = 1;
- pScene->mRootNode->mMeshes = new unsigned int[1];
- pScene->mRootNode->mMeshes[0] = 0;
- }
- else
- {
- pScene->mRootNode->mNumChildren = pScene->mNumMeshes+pScene->mNumLights+pScene->mNumCameras;
- aiNode** nodes = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
-
- // generate mesh nodes
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName = pScene->mMeshes[i]->mName;
-
- // setup mesh indices
- pcNode->mNumMeshes = 1;
- pcNode->mMeshes = new unsigned int[1];
- pcNode->mMeshes[0] = i;
- }
- // generate light nodes
- for (unsigned int i = 0; i < pScene->mNumLights;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "light_%u",i);
- pScene->mLights[i]->mName = pcNode->mName;
- }
- // generate camera nodes
- for (unsigned int i = 0; i < pScene->mNumCameras;++i,++nodes)
- {
- aiNode* pcNode = *nodes = new aiNode();
- pcNode->mParent = pScene->mRootNode;
- pcNode->mName.length = ::ai_snprintf(pcNode->mName.data,MAXLEN,"cam_%u",i);
- pScene->mCameras[i]->mName = pcNode->mName;
- }
- }
- }
- else {
- // ... and finally set the transformation matrix of all nodes to identity
- MakeIdentityTransform(pScene->mRootNode);
- }
-
- if (configNormalize) {
- // compute the boundary of all meshes
- aiVector3D min,max;
- MinMaxChooser<aiVector3D> ()(min,max);
-
- for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
- aiMesh* m = pScene->mMeshes[a];
- for (unsigned int i = 0; i < m->mNumVertices;++i) {
- min = std::min(m->mVertices[i],min);
- max = std::max(m->mVertices[i],max);
- }
- }
-
- // find the dominant axis
- aiVector3D d = max-min;
- const ai_real div = std::max(d.x,std::max(d.y,d.z))*ai_real( 0.5);
-
- d = min + d * (ai_real)0.5;
- for (unsigned int a = 0; a < pScene->mNumMeshes; ++a) {
- aiMesh* m = pScene->mMeshes[a];
- for (unsigned int i = 0; i < m->mNumVertices;++i) {
- m->mVertices[i] = (m->mVertices[i]-d)/div;
- }
- }
- }
-
- // print statistics
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[4096];
-
- DefaultLogger::get()->debug("PretransformVerticesProcess finished");
-
- ::ai_snprintf(buffer,4096,"Removed %u nodes and %u animation channels (%u output nodes)",
- iOldNodes,iOldAnimationChannels,CountNodes(pScene->mRootNode));
- DefaultLogger::get()->info(buffer);
-
- ai_snprintf(buffer, 4096,"Kept %u lights and %u cameras",
- pScene->mNumLights,pScene->mNumCameras);
- DefaultLogger::get()->info(buffer);
-
- ai_snprintf(buffer, 4096,"Moved %u meshes to WCS (number of output meshes: %u)",
- iOldMeshes,pScene->mNumMeshes);
- DefaultLogger::get()->info(buffer);
- }
-}
diff --git a/src/3rdparty/assimp/code/PretransformVertices.h b/src/3rdparty/assimp/code/PretransformVertices.h
deleted file mode 100644
index 65b4938b0..000000000
--- a/src/3rdparty/assimp/code/PretransformVertices.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 PretransformVertices.h
- * @brief Defines a post processing step to pretransform all
- * vertices in the scenegraph
- */
-#ifndef AI_PRETRANSFORMVERTICES_H_INC
-#define AI_PRETRANSFORMVERTICES_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-#include <list>
-#include <vector>
-
-struct aiNode;
-class PretransformVerticesTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** 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 ASSIMP_API PretransformVertices : public BaseProcess
-{
-public:
-
- PretransformVertices ();
- ~PretransformVertices ();
-
-public:
-
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Toggle the 'keep hierarchy' option
- * @param d hm ... difficult to guess what this means, hu!?
- */
- void KeepHierarchy(bool d) {
- configKeepHierarchy = d;
- }
-
- // -------------------------------------------------------------------
- /** @brief Check whether 'keep hierarchy' is currently enabled.
- * @return ...
- */
- bool IsHierarchyKept() const {
- return configKeepHierarchy;
- }
-
-private:
-
- // -------------------------------------------------------------------
- // Count the number of nodes
- unsigned int CountNodes( aiNode* pcNode );
-
- // -------------------------------------------------------------------
- // Get a bitwise combination identifying the vertex format of a mesh
- unsigned int GetMeshVFormat(aiMesh* pcMesh);
-
- // -------------------------------------------------------------------
- // Count the number of vertices in the whole scene and a given
- // material index
- void CountVerticesAndFaces( aiScene* pcScene, aiNode* pcNode,
- unsigned int iMat,
- unsigned int iVFormat,
- unsigned int* piFaces,
- unsigned int* piVertices);
-
- // -------------------------------------------------------------------
- // Collect vertex/face data
- void CollectData( aiScene* pcScene, aiNode* pcNode,
- unsigned int iMat,
- unsigned int iVFormat,
- aiMesh* pcMeshOut,
- unsigned int aiCurrent[2],
- unsigned int* num_refs);
-
- // -------------------------------------------------------------------
- // Get a list of all vertex formats that occur for a given material
- // The output list contains duplicate elements
- void GetVFormatList( aiScene* pcScene, unsigned int iMat,
- std::list<unsigned int>& aiOut);
-
- // -------------------------------------------------------------------
- // Compute the absolute transformation matrices of each node
- void ComputeAbsoluteTransform( aiNode* pcNode );
-
- // -------------------------------------------------------------------
- // Simple routine to build meshes in worldspace, no further optimization
- void BuildWCSMeshes(std::vector<aiMesh*>& out, aiMesh** in,
- unsigned int numIn, aiNode* node);
-
- // -------------------------------------------------------------------
- // Apply the node transformation to a mesh
- void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat);
-
- // -------------------------------------------------------------------
- // Reset transformation matrices to identity
- void MakeIdentityTransform(aiNode* nd);
-
- // -------------------------------------------------------------------
- // Build reference counters for all meshes
- void BuildMeshRefCountArray(aiNode* nd, unsigned int * refs);
-
-
-
- //! Configuration option: keep scene hierarchy as long as possible
- bool configKeepHierarchy;
- bool configNormalize;
- bool configTransform;
- aiMatrix4x4 configTransformation;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_GENFACENORMALPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/ProcessHelper.cpp b/src/3rdparty/assimp/code/ProcessHelper.cpp
deleted file mode 100644
index c255979bd..000000000
--- a/src/3rdparty/assimp/code/ProcessHelper.cpp
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ProcessHelper.cpp
-/** Implement shared utility functions for postprocessing steps */
-
-
-#include "ProcessHelper.h"
-
-
-#include <limits>
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
-{
- const char* s = in.c_str();
- while (*s) {
- SkipSpacesAndLineEnd(&s);
- if (*s == '\'') {
- const char* base = ++s;
- while (*s != '\'') {
- ++s;
- if (*s == '\0') {
- DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted");
- return;
- }
- }
- out.push_back(std::string(base,(size_t)(s-base)));
- ++s;
- }
- else {
- out.push_back(GetNextToken(s));
- }
- }
-}
-
-// -------------------------------------------------------------------------------
-void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
- const aiMatrix4x4& m)
-{
- min = aiVector3D ( ai_real( 10e10 ), ai_real( 10e10 ), ai_real( 10e10 ) );
- max = aiVector3D ( ai_real( -10e10 ), ai_real( -10e10 ), ai_real( -10e10 ) );
- for (unsigned int i = 0;i < mesh->mNumVertices;++i)
- {
- const aiVector3D v = m * mesh->mVertices[i];
- min = std::min(v,min);
- max = std::max(v,max);
- }
-}
-
-// -------------------------------------------------------------------------------
-void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max)
-{
- ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max);
- out = min + (max-min)*(ai_real)0.5;
-}
-
-// -------------------------------------------------------------------------------
-void FindSceneCenter (aiScene* scene, aiVector3D& out, aiVector3D& min, aiVector3D& max) {
- if ( NULL == scene ) {
- return;
- }
-
- if ( 0 == scene->mNumMeshes ) {
- return;
- }
- FindMeshCenter(scene->mMeshes[0], out, min, max);
- for (unsigned int i = 1; i < scene->mNumMeshes; ++i) {
- aiVector3D tout, tmin, tmax;
- FindMeshCenter(scene->mMeshes[i], tout, tmin, tmax);
- if (min[0] > tmin[0]) min[0] = tmin[0];
- if (min[1] > tmin[1]) min[1] = tmin[1];
- if (min[2] > tmin[2]) min[2] = tmin[2];
- if (max[0] < tmax[0]) max[0] = tmax[0];
- if (max[1] < tmax[1]) max[1] = tmax[1];
- if (max[2] < tmax[2]) max[2] = tmax[2];
- }
- out = min + (max-min)*(ai_real)0.5;
-}
-
-
-// -------------------------------------------------------------------------------
-void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,
- aiVector3D& max, const aiMatrix4x4& m)
-{
- FindAABBTransformed(mesh,min,max,m);
- out = min + (max-min)*(ai_real)0.5;
-}
-
-// -------------------------------------------------------------------------------
-void FindMeshCenter (aiMesh* mesh, aiVector3D& out)
-{
- aiVector3D min,max;
- FindMeshCenter(mesh,out,min,max);
-}
-
-// -------------------------------------------------------------------------------
-void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
- const aiMatrix4x4& m)
-{
- aiVector3D min,max;
- FindMeshCenterTransformed(mesh,out,min,max,m);
-}
-
-// -------------------------------------------------------------------------------
-ai_real ComputePositionEpsilon(const aiMesh* pMesh)
-{
- const ai_real epsilon = ai_real( 1e-4 );
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec, maxVec;
- ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec);
- return (maxVec - minVec).Length() * epsilon;
-}
-
-// -------------------------------------------------------------------------------
-ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
-{
- ai_assert( NULL != pMeshes );
-
- const ai_real epsilon = ai_real( 1e-4 );
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec, maxVec, mi, ma;
- MinMaxChooser<aiVector3D>()(minVec,maxVec);
-
- for (size_t a = 0; a < num; ++a) {
- const aiMesh* pMesh = pMeshes[a];
- ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma);
-
- minVec = std::min(minVec,mi);
- maxVec = std::max(maxVec,ma);
- }
- return (maxVec - minVec).Length() * epsilon;
-}
-
-
-// -------------------------------------------------------------------------------
-unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh)
-{
- ai_assert(NULL != pcMesh);
-
- // FIX: the hash may never be 0. Otherwise a comparison against
- // nullptr could be successful
- unsigned int iRet = 1;
-
- // normals
- if (pcMesh->HasNormals())iRet |= 0x2;
- // tangents and bitangents
- if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4;
-
-#ifdef BOOST_STATIC_ASSERT
- BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
- BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
-#endif
-
- // texture coordinates
- unsigned int p = 0;
- while (pcMesh->HasTextureCoords(p))
- {
- iRet |= (0x100 << p);
- if (3 == pcMesh->mNumUVComponents[p])
- iRet |= (0x10000 << p);
-
- ++p;
- }
- // vertex colors
- p = 0;
- while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++);
- return iRet;
-}
-
-// -------------------------------------------------------------------------------
-VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh)
-{
- if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
- return NULL;
- }
-
- VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
- for (unsigned int i = 0; i < pMesh->mNumBones;++i) {
-
- aiBone* bone = pMesh->mBones[i];
- for (unsigned int a = 0; a < bone->mNumWeights;++a) {
- const aiVertexWeight& weight = bone->mWeights[a];
- avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) );
- }
- }
- return avPerVertexWeights;
-}
-
-
-// -------------------------------------------------------------------------------
-const char* TextureTypeToString(aiTextureType in)
-{
- switch (in)
- {
- case aiTextureType_NONE:
- return "n/a";
- case aiTextureType_DIFFUSE:
- return "Diffuse";
- case aiTextureType_SPECULAR:
- return "Specular";
- case aiTextureType_AMBIENT:
- return "Ambient";
- case aiTextureType_EMISSIVE:
- return "Emissive";
- case aiTextureType_OPACITY:
- return "Opacity";
- case aiTextureType_NORMALS:
- return "Normals";
- case aiTextureType_HEIGHT:
- return "Height";
- case aiTextureType_SHININESS:
- return "Shininess";
- case aiTextureType_DISPLACEMENT:
- return "Displacement";
- case aiTextureType_LIGHTMAP:
- return "Lightmap";
- case aiTextureType_REFLECTION:
- return "Reflection";
- case aiTextureType_UNKNOWN:
- return "Unknown";
- default:
- break;
- }
-
- ai_assert(false);
- return "BUG";
-}
-
-// -------------------------------------------------------------------------------
-const char* MappingTypeToString(aiTextureMapping in)
-{
- switch (in)
- {
- case aiTextureMapping_UV:
- return "UV";
- case aiTextureMapping_BOX:
- return "Box";
- case aiTextureMapping_SPHERE:
- return "Sphere";
- case aiTextureMapping_CYLINDER:
- return "Cylinder";
- case aiTextureMapping_PLANE:
- return "Plane";
- case aiTextureMapping_OTHER:
- return "Other";
- default:
- break;
- }
-
- ai_assert(false);
- return "BUG";
-}
-
-
-// -------------------------------------------------------------------------------
-aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags)
-{
- aiMesh *oMesh = new aiMesh();
- std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX);
-
- size_t numSubVerts = 0;
- size_t numSubFaces = subMeshFaces.size();
-
- for(unsigned int i=0;i<numSubFaces;i++) {
- const aiFace &f = pMesh->mFaces[subMeshFaces[i]];
-
- for(unsigned int j=0;j<f.mNumIndices;j++) {
- if(vMap[f.mIndices[j]]==UINT_MAX) {
- vMap[f.mIndices[j]] = static_cast<unsigned int>(numSubVerts++);
- }
- }
- }
-
- oMesh->mName = pMesh->mName;
-
- oMesh->mMaterialIndex = pMesh->mMaterialIndex;
- oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
-
- // create all the arrays for this mesh if the old mesh contained them
-
- oMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
- oMesh->mNumVertices = static_cast<unsigned int>(numSubVerts);
- oMesh->mVertices = new aiVector3D[numSubVerts];
- if( pMesh->HasNormals() ) {
- oMesh->mNormals = new aiVector3D[numSubVerts];
- }
-
- if( pMesh->HasTangentsAndBitangents() ) {
- oMesh->mTangents = new aiVector3D[numSubVerts];
- oMesh->mBitangents = new aiVector3D[numSubVerts];
- }
-
- for( size_t a = 0; pMesh->HasTextureCoords(static_cast<unsigned int>(a)) ; ++a ) {
- oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts];
- oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
- }
-
- for( size_t a = 0; pMesh->HasVertexColors( static_cast<unsigned int>(a)); ++a ) {
- oMesh->mColors[a] = new aiColor4D[numSubVerts];
- }
-
- // and copy over the data, generating faces with linear indices along the way
- oMesh->mFaces = new aiFace[numSubFaces];
-
- for(unsigned int a = 0; a < numSubFaces; ++a ) {
-
- const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
- aiFace& dstFace = oMesh->mFaces[a];
- dstFace.mNumIndices = srcFace.mNumIndices;
- dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
-
- // accumulate linearly all the vertices of the source face
- for( size_t b = 0; b < dstFace.mNumIndices; ++b ) {
- dstFace.mIndices[b] = vMap[srcFace.mIndices[b]];
- }
- }
-
- for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) {
- unsigned int nvi = vMap[srcIndex];
- if(nvi==UINT_MAX) {
- continue;
- }
-
- oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
- if( pMesh->HasNormals() ) {
- oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
- }
-
- if( pMesh->HasTangentsAndBitangents() ) {
- oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
- oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
- }
- for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c ) {
- oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
- }
- for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c ) {
- oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
- }
- }
-
- if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES) {
- std::vector<unsigned int> subBones(pMesh->mNumBones,0);
-
- for(unsigned int a=0;a<pMesh->mNumBones;++a) {
- const aiBone* bone = pMesh->mBones[a];
-
- for(unsigned int b=0;b<bone->mNumWeights;b++) {
- unsigned int v = vMap[bone->mWeights[b].mVertexId];
-
- if(v!=UINT_MAX) {
- subBones[a]++;
- }
- }
- }
-
- for(unsigned int a=0;a<pMesh->mNumBones;++a) {
- if(subBones[a]>0) {
- oMesh->mNumBones++;
- }
- }
-
- if(oMesh->mNumBones) {
- oMesh->mBones = new aiBone*[oMesh->mNumBones]();
- unsigned int nbParanoia = oMesh->mNumBones;
-
- oMesh->mNumBones = 0; //rewind
-
- for(unsigned int a=0;a<pMesh->mNumBones;++a) {
- if(subBones[a]==0) {
- continue;
- }
- aiBone *newBone = new aiBone;
- oMesh->mBones[oMesh->mNumBones++] = newBone;
-
- const aiBone* bone = pMesh->mBones[a];
-
- newBone->mName = bone->mName;
- newBone->mOffsetMatrix = bone->mOffsetMatrix;
- newBone->mWeights = new aiVertexWeight[subBones[a]];
-
- for(unsigned int b=0;b<bone->mNumWeights;b++) {
- const unsigned int v = vMap[bone->mWeights[b].mVertexId];
-
- if(v!=UINT_MAX) {
- aiVertexWeight w(v,bone->mWeights[b].mWeight);
- newBone->mWeights[newBone->mNumWeights++] = w;
- }
- }
- }
-
- ai_assert(nbParanoia==oMesh->mNumBones);
- (void)nbParanoia; // remove compiler warning on release build
- }
- }
-
- return oMesh;
-}
-
-} // namespace Assimp
diff --git a/src/3rdparty/assimp/code/ProcessHelper.h b/src/3rdparty/assimp/code/ProcessHelper.h
deleted file mode 100644
index a49115936..000000000
--- a/src/3rdparty/assimp/code/ProcessHelper.h
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_PROCESS_HELPER_H_INCLUDED
-#define AI_PROCESS_HELPER_H_INCLUDED
-
-#include <assimp/postprocess.h>
-#include <assimp/anim.h>
-#include <assimp/mesh.h>
-#include <assimp/material.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-
-#include "SpatialSort.h"
-#include "BaseProcess.h"
-#include "ParsingUtils.h"
-
-#include <list>
-
-// -------------------------------------------------------------------------------
-// Some extensions to std namespace. Mainly std::min and std::max for all
-// flat data types in the aiScene. They're used to quickly determine the
-// min/max bounds of data arrays.
-#ifdef __cplusplus
-namespace std {
-
- // std::min for aiVector3D
- template <typename TReal>
- inline ::aiVector3t<TReal> min (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b) {
- return ::aiVector3t<TReal> (min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
- }
-
- // std::max for aiVector3t<TReal>
- template <typename TReal>
- inline ::aiVector3t<TReal> max (const ::aiVector3t<TReal>& a, const ::aiVector3t<TReal>& b) {
- return ::aiVector3t<TReal> (max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
- }
-
- // std::min for aiVector2t<TReal>
- template <typename TReal>
- inline ::aiVector2t<TReal> min (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b) {
- return ::aiVector2t<TReal> (min(a.x,b.x),min(a.y,b.y));
- }
-
- // std::max for aiVector2t<TReal>
- template <typename TReal>
- inline ::aiVector2t<TReal> max (const ::aiVector2t<TReal>& a, const ::aiVector2t<TReal>& b) {
- return ::aiVector2t<TReal> (max(a.x,b.x),max(a.y,b.y));
- }
-
- // std::min for aiColor4D
- template <typename TReal>
- inline ::aiColor4t<TReal> min (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b) {
- return ::aiColor4t<TReal> (min(a.r,b.r),min(a.g,b.g),min(a.b,b.b),min(a.a,b.a));
- }
-
- // std::max for aiColor4D
- template <typename TReal>
- inline ::aiColor4t<TReal> max (const ::aiColor4t<TReal>& a, const ::aiColor4t<TReal>& b) {
- return ::aiColor4t<TReal> (max(a.r,b.r),max(a.g,b.g),max(a.b,b.b),max(a.a,b.a));
- }
-
-
- // std::min for aiQuaterniont<TReal>
- template <typename TReal>
- inline ::aiQuaterniont<TReal> min (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b) {
- return ::aiQuaterniont<TReal> (min(a.w,b.w),min(a.x,b.x),min(a.y,b.y),min(a.z,b.z));
- }
-
- // std::max for aiQuaterniont<TReal>
- template <typename TReal>
- inline ::aiQuaterniont<TReal> max (const ::aiQuaterniont<TReal>& a, const ::aiQuaterniont<TReal>& b) {
- return ::aiQuaterniont<TReal> (max(a.w,b.w),max(a.x,b.x),max(a.y,b.y),max(a.z,b.z));
- }
-
-
-
- // std::min for aiVectorKey
- inline ::aiVectorKey min (const ::aiVectorKey& a, const ::aiVectorKey& b) {
- return ::aiVectorKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
- }
-
- // std::max for aiVectorKey
- inline ::aiVectorKey max (const ::aiVectorKey& a, const ::aiVectorKey& b) {
- return ::aiVectorKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
- }
-
- // std::min for aiQuatKey
- inline ::aiQuatKey min (const ::aiQuatKey& a, const ::aiQuatKey& b) {
- return ::aiQuatKey (min(a.mTime,b.mTime),min(a.mValue,b.mValue));
- }
-
- // std::max for aiQuatKey
- inline ::aiQuatKey max (const ::aiQuatKey& a, const ::aiQuatKey& b) {
- return ::aiQuatKey (max(a.mTime,b.mTime),max(a.mValue,b.mValue));
- }
-
- // std::min for aiVertexWeight
- inline ::aiVertexWeight min (const ::aiVertexWeight& a, const ::aiVertexWeight& b) {
- return ::aiVertexWeight (min(a.mVertexId,b.mVertexId),min(a.mWeight,b.mWeight));
- }
-
- // std::max for aiVertexWeight
- inline ::aiVertexWeight max (const ::aiVertexWeight& a, const ::aiVertexWeight& b) {
- return ::aiVertexWeight (max(a.mVertexId,b.mVertexId),max(a.mWeight,b.mWeight));
- }
-
-} // end namespace std
-#endif // !! C++
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-// Start points for ArrayBounds<T> for all supported Ts
-template <typename T>
-struct MinMaxChooser;
-
-template <> struct MinMaxChooser<float> {
- void operator ()(float& min,float& max) {
- max = -1e10f;
- min = 1e10f;
-}};
-template <> struct MinMaxChooser<double> {
- void operator ()(double& min,double& max) {
- max = -1e10;
- min = 1e10;
-}};
-template <> struct MinMaxChooser<unsigned int> {
- void operator ()(unsigned int& min,unsigned int& max) {
- max = 0;
- min = (1u<<(sizeof(unsigned int)*8-1));
-}};
-
-template <typename T> struct MinMaxChooser< aiVector3t<T> > {
- void operator ()(aiVector3t<T>& min,aiVector3t<T>& max) {
- max = aiVector3t<T>(-1e10f,-1e10f,-1e10f);
- min = aiVector3t<T>( 1e10f, 1e10f, 1e10f);
-}};
-template <typename T> struct MinMaxChooser< aiVector2t<T> > {
- void operator ()(aiVector2t<T>& min,aiVector2t<T>& max) {
- max = aiVector2t<T>(-1e10f,-1e10f);
- min = aiVector2t<T>( 1e10f, 1e10f);
- }};
-template <typename T> struct MinMaxChooser< aiColor4t<T> > {
- void operator ()(aiColor4t<T>& min,aiColor4t<T>& max) {
- max = aiColor4t<T>(-1e10f,-1e10f,-1e10f,-1e10f);
- min = aiColor4t<T>( 1e10f, 1e10f, 1e10f, 1e10f);
-}};
-
-template <typename T> struct MinMaxChooser< aiQuaterniont<T> > {
- void operator ()(aiQuaterniont<T>& min,aiQuaterniont<T>& max) {
- max = aiQuaterniont<T>(-1e10f,-1e10f,-1e10f,-1e10f);
- min = aiQuaterniont<T>( 1e10f, 1e10f, 1e10f, 1e10f);
-}};
-
-template <> struct MinMaxChooser<aiVectorKey> {
- void operator ()(aiVectorKey& min,aiVectorKey& max) {
- MinMaxChooser<double>()(min.mTime,max.mTime);
- MinMaxChooser<aiVector3D>()(min.mValue,max.mValue);
-}};
-template <> struct MinMaxChooser<aiQuatKey> {
- void operator ()(aiQuatKey& min,aiQuatKey& max) {
- MinMaxChooser<double>()(min.mTime,max.mTime);
- MinMaxChooser<aiQuaternion>()(min.mValue,max.mValue);
-}};
-
-template <> struct MinMaxChooser<aiVertexWeight> {
- void operator ()(aiVertexWeight& min,aiVertexWeight& max) {
- MinMaxChooser<unsigned int>()(min.mVertexId,max.mVertexId);
- MinMaxChooser<float>()(min.mWeight,max.mWeight);
-}};
-
-// -------------------------------------------------------------------------------
-/** @brief Find the min/max values of an array of Ts
- * @param in Input array
- * @param size Numebr of elements to process
- * @param[out] min minimum value
- * @param[out] max maximum value
- */
-template <typename T>
-inline void ArrayBounds(const T* in, unsigned int size, T& min, T& max)
-{
- MinMaxChooser<T> ()(min,max);
- for (unsigned int i = 0; i < size;++i) {
- min = std::min(in[i],min);
- max = std::max(in[i],max);
- }
-}
-
-
-// -------------------------------------------------------------------------------
-/** Little helper function to calculate the quadratic difference
- * of two colours.
- * @param pColor1 First color
- * @param pColor2 second color
- * @return Quadratic color difference */
-inline ai_real GetColorDifference( const aiColor4D& pColor1, const aiColor4D& pColor2)
-{
- const aiColor4D c (pColor1.r - pColor2.r, pColor1.g - pColor2.g, pColor1.b - pColor2.b, pColor1.a - pColor2.a);
- return c.r*c.r + c.g*c.g + c.b*c.b + c.a*c.a;
-}
-
-
-// -------------------------------------------------------------------------------
-/** @brief Extract single strings from a list of identifiers
- * @param in Input string list.
- * @param out Receives a list of clean output strings
- * @sdee #AI_CONFIG_PP_OG_EXCLUDE_LIST */
-void ConvertListToStrings(const std::string& in, std::list<std::string>& out);
-
-
-// -------------------------------------------------------------------------------
-/** @brief Compute the AABB of a mesh after applying a given transform
- * @param mesh Input mesh
- * @param[out] min Receives minimum transformed vertex
- * @param[out] max Receives maximum transformed vertex
- * @param m Transformation matrix to be applied */
-void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, const aiMatrix4x4& m);
-
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to determine the 'real' center of a mesh
- *
- * That is the center of its axis-aligned bounding box.
- * @param mesh Input mesh
- * @param[out] min Minimum vertex of the mesh
- * @param[out] max maximum vertex of the mesh
- * @param[out] out Center point */
-void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max);
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to determine the 'real' center of a scene
- *
- * That is the center of its axis-aligned bounding box.
- * @param scene Input scene
- * @param[out] min Minimum vertex of the scene
- * @param[out] max maximum vertex of the scene
- * @param[out] out Center point */
-void FindSceneCenter (aiScene* scene, aiVector3D& out, aiVector3D& min, aiVector3D& max);
-
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh after applying a given transform
-void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,aiVector3D& max, const aiMatrix4x4& m);
-
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh
-void FindMeshCenter (aiMesh* mesh, aiVector3D& out);
-
-
-// -------------------------------------------------------------------------------
-// Helper function to determine the 'real' center of a mesh after applying a given transform
-void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,const aiMatrix4x4& m);
-
-
-// -------------------------------------------------------------------------------
-// Compute a good epsilon value for position comparisons on a mesh
-ai_real ComputePositionEpsilon(const aiMesh* pMesh);
-
-
-// -------------------------------------------------------------------------------
-// Compute a good epsilon value for position comparisons on a array of meshes
-ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num);
-
-
-// -------------------------------------------------------------------------------
-// Compute an unique value for the vertex format of a mesh
-unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh);
-
-
-// defs for ComputeVertexBoneWeightTable()
-typedef std::pair <unsigned int,float> PerVertexWeight;
-typedef std::vector <PerVertexWeight> VertexWeightTable;
-
-// -------------------------------------------------------------------------------
-// Compute a per-vertex bone weight table
-VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh);
-
-
-// -------------------------------------------------------------------------------
-// Get a string for a given aiTextureType
-const char* TextureTypeToString(aiTextureType in);
-
-
-// -------------------------------------------------------------------------------
-// Get a string for a given aiTextureMapping
-const char* MappingTypeToString(aiTextureMapping in);
-
-
-// flags for MakeSubmesh()
-#define AI_SUBMESH_FLAGS_SANS_BONES 0x1
-
-// -------------------------------------------------------------------------------
-// Split a mesh given a list of faces to be contained in the sub mesh
-aiMesh* MakeSubmesh(const aiMesh *superMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags);
-
-// -------------------------------------------------------------------------------
-// Utility postprocess step to share the spatial sort tree between
-// all steps which use it to speedup its computations.
-class ComputeSpatialSortProcess : public BaseProcess
-{
- bool IsActive( unsigned int pFlags) const
- {
- return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
- aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
- }
-
- void Execute( aiScene* pScene)
- {
- typedef std::pair<SpatialSort, ai_real> _Type;
- DefaultLogger::get()->debug("Generate spatially-sorted vertex cache");
-
- std::vector<_Type>* p = new std::vector<_Type>(pScene->mNumMeshes);
- std::vector<_Type>::iterator it = p->begin();
-
- for (unsigned int i = 0; i < pScene->mNumMeshes; ++i, ++it) {
- aiMesh* mesh = pScene->mMeshes[i];
- _Type& blubb = *it;
- blubb.first.Fill(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D));
- blubb.second = ComputePositionEpsilon(mesh);
- }
-
- shared->AddProperty(AI_SPP_SPATIAL_SORT,p);
- }
-};
-
-// -------------------------------------------------------------------------------
-// ... and the same again to cleanup the whole stuff
-class DestroySpatialSortProcess : public BaseProcess
-{
- bool IsActive( unsigned int pFlags) const
- {
- return NULL != shared && 0 != (pFlags & (aiProcess_CalcTangentSpace |
- aiProcess_GenNormals | aiProcess_JoinIdenticalVertices));
- }
-
- void Execute( aiScene* /*pScene*/)
- {
- shared->RemoveProperty(AI_SPP_SPATIAL_SORT);
- }
-};
-
-
-
-} // ! namespace Assimp
-#endif // !! AI_PROCESS_HELPER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/Profiler.h b/src/3rdparty/assimp/code/Profiler.h
deleted file mode 100644
index 1c9ca60b5..000000000
--- a/src/3rdparty/assimp/code/Profiler.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Profiler.h
- * @brief Utility to measure the respective runtime of each import step
- */
-#ifndef INCLUDED_PROFILER_H
-#define INCLUDED_PROFILER_H
-
-#include <chrono>
-#include <assimp/DefaultLogger.hpp>
-#include "TinyFormatter.h"
-
-#include <map>
-
-namespace Assimp {
-namespace Profiling {
-
-using namespace Formatter;
-
-// ------------------------------------------------------------------------------------------------
-/** Simple wrapper around boost::timer to simplify reporting. Timings are automatically
- * dumped to the log file.
- */
-class Profiler {
-public:
- Profiler() {
- // empty
- }
-
-public:
-
- /** Start a named timer */
- void BeginRegion(const std::string& region) {
- regions[region] = std::chrono::system_clock::now();
- DefaultLogger::get()->debug((format("START `"),region,"`"));
- }
-
-
- /** End a specific named timer and write its end time to the log */
- void EndRegion(const std::string& region) {
- RegionMap::const_iterator it = regions.find(region);
- if (it == regions.end()) {
- return;
- }
-
- std::chrono::duration<double> elapsedSeconds = std::chrono::system_clock::now() - regions[region];
- DefaultLogger::get()->debug((format("END `"),region,"`, dt= ", elapsedSeconds.count()," s"));
- }
-
-private:
- typedef std::map<std::string,std::chrono::time_point<std::chrono::system_clock>> RegionMap;
- RegionMap regions;
-};
-
-}
-}
-
-#endif
-
diff --git a/src/3rdparty/assimp/code/Q3BSPFileData.h b/src/3rdparty/assimp/code/Q3BSPFileData.h
deleted file mode 100644
index b836795f8..000000000
--- a/src/3rdparty/assimp/code/Q3BSPFileData.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_Q3BSPFILEDATA_H_INC
-#define ASSIMP_Q3BSPFILEDATA_H_INC
-
-#include <vector>
-#include <string.h> //memset
-#include <string>
-
-namespace Assimp {
-namespace Q3BSP {
-
-static const unsigned int CE_BSP_LIGHTMAPWIDTH = 128;
-static const unsigned int CE_BSP_LIGHTMAPHEIGHT = 128;
-
-static const unsigned int CE_BSP_LIGHTMAPSIZE = 128*128*3; ///< = 128( width ) * 128 ( height ) * 3 ( channels / RGB ).
-static const int VERION_Q3LEVEL = 46; ///< Supported version.
-
-/// Geometric type enumeration
-enum Q3BSPGeoType {
- Polygon = 1,
- Patch,
- TriangleMesh,
- Billboard
-};
-
-/// Integer vector.
-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 */ }
-};
-
-/// the file header
-struct sQ3BSPHeader {
- char strID[ 4 ]; ///< Should be "IBSP"
- int iVersion; ///< 46 for standard levels
-};
-
-/// Describes an entry.
-struct sQ3BSPLump
-{
- int iOffset; ///< Offset from start pointer of file
- int iSize; ///< Size of part
-};
-
-struct vec2f
-{
- float x,y;
-};
-
-struct vec3f
-{
- float x, y, z;
-};
-
-/// Vertex of a Q3 level
-struct sQ3BSPVertex
-{
- vec3f vPosition; ///< Position of vertex
- vec2f vTexCoord; ///< (u,v) Texturecoordinate of detailtexture
- vec2f vLightmap; ///< (u,v) Texturecoordinate of lightmap
- vec3f vNormal; ///< vertex normale
- unsigned char bColor[ 4 ]; ///< Color in RGBA
-};
-
-/// A face in bsp format info
-struct sQ3BSPFace
-{
- int iTextureID; ///< Index in texture array
- 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; ///< 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 extension
- int iFlags; ///< Not used
- int iContents; ///< Not used
-};
-
-/// 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 );
- }
-};
-
-struct SubPatch {
- std::vector<size_t> indices;
- int lightmapID;
-};
-
-enum eLumps {
- kEntities = 0,
- kTextures,
- kPlanes,
- kNodes,
- kLeafs,
- kLeafFaces,
- kLeafBrushes,
- kModels,
- kBrushes,
- kBrushSides,
- kVertices,
- kMeshVerts,
- kShaders,
- kFaces,
- kLightmaps,
- kLightVolumes,
- kVisData,
- kMaxLumps
-};
-
-struct Q3BSPModel {
- std::vector<unsigned char> m_Data;
- std::vector<sQ3BSPLump*> m_Lumps;
- std::vector<sQ3BSPVertex*> m_Vertices;
- std::vector<sQ3BSPFace*> m_Faces;
- std::vector<int> m_Indices;
- std::vector<sQ3BSPTexture*> m_Textures;
- std::vector<sQ3BSPLightmap*> m_Lightmaps;
- std::vector<char> m_EntityData;
- std::string m_ModelName;
-
- Q3BSPModel() :
- m_Data(),
- m_Lumps(),
- m_Vertices(),
- m_Faces(),
- m_Indices(),
- m_Textures(),
- m_Lightmaps(),
- m_EntityData(),
- m_ModelName( "" )
- {
- // empty
- }
-
- ~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();
- m_Faces.clear();
- m_Textures.clear();
- m_Lightmaps.clear();
- }
-};
-
-} // Namespace Q3BSP
-} // Namespace Assimp
-
-#endif // ASSIMP_Q3BSPFILEDATA_H_INC
diff --git a/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp b/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp
deleted file mode 100644
index 9d6d8e870..000000000
--- a/src/3rdparty/assimp/code/Q3BSPFileImporter.cpp
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-
-#include "Q3BSPFileImporter.h"
-#include "Q3BSPZipArchive.h"
-#include "Q3BSPFileParser.h"
-#include "Q3BSPFileData.h"
-
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-#else
-# include "../contrib/zlib/zlib.h"
-#endif
-
-#include <assimp/types.h>
-#include <assimp/mesh.h>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/importerdesc.h>
-#include <vector>
-#include <sstream>
-#include "StringComparison.h"
-
-static const aiImporterDesc desc = {
- "Quake III BSP Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "pk3"
-};
-
-namespace Assimp {
-
-using namespace Q3BSP;
-
-// ------------------------------------------------------------------------------------------------
-// Local function to create a material key name.
-static void createKey( int id1, int id2, std::string &rKey )
-{
- std::ostringstream str;
- str << id1 << "." << id2;
- rKey = str.str();
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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;
- rId2 = -1;
- if ( rKey.empty() )
- return;
-
- std::string::size_type pos = rKey.find( "." );
- if ( std::string::npos == pos )
- return;
-
- std::string tmp1 = rKey.substr( 0, pos );
- std::string tmp2 = rKey.substr( pos + 1, rKey.size() - pos - 1 );
- rId1 = atoi( tmp1.c_str() );
- rId2 = atoi( tmp2.c_str() );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Local helper function to normalize filenames.
-static void normalizePathName( const std::string &rPath, std::string &rNormalizedPath )
-{
- rNormalizedPath = "";
- if ( rPath.empty() )
- return;
-
-#ifdef _WIN32
- std::string sep = "\\";
-#else
- std::string sep = "/";
-#endif
-
- static const unsigned int numDelimiters = 2;
- const char delimiters[ numDelimiters ] = { '/', '\\' };
- rNormalizedPath = rPath;
- for (const char delimiter : delimiters)
- {
- for ( size_t j=0; j<rNormalizedPath.size(); j++ )
- {
- if ( rNormalizedPath[j] == delimiter )
- {
- rNormalizedPath[ j ] = sep[ 0 ];
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor.
-Q3BSPFileImporter::Q3BSPFileImporter() :
- m_pCurrentMesh( NULL ),
- m_pCurrentFace( NULL ),
- m_MaterialLookupMap(),
- mTextures()
-{
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-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() ) {
- delete it->second;
- }
- }
- m_MaterialLookupMap.clear();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the loader can read this.
-bool Q3BSPFileImporter::CanRead( const std::string& rFile, IOSystem* /*pIOHandler*/, bool checkSig ) const
-{
- if(!checkSig) {
- return SimpleExtensionCheck( rFile, "pk3", "bsp" );
- }
- // TODO perhaps add keyword based detection
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Adds extensions.
-const aiImporterDesc* Q3BSPFileImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Import method.
-void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- Q3BSPZipArchive Archive( pIOHandler, rFile );
- if ( !Archive.isOpen() )
- {
- throw DeadlyImportError( "Failed to open file " + rFile + "." );
- }
-
- std::string archiveName( "" ), mapName( "" );
- separateMapName( rFile, archiveName, mapName );
-
- if ( mapName.empty() )
- {
- if ( !findFirstMapInArchive( Archive, mapName ) )
- {
- return;
- }
- }
-
- Q3BSPFileParser fileParser( mapName, &Archive );
- Q3BSPModel *pBSPModel = fileParser.getModel();
- if ( NULL != pBSPModel )
- {
- CreateDataFromImport( pBSPModel, pScene, &Archive );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Separates the map name from the import name.
-void Q3BSPFileImporter::separateMapName( const std::string &rImportName, std::string &rArchiveName,
- std::string &rMapName )
-{
- rArchiveName = "";
- rMapName = "";
- if ( rImportName.empty() )
- return;
-
- std::string::size_type pos = rImportName.rfind( "," );
- if ( std::string::npos == pos )
- {
- rArchiveName = rImportName;
- return;
- }
-
- rArchiveName = rImportName.substr( 0, pos );
- rMapName = rImportName.substr( pos, rImportName.size() - pos - 1 );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the first map in the map archive.
-bool Q3BSPFileImporter::findFirstMapInArchive( Q3BSPZipArchive &rArchive, std::string &rMapName )
-{
- rMapName = "";
- std::vector<std::string> fileList;
- rArchive.getFileList( fileList );
- if ( fileList.empty() )
- return false;
-
- for ( std::vector<std::string>::iterator it = fileList.begin(); it != fileList.end();
- ++it )
- {
- std::string::size_type pos = (*it).find( "maps/" );
- if ( std::string::npos != pos )
- {
- std::string::size_type extPos = (*it).find( ".bsp" );
- if ( std::string::npos != extPos )
- {
- rMapName = *it;
- return true;
- }
- }
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the assimp specific data.
-void Q3BSPFileImporter::CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- Q3BSPZipArchive *pArchive )
-{
- if ( NULL == pModel || NULL == pScene )
- return;
-
- pScene->mRootNode = new aiNode;
- if ( !pModel->m_ModelName.empty() )
- {
- pScene->mRootNode->mName.Set( pModel->m_ModelName );
- }
-
- // Create the face to material relation map
- createMaterialMap( pModel );
-
- // Create all nodes
- CreateNodes( pModel, pScene, pScene->mRootNode );
-
- // Create the assigned materials
- createMaterials( pModel, pScene, pArchive );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all assimp nodes.
-void Q3BSPFileImporter::CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- aiNode *pParent )
-{
- ai_assert( NULL != pModel );
- if ( NULL == pModel )
- {
- return;
- }
-
- unsigned int matIdx = 0;
- std::vector<aiMesh*> MeshArray;
- std::vector<aiNode*> NodeArray;
- for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end(); ++it )
- {
- std::vector<Q3BSP::sQ3BSPFace*> *pArray = (*it).second;
- size_t numVerts = countData( *pArray );
- if ( 0 != numVerts )
- {
- aiMesh* pMesh = new aiMesh;
- aiNode *pNode = CreateTopology( pModel, matIdx, *pArray, pMesh );
- if ( NULL != pNode )
- {
- NodeArray.push_back( pNode );
- MeshArray.push_back( pMesh );
- }
- else
- {
- delete pMesh;
- }
- }
- matIdx++;
- }
-
- pScene->mNumMeshes = static_cast<unsigned int>( MeshArray.size() );
- if ( pScene->mNumMeshes > 0 )
- {
- pScene->mMeshes = new aiMesh*[ pScene->mNumMeshes ];
- for ( size_t i = 0; i < MeshArray.size(); i++ )
- {
- aiMesh *pMesh = MeshArray[ i ];
- if ( NULL != pMesh )
- {
- pScene->mMeshes[ i ] = pMesh;
- }
- }
- }
-
- pParent->mNumChildren = static_cast<unsigned int>(MeshArray.size());
- pParent->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren ];
- for ( size_t i=0; i<NodeArray.size(); i++ )
- {
- aiNode *pNode = NodeArray[ i ];
- pNode->mParent = pParent;
- pParent->mChildren[ i ] = pNode;
- pParent->mChildren[ i ]->mMeshes[ 0 ] = static_cast<unsigned int>(i);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the topology.
-aiNode *Q3BSPFileImporter::CreateTopology( const Q3BSP::Q3BSPModel *pModel,
- unsigned int materialIdx,
- std::vector<sQ3BSPFace*> &rArray,
- aiMesh* pMesh )
-{
- size_t numVerts = countData( rArray );
- if ( 0 == numVerts )
- {
- return NULL;
- }
-
- size_t numFaces = countFaces( rArray );
- if ( 0 == numFaces )
- {
- return NULL;
- }
-
- size_t numTriangles = countTriangles( rArray );
- pMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- pMesh->mFaces = new aiFace[ numTriangles ];
- pMesh->mNumFaces = static_cast<unsigned int>(numTriangles);
-
- pMesh->mNumVertices = static_cast<unsigned int>(numVerts);
- pMesh->mVertices = new aiVector3D[ numVerts ];
- pMesh->mNormals = new aiVector3D[ numVerts ];
- pMesh->mTextureCoords[ 0 ] = new aiVector3D[ numVerts ];
- pMesh->mTextureCoords[ 1 ] = new aiVector3D[ numVerts ];
- pMesh->mMaterialIndex = materialIdx;
-
- unsigned int faceIdx = 0;
- unsigned int vertIdx = 0;
- pMesh->mNumUVComponents[ 0 ] = 2;
- pMesh->mNumUVComponents[ 1 ] = 2;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end(); ++it )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- ai_assert( NULL != pQ3BSPFace );
- if ( NULL == pQ3BSPFace )
- {
- continue;
- }
-
- if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
- {
- if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
- {
- createTriangleTopology( pModel, pQ3BSPFace, pMesh, faceIdx, vertIdx );
- }
- }
- }
-
- aiNode *pNode = new aiNode;
- pNode->mNumMeshes = 1;
- pNode->mMeshes = new unsigned int[ 1 ];
-
- return pNode;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the triangle topology from a face array.
-void Q3BSPFileImporter::createTriangleTopology( const Q3BSP::Q3BSPModel *pModel,
- Q3BSP::sQ3BSPFace *pQ3BSPFace,
- aiMesh* pMesh,
- unsigned int &rFaceIdx,
- unsigned int &rVertIdx )
-{
- ai_assert( rFaceIdx < pMesh->mNumFaces );
-
- m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
- ai_assert( NULL != m_pCurrentFace );
- if ( NULL == m_pCurrentFace )
- {
- return;
- }
-
- m_pCurrentFace->mNumIndices = 3;
- m_pCurrentFace->mIndices = new unsigned int[ m_pCurrentFace->mNumIndices ];
-
- size_t idx = 0;
- for ( size_t i = 0; i < (size_t) pQ3BSPFace->iNumOfFaceVerts; i++ )
- {
- const size_t index = pQ3BSPFace->iVertexIndex + pModel->m_Indices[ pQ3BSPFace->iFaceVertexIndex + i ];
- ai_assert( index < pModel->m_Vertices.size() );
- if ( index >= pModel->m_Vertices.size() )
- {
- continue;
- }
-
- sQ3BSPVertex *pVertex = pModel->m_Vertices[ index ];
- ai_assert( NULL != pVertex );
- if ( NULL == pVertex )
- {
- continue;
- }
-
- pMesh->mVertices[ rVertIdx ].Set( pVertex->vPosition.x, pVertex->vPosition.y, pVertex->vPosition.z );
- pMesh->mNormals[ rVertIdx ].Set( pVertex->vNormal.x, pVertex->vNormal.y, pVertex->vNormal.z );
-
- pMesh->mTextureCoords[ 0 ][ rVertIdx ].Set( pVertex->vTexCoord.x, pVertex->vTexCoord.y, 0.0f );
- pMesh->mTextureCoords[ 1 ][ rVertIdx ].Set( pVertex->vLightmap.x, pVertex->vLightmap.y, 0.0f );
-
- m_pCurrentFace->mIndices[ idx ] = rVertIdx;
- rVertIdx++;
-
- idx++;
- if ( idx > 2 )
- {
- idx = 0;
- m_pCurrentFace = getNextFace( pMesh, rFaceIdx );
- if ( NULL != m_pCurrentFace )
- {
- m_pCurrentFace->mNumIndices = 3;
- m_pCurrentFace->mIndices = new unsigned int[ 3 ];
- }
- }
- }
- rFaceIdx--;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates all referenced materials.
-void Q3BSPFileImporter::createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- Q3BSPZipArchive *pArchive )
-{
- if ( m_MaterialLookupMap.empty() )
- {
- return;
- }
-
- pScene->mMaterials = new aiMaterial*[ m_MaterialLookupMap.size() ];
- aiString aiMatName;
- int textureId( -1 ), lightmapId( -1 );
- for ( FaceMapIt it = m_MaterialLookupMap.begin(); it != m_MaterialLookupMap.end();
- ++it )
- {
- const std::string matName = (*it).first;
- if ( matName.empty() )
- {
- continue;
- }
-
- aiMatName.Set( matName );
- aiMaterial *pMatHelper = new aiMaterial;
- pMatHelper->AddProperty( &aiMatName, AI_MATKEY_NAME );
-
- extractIds( matName, textureId, lightmapId );
-
- // Adding the texture
- if ( -1 != textureId )
- {
- sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
- if ( NULL != pTexture )
- {
- std::string tmp( "*" ), texName( "" );
- tmp += pTexture->strName;
- tmp += ".jpg";
- normalizePathName( tmp, texName );
-
- if ( !importTextureFromArchive( pModel, pArchive, pScene, pMatHelper, textureId ) )
- {
- }
- }
-
- }
- if ( -1 != lightmapId )
- {
- importLightmap( pModel, pScene, pMatHelper, lightmapId );
- }
- pScene->mMaterials[ pScene->mNumMaterials ] = pMatHelper;
- pScene->mNumMaterials++;
- }
- pScene->mNumTextures = static_cast<unsigned int>(mTextures.size());
- pScene->mTextures = new aiTexture*[ pScene->mNumTextures ];
- std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts the number of referenced vertices.
-size_t Q3BSPFileImporter::countData( const std::vector<sQ3BSPFace*> &rArray ) const
-{
- size_t numVerts = 0;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- sQ3BSPFace *pQ3BSPFace = *it;
- if ( pQ3BSPFace->iType == Polygon || pQ3BSPFace->iType == TriangleMesh )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- ai_assert( NULL != pQ3BSPFace );
- numVerts += pQ3BSPFace->iNumOfFaceVerts;
- }
- }
-
- return numVerts;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Counts the faces with vertices.
-size_t Q3BSPFileImporter::countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const
-{
- size_t numFaces = 0;
- for ( std::vector<sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- if ( pQ3BSPFace->iNumOfFaceVerts > 0 )
- {
- numFaces++;
- }
- }
-
- return numFaces;
-}
-
-// ------------------------------------------------------------------------------------------------
-// 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;
- for ( std::vector<Q3BSP::sQ3BSPFace*>::const_iterator it = rArray.begin(); it != rArray.end();
- ++it )
- {
- const Q3BSP::sQ3BSPFace *pQ3BSPFace = *it;
- if ( NULL != pQ3BSPFace )
- {
- numTriangles += pQ3BSPFace->iNumOfFaceVerts / 3;
- }
- }
-
- return numTriangles;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the faces-to-material map.
-void Q3BSPFileImporter::createMaterialMap( const Q3BSP::Q3BSPModel *pModel )
-{
- std::string key( "" );
- std::vector<sQ3BSPFace*> *pCurFaceArray = NULL;
- for ( size_t idx = 0; idx < pModel->m_Faces.size(); idx++ )
- {
- Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[ idx ];
- const int texId = pQ3BSPFace->iTextureID;
- const int lightMapId = pQ3BSPFace->iLightmapID;
- createKey( texId, lightMapId, key );
- FaceMapIt it = m_MaterialLookupMap.find( key );
- if ( m_MaterialLookupMap.end() == it )
- {
- pCurFaceArray = new std::vector<Q3BSP::sQ3BSPFace*>;
- m_MaterialLookupMap[ key ] = pCurFaceArray;
- }
- else
- {
- pCurFaceArray = (*it).second;
- }
- ai_assert( NULL != pCurFaceArray );
- if ( NULL != pCurFaceArray )
- {
- pCurFaceArray->push_back( pQ3BSPFace );
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the next face.
-aiFace *Q3BSPFileImporter::getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx )
-{
- aiFace *pFace( NULL );
- if ( rFaceIdx < pMesh->mNumFaces ) {
- pFace = &pMesh->mFaces[ rFaceIdx ];
- rFaceIdx++;
- }
-
- return pFace;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports a texture file.
-bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel,
- Q3BSP::Q3BSPZipArchive *pArchive, aiScene*,
- aiMaterial *pMatHelper, int textureId ) {
- if ( NULL == pArchive || NULL == pMatHelper ) {
- return false;
- }
-
- if ( textureId < 0 || textureId >= static_cast<int>( pModel->m_Textures.size() ) ) {
- return false;
- }
-
- bool res = true;
- sQ3BSPTexture *pTexture = pModel->m_Textures[ textureId ];
- 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 ) ) {
- IOStream *pTextureStream = pArchive->Open( textureName.c_str() );
- if ( pTextureStream ) {
- size_t texSize = pTextureStream->FileSize();
- aiTexture *pTexture = new aiTexture;
- pTexture->mHeight = 0;
- pTexture->mWidth = static_cast<unsigned int>(texSize);
- unsigned char *pData = new unsigned char[ pTexture->mWidth ];
- size_t readSize = pTextureStream->Read( pData, sizeof( unsigned char ), pTexture->mWidth );
- (void)readSize;
- ai_assert( readSize == pTexture->mWidth );
- pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
- pTexture->achFormatHint[ 0 ] = ext[ 1 ];
- pTexture->achFormatHint[ 1 ] = ext[ 2 ];
- pTexture->achFormatHint[ 2 ] = ext[ 3 ];
- pTexture->achFormatHint[ 3 ] = '\0';
- res = true;
-
- aiString name;
- name.data[ 0 ] = '*';
- name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) );
-
- pArchive->Close( pTextureStream );
-
- pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
- mTextures.push_back( pTexture );
- } 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;
- strncpy( name.data, pTexture->strName, sizeof name.data );
- name.length = strlen( name.data );
- pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
- }
- }
-
- return res;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports a light map file.
-bool Q3BSPFileImporter::importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene,
- aiMaterial *pMatHelper, int lightmapId )
-{
- if ( NULL == pModel || NULL == pScene || NULL == pMatHelper )
- {
- return false;
- }
-
- if ( lightmapId < 0 || lightmapId >= static_cast<int>( pModel->m_Lightmaps.size() ) )
- {
- return false;
- }
-
- sQ3BSPLightmap *pLightMap = pModel->m_Lightmaps[ lightmapId ];
- if ( NULL == pLightMap )
- {
- return false;
- }
-
- aiTexture *pTexture = new aiTexture;
-
- pTexture->mWidth = CE_BSP_LIGHTMAPWIDTH;
- pTexture->mHeight = CE_BSP_LIGHTMAPHEIGHT;
- pTexture->pcData = new aiTexel[CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT];
-
- ::memcpy( pTexture->pcData, pLightMap->bLMapData, pTexture->mWidth );
- size_t p = 0;
- for ( size_t i = 0; i < CE_BSP_LIGHTMAPWIDTH * CE_BSP_LIGHTMAPHEIGHT; ++i )
- {
- pTexture->pcData[ i ].r = pLightMap->bLMapData[ p++ ];
- pTexture->pcData[ i ].g = pLightMap->bLMapData[ p++ ];
- pTexture->pcData[ i ].b = pLightMap->bLMapData[ p++ ];
- pTexture->pcData[ i ].a = 0xFF;
- }
-
- aiString name;
- name.data[ 0 ] = '*';
- name.length = 1 + ASSIMP_itoa10( name.data + 1, static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(mTextures.size()) );
-
- pMatHelper->AddProperty( &name,AI_MATKEY_TEXTURE_LIGHTMAP( 1 ) );
- mTextures.push_back( pTexture );
-
- return true;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Will search for a supported extension.
-bool Q3BSPFileImporter::expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename,
- const std::vector<std::string> &rExtList, std::string &rFile,
- std::string &rExt )
-{
- ai_assert( NULL != pArchive );
- ai_assert( !rFilename.empty() );
-
- if ( rExtList.empty() )
- {
- rFile = rFilename;
- rExt = "";
- return true;
- }
-
- bool found = false;
- for ( std::vector<std::string>::const_iterator it = rExtList.begin(); it != rExtList.end(); ++it )
- {
- const std::string textureName = rFilename + *it;
- if ( pArchive->Exists( textureName.c_str() ) )
- {
- rExt = *it;
- rFile = textureName;
- found = true;
- break;
- }
- }
-
- return found;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
diff --git a/src/3rdparty/assimp/code/Q3BSPFileImporter.h b/src/3rdparty/assimp/code/Q3BSPFileImporter.h
deleted file mode 100644
index cf53d4db0..000000000
--- a/src/3rdparty/assimp/code/Q3BSPFileImporter.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_Q3BSPFILEIMPORTER_H_INC
-#define ASSIMP_Q3BSPFILEIMPORTER_H_INC
-
-#include "BaseImporter.h"
-
-#include <map>
-
-struct aiMesh;
-struct aiNode;
-struct aiFace;
-struct aiMaterial;
-struct aiTexture;
-
-namespace Assimp {
-namespace Q3BSP {
- class Q3BSPZipArchive;
- struct Q3BSPModel;
- struct sQ3BSPFace;
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Loader to import BSP-levels from a PK3 archive or from a unpacked BSP-level.
- */
-// ------------------------------------------------------------------------------------------------
-class Q3BSPFileImporter : public BaseImporter {
-public:
- /// @brief Default constructor.
- Q3BSPFileImporter();
-
- /// @brief Destructor.
- ~Q3BSPFileImporter();
-
-public:
- /// @brief Returns whether the class can handle the format of the given file.
- /// @remark See BaseImporter::CanRead() for details.
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
-
-private:
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*> FaceMap;
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>* >::iterator FaceMapIt;
- typedef std::map<std::string, std::vector<Q3BSP::sQ3BSPFace*>*>::const_iterator FaceMapConstIt;
-
- const aiImporterDesc* GetInfo () const;
- void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
- void separateMapName( const std::string &rImportName, std::string &rArchiveName, std::string &rMapName );
- bool findFirstMapInArchive( Q3BSP::Q3BSPZipArchive &rArchive, std::string &rMapName );
- void CreateDataFromImport( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
- void CreateNodes( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiNode *pParent );
- aiNode *CreateTopology( const Q3BSP::Q3BSPModel *pModel, unsigned int materialIdx,
- std::vector<Q3BSP::sQ3BSPFace*> &rArray, aiMesh* pMesh );
- void createTriangleTopology( const Q3BSP::Q3BSPModel *pModel, Q3BSP::sQ3BSPFace *pQ3BSPFace, aiMesh* pMesh, unsigned int &rFaceIdx,
- unsigned int &rVertIdx );
- void createMaterials( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, Q3BSP::Q3BSPZipArchive *pArchive );
- size_t countData( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- size_t countFaces( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- size_t countTriangles( const std::vector<Q3BSP::sQ3BSPFace*> &rArray ) const;
- void createMaterialMap( const Q3BSP::Q3BSPModel *pModel);
- aiFace *getNextFace( aiMesh *pMesh, unsigned int &rFaceIdx );
- bool importTextureFromArchive( const Q3BSP::Q3BSPModel *pModel, Q3BSP::Q3BSPZipArchive *pArchive, aiScene* pScene,
- aiMaterial *pMatHelper, int textureId );
- bool importLightmap( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene, aiMaterial *pMatHelper, int lightmapId );
- bool importEntities( const Q3BSP::Q3BSPModel *pModel, aiScene* pScene );
- bool expandFile( Q3BSP::Q3BSPZipArchive *pArchive, const std::string &rFilename, const std::vector<std::string> &rExtList,
- std::string &rFile, std::string &rExt );
-
-private:
- aiMesh *m_pCurrentMesh;
- aiFace *m_pCurrentFace;
- FaceMap m_MaterialLookupMap;
- std::vector<aiTexture*> mTextures;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-
-#endif // ASSIMP_Q3BSPFILEIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/Q3BSPFileParser.cpp b/src/3rdparty/assimp/code/Q3BSPFileParser.cpp
deleted file mode 100644
index 69721fc2d..000000000
--- a/src/3rdparty/assimp/code/Q3BSPFileParser.cpp
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-
-#include "Q3BSPFileParser.h"
-#include "Q3BSPFileData.h"
-#include "Q3BSPZipArchive.h"
-#include <vector>
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/ai_assert.h>
-
-namespace Assimp {
-
-using namespace Q3BSP;
-
-// ------------------------------------------------------------------------------------------------
-Q3BSPFileParser::Q3BSPFileParser( const std::string &rMapName, Q3BSPZipArchive *pZipArchive ) :
- m_sOffset( 0 ),
- m_Data(),
- m_pModel( NULL ),
- m_pZipArchive( pZipArchive )
-{
- ai_assert( NULL != m_pZipArchive );
- ai_assert( !rMapName.empty() );
-
- if ( !readData( rMapName ) )
- return;
-
- m_pModel = new Q3BSPModel;
- m_pModel->m_ModelName = rMapName;
- if ( !parseFile() )
- {
- delete m_pModel;
- m_pModel = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-Q3BSPFileParser::~Q3BSPFileParser()
-{
- delete m_pModel;
- m_pModel = NULL;
-}
-
-// ------------------------------------------------------------------------------------------------
-Q3BSP::Q3BSPModel *Q3BSPFileParser::getModel() const
-{
- return m_pModel;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::readData( const std::string &rMapName )
-{
- if ( !m_pZipArchive->Exists( rMapName.c_str() ) )
- return false;
-
- IOStream *pMapFile = m_pZipArchive->Open( rMapName.c_str() );
- if ( NULL == pMapFile )
- return false;
-
- const size_t size = pMapFile->FileSize();
- m_Data.resize( size );
-
- const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
- if ( readSize != size )
- {
- m_Data.clear();
- return false;
- }
- m_pZipArchive->Close( pMapFile );
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::parseFile()
-{
- if ( m_Data.empty() )
- {
- return false;
- }
-
- if ( !validateFormat() )
- {
- return false;
- }
-
- // Imports the dictionary of the level
- getLumps();
-
- // Conunt data and prepare model data
- countLumps();
-
- // Read in Vertices
- getVertices();
-
- // Read in Indices
- getIndices();
-
- // Read Faces
- getFaces();
-
- // Read Textures
- getTextures();
-
- // Read Lightmaps
- getLightMaps();
-
- // Load the entities
- getEntities();
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool Q3BSPFileParser::validateFormat()
-{
- sQ3BSPHeader *pHeader = (sQ3BSPHeader*) &m_Data[ 0 ];
- m_sOffset += sizeof( sQ3BSPHeader );
-
- // Version and identify string validation
- if (pHeader->strID[ 0 ] != 'I' || pHeader->strID[ 1 ] != 'B' || pHeader->strID[ 2 ] != 'S'
- || pHeader->strID[ 3 ] != 'P')
- {
- return false;
- }
-
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getLumps()
-{
- size_t Offset = m_sOffset;
- m_pModel->m_Lumps.resize( kMaxLumps );
- for ( size_t idx=0; idx < kMaxLumps; idx++ )
- {
- sQ3BSPLump *pLump = new sQ3BSPLump;
- memcpy( pLump, &m_Data[ Offset ], sizeof( sQ3BSPLump ) );
- Offset += sizeof( sQ3BSPLump );
- m_pModel->m_Lumps[ idx ] = pLump;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::countLumps()
-{
- m_pModel->m_Vertices.resize( m_pModel->m_Lumps[ kVertices ]->iSize / sizeof( sQ3BSPVertex ) );
- m_pModel->m_Indices.resize( m_pModel->m_Lumps[ kMeshVerts ]->iSize / sizeof( int ) );
- m_pModel->m_Faces.resize( m_pModel->m_Lumps[ kFaces ]->iSize / sizeof( sQ3BSPFace ) );
- m_pModel->m_Textures.resize( m_pModel->m_Lumps[ kTextures ]->iSize / sizeof( sQ3BSPTexture ) );
- m_pModel->m_Lightmaps.resize( m_pModel->m_Lumps[ kLightmaps ]->iSize / sizeof( sQ3BSPLightmap ) );
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getVertices()
-{
- size_t Offset = m_pModel->m_Lumps[ kVertices ]->iOffset;
- for ( size_t idx = 0; idx < m_pModel->m_Vertices.size(); idx++ )
- {
- sQ3BSPVertex *pVertex = new sQ3BSPVertex;
- memcpy( pVertex, &m_Data[ Offset ], sizeof( sQ3BSPVertex ) );
- Offset += sizeof( sQ3BSPVertex );
- m_pModel->m_Vertices[ idx ] = pVertex;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getIndices()
-{
- ai_assert( NULL != m_pModel );
-
- sQ3BSPLump *lump = m_pModel->m_Lumps[ kMeshVerts ];
- size_t Offset = (size_t) lump->iOffset;
- const size_t nIndices = lump->iSize / sizeof( int );
- m_pModel->m_Indices.resize( nIndices );
- memcpy( &m_pModel->m_Indices[ 0 ], &m_Data[ Offset ], lump->iSize );
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getFaces()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[ kFaces ]->iOffset;
- for ( size_t idx = 0; idx < m_pModel->m_Faces.size(); idx++ )
- {
- sQ3BSPFace *pFace = new sQ3BSPFace;
- memcpy( pFace, &m_Data[ Offset ], sizeof( sQ3BSPFace ) );
- m_pModel->m_Faces[ idx ] = pFace;
- Offset += sizeof( sQ3BSPFace );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getTextures()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[ kTextures ]->iOffset;
- for ( size_t idx=0; idx < m_pModel->m_Textures.size(); idx++ )
- {
- sQ3BSPTexture *pTexture = new sQ3BSPTexture;
- memcpy( pTexture, &m_Data[ Offset ], sizeof(sQ3BSPTexture) );
- m_pModel->m_Textures[ idx ] = pTexture;
- Offset += sizeof(sQ3BSPTexture);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getLightMaps()
-{
- ai_assert( NULL != m_pModel );
-
- size_t Offset = m_pModel->m_Lumps[kLightmaps]->iOffset;
- for ( size_t idx=0; idx < m_pModel->m_Lightmaps.size(); idx++ )
- {
- sQ3BSPLightmap *pLightmap = new sQ3BSPLightmap;
- memcpy( pLightmap, &m_Data[ Offset ], sizeof( sQ3BSPLightmap ) );
- Offset += sizeof( sQ3BSPLightmap );
- m_pModel->m_Lightmaps[ idx ] = pLightmap;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void Q3BSPFileParser::getEntities()
-{
- int size = m_pModel->m_Lumps[ kEntities ]->iSize;
- m_pModel->m_EntityData.resize( size );
- if ( size > 0 )
- {
- size_t Offset = m_pModel->m_Lumps[ kEntities ]->iOffset;
- memcpy( &m_pModel->m_EntityData[ 0 ], &m_Data[ Offset ], sizeof( char ) * size );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER
diff --git a/src/3rdparty/assimp/code/Q3BSPFileParser.h b/src/3rdparty/assimp/code/Q3BSPFileParser.h
deleted file mode 100644
index 1ee6d4aef..000000000
--- a/src/3rdparty/assimp/code/Q3BSPFileParser.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_Q3BSPFILEPARSER_H_INC
-#define ASSIMP_Q3BSPFILEPARSER_H_INC
-
-#include "BaseImporter.h"
-#include <string>
-
-namespace Assimp
-{
-namespace Q3BSP
-{
-
-class Q3BSPZipArchive;
-struct Q3BSPModel;
-class ZipFile;
-
-}
-
-// -------------------------------------------------------------------
-// -------------------------------------------------------------------
-class Q3BSPFileParser
-{
-public:
- Q3BSPFileParser( const std::string &rMapName, Q3BSP::Q3BSPZipArchive *pZipArchive );
- ~Q3BSPFileParser();
- Q3BSP::Q3BSPModel *getModel() const;
-
-protected:
- bool readData(const std::string &rMapName);
- bool parseFile();
- bool validateFormat();
- void getLumps();
- void countLumps();
- void getVertices();
- void getIndices();
- void getFaces();
- void getTextures();
- void getLightMaps();
- void getEntities();
-
-private:
- size_t m_sOffset;
- std::vector<char> m_Data;
- Q3BSP::Q3BSPModel *m_pModel;
- Q3BSP::Q3BSPZipArchive *m_pZipArchive;
-};
-
-} // Namespace Assimp
-
-#endif // ASSIMP_Q3BSPFILEPARSER_H_INC
diff --git a/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp b/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp
deleted file mode 100644
index 86c966d8e..000000000
--- a/src/3rdparty/assimp/code/Q3BSPZipArchive.cpp
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_Q3BSP_IMPORTER
-
-#include "Q3BSPZipArchive.h"
-#include <cassert>
-#include <assimp/ai_assert.h>
-
-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 static_cast<uLong>(io_stream->Read(buf, 1, size));
-}
-
-uLong IOSystem2Unzip::write(voidpf /*opaque*/, voidpf stream, const void* buf, uLong size) {
- IOStream* io_stream = (IOStream*) stream;
-
- return static_cast<uLong>(io_stream->Write(buf, 1, size));
-}
-
-long IOSystem2Unzip::tell(voidpf /*opaque*/, voidpf stream) {
- IOStream* io_stream = (IOStream*) stream;
-
- return static_cast<long>(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 = malloc(m_Size);
-}
-
-ZipFile::~ZipFile() {
- 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(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();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor.
-Q3BSPZipArchive::~Q3BSPZipArchive() {
- for(auto &file : m_ArchiveMap) {
- delete file.second;
- }
- m_ArchiveMap.clear();
-
- if(m_ZipFileHandle != NULL) {
- unzClose(m_ZipFileHandle);
- m_ZipFileHandle = NULL;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns true, if the archive is already open.
-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(pFile != NULL);
-
- bool exist = false;
-
- if (pFile != NULL) {
- std::string rFile(pFile);
- std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
-
- if(it != m_ArchiveMap.end()) {
- exist = true;
- }
- }
-
- return exist;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns the separator delimiter.
-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(pFile != NULL);
-
- IOStream* result = NULL;
-
- std::map<std::string, ZipFile*>::iterator it = m_ArchiveMap.find(pFile);
-
- if(it != m_ArchiveMap.end()) {
- result = (IOStream*) it->second;
- }
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Close a filestream.
-void Q3BSPZipArchive::Close(IOStream *pFile) {
- (void)(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.clear();
-
- for(auto &file : m_ArchiveMap) {
- rFileList.push_back(file.first);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Maps the archive content.
-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(fileInfo.uncompressed_size != 0 && 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;
- }
-
- 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
deleted file mode 100644
index 5430bac6f..000000000
--- a/src/3rdparty/assimp/code/Q3BSPZipArchive.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_Q3BSP_ZIPARCHIVE_H_INC
-#define AI_Q3BSP_ZIPARCHIVE_H_INC
-
-#include <contrib/unzip/unzip.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/IOSystem.hpp>
-#include <vector>
-#include <map>
-#include <cassert>
-
-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
-/// \ingroup Assimp::Q3BSP
-///
-/// \brief
-// ------------------------------------------------------------------------------------------------
-class ZipFile : public IOStream {
- friend class Q3BSPZipArchive;
-
-public:
- explicit ZipFile(size_t size);
- ~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;
-};
-
-// ------------------------------------------------------------------------------------------------
-/// \class Q3BSPZipArchive
-/// \ingroup Assimp::Q3BSP
-///
-/// \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(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;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Q3BSP
-} // Namespace Assimp
-
-#endif // AI_Q3BSP_ZIPARCHIVE_H_INC
diff --git a/src/3rdparty/assimp/code/Q3DLoader.cpp b/src/3rdparty/assimp/code/Q3DLoader.cpp
deleted file mode 100644
index 5aa639d09..000000000
--- a/src/3rdparty/assimp/code/Q3DLoader.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Q3DLoader.cpp
- * @brief Implementation of the Q3D importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER
-
-// internal headers
-#include "Q3DLoader.h"
-#include "StreamReader.h"
-#include "fast_atof.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Quick3D Importer",
- "",
- "",
- "http://www.quick3d.com/",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "q3o q3s"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-Q3DImporter::Q3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Q3DImporter::~Q3DImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if (extension == "q3s" || extension == "q3o")
- return true;
- else if (!extension.length() || checkSig) {
- if (!pIOHandler)
- return true;
- const char* tokens[] = {"quick3Do","quick3Ds"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* Q3DImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void Q3DImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
-
- // The header is 22 bytes large
- if (stream.GetRemainingSize() < 22)
- throw DeadlyImportError("File is either empty or corrupt: " + pFile);
-
- // Check the file's signature
- if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) &&
- ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 ))
- {
- throw DeadlyImportError("Not a Quick3D file. Signature string is: " +
- std::string((const char*)stream.GetPtr(),8));
- }
-
- // Print the file format version
- DefaultLogger::get()->info("Quick3D File format version: " +
- std::string(&((const char*)stream.GetPtr())[8],2));
-
- // ... an store it
- char major = ((const char*)stream.GetPtr())[8];
- char minor = ((const char*)stream.GetPtr())[9];
-
- stream.IncPtr(10);
- unsigned int numMeshes = (unsigned int)stream.GetI4();
- unsigned int numMats = (unsigned int)stream.GetI4();
- unsigned int numTextures = (unsigned int)stream.GetI4();
-
- std::vector<Material> materials;
- materials.reserve(numMats);
-
- std::vector<Mesh> meshes;
- meshes.reserve(numMeshes);
-
- // Allocate the scene root node
- pScene->mRootNode = new aiNode();
-
- aiColor3D fgColor (0.6f,0.6f,0.6f);
-
- // Now read all file chunks
- while (true)
- {
- if (stream.GetRemainingSize() < 1)break;
- char c = stream.GetI1();
- switch (c)
- {
- // Meshes chunk
- case 'm':
- {
- for (unsigned int quak = 0; quak < numMeshes; ++quak)
- {
- meshes.push_back(Mesh());
- Mesh& mesh = meshes.back();
-
- // read all vertices
- unsigned int numVerts = (unsigned int)stream.GetI4();
- if (!numVerts)
- throw DeadlyImportError("Quick3D: Found mesh with zero vertices");
-
- std::vector<aiVector3D>& verts = mesh.verts;
- verts.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- verts[i].x = stream.GetF4();
- verts[i].y = stream.GetF4();
- verts[i].z = stream.GetF4();
- }
-
- // read all faces
- numVerts = (unsigned int)stream.GetI4();
- if (!numVerts)
- throw DeadlyImportError("Quick3D: Found mesh with zero faces");
-
- std::vector<Face >& faces = mesh.faces;
- faces.reserve(numVerts);
-
- // number of indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- faces.push_back(Face(stream.GetI2()) );
- if (faces.back().indices.empty())
- throw DeadlyImportError("Quick3D: Found face with zero indices");
- }
-
- // indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- Face& vec = faces[i];
- for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
- vec.indices[a] = stream.GetI4();
- }
-
- // material indices
- for (unsigned int i = 0; i < numVerts;++i)
- {
- faces[i].mat = (unsigned int)stream.GetI4();
- }
-
- // read all normals
- numVerts = (unsigned int)stream.GetI4();
- std::vector<aiVector3D>& normals = mesh.normals;
- normals.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- normals[i].x = stream.GetF4();
- normals[i].y = stream.GetF4();
- normals[i].z = stream.GetF4();
- }
-
- numVerts = (unsigned int)stream.GetI4();
- if (numTextures && numVerts)
- {
- // read all texture coordinates
- std::vector<aiVector3D>& uv = mesh.uv;
- uv.resize(numVerts);
-
- for (unsigned int i = 0; i < numVerts;++i)
- {
- uv[i].x = stream.GetF4();
- uv[i].y = stream.GetF4();
- }
-
- // UV indices
- for (unsigned int i = 0; i < (unsigned int)faces.size();++i)
- {
- Face& vec = faces[i];
- for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a)
- {
- vec.uvindices[a] = stream.GetI4();
- if (!i && !a)
- mesh.prevUVIdx = vec.uvindices[a];
- else if (vec.uvindices[a] != mesh.prevUVIdx)
- mesh.prevUVIdx = UINT_MAX;
- }
- }
- }
-
- // we don't need the rest, but we need to get to the next chunk
- stream.IncPtr(36);
- if (minor > '0' && major == '3')
- stream.IncPtr(mesh.faces.size());
- }
- // stream.IncPtr(4); // unknown value here
- }
- break;
-
- // materials chunk
- case 'c':
-
- for (unsigned int i = 0; i < numMats; ++i)
- {
- materials.push_back(Material());
- Material& mat = materials.back();
-
- // read the material name
- while (( c = stream.GetI1()))
- mat.name.data[mat.name.length++] = c;
-
- // add the terminal character
- mat.name.data[mat.name.length] = '\0';
-
- // read the ambient color
- mat.ambient.r = stream.GetF4();
- mat.ambient.g = stream.GetF4();
- mat.ambient.b = stream.GetF4();
-
- // read the diffuse color
- mat.diffuse.r = stream.GetF4();
- mat.diffuse.g = stream.GetF4();
- mat.diffuse.b = stream.GetF4();
-
- // read the ambient color
- mat.specular.r = stream.GetF4();
- mat.specular.g = stream.GetF4();
- mat.specular.b = stream.GetF4();
-
- // read the transparency
- mat.transparency = stream.GetF4();
-
- // unknown value here
- // stream.IncPtr(4);
- // FIX: it could be the texture index ...
- mat.texIdx = (unsigned int)stream.GetI4();
- }
-
- break;
-
- // texture chunk
- case 't':
-
- pScene->mNumTextures = numTextures;
- if (!numTextures)break;
- pScene->mTextures = new aiTexture*[pScene->mNumTextures];
- // to make sure we won't crash if we leave through an exception
- ::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures);
- for (unsigned int i = 0; i < pScene->mNumTextures; ++i)
- {
- aiTexture* tex = pScene->mTextures[i] = new aiTexture();
-
- // skip the texture name
- while (stream.GetI1());
-
- // read texture width and height
- tex->mWidth = (unsigned int)stream.GetI4();
- tex->mHeight = (unsigned int)stream.GetI4();
-
- if (!tex->mWidth || !tex->mHeight)
- throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
-
- unsigned int mul = tex->mWidth * tex->mHeight;
- aiTexel* begin = tex->pcData = new aiTexel[mul];
- aiTexel* const end = & begin [mul];
-
- for (;begin != end; ++begin)
- {
- begin->r = stream.GetI1();
- begin->g = stream.GetI1();
- begin->b = stream.GetI1();
- begin->a = 0xff;
- }
- }
-
- break;
-
- // scene chunk
- case 's':
- {
- // skip position and rotation
- stream.IncPtr(12);
-
- for (unsigned int i = 0; i < 4;++i)
- for (unsigned int a = 0; a < 4;++a)
- pScene->mRootNode->mTransformation[i][a] = stream.GetF4();
-
- stream.IncPtr(16);
-
- // now setup a single camera
- pScene->mNumCameras = 1;
- pScene->mCameras = new aiCamera*[1];
- aiCamera* cam = pScene->mCameras[0] = new aiCamera();
- cam->mPosition.x = stream.GetF4();
- cam->mPosition.y = stream.GetF4();
- cam->mPosition.z = stream.GetF4();
- cam->mName.Set("Q3DCamera");
-
- // skip eye rotation for the moment
- stream.IncPtr(12);
-
- // read the default material color
- fgColor .r = stream.GetF4();
- fgColor .g = stream.GetF4();
- fgColor .b = stream.GetF4();
-
- // skip some unimportant properties
- stream.IncPtr(29);
-
- // setup a single point light with no attenuation
- pScene->mNumLights = 1;
- pScene->mLights = new aiLight*[1];
- aiLight* light = pScene->mLights[0] = new aiLight();
- light->mName.Set("Q3DLight");
- light->mType = aiLightSource_POINT;
-
- light->mAttenuationConstant = 1;
- light->mAttenuationLinear = 0;
- light->mAttenuationQuadratic = 0;
-
- light->mColorDiffuse.r = stream.GetF4();
- light->mColorDiffuse.g = stream.GetF4();
- light->mColorDiffuse.b = stream.GetF4();
-
- light->mColorSpecular = light->mColorDiffuse;
-
-
- // 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
- while (stream.GetI1());
-
- // skip background texture data + the remaining fields
- stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here
-
- // TODO
- goto outer;
- }
- break;
-
- default:
- throw DeadlyImportError("Quick3D: Unknown chunk");
- break;
- };
- }
-outer:
-
- // If we have no mesh loaded - break here
- if (meshes.empty())
- throw DeadlyImportError("Quick3D: No meshes loaded");
-
- // If we have no materials loaded - generate a default mat
- if (materials.empty())
- {
- DefaultLogger::get()->info("Quick3D: No material found, generating one");
- materials.push_back(Material());
- materials.back().diffuse = fgColor ;
- }
-
- // find out which materials we'll need
- typedef std::pair<unsigned int, unsigned int> FaceIdx;
- typedef std::vector< FaceIdx > FaceIdxArray;
- FaceIdxArray* fidx = new FaceIdxArray[materials.size()];
-
- unsigned int p = 0;
- for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end();
- it != end; ++it,++p)
- {
- unsigned int q = 0;
- for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end();
- fit != fend; ++fit,++q)
- {
- if ((*fit).mat >= materials.size())
- {
- DefaultLogger::get()->warn("Quick3D: Material index overflow");
- (*fit).mat = 0;
- }
- if (fidx[(*fit).mat].empty())++pScene->mNumMeshes;
- fidx[(*fit).mat].push_back( FaceIdx(p,q) );
- }
- }
- pScene->mNumMaterials = pScene->mNumMeshes;
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- pScene->mMeshes = new aiMesh*[pScene->mNumMaterials];
-
- for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i)
- {
- if (fidx[i].empty())continue;
-
- // Allocate a mesh and a material
- aiMesh* mesh = pScene->mMeshes[real] = new aiMesh();
- aiMaterial* mat = new aiMaterial();
- pScene->mMaterials[real] = mat;
-
- mesh->mMaterialIndex = real;
-
- // Build the output material
- Material& srcMat = materials[i];
- mat->AddProperty(&srcMat.diffuse, 1,AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR);
- mat->AddProperty(&srcMat.ambient, 1,AI_MATKEY_COLOR_AMBIENT);
-
- // NOTE: Ignore transparency for the moment - it seems
- // unclear how to interpret the data
-#if 0
- if (!(minor > '0' && major == '3'))
- srcMat.transparency = 1.0f - srcMat.transparency;
- mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY);
-#endif
-
- // add shininess - Quick3D seems to use it ins its viewer
- srcMat.transparency = 16.f;
- mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS);
-
- int m = (int)aiShadingMode_Phong;
- mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL);
-
- if (srcMat.name.length)
- mat->AddProperty(&srcMat.name,AI_MATKEY_NAME);
-
- // Add a texture
- if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures)
- {
- srcMat.name.data[0] = '*';
- srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1],1000,
- (srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real));
- mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
-
- mesh->mNumFaces = (unsigned int)fidx[i].size();
- aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- // Now build the output mesh. First find out how many
- // vertices we'll need
- for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
- it != end; ++it)
- {
- mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[
- (*it).second].indices.size();
- }
-
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiVector3D* norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- aiVector3D* uv;
- if (real < pScene->mNumTextures)
- {
- uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
- }
- else uv = NULL;
-
- // Build the final array
- unsigned int cnt = 0;
- for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end();
- it != end; ++it, ++faces)
- {
- Mesh& m = meshes[(*it).first];
- Face& face = m.faces[(*it).second];
- faces->mNumIndices = (unsigned int)face.indices.size();
- faces->mIndices = new unsigned int [faces->mNumIndices];
-
-
- aiVector3D faceNormal;
- bool fnOK = false;
-
- for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts)
- {
- if (face.indices[n] >= m.verts.size())
- {
- DefaultLogger::get()->warn("Quick3D: Vertex index overflow");
- face.indices[n] = 0;
- }
-
- // copy vertices
- *verts = m.verts[ face.indices[n] ];
-
- if (face.indices[n] >= m.normals.size() && faces->mNumIndices >= 3)
- {
- // we have no normal here - assign the face normal
- if (!fnOK)
- {
- const aiVector3D& pV1 = m.verts[ face.indices[0] ];
- const aiVector3D& pV2 = m.verts[ face.indices[1] ];
- const aiVector3D& pV3 = m.verts[ face.indices.size() - 1 ];
- faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize();
- fnOK = true;
- }
- *norms = faceNormal;
- }
- else *norms = m.normals[ face.indices[n] ];
-
- // copy texture coordinates
- if (uv && m.uv.size())
- {
- if (m.prevUVIdx != 0xffffffff && m.uv.size() >= m.verts.size()) // workaround
- {
- *uv = m.uv[face.indices[n]];
- }
- else
- {
- if (face.uvindices[n] >= m.uv.size())
- {
- DefaultLogger::get()->warn("Quick3D: Texture coordinate index overflow");
- face.uvindices[n] = 0;
- }
- *uv = m.uv[face.uvindices[n]];
- }
- uv->y = 1.f - uv->y;
- ++uv;
- }
-
- // setup the new vertex index
- faces->mIndices[n] = cnt;
- }
-
- }
- ++real;
- }
-
- // Delete our nice helper array
- delete[] fidx;
-
- // Now we need to attach the meshes to the root node of the scene
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int [pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
-
- /*pScene->mRootNode->mTransformation *= aiMatrix4x4(
- 1.f, 0.f, 0.f, 0.f,
- 0.f, -1.f,0.f, 0.f,
- 0.f, 0.f, 1.f, 0.f,
- 0.f, 0.f, 0.f, 1.f);*/
-
- // Add cameras and light sources to the scene root node
- pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras;
- if (pScene->mRootNode->mNumChildren)
- {
- pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ];
-
- // the light source
- aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode();
- nd->mParent = pScene->mRootNode;
- nd->mName.Set("Q3DLight");
- nd->mTransformation = pScene->mRootNode->mTransformation;
- nd->mTransformation.Inverse();
-
- // camera
- nd = pScene->mRootNode->mChildren[1] = new aiNode();
- nd->mParent = pScene->mRootNode;
- nd->mName.Set("Q3DCamera");
- nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/Q3DLoader.h b/src/3rdparty/assimp/code/Q3DLoader.h
deleted file mode 100644
index 97184a5ff..000000000
--- a/src/3rdparty/assimp/code/Q3DLoader.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Q3DLoader.h
- * @brief Declaration of the Q3D importer class.
- */
-#ifndef AI_Q3DLOADER_H_INCLUDED
-#define AI_Q3DLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include <vector>
-#include <stdint.h>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the Quick3D Object and Scene formats.
-*/
-class Q3DImporter : public BaseImporter
-{
-public:
- Q3DImporter();
- ~Q3DImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- struct Material
- {
- Material()
- : diffuse (0.6f,0.6f,0.6f)
- , transparency (0.f)
- , texIdx (UINT_MAX)
- {}
-
- aiString name;
- aiColor3D ambient, diffuse, specular;
- float transparency;
-
- unsigned int texIdx;
- };
-
- struct Face
- {
- explicit Face(unsigned int s)
- : indices (s)
- , uvindices (s)
- , mat (0)
- {
- }
-
- std::vector<unsigned int> indices;
- std::vector<unsigned int> uvindices;
- unsigned int mat;
- };
-
- struct Mesh
- {
-
- std::vector<aiVector3D> verts;
- std::vector<aiVector3D> normals;
- std::vector<aiVector3D> uv;
- std::vector<Face> faces;
-
- uint32_t prevUVIdx;
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_Q3DIMPORTER_H_IN
diff --git a/src/3rdparty/assimp/code/RawLoader.cpp b/src/3rdparty/assimp/code/RawLoader.cpp
deleted file mode 100644
index 2b76455d7..000000000
--- a/src/3rdparty/assimp/code/RawLoader.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 RawLoader.cpp
- * @brief Implementation of the RAW importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
-
-// internal headers
-#include "RawLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Raw Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "raw"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RAWImporter::RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RAWImporter::~RAWImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool RAWImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"raw");
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* RAWImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void RAWImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open RAW file " + pFile + ".");
- }
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
- const char* buffer = &mBuffer2[0];
-
- // list of groups loaded from the file
- std::vector< GroupInformation > outGroups(1,GroupInformation("<default>"));
- std::vector< GroupInformation >::iterator curGroup = outGroups.begin();
-
- // now read all lines
- char line[4096];
- while (GetNextLine(buffer,line))
- {
- // if the line starts with a non-numeric identifier, it marks
- // the beginning of a new group
- const char* sz = line;SkipSpaces(&sz);
- if (IsLineEnd(*sz))continue;
- if (!IsNumeric(*sz))
- {
- const char* sz2 = sz;
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- const unsigned int length = (unsigned int)(sz2-sz);
-
- // find an existing group with this name
- for (std::vector< GroupInformation >::iterator it = outGroups.begin(), end = outGroups.end();
- it != end;++it)
- {
- if (length == (*it).name.length() && !::strcmp(sz,(*it).name.c_str()))
- {
- curGroup = it;sz2 = NULL;
- break;
- }
- }
- if (sz2)
- {
- outGroups.push_back(GroupInformation(std::string(sz,length)));
- curGroup = outGroups.end()-1;
- }
- }
- else
- {
- // there can be maximally 12 floats plus an extra texture file name
- float data[12];
- unsigned int num;
- for (num = 0; num < 12;++num)
- {
- if(!SkipSpaces(&sz) || !IsNumeric(*sz))break;
- sz = fast_atoreal_move<float>(sz,data[num]);
- }
- if (num != 12 && num != 9)
- {
- DefaultLogger::get()->error("A line may have either 9 or 12 floats and an optional texture");
- continue;
- }
-
- MeshInformation* output = NULL;
-
- const char* sz2 = sz;
- unsigned int length;
- if (!IsLineEnd(*sz))
- {
- while (!IsSpaceOrNewLine(*sz2))++sz2;
- length = (unsigned int)(sz2-sz);
- }
- else if (9 == num)
- {
- sz = "%default%";
- length = 9;
- }
- else
- {
- sz = "";
- length = 0;
- }
-
- // search in the list of meshes whether we have one with this texture
- for (auto &mesh : (*curGroup).meshes)
- {
- if (length == mesh.name.length() && (length ? !::strcmp(sz, mesh.name.c_str()) : true))
- {
- output = &mesh;
- break;
- }
- }
- // if we don't have the mesh, create it
- if (!output)
- {
- (*curGroup).meshes.push_back(MeshInformation(std::string(sz,length)));
- output = &((*curGroup).meshes.back());
- }
- if (12 == num)
- {
- aiColor4D v(data[0],data[1],data[2],1.0f);
- output->colors.push_back(v);
- output->colors.push_back(v);
- output->colors.push_back(v);
-
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- output->vertices.push_back(aiVector3D(data[9],data[10],data[11]));
- }
- else
- {
- output->vertices.push_back(aiVector3D(data[0],data[1],data[2]));
- output->vertices.push_back(aiVector3D(data[3],data[4],data[5]));
- output->vertices.push_back(aiVector3D(data[6],data[7],data[8]));
- }
- }
- }
-
- pScene->mRootNode = new aiNode();
- pScene->mRootNode->mName.Set("<RawRoot>");
-
- // count the number of valid groups
- // (meshes can't be empty)
- for (auto & outGroup : outGroups)
- {
- if (!outGroup.meshes.empty())
- {
- ++pScene->mRootNode->mNumChildren;
- pScene->mNumMeshes += (unsigned int) outGroup.meshes.size();
- }
- }
-
- if (!pScene->mNumMeshes)
- {
- throw DeadlyImportError("RAW: No meshes loaded. The file seems to be corrupt or empty.");
- }
-
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- aiNode** cc;
- if (1 == pScene->mRootNode->mNumChildren)
- {
- cc = &pScene->mRootNode;
- pScene->mRootNode->mNumChildren = 0;
- }
- else cc = pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
-
- pScene->mNumMaterials = pScene->mNumMeshes;
- aiMaterial** mats = pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
-
- unsigned int meshIdx = 0;
- for (auto & outGroup : outGroups)
- {
- if (outGroup.meshes.empty())continue;
-
- aiNode* node;
- if (pScene->mRootNode->mNumChildren)
- {
- node = *cc = new aiNode();
- node->mParent = pScene->mRootNode;
- }
- else node = *cc;
- node->mName.Set(outGroup.name);
-
- // add all meshes
- node->mNumMeshes = (unsigned int) outGroup.meshes.size();
- unsigned int* pi = node->mMeshes = new unsigned int[ node->mNumMeshes ];
- for (std::vector< MeshInformation >::iterator it2 = outGroup.meshes.begin(),
- end2 = outGroup.meshes.end(); it2 != end2; ++it2)
- {
- ai_assert(!(*it2).vertices.empty());
-
- // allocate the mesh
- *pi++ = meshIdx;
- aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
- mesh->mMaterialIndex = meshIdx++;
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- // allocate storage for the vertex components and copy them
- mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
- mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];
- ::memcpy(mesh->mVertices,&(*it2).vertices[0],sizeof(aiVector3D)*mesh->mNumVertices);
-
- if ((*it2).colors.size())
- {
- ai_assert((*it2).colors.size() == mesh->mNumVertices);
-
- mesh->mColors[0] = new aiColor4D[ mesh->mNumVertices ];
- ::memcpy(mesh->mColors[0],&(*it2).colors[0],sizeof(aiColor4D)*mesh->mNumVertices);
- }
-
- // generate triangles
- ai_assert(0 == mesh->mNumVertices % 3);
- aiFace* fc = mesh->mFaces = new aiFace[ mesh->mNumFaces = mesh->mNumVertices/3 ];
- aiFace* const fcEnd = fc + mesh->mNumFaces;
- unsigned int n = 0;
- while (fc != fcEnd)
- {
- aiFace& f = *fc++;
- f.mIndices = new unsigned int[f.mNumIndices = 3];
- for (unsigned int m = 0; m < 3;++m)
- f.mIndices[m] = n++;
- }
-
- // generate a material for the mesh
- aiMaterial* mat = new aiMaterial();
-
- aiColor4D clr(1.0f,1.0f,1.0f,1.0f);
- if ("%default%" == (*it2).name) // a gray default material
- {
- clr.r = clr.g = clr.b = 0.6f;
- }
- else if ((*it2).name.length() > 0) // a texture
- {
- aiString s;
- s.Set((*it2).name);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- mat->AddProperty<aiColor4D>(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
- *mats++ = mat;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_RAW_IMPORTER
diff --git a/src/3rdparty/assimp/code/RawLoader.h b/src/3rdparty/assimp/code/RawLoader.h
deleted file mode 100644
index 0a1a35815..000000000
--- a/src/3rdparty/assimp/code/RawLoader.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 RAWLoader.h
- * @brief Declaration of the RAW importer class.
- */
-#ifndef AI_RAWLOADER_H_INCLUDED
-#define AI_RAWLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the PovRay RAW triangle format
-*/
-class RAWImporter : public BaseImporter
-{
-public:
- RAWImporter();
- ~RAWImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- struct MeshInformation
- {
- explicit MeshInformation(const std::string& _name)
- : name(_name)
- {
- vertices.reserve(100);
- colors.reserve(100);
- }
-
- std::string name;
-
- std::vector<aiVector3D> vertices;
- std::vector<aiColor4D> colors;
- };
-
- struct GroupInformation
- {
- explicit GroupInformation(const std::string& _name)
- : name(_name)
- {
- meshes.reserve(10);
- }
-
- std::string name;
- std::vector<MeshInformation> meshes;
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/src/3rdparty/assimp/code/RemoveComments.cpp b/src/3rdparty/assimp/code/RemoveComments.cpp
deleted file mode 100644
index 37d74124d..000000000
--- a/src/3rdparty/assimp/code/RemoveComments.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 RemoveComments.cpp
- * @brief Defines the CommentRemover utility class
- */
-
-#include "RemoveComments.h"
-#include "ParsingUtils.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Remove line comments from a file
-void CommentRemover::RemoveLineComments(const char* szComment,
- char* szBuffer, char chReplacement /* = ' ' */)
-{
- // validate parameters
- ai_assert(NULL != szComment && NULL != szBuffer && *szComment);
-
- const size_t len = strlen(szComment);
- while (*szBuffer) {
-
- // skip over quotes
- if (*szBuffer == '\"' || *szBuffer == '\'')
- while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
-
- if (!strncmp(szBuffer,szComment,len)) {
- while (!IsLineEnd(*szBuffer))
- *szBuffer++ = chReplacement;
- }
- ++szBuffer;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Remove multi-line comments from a file
-void CommentRemover::RemoveMultiLineComments(const char* szCommentStart,
- const char* szCommentEnd,char* szBuffer,
- char chReplacement)
-{
- // validate parameters
- ai_assert(NULL != szCommentStart && NULL != szCommentEnd &&
- NULL != szBuffer && *szCommentStart && *szCommentEnd);
-
- const size_t len = strlen(szCommentEnd);
- const size_t len2 = strlen(szCommentStart);
-
- while (*szBuffer) {
- // skip over quotes
- if (*szBuffer == '\"' || *szBuffer == '\'')
- while (*szBuffer++ && *szBuffer != '\"' && *szBuffer != '\'');
-
- if (!strncmp(szBuffer,szCommentStart,len2)) {
- while (*szBuffer) {
- if (!::strncmp(szBuffer,szCommentEnd,len)) {
- for (unsigned int i = 0; i < len;++i)
- *szBuffer++ = chReplacement;
-
- break;
- }
- *szBuffer++ = chReplacement;
- }
- continue;
- }
- ++szBuffer;
- }
-}
-
-} // !! Assimp
diff --git a/src/3rdparty/assimp/code/RemoveComments.h b/src/3rdparty/assimp/code/RemoveComments.h
deleted file mode 100644
index 0a00a8f0f..000000000
--- a/src/3rdparty/assimp/code/RemoveComments.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Declares a helper class, "CommentRemover", which can be
- * used to remove comments (single and multi line) from a text file.
- */
-#ifndef AI_REMOVE_COMMENTS_H_INC
-#define AI_REMOVE_COMMENTS_H_INC
-
-
-#include <assimp/defs.h>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper class to remove single and multi line comments from a file
- *
- * Some mesh formats like MD5 have comments that are quite similar
- * to those in C or C++ so this code has been moved to a separate
- * module.
- */
-class ASSIMP_API CommentRemover
-{
- // class cannot be instanced
- CommentRemover() {}
-
-public:
-
- //! Remove single-line comments. The end of a line is
- //! expected to be either NL or CR or NLCR.
- //! \param szComment The start sequence of the comment, e.g. "//"
- //! \param szBuffer Buffer to work with
- //! \param chReplacement Character to be used as replacement
- //! for commented lines. By default this is ' '
- static void RemoveLineComments(const char* szComment,
- char* szBuffer, char chReplacement = ' ');
-
- //! Remove multi-line comments. The end of a line is
- //! expected to be either NL or CR or NLCR. Multi-line comments
- //! may not be nested (as in C).
- //! \param szCommentStart The start sequence of the comment, e.g. "/*"
- //! \param szCommentEnd The end sequence of the comment, e.g. "*/"
- //! \param szBuffer Buffer to work with
- //! \param chReplacement Character to be used as replacement
- //! for commented lines. By default this is ' '
- static void RemoveMultiLineComments(const char* szCommentStart,
- const char* szCommentEnd,char* szBuffer,
- char chReplacement = ' ');
-};
-} // ! Assimp
-
-#endif // !! AI_REMOVE_COMMENTS_H_INC
diff --git a/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp b/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp
deleted file mode 100644
index c6319f892..000000000
--- a/src/3rdparty/assimp/code/RemoveRedundantMaterials.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 RemoveRedundantMaterials.cpp
- * @brief Implementation of the "RemoveRedundantMaterials" post processing step
-*/
-
-// internal headers
-
-#include "RemoveRedundantMaterials.h"
-#include "ParsingUtils.h"
-#include "ProcessHelper.h"
-#include "MaterialSystem.h"
-#include <stdio.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
-: configFixedMaterials() {
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveRedundantMatsProcess::~RemoveRedundantMatsProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
-{
- // Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
- configFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("RemoveRedundantMatsProcess begin");
-
- unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
- if (pScene->mNumMaterials)
- {
- // Find out which materials are referenced by meshes
- std::vector<bool> abReferenced(pScene->mNumMaterials,false);
- for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
- abReferenced[pScene->mMeshes[i]->mMaterialIndex] = true;
-
- // If a list of materials to be excluded was given, match the list with
- // our imported materials and 'salt' all positive matches to ensure that
- // we get unique hashes later.
- if (configFixedMaterials.length()) {
-
- std::list<std::string> strings;
- ConvertListToStrings(configFixedMaterials,strings);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
- aiMaterial* mat = pScene->mMaterials[i];
-
- aiString name;
- mat->Get(AI_MATKEY_NAME,name);
-
- if (name.length) {
- std::list<std::string>::const_iterator it = std::find(strings.begin(), strings.end(), name.data);
- if (it != strings.end()) {
-
- // Our brilliant 'salt': A single material property with ~ as first
- // character to mark it as internal and temporary.
- const int dummy = 1;
- ((aiMaterial*)mat)->AddProperty(&dummy,1,"~RRM.UniqueMaterial",0,0);
-
- // Keep this material even if no mesh references it
- abReferenced[i] = true;
- DefaultLogger::get()->debug(std::string("Found positive match in exclusion list: \'") + name.data + "\'");
- }
- }
- }
- }
-
- // TODO: re-implement this algorithm to work in-place
- unsigned int *aiMappingTable = new unsigned int[pScene->mNumMaterials];
- for ( unsigned int i=0; i<pScene->mNumMaterials; i++ ) {
- aiMappingTable[ i ] = 0;
- }
- unsigned int iNewNum = 0;
-
- // Iterate through all materials and calculate a hash for them
- // store all hashes in a list and so a quick search whether
- // we do already have a specific hash. This allows us to
- // determine which materials are identical.
- uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
- {
- // No mesh is referencing this material, remove it.
- if (!abReferenced[i]) {
- ++unreferencedRemoved;
- delete pScene->mMaterials[i];
- pScene->mMaterials[i] = nullptr;
- 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]) {
- ++redundantRemoved;
- me = 0;
- aiMappingTable[i] = aiMappingTable[a];
- delete pScene->mMaterials[i];
- pScene->mMaterials[i] = nullptr;
- break;
- }
- }
- // This is a new material that is referenced, add to the map.
- if (me) {
- aiMappingTable[i] = iNewNum++;
- }
- }
- // 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) {
- ai_assert(iNewNum > 0);
- 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]) {
- continue;
- }
-
- // generate new names for modified materials that had no names
- const unsigned int idx = aiMappingTable[p];
- if (ppcMaterials[idx]) {
- aiString sz;
- if( ppcMaterials[idx]->Get(AI_MATKEY_NAME, sz) != AI_SUCCESS ) {
- sz.length = ::ai_snprintf(sz.data,MAXLEN,"JoinedMaterial_#%u",p);
- ((aiMaterial*)ppcMaterials[idx])->AddProperty(&sz,AI_MATKEY_NAME);
- }
- } else {
- ppcMaterials[idx] = pScene->mMaterials[p];
- }
- }
- // update all material indices
- for (unsigned int p = 0; p < pScene->mNumMeshes;++p) {
- aiMesh* mesh = pScene->mMeshes[p];
- ai_assert( NULL!=mesh );
- mesh->mMaterialIndex = aiMappingTable[mesh->mMaterialIndex];
- }
- // delete the old material list
- delete[] pScene->mMaterials;
- pScene->mMaterials = ppcMaterials;
- pScene->mNumMaterials = iNewNum;
- }
- // delete temporary storage
- delete[] aiHashes;
- delete[] aiMappingTable;
- }
- if (redundantRemoved == 0 && unreferencedRemoved == 0)
- {
- DefaultLogger::get()->debug("RemoveRedundantMatsProcess finished ");
- }
- else
- {
- char szBuffer[128]; // should be sufficiently large
- ::ai_snprintf(szBuffer,128,"RemoveRedundantMatsProcess finished. Removed %u redundant and %u unused materials.",
- redundantRemoved,unreferencedRemoved);
- DefaultLogger::get()->info(szBuffer);
- }
-}
diff --git a/src/3rdparty/assimp/code/RemoveRedundantMaterials.h b/src/3rdparty/assimp/code/RemoveRedundantMaterials.h
deleted file mode 100644
index cb4ec02bb..000000000
--- a/src/3rdparty/assimp/code/RemoveRedundantMaterials.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 RemoveRedundantMaterials.h
- * @brief Defines a post processing step to remove redundant materials
- */
-#ifndef AI_REMOVEREDUNDANTMATERIALS_H_INC
-#define AI_REMOVEREDUNDANTMATERIALS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-class RemoveRedundantMatsTest;
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** RemoveRedundantMatsProcess: Post-processing step to remove redundant
- * materials from the imported scene.
- */
-class ASSIMP_API RemoveRedundantMatsProcess : public BaseProcess
-{
-public:
- /// The default class constructor.
- RemoveRedundantMatsProcess();
-
- /// The class destructor.
- ~RemoveRedundantMatsProcess();
-
-public:
- // -------------------------------------------------------------------
- // Check whether step is active
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- // Execute step on a given scene
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- // Setup import settings
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Set list of fixed (unmutable) materials
- * @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
- */
- void SetFixedMaterialsString(const std::string& fixed = "") {
- configFixedMaterials = fixed;
- }
-
- // -------------------------------------------------------------------
- /** @brief Get list of fixed (unmutable) materials
- * @return See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
- */
- const std::string& GetFixedMaterialsString() const {
- return configFixedMaterials;
- }
-
-private:
-
- //! Configuration option: list of all fixed materials
- std::string configFixedMaterials;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_REMOVEREDUNDANTMATERIALS_H_INC
diff --git a/src/3rdparty/assimp/code/RemoveVCProcess.cpp b/src/3rdparty/assimp/code/RemoveVCProcess.cpp
deleted file mode 100644
index 016757dbb..000000000
--- a/src/3rdparty/assimp/code/RemoveVCProcess.cpp
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the post processing step to remove
- * any parts of the mesh structure from the imported data.
-*/
-
-
-#include "RemoveVCProcess.h"
-#include <assimp/postprocess.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-RemoveVCProcess::RemoveVCProcess() :
- configDeleteFlags()
- , mScene()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-RemoveVCProcess::~RemoveVCProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool RemoveVCProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_RemoveComponent) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Small helper function to delete all elements in a T** aray using delete
-template <typename T>
-inline void ArrayDelete(T**& in, unsigned int& num)
-{
- for (unsigned int i = 0; i < num; ++i)
- delete in[i];
-
- delete[] in;
- in = NULL;
- num = 0;
-}
-
-#if 0
-// ------------------------------------------------------------------------------------------------
-// Updates the node graph - removes all nodes which have the "remove" flag set and the
-// "don't remove" flag not set. Nodes with meshes are never deleted.
-bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
-{
- bool b = false;
-
- std::list<aiNode*> mine;
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- {
- if(UpdateNodeGraph(node->mChildren[i],mine,false))
- b = true;
- }
-
- // somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
- // so we can do a simple comparison against MSB here
- if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
- {
- // this node needs to be removed
- if(node->mNumChildren)
- {
- childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
-
- // set all children to NULL to make sure they are not deleted when we delete ourself
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- node->mChildren[i] = NULL;
- }
- b = true;
- delete node;
- }
- else
- {
- AI_RC_UNMASK(node->mNumMeshes);
- childsOfParent.push_back(node);
-
- if (b)
- {
- // reallocate the array of our children here
- node->mNumChildren = (unsigned int)mine.size();
- aiNode** const children = new aiNode*[mine.size()];
- aiNode** ptr = children;
-
- for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
- it != end; ++it)
- {
- *ptr++ = *it;
- }
- delete[] node->mChildren;
- node->mChildren = children;
- return false;
- }
- }
- return b;
-}
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void RemoveVCProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("RemoveVCProcess begin");
- bool bHas = false; //,bMasked = false;
-
- mScene = pScene;
-
- // handle animations
- if ( configDeleteFlags & aiComponent_ANIMATIONS)
- {
-
- bHas = true;
- ArrayDelete(pScene->mAnimations,pScene->mNumAnimations);
- }
-
- // handle textures
- if ( configDeleteFlags & aiComponent_TEXTURES)
- {
- bHas = true;
- ArrayDelete(pScene->mTextures,pScene->mNumTextures);
- }
-
- // handle materials
- if ( configDeleteFlags & aiComponent_MATERIALS && pScene->mNumMaterials)
- {
- bHas = true;
- for (unsigned int i = 1;i < pScene->mNumMaterials;++i)
- delete pScene->mMaterials[i];
-
- pScene->mNumMaterials = 1;
- aiMaterial* helper = (aiMaterial*) pScene->mMaterials[0];
- ai_assert(NULL != helper);
- helper->Clear();
-
- // gray
- aiColor3D clr(0.6f,0.6f,0.6f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // add a small ambient color value
- clr = aiColor3D(0.05f,0.05f,0.05f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString s;
- s.Set("Dummy_MaterialsRemoved");
- helper->AddProperty(&s,AI_MATKEY_NAME);
- }
-
- // handle light sources
- if ( configDeleteFlags & aiComponent_LIGHTS)
- {
- bHas = true;
- ArrayDelete(pScene->mLights,pScene->mNumLights);
- }
-
- // handle camneras
- if ( configDeleteFlags & aiComponent_CAMERAS)
- {
- bHas = true;
- ArrayDelete(pScene->mCameras,pScene->mNumCameras);
- }
-
- // handle meshes
- if (configDeleteFlags & aiComponent_MESHES)
- {
- bHas = true;
- ArrayDelete(pScene->mMeshes,pScene->mNumMeshes);
- }
- else
- {
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if( ProcessMesh( pScene->mMeshes[a]))
- bHas = true;
- }
- }
-
-
- // now check whether the result is still a full scene
- if (!pScene->mNumMeshes || !pScene->mNumMaterials)
- {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- DefaultLogger::get()->debug("Setting AI_SCENE_FLAGS_INCOMPLETE flag");
-
- // If we have no meshes anymore we should also clear another flag ...
- if (!pScene->mNumMeshes)
- pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- }
-
- if (bHas)DefaultLogger::get()->info("RemoveVCProcess finished. Data structure cleanup has been done.");
- else DefaultLogger::get()->debug("RemoveVCProcess finished. Nothing to be done ...");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the step
-void RemoveVCProcess::SetupProperties(const Importer* pImp)
-{
- configDeleteFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS,0x0);
- if (!configDeleteFlags)
- {
- DefaultLogger::get()->warn("RemoveVCProcess: AI_CONFIG_PP_RVC_FLAGS is zero.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-bool RemoveVCProcess::ProcessMesh(aiMesh* pMesh)
-{
- bool ret = false;
-
- // if all materials have been deleted let the material
- // index of the mesh point to the created default material
- if ( configDeleteFlags & aiComponent_MATERIALS)
- pMesh->mMaterialIndex = 0;
-
- // handle normals
- if (configDeleteFlags & aiComponent_NORMALS && pMesh->mNormals)
- {
- delete[] pMesh->mNormals;
- pMesh->mNormals = NULL;
- ret = true;
- }
-
- // handle tangents and bitangents
- if (configDeleteFlags & aiComponent_TANGENTS_AND_BITANGENTS && pMesh->mTangents)
- {
- delete[] pMesh->mTangents;
- pMesh->mTangents = NULL;
-
- delete[] pMesh->mBitangents;
- pMesh->mBitangents = NULL;
- ret = true;
- }
-
- // handle texture coordinates
- bool b = (0 != (configDeleteFlags & aiComponent_TEXCOORDS));
- for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++real)
- {
- if (!pMesh->mTextureCoords[i])break;
- if (configDeleteFlags & aiComponent_TEXCOORDSn(real) || b)
- {
- delete [] pMesh->mTextureCoords[i];
- pMesh->mTextureCoords[i] = NULL;
- ret = true;
-
- if (!b)
- {
- // collapse the rest of the array
- for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_TEXTURECOORDS;++a)
- pMesh->mTextureCoords[a-1] = pMesh->mTextureCoords[a];
-
- pMesh->mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS-1] = NULL;
- continue;
- }
- }
- ++i;
- }
-
- // handle vertex colors
- b = (0 != (configDeleteFlags & aiComponent_COLORS));
- for (unsigned int i = 0, real = 0; real < AI_MAX_NUMBER_OF_COLOR_SETS; ++real)
- {
- if (!pMesh->mColors[i])break;
- if (configDeleteFlags & aiComponent_COLORSn(i) || b)
- {
- delete [] pMesh->mColors[i];
- pMesh->mColors[i] = NULL;
- ret = true;
-
- if (!b)
- {
- // collapse the rest of the array
- for (unsigned int a = i+1; a < AI_MAX_NUMBER_OF_COLOR_SETS;++a)
- pMesh->mColors[a-1] = pMesh->mColors[a];
-
- pMesh->mColors[AI_MAX_NUMBER_OF_COLOR_SETS-1] = NULL;
- continue;
- }
- }
- ++i;
- }
-
- // handle bones
- if (configDeleteFlags & aiComponent_BONEWEIGHTS && pMesh->mBones)
- {
- ArrayDelete(pMesh->mBones,pMesh->mNumBones);
- ret = true;
- }
- return ret;
-}
diff --git a/src/3rdparty/assimp/code/RemoveVCProcess.h b/src/3rdparty/assimp/code/RemoveVCProcess.h
deleted file mode 100644
index d7d45e73e..000000000
--- a/src/3rdparty/assimp/code/RemoveVCProcess.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to remove specific parts of the scene */
-#ifndef AI_REMOVEVCPROCESS_H_INCLUDED
-#define AI_REMOVEVCPROCESS_H_INCLUDED
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-class RemoveVCProcessTest;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** RemoveVCProcess: Class to exclude specific parts of the data structure
- * from further processing by removing them,
-*/
-class ASSIMP_API RemoveVCProcess : public BaseProcess {
-public:
- /// The default class constructor.
- RemoveVCProcess();
-
- /// The class destructor.
- ~RemoveVCProcess();
-
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
- // -------------------------------------------------------------------
- /** Manually setup the configuration flags for the step
- *
- * @param Bitwise combination of the #aiComponent enumerated values.
- */
- void SetDeleteFlags(unsigned int f)
- {
- configDeleteFlags = f;
- }
-
- // -------------------------------------------------------------------
- /** Query the current configuration.
- */
- unsigned int GetDeleteFlags() const
- {
- return configDeleteFlags;
- }
-
-private:
-
- bool ProcessMesh (aiMesh* pcMesh);
-
- /** Configuration flag
- */
- unsigned int configDeleteFlags;
-
- /** The scene we're working with
- */
- aiScene* mScene;
-};
-
-// ---------------------------------------------------------------------------
-
-} // end of namespace Assimp
-
-#endif // !!AI_REMOVEVCPROCESS_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/SGSpatialSort.cpp b/src/3rdparty/assimp/code/SGSpatialSort.cpp
deleted file mode 100644
index 7a80381e2..000000000
--- a/src/3rdparty/assimp/code/SGSpatialSort.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the helper class to quickly find
-vertices close to a given position. Special implementation for
-the 3ds loader handling smooth groups correctly */
-
-#include "SGSpatialSort.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-SGSpatialSort::SGSpatialSort()
-{
- // define the reference plane. We choose some arbitrary vector away from all basic axises
- // in the hope that no model spreads all its vertices along this plane.
- mPlaneNormal.Set( 0.8523f, 0.34321f, 0.5736f);
- mPlaneNormal.Normalize();
-}
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SGSpatialSort::~SGSpatialSort()
-{
- // nothing to do here, everything destructs automatically
-}
-// ------------------------------------------------------------------------------------------------
-void SGSpatialSort::Add(const aiVector3D& vPosition, unsigned int index,
- unsigned int smoothingGroup)
-{
- // store position by index and distance
- float distance = vPosition * mPlaneNormal;
- mPositions.push_back( Entry( index, vPosition,
- distance, smoothingGroup));
-}
-// ------------------------------------------------------------------------------------------------
-void SGSpatialSort::Prepare()
-{
- // now sort the array ascending by distance.
- std::sort( this->mPositions.begin(), this->mPositions.end());
-}
-// ------------------------------------------------------------------------------------------------
-// Returns an iterator for all positions close to the given position.
-void SGSpatialSort::FindPositions( const aiVector3D& pPosition,
- uint32_t pSG,
- float pRadius,
- std::vector<unsigned int>& poResults,
- bool exactMatch /*= false*/) const
-{
- float dist = pPosition * mPlaneNormal;
- float minDist = dist - pRadius, maxDist = dist + pRadius;
-
- // clear the array
- poResults.clear();
-
- // quick check for positions outside the range
- if( mPositions.empty() )
- return;
- if( maxDist < mPositions.front().mDistance)
- return;
- if( minDist > mPositions.back().mDistance)
- return;
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while( binaryStepSize > 1)
- {
- if( mPositions[index].mDistance < minDist)
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while( index > 0 && mPositions[index].mDistance > minDist)
- index--;
- while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
- index++;
-
- // Mow start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the given radius to the result aray
-
- float squareEpsilon = pRadius * pRadius;
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- std::vector<Entry>::const_iterator end = mPositions.end();
-
- if (exactMatch)
- {
- while( it->mDistance < maxDist)
- {
- if((it->mPosition - pPosition).SquareLength() < squareEpsilon && it->mSmoothGroups == pSG)
- {
- poResults.push_back( it->mIndex);
- }
- ++it;
- if( end == it )break;
- }
- }
- else
- {
- // if the given smoothing group is 0, we'll return all surrounding vertices
- if (!pSG)
- {
- while( it->mDistance < maxDist)
- {
- if((it->mPosition - pPosition).SquareLength() < squareEpsilon)
- poResults.push_back( it->mIndex);
- ++it;
- if( end == it)break;
- }
- }
- else while( it->mDistance < maxDist)
- {
- if((it->mPosition - pPosition).SquareLength() < squareEpsilon &&
- (it->mSmoothGroups & pSG || !it->mSmoothGroups))
- {
- poResults.push_back( it->mIndex);
- }
- ++it;
- if( end == it)break;
- }
- }
-}
-
-
diff --git a/src/3rdparty/assimp/code/SGSpatialSort.h b/src/3rdparty/assimp/code/SGSpatialSort.h
deleted file mode 100644
index e7cd38724..000000000
--- a/src/3rdparty/assimp/code/SGSpatialSort.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-/** Small helper classes to optimize finding vertices close to a given location
- */
-#ifndef AI_D3DSSPATIALSORT_H_INC
-#define AI_D3DSSPATIALSORT_H_INC
-
-#include <assimp/types.h>
-#include <vector>
-#include <stdint.h>
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** Specialized version of SpatialSort to support smoothing groups
- * This is used in by the 3DS, ASE and LWO loaders. 3DS and ASE share their
- * normal computation code in SmoothingGroups.inl, the LWO loader has its own
- * implementation to handle all details of its file format correctly.
- */
-// ----------------------------------------------------------------------------------
-class SGSpatialSort
-{
-public:
-
- SGSpatialSort();
-
- // -------------------------------------------------------------------
- /** Construction from a given face array, handling smoothing groups
- * properly
- */
- explicit SGSpatialSort(const std::vector<aiVector3D>& vPositions);
-
- // -------------------------------------------------------------------
- /** Add a vertex to the spatial sort
- * @param vPosition Vertex position to be added
- * @param index Index of the vrtex
- * @param smoothingGroup SmoothingGroup for this vertex
- */
- void Add(const aiVector3D& vPosition, unsigned int index,
- unsigned int smoothingGroup);
-
- // -------------------------------------------------------------------
- /** Prepare the spatial sorter for use. This step runs in O(logn)
- */
- void Prepare();
-
- /** Destructor */
- ~SGSpatialSort();
-
- // -------------------------------------------------------------------
- /** Returns an iterator for all positions close to the given position.
- * @param pPosition The position to look for vertices.
- * @param pSG Only included vertices with at least one shared smooth group
- * @param pRadius Maximal distance from the position a vertex may have
- * to be counted in.
- * @param poResults The container to store the indices of the found
- * positions. Will be emptied by the call so it may contain anything.
- * @param exactMatch Specifies whether smoothing groups are bit masks
- * (false) or integral values (true). In the latter case, a vertex
- * cannot belong to more than one smoothing group.
- * @return An iterator to iterate over all vertices in the given area.
- */
- // -------------------------------------------------------------------
- void FindPositions( const aiVector3D& pPosition, uint32_t pSG,
- float pRadius, std::vector<unsigned int>& poResults,
- bool exactMatch = false) const;
-
-protected:
- /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
- aiVector3D mPlaneNormal;
-
- // -------------------------------------------------------------------
- /** An entry in a spatially sorted position array. Consists of a
- * vertex index, its position and its precalculated distance from
- * the reference plane */
- // -------------------------------------------------------------------
- struct Entry
- {
- unsigned int mIndex; ///< The vertex referred by this entry
- aiVector3D mPosition; ///< Position
- uint32_t mSmoothGroups;
- float mDistance; ///< Distance of this vertex to the sorting plane
-
- Entry() { /** intentionally not initialized.*/ }
- Entry( unsigned int pIndex, const aiVector3D& pPosition, float pDistance,uint32_t pSG)
- :
- mIndex( pIndex),
- mPosition( pPosition),
- mSmoothGroups (pSG),
- mDistance( pDistance)
- { }
-
- bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
- };
-
- // all positions, sorted by distance to the sorting plane
- std::vector<Entry> mPositions;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SPATIALSORT_H_INC
diff --git a/src/3rdparty/assimp/code/SIBImporter.cpp b/src/3rdparty/assimp/code/SIBImporter.cpp
deleted file mode 100644
index 2127e2e0c..000000000
--- a/src/3rdparty/assimp/code/SIBImporter.cpp
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SIBImporter.cpp
- * @brief Implementation of the SIB importer class.
- *
- * The Nevercenter Silo SIB format is undocumented.
- * All details here have been reverse engineered from
- * studying the binary files output by Silo.
- *
- * Nevertheless, this implementation is reasonably complete.
- */
-
-
-#ifndef ASSIMP_BUILD_NO_SIB_IMPORTER
-
-// internal headers
-#include "SIBImporter.h"
-#include "ByteSwapper.h"
-#include "StreamReader.h"
-#include "TinyFormatter.h"
-//#include "../contrib/ConvertUTF/ConvertUTF.h"
-#include "../contrib/utf8cpp/source/utf8.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include <map>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Silo SIB Importer",
- "Richard Mitton (http://www.codersnotes.com/about)",
- "",
- "Does not apply subdivision.",
- aiImporterFlags_SupportBinaryFlavour,
- 0, 0,
- 0, 0,
- "sib"
-};
-
-struct SIBChunk {
- uint32_t Tag;
- uint32_t Size;
-} PACK_STRUCT;
-
-enum {
- POS,
- NRM,
- UV,
- N
-};
-
-typedef std::pair<uint32_t, uint32_t> SIBPair;
-
-struct SIBEdge {
- uint32_t faceA, faceB;
- bool creased;
-};
-
-struct SIBMesh {
- aiMatrix4x4 axis;
- uint32_t numPts;
- std::vector<aiVector3D> pos, nrm, uv;
- std::vector<uint32_t> idx;
- std::vector<uint32_t> faceStart;
- std::vector<uint32_t> mtls;
- std::vector<SIBEdge> edges;
- std::map<SIBPair, uint32_t> edgeMap;
-};
-
-struct SIBObject {
- aiString name;
- aiMatrix4x4 axis;
- size_t meshIdx, meshCount;
-};
-
-struct SIB {
- std::vector<aiMaterial*> mtls;
- std::vector<aiMesh*> meshes;
- std::vector<aiLight*> lights;
- std::vector<SIBObject> objs, insts;
-};
-
-// ------------------------------------------------------------------------------------------------
-static SIBEdge& GetEdge(SIBMesh* mesh, uint32_t posA, uint32_t posB) {
- SIBPair pair = (posA < posB) ? SIBPair(posA, posB) : SIBPair(posB, posA);
- std::map<SIBPair, uint32_t>::iterator it = mesh->edgeMap.find(pair);
- if (it != mesh->edgeMap.end())
- return mesh->edges[it->second];
-
- SIBEdge edge;
- edge.creased = false;
- edge.faceA = edge.faceB = 0xffffffff;
- mesh->edgeMap[pair] = static_cast<uint32_t>(mesh->edges.size());
- mesh->edges.push_back(edge);
- return mesh->edges.back();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Helpers for reading chunked data.
-
-#define TAG(A,B,C,D) ((A << 24) | (B << 16) | (C << 8) | D)
-
-static SIBChunk ReadChunk(StreamReaderLE* stream)
-{
- SIBChunk chunk;
- chunk.Tag = stream->GetU4();
- chunk.Size = stream->GetU4();
- if (chunk.Size > stream->GetRemainingSizeToLimit())
- DefaultLogger::get()->error("SIB: Chunk overflow");
- ByteSwap::Swap4(&chunk.Tag);
- return chunk;
-}
-
-static aiColor3D ReadColor(StreamReaderLE* stream)
-{
- float r = stream->GetF4();
- float g = stream->GetF4();
- float b = stream->GetF4();
- stream->GetU4(); // Colors have an unused(?) 4th component.
- return aiColor3D(r, g, b);
-}
-
-static void UnknownChunk(StreamReaderLE* /*stream*/, const SIBChunk& chunk)
-{
- char temp[5] = {
- static_cast<char>(( chunk.Tag>>24 ) & 0xff),
- static_cast<char>(( chunk.Tag>>16 ) & 0xff),
- static_cast<char>(( chunk.Tag>>8 ) & 0xff),
- static_cast<char>(chunk.Tag & 0xff), '\0'
- };
-
- DefaultLogger::get()->warn((Formatter::format(), "SIB: Skipping unknown '",temp,"' chunk."));
-}
-
-// Reads a UTF-16LE string and returns it at UTF-8.
-static aiString ReadString(StreamReaderLE *stream, uint32_t numWChars) {
- if ( nullptr == stream || 0 == numWChars ) {
- static const aiString empty;
- return empty;
- }
-
- // Allocate buffers (max expansion is 1 byte -> 4 bytes for UTF-8)
- std::vector<unsigned char> str;
- str.reserve( numWChars * 4 + 1 );
- uint16_t *temp = new uint16_t[ numWChars ];
- for ( uint32_t n = 0; n < numWChars; ++n ) {
- temp[ n ] = stream->GetU2();
- }
-
- // Convert it and NUL-terminate.
- const uint16_t *start( temp ), *end( temp + numWChars );
- utf8::utf16to8( start, end, back_inserter( str ) );
- str[ str.size() - 1 ] = '\0';
-
- // Return the final string.
- aiString result = aiString((const char *)&str[0]);
- delete[] temp;
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-SIBImporter::SIBImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SIBImporter::~SIBImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool SIBImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
- return SimpleExtensionCheck(pFile, "sib");
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* SIBImporter::GetInfo () const {
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadVerts(SIBMesh* mesh, StreamReaderLE* stream, uint32_t count) {
- if ( nullptr == mesh || nullptr == stream ) {
- return;
- }
-
- mesh->pos.resize(count);
- for ( uint32_t n=0; n<count; ++n ) {
- mesh->pos[ n ].x = stream->GetF4();
- mesh->pos[ n ].y = stream->GetF4();
- mesh->pos[ n ].z = stream->GetF4();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadFaces(SIBMesh* mesh, StreamReaderLE* stream)
-{
- uint32_t ptIdx = 0;
- while (stream->GetRemainingSizeToLimit() > 0)
- {
- uint32_t numPoints = stream->GetU4();
-
- // Store room for the N index channels, plus the point count.
- size_t pos = mesh->idx.size() + 1;
- mesh->idx.resize(pos + numPoints*N);
- mesh->idx[pos-1] = numPoints;
- uint32_t *idx = &mesh->idx[pos];
-
- mesh->faceStart.push_back(static_cast<uint32_t>(pos-1));
- mesh->mtls.push_back(0);
-
- // Read all the position data.
- // UV/normals will be supplied later.
- // Positions are supplied indexed already, so we preserve that
- // mapping. UVs are supplied uniquely, so we allocate unique indices.
- for (uint32_t n=0;n<numPoints;n++,idx+=N,ptIdx++)
- {
- uint32_t p = stream->GetU4();
- if (p >= mesh->pos.size())
- throw DeadlyImportError("Vertex index is out of range.");
- idx[POS] = p;
- idx[NRM] = ptIdx;
- idx[UV] = ptIdx;
- }
- }
-
- // Allocate data channels for normals/UVs.
- mesh->nrm.resize(ptIdx, aiVector3D(0,0,0));
- mesh->uv.resize(ptIdx, aiVector3D(0,0,0));
-
- mesh->numPts = ptIdx;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadUVs(SIBMesh* mesh, StreamReaderLE* stream)
-{
- while (stream->GetRemainingSizeToLimit() > 0)
- {
- uint32_t faceIdx = stream->GetU4();
- uint32_t numPoints = stream->GetU4();
-
- if (faceIdx >= mesh->faceStart.size())
- throw DeadlyImportError("Invalid face index.");
-
- uint32_t pos = mesh->faceStart[faceIdx];
- uint32_t *idx = &mesh->idx[pos + 1];
-
- for (uint32_t n=0;n<numPoints;n++,idx+=N)
- {
- uint32_t id = idx[UV];
- mesh->uv[id].x = stream->GetF4();
- mesh->uv[id].y = stream->GetF4();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadMtls(SIBMesh* mesh, StreamReaderLE* stream)
-{
- // Material assignments are stored run-length encoded.
- // Also, we add 1 to each material so that we can use mtl #0
- // as the default material.
- uint32_t prevFace = stream->GetU4();
- uint32_t prevMtl = stream->GetU4() + 1;
- while (stream->GetRemainingSizeToLimit() > 0)
- {
- uint32_t face = stream->GetU4();
- uint32_t mtl = stream->GetU4() + 1;
- while (prevFace < face)
- {
- if (prevFace >= mesh->mtls.size())
- throw DeadlyImportError("Invalid face index.");
- mesh->mtls[prevFace++] = prevMtl;
- }
-
- prevFace = face;
- prevMtl = mtl;
- }
-
- while (prevFace < mesh->mtls.size())
- mesh->mtls[prevFace++] = prevMtl;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadAxis(aiMatrix4x4& axis, StreamReaderLE* stream)
-{
- axis.a4 = stream->GetF4();
- axis.b4 = stream->GetF4();
- axis.c4 = stream->GetF4();
- axis.d4 = 1;
- axis.a1 = stream->GetF4();
- axis.b1 = stream->GetF4();
- axis.c1 = stream->GetF4();
- axis.d1 = 0;
- axis.a2 = stream->GetF4();
- axis.b2 = stream->GetF4();
- axis.c2 = stream->GetF4();
- axis.d2 = 0;
- axis.a3 = stream->GetF4();
- axis.b3 = stream->GetF4();
- axis.c3 = stream->GetF4();
- axis.d3 = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadEdges(SIBMesh* mesh, StreamReaderLE* stream)
-{
- while (stream->GetRemainingSizeToLimit() > 0)
- {
- uint32_t posA = stream->GetU4();
- uint32_t posB = stream->GetU4();
- GetEdge(mesh, posA, posB);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadCreases(SIBMesh* mesh, StreamReaderLE* stream)
-{
- while (stream->GetRemainingSizeToLimit() > 0)
- {
- uint32_t edge = stream->GetU4();
- if (edge >= mesh->edges.size())
- throw DeadlyImportError("SIB: Invalid edge index.");
- mesh->edges[edge].creased = true;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ConnectFaces(SIBMesh* mesh)
-{
- // Find faces connected to each edge.
- size_t numFaces = mesh->faceStart.size();
- for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
- {
- uint32_t *idx = &mesh->idx[mesh->faceStart[faceIdx]];
- uint32_t numPoints = *idx++;
- uint32_t prev = idx[(numPoints-1)*N+POS];
-
- for (uint32_t i=0;i<numPoints;i++,idx+=N)
- {
- uint32_t next = idx[POS];
-
- // Find this edge.
- SIBEdge& edge = GetEdge(mesh, prev, next);
-
- // Link this face onto it.
- // This gives potentially undesirable normals when used
- // with non-2-manifold surfaces, but then so does Silo to begin with.
- if (edge.faceA == 0xffffffff)
- edge.faceA = static_cast<uint32_t>(faceIdx);
- else if (edge.faceB == 0xffffffff)
- edge.faceB = static_cast<uint32_t>(faceIdx);
-
- prev = next;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-static aiVector3D CalculateVertexNormal(SIBMesh* mesh, uint32_t faceIdx, uint32_t pos,
- const std::vector<aiVector3D>& faceNormals)
-{
- // Creased edges complicate this. We need to find the start/end range of the
- // ring of faces that touch this position.
- // We do this in two passes. The first pass is to find the end of the range,
- // the second is to work backwards to the start and calculate the final normal.
- aiVector3D vtxNormal;
- for (int pass=0;pass<2;pass++)
- {
- vtxNormal = aiVector3D(0, 0, 0);
- uint32_t startFaceIdx = faceIdx;
- uint32_t prevFaceIdx = faceIdx;
-
- // Process each connected face.
- while (true)
- {
- // Accumulate the face normal.
- vtxNormal += faceNormals[faceIdx];
-
- uint32_t nextFaceIdx = 0xffffffff;
-
- // Move to the next edge sharing this position.
- uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]];
- uint32_t numPoints = *idx++;
- uint32_t posA = idx[(numPoints-1)*N+POS];
- for (uint32_t n=0;n<numPoints;n++,idx+=N)
- {
- uint32_t posB = idx[POS];
-
- // Test if this edge shares our target position.
- if (posA == pos || posB == pos)
- {
- SIBEdge& edge = GetEdge(mesh, posA, posB);
-
- // Non-manifold meshes can produce faces which share
- // positions but have no edge entry, so check it.
- if (edge.faceA == faceIdx || edge.faceB == faceIdx)
- {
- // Move to whichever side we didn't just come from.
- if (!edge.creased) {
- if (edge.faceA != prevFaceIdx && edge.faceA != faceIdx && edge.faceA != 0xffffffff)
- nextFaceIdx = edge.faceA;
- else if (edge.faceB != prevFaceIdx && edge.faceB != faceIdx && edge.faceB != 0xffffffff)
- nextFaceIdx = edge.faceB;
- }
- }
- }
-
- posA = posB;
- }
-
- // Stop once we hit either an creased/unconnected edge, or we
- // wrapped around and hit our start point.
- if (nextFaceIdx == 0xffffffff || nextFaceIdx == startFaceIdx)
- break;
-
- prevFaceIdx = faceIdx;
- faceIdx = nextFaceIdx;
- }
- }
-
- // Normalize it.
- float len = vtxNormal.Length();
- if (len > 0.000000001f)
- vtxNormal /= len;
- return vtxNormal;
-}
-
-// ------------------------------------------------------------------------------------------------
-static void CalculateNormals(SIBMesh* mesh)
-{
- size_t numFaces = mesh->faceStart.size();
-
- // Calculate face normals.
- std::vector<aiVector3D> faceNormals(numFaces);
- for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
- {
- uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]];
- uint32_t numPoints = *idx++;
-
- aiVector3D faceNormal(0, 0, 0);
-
- uint32_t *prev = &idx[(numPoints-1)*N];
-
- for (uint32_t i=0;i<numPoints;i++)
- {
- uint32_t *next = &idx[i*N];
-
- faceNormal += mesh->pos[prev[POS]] ^ mesh->pos[next[POS]];
- prev = next;
- }
-
- faceNormals[faceIdx] = faceNormal;
- }
-
- // Calculate vertex normals.
- for (size_t faceIdx=0;faceIdx<numFaces;faceIdx++)
- {
- uint32_t* idx = &mesh->idx[mesh->faceStart[faceIdx]];
- uint32_t numPoints = *idx++;
-
- for (uint32_t i=0;i<numPoints;i++)
- {
- uint32_t pos = idx[i*N+POS];
- uint32_t nrm = idx[i*N+NRM];
- aiVector3D vtxNorm = CalculateVertexNormal(mesh, static_cast<uint32_t>(faceIdx), pos, faceNormals);
- mesh->nrm[nrm] = vtxNorm;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-struct TempMesh
-{
- std::vector<aiVector3D> vtx;
- std::vector<aiVector3D> nrm;
- std::vector<aiVector3D> uv;
- std::vector<aiFace> faces;
-};
-
-static void ReadShape(SIB* sib, StreamReaderLE* stream)
-{
- SIBMesh smesh;
- aiString name;
-
- while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
- {
- SIBChunk chunk = ReadChunk(stream);
- unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
-
- switch (chunk.Tag)
- {
- case TAG('M','I','R','P'): break; // mirror plane maybe?
- case TAG('I','M','R','P'): break; // instance mirror? (not supported here yet)
- case TAG('D','I','N','F'): break; // display info, not needed
- case TAG('P','I','N','F'): break; // ?
- case TAG('V','M','I','R'): break; // ?
- case TAG('F','M','I','R'): break; // ?
- case TAG('T','X','S','M'): break; // ?
- case TAG('F','A','H','S'): break; // ?
- case TAG('V','R','T','S'): ReadVerts(&smesh, stream, chunk.Size/12); break;
- case TAG('F','A','C','S'): ReadFaces(&smesh, stream); break;
- case TAG('F','T','V','S'): ReadUVs(&smesh, stream); break;
- case TAG('S','N','A','M'): name = ReadString(stream, chunk.Size/2); break;
- case TAG('F','A','M','A'): ReadMtls(&smesh, stream); break;
- case TAG('A','X','I','S'): ReadAxis(smesh.axis, stream); break;
- case TAG('E','D','G','S'): ReadEdges(&smesh, stream); break;
- case TAG('E','C','R','S'): ReadCreases(&smesh, stream); break;
- default: UnknownChunk(stream, chunk); break;
- }
-
- stream->SetCurrentPos(stream->GetReadLimit());
- stream->SetReadLimit(oldLimit);
- }
-
- ai_assert(smesh.faceStart.size() == smesh.mtls.size()); // sanity check
-
- // Silo doesn't store any normals in the file - we need to compute
- // them ourselves. We can't let AssImp handle it as AssImp doesn't
- // know about our creased edges.
- ConnectFaces(&smesh);
- CalculateNormals(&smesh);
-
- // Construct the transforms.
- aiMatrix4x4 worldToLocal = smesh.axis;
- worldToLocal.Inverse();
- aiMatrix4x4 worldToLocalN = worldToLocal;
- worldToLocalN.a4 = worldToLocalN.b4 = worldToLocalN.c4 = 0.0f;
- worldToLocalN.Inverse().Transpose();
-
- // Allocate final mesh data.
- // We'll allocate one mesh for each material. (we'll strip unused ones after)
- std::vector<TempMesh> meshes(sib->mtls.size());
-
- // Un-index the source data and apply to each vertex.
- for (unsigned fi=0;fi<smesh.faceStart.size();fi++)
- {
- uint32_t start = smesh.faceStart[fi];
- uint32_t mtl = smesh.mtls[fi];
- uint32_t *idx = &smesh.idx[start];
-
- if (mtl >= meshes.size())
- {
- DefaultLogger::get()->error("SIB: Face material index is invalid.");
- mtl = 0;
- }
-
- TempMesh& dest = meshes[mtl];
-
- aiFace face;
- face.mNumIndices = *idx++;
- face.mIndices = new unsigned[face.mNumIndices];
- for (unsigned pt=0;pt<face.mNumIndices;pt++,idx+=N)
- {
- size_t vtxIdx = dest.vtx.size();
- face.mIndices[pt] = static_cast<unsigned int>(vtxIdx);
-
- // De-index it. We don't need to validate here as
- // we did it when creating the data.
- aiVector3D pos = smesh.pos[idx[POS]];
- aiVector3D nrm = smesh.nrm[idx[NRM]];
- aiVector3D uv = smesh.uv[idx[UV]];
-
- // The verts are supplied in world-space, so let's
- // transform them back into the local space of this mesh:
- pos = worldToLocal * pos;
- nrm = worldToLocalN * nrm;
-
- dest.vtx.push_back(pos);
- dest.nrm.push_back(nrm);
- dest.uv.push_back(uv);
- }
- dest.faces.push_back(face);
- }
-
- SIBObject obj;
- obj.name = name;
- obj.axis = smesh.axis;
- obj.meshIdx = sib->meshes.size();
-
- // Now that we know the size of everything,
- // we can build the final one-material-per-mesh data.
- for (size_t n=0;n<meshes.size();n++)
- {
- TempMesh& src = meshes[n];
- if (src.faces.empty())
- continue;
-
- aiMesh* mesh = new aiMesh;
- mesh->mName = name;
- mesh->mNumFaces = static_cast<unsigned int>(src.faces.size());
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- mesh->mNumVertices = static_cast<unsigned int>(src.vtx.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
- mesh->mNumUVComponents[0] = 2;
- mesh->mMaterialIndex = static_cast<unsigned int>(n);
-
- for (unsigned i=0;i<mesh->mNumVertices;i++)
- {
- mesh->mVertices[i] = src.vtx[i];
- mesh->mNormals[i] = src.nrm[i];
- mesh->mTextureCoords[0][i] = src.uv[i];
- }
- for (unsigned i=0;i<mesh->mNumFaces;i++)
- {
- mesh->mFaces[i] = src.faces[i];
- }
-
- sib->meshes.push_back(mesh);
- }
-
- obj.meshCount = sib->meshes.size() - obj.meshIdx;
- sib->objs.push_back(obj);
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadMaterial(SIB* sib, StreamReaderLE* stream)
-{
- aiColor3D diff = ReadColor(stream);
- aiColor3D ambi = ReadColor(stream);
- aiColor3D spec = ReadColor(stream);
- aiColor3D emis = ReadColor(stream);
- float shiny = (float)stream->GetU4();
-
- uint32_t nameLen = stream->GetU4();
- aiString name = ReadString(stream, nameLen/2);
- uint32_t texLen = stream->GetU4();
- aiString tex = ReadString(stream, texLen/2);
-
- aiMaterial* mtl = new aiMaterial();
- mtl->AddProperty(&diff, 1, AI_MATKEY_COLOR_DIFFUSE);
- mtl->AddProperty(&ambi, 1, AI_MATKEY_COLOR_AMBIENT);
- mtl->AddProperty(&spec, 1, AI_MATKEY_COLOR_SPECULAR);
- mtl->AddProperty(&emis, 1, AI_MATKEY_COLOR_EMISSIVE);
- mtl->AddProperty(&shiny, 1, AI_MATKEY_SHININESS);
- mtl->AddProperty(&name, AI_MATKEY_NAME);
- if (tex.length > 0) {
- mtl->AddProperty(&tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
- mtl->AddProperty(&tex, AI_MATKEY_TEXTURE_AMBIENT(0));
- }
-
- sib->mtls.push_back(mtl);
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadLightInfo(aiLight* light, StreamReaderLE* stream)
-{
- uint32_t type = stream->GetU4();
- switch (type) {
- case 0: light->mType = aiLightSource_POINT; break;
- case 1: light->mType = aiLightSource_SPOT; break;
- case 2: light->mType = aiLightSource_DIRECTIONAL; break;
- default: light->mType = aiLightSource_UNDEFINED; break;
- }
-
- light->mPosition.x = stream->GetF4();
- light->mPosition.y = stream->GetF4();
- light->mPosition.z = stream->GetF4();
- light->mDirection.x = stream->GetF4();
- light->mDirection.y = stream->GetF4();
- light->mDirection.z = stream->GetF4();
- light->mColorDiffuse = ReadColor(stream);
- light->mColorAmbient = ReadColor(stream);
- light->mColorSpecular = ReadColor(stream);
- ai_real spotExponent = stream->GetF4();
- ai_real spotCutoff = stream->GetF4();
- light->mAttenuationConstant = stream->GetF4();
- light->mAttenuationLinear = stream->GetF4();
- light->mAttenuationQuadratic = stream->GetF4();
-
- // Silo uses the OpenGL default lighting model for it's
- // spot cutoff/exponent. AssImp unfortunately, does not.
- // Let's try and approximate it by solving for the
- // 99% and 1% percentiles.
- // OpenGL: I = cos(angle)^E
- // Solving: angle = acos(I^(1/E))
- ai_real E = ai_real( 1.0 ) / std::max(spotExponent, (ai_real)0.00001);
- ai_real inner = std::acos(std::pow((ai_real)0.99, E));
- ai_real outer = std::acos(std::pow((ai_real)0.01, E));
-
- // Apply the cutoff.
- outer = std::min(outer, AI_DEG_TO_RAD(spotCutoff));
-
- light->mAngleInnerCone = std::min(inner, outer);
- light->mAngleOuterCone = outer;
-}
-
-static void ReadLight(SIB* sib, StreamReaderLE* stream)
-{
- aiLight* light = new aiLight();
-
- while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
- {
- SIBChunk chunk = ReadChunk(stream);
- unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
-
- switch (chunk.Tag)
- {
- case TAG('L','N','F','O'): ReadLightInfo(light, stream); break;
- case TAG('S','N','A','M'): light->mName = ReadString(stream, chunk.Size/2); break;
- default: UnknownChunk(stream, chunk); break;
- }
-
- stream->SetCurrentPos(stream->GetReadLimit());
- stream->SetReadLimit(oldLimit);
- }
-
- sib->lights.push_back(light);
-}
-
-// ------------------------------------------------------------------------------------------------
-static void ReadScale(aiMatrix4x4& axis, StreamReaderLE* stream)
-{
- aiMatrix4x4 scale;
- scale.a1 = stream->GetF4();
- scale.b1 = stream->GetF4();
- scale.c1 = stream->GetF4();
- scale.d1 = stream->GetF4();
- scale.a2 = stream->GetF4();
- scale.b2 = stream->GetF4();
- scale.c2 = stream->GetF4();
- scale.d2 = stream->GetF4();
- scale.a3 = stream->GetF4();
- scale.b3 = stream->GetF4();
- scale.c3 = stream->GetF4();
- scale.d3 = stream->GetF4();
- scale.a4 = stream->GetF4();
- scale.b4 = stream->GetF4();
- scale.c4 = stream->GetF4();
- scale.d4 = stream->GetF4();
-
- axis = axis * scale;
-}
-
-static void ReadInstance(SIB* sib, StreamReaderLE* stream)
-{
- SIBObject inst;
- uint32_t shapeIndex = 0;
-
- while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
- {
- SIBChunk chunk = ReadChunk(stream);
- unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
-
- switch (chunk.Tag)
- {
- case TAG('D','I','N','F'): break; // display info, not needed
- case TAG('P','I','N','F'): break; // ?
- case TAG('A','X','I','S'): ReadAxis(inst.axis, stream); break;
- case TAG('I','N','S','I'): shapeIndex = stream->GetU4(); break;
- case TAG('S','M','T','X'): ReadScale(inst.axis, stream); break;
- case TAG('S','N','A','M'): inst.name = ReadString(stream, chunk.Size/2); break;
- default: UnknownChunk(stream, chunk); break;
- }
-
- stream->SetCurrentPos(stream->GetReadLimit());
- stream->SetReadLimit(oldLimit);
- }
-
- if ( shapeIndex >= sib->objs.size() ) {
- throw DeadlyImportError( "SIB: Invalid shape index." );
- }
-
- const SIBObject& src = sib->objs[shapeIndex];
- inst.meshIdx = src.meshIdx;
- inst.meshCount = src.meshCount;
- sib->insts.push_back(inst);
-}
-
-// ------------------------------------------------------------------------------------------------
-static void CheckVersion(StreamReaderLE* stream)
-{
- uint32_t version = stream->GetU4();
- if ( version < 1 || version > 2 ) {
- throw DeadlyImportError( "SIB: Unsupported file version." );
- }
-}
-
-static void ReadScene(SIB* sib, StreamReaderLE* stream)
-{
- // Parse each chunk in turn.
- while (stream->GetRemainingSizeToLimit() >= sizeof(SIBChunk))
- {
- SIBChunk chunk = ReadChunk(stream);
- unsigned oldLimit = stream->SetReadLimit(stream->GetCurrentPos() + chunk.Size);
-
- switch (chunk.Tag)
- {
- case TAG('H','E','A','D'): CheckVersion(stream); break;
- case TAG('S','H','A','P'): ReadShape(sib, stream); break;
- case TAG('G','R','P','S'): break; // group assignment, we don't import this
- case TAG('T','E','X','P'): break; // ?
- case TAG('I','N','S','T'): ReadInstance(sib, stream); break;
- case TAG('M','A','T','R'): ReadMaterial(sib, stream); break;
- case TAG('L','G','H','T'): ReadLight(sib, stream); break;
- default: UnknownChunk(stream, chunk); break;
- }
-
- stream->SetCurrentPos(stream->GetReadLimit());
- stream->SetReadLimit(oldLimit);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void SIBImporter::InternReadFile(const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
-
- // We should have at least one chunk
- if (stream.GetRemainingSize() < 16)
- throw DeadlyImportError("SIB file is either empty or corrupt: " + pFile);
-
- SIB sib;
-
- // Default material.
- aiMaterial* defmtl = new aiMaterial;
- aiString defname = aiString(AI_DEFAULT_MATERIAL_NAME);
- defmtl->AddProperty(&defname, AI_MATKEY_NAME);
- sib.mtls.push_back(defmtl);
-
- // Read it all.
- ReadScene(&sib, &stream);
-
- // Join the instances and objects together.
- size_t firstInst = sib.objs.size();
- sib.objs.insert(sib.objs.end(), sib.insts.begin(), sib.insts.end());
- sib.insts.clear();
-
- // Transfer to the aiScene.
- pScene->mNumMaterials = static_cast<unsigned int>(sib.mtls.size());
- pScene->mNumMeshes = static_cast<unsigned int>(sib.meshes.size());
- pScene->mNumLights = static_cast<unsigned int>(sib.lights.size());
- pScene->mMaterials = pScene->mNumMaterials ? new aiMaterial*[pScene->mNumMaterials] : NULL;
- pScene->mMeshes = pScene->mNumMeshes ? new aiMesh*[pScene->mNumMeshes] : NULL;
- pScene->mLights = pScene->mNumLights ? new aiLight*[pScene->mNumLights] : NULL;
- if (pScene->mNumMaterials)
- memcpy(pScene->mMaterials, &sib.mtls[0], sizeof(aiMaterial*) * pScene->mNumMaterials);
- if (pScene->mNumMeshes)
- memcpy(pScene->mMeshes, &sib.meshes[0], sizeof(aiMesh*) * pScene->mNumMeshes);
- if (pScene->mNumLights)
- memcpy(pScene->mLights, &sib.lights[0], sizeof(aiLight*) * pScene->mNumLights);
-
- // Construct the root node.
- size_t childIdx = 0;
- aiNode *root = new aiNode();
- root->mName.Set("<SIBRoot>");
- root->mNumChildren = static_cast<unsigned int>(sib.objs.size() + sib.lights.size());
- root->mChildren = root->mNumChildren ? new aiNode*[root->mNumChildren] : NULL;
- pScene->mRootNode = root;
-
- // Add nodes for each object.
- for (size_t n=0;n<sib.objs.size();n++)
- {
- ai_assert(root->mChildren);
- SIBObject& obj = sib.objs[n];
- aiNode* node = new aiNode;
- root->mChildren[childIdx++] = node;
- node->mName = obj.name;
- node->mParent = root;
- node->mTransformation = obj.axis;
-
- node->mNumMeshes = static_cast<unsigned int>(obj.meshCount);
- node->mMeshes = node->mNumMeshes ? new unsigned[node->mNumMeshes] : NULL;
- for (unsigned i=0;i<node->mNumMeshes;i++)
- node->mMeshes[i] = static_cast<unsigned int>(obj.meshIdx + i);
-
- // Mark instanced objects as being so.
- if (n >= firstInst)
- {
- node->mMetaData = aiMetadata::Alloc( 1 );
- node->mMetaData->Set( 0, "IsInstance", true );
- }
- }
-
- // Add nodes for each light.
- // (no transformation as the light is already in world space)
- for (size_t n=0;n<sib.lights.size();n++)
- {
- ai_assert(root->mChildren);
- aiLight* light = sib.lights[n];
- if ( nullptr != light ) {
- aiNode* node = new aiNode;
- root->mChildren[ childIdx++ ] = node;
- node->mName = light->mName;
- node->mParent = root;
- }
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_SIB_IMPORTER
diff --git a/src/3rdparty/assimp/code/SIBImporter.h b/src/3rdparty/assimp/code/SIBImporter.h
deleted file mode 100644
index e7e2ec0b9..000000000
--- a/src/3rdparty/assimp/code/SIBImporter.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SIBImporter.h
- * @brief Declaration of the SIB importer class.
- */
-#ifndef AI_SIBIMPORTER_H_INCLUDED
-#define AI_SIBIMPORTER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Importer class for the Nevercenter Silo SIB scene format
-*/
-class ASSIMP_API SIBImporter : public BaseImporter
-{
-public:
- SIBImporter();
- ~SIBImporter();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
- struct MeshInformation
- {
- explicit MeshInformation(const std::string& _name)
- : name(_name)
- {
- vertices.reserve(100);
- colors.reserve(100);
- }
-
- std::string name;
-
- std::vector<aiVector3D> vertices;
- std::vector<aiColor4D> colors;
- };
-
- struct GroupInformation
- {
- explicit GroupInformation(const std::string& _name)
- : name(_name)
- {
- meshes.reserve(10);
- }
-
- std::string name;
- std::vector<MeshInformation> meshes;
- };
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SIBIMPORTER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/SMDLoader.cpp b/src/3rdparty/assimp/code/SMDLoader.cpp
deleted file mode 100644
index 60e3f63c8..000000000
--- a/src/3rdparty/assimp/code/SMDLoader.cpp
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SMDLoader.cpp
- * @brief Implementation of the SMD importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_SMD_IMPORTER
-
-// internal headers
-#include "SMDLoader.h"
-#include "fast_atof.h"
-#include "SkeletonMeshBuilder.h"
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include <memory>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Valve SMD Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "smd vta"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-SMDImporter::SMDImporter()
-: configFrameID(),
-mBuffer(),
-pScene( nullptr ),
-iFileSize( 0 ),
-iSmallestFrame( -1 ),
-dLengthOfAnim( 0.0 ),
-bHasUVs(false ),
-iLineNumber(-1) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SMDImporter::~SMDImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool SMDImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool) const
-{
- // fixme: auto format detection
- return SimpleExtensionCheck(pFile,"smd","vta");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all supported file extensions
-const aiImporterDesc* SMDImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties
-void SMDImporter::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_SMD_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_SMD_KEYFRAME,-1);
- if(static_cast<unsigned int>(-1) == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void SMDImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open SMD/VTA file " + pFile + ".");
- }
-
- iFileSize = (unsigned int)file->FileSize();
-
- // Allocate storage and copy the contents of the file to a memory buffer
- this->pScene = pScene;
-
- mBuffer.resize( iFileSize + 1 );
- TextFileToBuffer(file.get(), mBuffer );
-
- iSmallestFrame = (1 << 31);
- bHasUVs = true;
- iLineNumber = 1;
-
- // Reserve enough space for ... hm ... 10 textures
- aszTextures.reserve(10);
-
- // Reserve enough space for ... hm ... 1000 triangles
- asTriangles.reserve(1000);
-
- // Reserve enough space for ... hm ... 20 bones
- asBones.reserve(20);
-
-
- // parse the file ...
- ParseFile();
-
- // If there are no triangles it seems to be an animation SMD,
- // containing only the animation skeleton.
- if (asTriangles.empty())
- {
- if (asBones.empty())
- {
- throw DeadlyImportError("SMD: No triangles and no bones have "
- "been found in the file. This file seems to be invalid.");
- }
-
- // Set the flag in the scene structure which indicates
- // that there is nothing than an animation skeleton
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- if (!asBones.empty())
- {
- // Check whether all bones have been initialized
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if (!(*i).mName.length())
- {
- DefaultLogger::get()->warn("SMD: Not all bones have been initialized");
- break;
- }
- }
-
- // now fix invalid time values and make sure the animation starts at frame 0
- FixTimeValues();
-
- // compute absolute bone transformation matrices
- // ComputeAbsoluteBoneTransformations();
- }
-
- if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
- {
- // create output meshes
- CreateOutputMeshes();
-
- // build an output material list
- CreateOutputMaterials();
- }
-
- // build the output animation
- CreateOutputAnimations();
-
- // build output nodes (bones are added as empty dummy nodes)
- CreateOutputNodes();
-
- if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)
- {
- SkeletonMeshBuilder skeleton(pScene);
- }
-}
-// ------------------------------------------------------------------------------------------------
-// Write an error message with line number to the log file
-void SMDImporter::LogErrorNoThrow(const char* msg)
-{
- char szTemp[1024];
- ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,msg);
- DefaultLogger::get()->error(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Write a warning with line number to the log file
-void SMDImporter::LogWarning(const char* msg)
-{
- char szTemp[1024];
- ai_assert(strlen(msg) < 1000);
- ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,msg);
- DefaultLogger::get()->warn(szTemp);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Fix invalid time values in the file
-void SMDImporter::FixTimeValues()
-{
- double dDelta = (double)iSmallestFrame;
- double dMax = 0.0f;
- for (std::vector<SMD::Bone>::iterator
- iBone = asBones.begin();
- iBone != asBones.end();++iBone)
- {
- for (std::vector<SMD::Bone::Animation::MatrixKey>::iterator
- iKey = (*iBone).sAnim.asKeys.begin();
- iKey != (*iBone).sAnim.asKeys.end();++iKey)
- {
- (*iKey).dTime -= dDelta;
- dMax = std::max(dMax, (*iKey).dTime);
- }
- }
- dLengthOfAnim = dMax;
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output meshes
-void SMDImporter::CreateOutputMeshes()
-{
- if (aszTextures.empty())
- aszTextures.push_back(std::string());
-
- // we need to sort all faces by their material index
- // in opposition to other loaders we can be sure that each
- // material is at least used once.
- pScene->mNumMeshes = (unsigned int) aszTextures.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
-
- typedef std::vector<unsigned int> FaceList;
- FaceList* aaiFaces = new FaceList[pScene->mNumMeshes];
-
- // approximate the space that will be required
- unsigned int iNum = (unsigned int)asTriangles.size() / pScene->mNumMeshes;
- iNum += iNum >> 1;
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- aaiFaces[i].reserve(iNum);
-
-
- // collect all faces
- iNum = 0;
- for (std::vector<SMD::Face>::const_iterator
- iFace = asTriangles.begin();
- iFace != asTriangles.end();++iFace,++iNum)
- {
- if (UINT_MAX == (*iFace).iTexture)aaiFaces[(*iFace).iTexture].push_back( 0 );
- else if ((*iFace).iTexture >= aszTextures.size())
- {
- DefaultLogger::get()->error("[SMD/VTA] Material index overflow in face");
- aaiFaces[(*iFace).iTexture].push_back((unsigned int)aszTextures.size()-1);
- }
- else aaiFaces[(*iFace).iTexture].push_back(iNum);
- }
-
- // now create the output meshes
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- {
- aiMesh*& pcMesh = pScene->mMeshes[i] = new aiMesh();
- ai_assert(!aaiFaces[i].empty()); // should not be empty ...
-
- pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- pcMesh->mNumVertices = (unsigned int)aaiFaces[i].size()*3;
- pcMesh->mNumFaces = (unsigned int)aaiFaces[i].size();
- pcMesh->mMaterialIndex = i;
-
- // storage for bones
- typedef std::pair<unsigned int,float> TempWeightListEntry;
- typedef std::vector< TempWeightListEntry > TempBoneWeightList;
-
- TempBoneWeightList* aaiBones = new TempBoneWeightList[asBones.size()]();
-
- // try to reserve enough memory without wasting too much
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- aaiBones[iBone].reserve(pcMesh->mNumVertices/asBones.size());
- }
-
- // allocate storage
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
- aiVector3D* pcNormals = pcMesh->mNormals = new aiVector3D[pcMesh->mNumVertices];
- aiVector3D* pcVerts = pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
-
- aiVector3D* pcUVs = NULL;
- if (bHasUVs)
- {
- pcUVs = pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
- pcMesh->mNumUVComponents[0] = 2;
- }
-
- iNum = 0;
- for (unsigned int iFace = 0; iFace < pcMesh->mNumFaces;++iFace)
- {
- pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
- pcMesh->mFaces[iFace].mNumIndices = 3;
-
- // fill the vertices
- unsigned int iSrcFace = aaiFaces[i][iFace];
- SMD::Face& face = asTriangles[iSrcFace];
-
- *pcVerts++ = face.avVertices[0].pos;
- *pcVerts++ = face.avVertices[1].pos;
- *pcVerts++ = face.avVertices[2].pos;
-
- // fill the normals
- *pcNormals++ = face.avVertices[0].nor;
- *pcNormals++ = face.avVertices[1].nor;
- *pcNormals++ = face.avVertices[2].nor;
-
- // fill the texture coordinates
- if (pcUVs)
- {
- *pcUVs++ = face.avVertices[0].uv;
- *pcUVs++ = face.avVertices[1].uv;
- *pcUVs++ = face.avVertices[2].uv;
- }
-
- for (unsigned int iVert = 0; iVert < 3;++iVert)
- {
- float fSum = 0.0f;
- for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
- {
- TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
-
- // FIX: The second check is here just to make sure we won't
- // assign more than one weight to a single vertex index
- if (pairval.first >= asBones.size() ||
- pairval.first == face.avVertices[iVert].iParentNode)
- {
- DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
- "The bone index will be ignored, the weight will be assigned "
- "to the vertex' parent node");
- continue;
- }
- aaiBones[pairval.first].push_back(TempWeightListEntry(iNum,pairval.second));
- fSum += pairval.second;
- }
- // ******************************************************************
- // If the sum of all vertex weights is not 1.0 we must assign
- // the rest to the vertex' parent node. Well, at least the doc says
- // we should ...
- // FIX: We use 0.975 as limit, floating-point inaccuracies seem to
- // be very strong in some SMD exporters. Furthermore it is possible
- // that the parent of a vertex is 0xffffffff (if the corresponding
- // entry in the file was unreadable)
- // ******************************************************************
- if (fSum < 0.975f && face.avVertices[iVert].iParentNode != UINT_MAX)
- {
- if (face.avVertices[iVert].iParentNode >= asBones.size())
- {
- DefaultLogger::get()->error("[SMD/VTA] Bone index overflow. "
- "The index of the vertex parent bone is invalid. "
- "The remaining weights will be normalized to 1.0");
-
- if (fSum)
- {
- fSum = 1 / fSum;
- for (unsigned int iBone = 0;iBone < face.avVertices[iVert].aiBoneLinks.size();++iBone)
- {
- TempWeightListEntry& pairval = face.avVertices[iVert].aiBoneLinks[iBone];
- if (pairval.first >= asBones.size())continue;
- aaiBones[pairval.first].back().second *= fSum;
- }
- }
- }
- else
- {
- aaiBones[face.avVertices[iVert].iParentNode].push_back(
- TempWeightListEntry(iNum,1.0f-fSum));
- }
- }
- pcMesh->mFaces[iFace].mIndices[iVert] = iNum++;
- }
- }
-
- // now build all bones of the mesh
- iNum = 0;
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- if (!aaiBones[iBone].empty())++iNum;
-
- if (false && iNum)
- {
- pcMesh->mNumBones = iNum;
- pcMesh->mBones = new aiBone*[pcMesh->mNumBones];
- iNum = 0;
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- if (aaiBones[iBone].empty())continue;
- aiBone*& bone = pcMesh->mBones[iNum] = new aiBone();
-
- bone->mNumWeights = (unsigned int)aaiBones[iBone].size();
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- bone->mOffsetMatrix = asBones[iBone].mOffsetMatrix;
- bone->mName.Set( asBones[iBone].mName );
-
- asBones[iBone].bIsUsed = true;
-
- for (unsigned int iWeight = 0; iWeight < bone->mNumWeights;++iWeight)
- {
- bone->mWeights[iWeight].mVertexId = aaiBones[iBone][iWeight].first;
- bone->mWeights[iWeight].mWeight = aaiBones[iBone][iWeight].second;
- }
- ++iNum;
- }
- }
- delete[] aaiBones;
- }
- delete[] aaiFaces;
-}
-
-// ------------------------------------------------------------------------------------------------
-// add bone child nodes
-void SMDImporter::AddBoneChildren(aiNode* pcNode, uint32_t iParent)
-{
- ai_assert( NULL != pcNode );
- ai_assert( 0 == pcNode->mNumChildren );
- ai_assert( NULL == pcNode->mChildren);
-
- // first count ...
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
- if (bone.iParent == iParent)++pcNode->mNumChildren;
- }
-
- // now allocate the output array
- pcNode->mChildren = new aiNode*[pcNode->mNumChildren];
-
- // and fill all subnodes
- unsigned int qq = 0;
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
- if (bone.iParent != iParent)continue;
-
- aiNode* pc = pcNode->mChildren[qq++] = new aiNode();
- pc->mName.Set(bone.mName);
-
- // store the local transformation matrix of the bind pose
- pc->mTransformation = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrix;
- pc->mParent = pcNode;
-
- // add children to this node, too
- AddBoneChildren(pc,i);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output nodes
-void SMDImporter::CreateOutputNodes()
-{
- pScene->mRootNode = new aiNode();
- if (!(pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE))
- {
- // create one root node that renders all meshes
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
- pScene->mRootNode->mMeshes[i] = i;
- }
-
- // now add all bones as dummy sub nodes to the graph
- // AddBoneChildren(pScene->mRootNode,(uint32_t)-1);
-
- // if we have only one bone we can even remove the root node
- if (pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE &&
- 1 == pScene->mRootNode->mNumChildren)
- {
- aiNode* pcOldRoot = pScene->mRootNode;
- pScene->mRootNode = pcOldRoot->mChildren[0];
- pcOldRoot->mChildren[0] = NULL;
- delete pcOldRoot;
-
- pScene->mRootNode->mParent = NULL;
- }
- else
- {
- ::strcpy(pScene->mRootNode->mName.data, "<SMD_root>");
- pScene->mRootNode->mName.length = 10;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// create output animations
-void SMDImporter::CreateOutputAnimations()
-{
- unsigned int iNumBones = 0;
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if ((*i).bIsUsed)++iNumBones;
- }
- if (!iNumBones)
- {
- // just make sure this case doesn't occur ... (it could occur
- // if the file was invalid)
- return;
- }
-
- pScene->mNumAnimations = 1;
- pScene->mAnimations = new aiAnimation*[1];
- aiAnimation*& anim = pScene->mAnimations[0] = new aiAnimation();
-
- anim->mDuration = dLengthOfAnim;
- anim->mNumChannels = iNumBones;
- anim->mTicksPerSecond = 25.0; // FIXME: is this correct?
-
- aiNodeAnim** pp = anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
-
- // now build valid keys
- unsigned int a = 0;
- for (std::vector<SMD::Bone>::const_iterator
- i = asBones.begin();
- i != asBones.end();++i)
- {
- if (!(*i).bIsUsed)continue;
-
- aiNodeAnim* p = pp[a] = new aiNodeAnim();
-
- // copy the name of the bone
- p->mNodeName.Set( i->mName);
-
- p->mNumRotationKeys = (unsigned int) (*i).sAnim.asKeys.size();
- if (p->mNumRotationKeys)
- {
- p->mNumPositionKeys = p->mNumRotationKeys;
- aiVectorKey* pVecKeys = p->mPositionKeys = new aiVectorKey[p->mNumRotationKeys];
- aiQuatKey* pRotKeys = p->mRotationKeys = new aiQuatKey[p->mNumRotationKeys];
-
- for (std::vector<SMD::Bone::Animation::MatrixKey>::const_iterator
- qq = (*i).sAnim.asKeys.begin();
- qq != (*i).sAnim.asKeys.end(); ++qq)
- {
- pRotKeys->mTime = pVecKeys->mTime = (*qq).dTime;
-
- // compute the rotation quaternion from the euler angles
- pRotKeys->mValue = aiQuaternion( (*qq).vRot.x, (*qq).vRot.y, (*qq).vRot.z );
- pVecKeys->mValue = (*qq).vPos;
-
- ++pVecKeys; ++pRotKeys;
- }
- }
- ++a;
-
- // there are no scaling keys ...
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SMDImporter::ComputeAbsoluteBoneTransformations()
-{
- // For each bone: determine the key with the lowest time value
- // theoretically the SMD format should have all keyframes
- // in order. However, I've seen a file where this wasn't true.
- for (unsigned int i = 0; i < asBones.size();++i)
- {
- SMD::Bone& bone = asBones[i];
-
- uint32_t iIndex = 0;
- double dMin = 10e10;
- for (unsigned int i = 0; i < bone.sAnim.asKeys.size();++i)
- {
- double d = std::min(bone.sAnim.asKeys[i].dTime,dMin);
- if (d < dMin)
- {
- dMin = d;
- iIndex = i;
- }
- }
- bone.sAnim.iFirstTimeKey = iIndex;
- }
-
- unsigned int iParent = 0;
- while (iParent < asBones.size())
- {
- for (unsigned int iBone = 0; iBone < asBones.size();++iBone)
- {
- SMD::Bone& bone = asBones[iBone];
-
- if (iParent == bone.iParent)
- {
- SMD::Bone& parentBone = asBones[iParent];
-
-
- uint32_t iIndex = bone.sAnim.iFirstTimeKey;
- const aiMatrix4x4& mat = bone.sAnim.asKeys[iIndex].matrix;
- aiMatrix4x4& matOut = bone.sAnim.asKeys[iIndex].matrixAbsolute;
-
- // The same for the parent bone ...
- iIndex = parentBone.sAnim.iFirstTimeKey;
- const aiMatrix4x4& mat2 = parentBone.sAnim.asKeys[iIndex].matrixAbsolute;
-
- // Compute the absolute transformation matrix
- matOut = mat * mat2;
- }
- }
- ++iParent;
- }
-
- // Store the inverse of the absolute transformation matrix
- // of the first key as bone offset matrix
- for (iParent = 0; iParent < asBones.size();++iParent)
- {
- SMD::Bone& bone = asBones[iParent];
- bone.mOffsetMatrix = bone.sAnim.asKeys[bone.sAnim.iFirstTimeKey].matrixAbsolute;
- bone.mOffsetMatrix.Inverse();
- }
-}
-\
-// ------------------------------------------------------------------------------------------------
-// create output materials
-void SMDImporter::CreateOutputMaterials()
-{
- ai_assert( nullptr != pScene );
-
- pScene->mNumMaterials = (unsigned int)aszTextures.size();
- pScene->mMaterials = new aiMaterial*[std::max(1u, pScene->mNumMaterials)];
-
- for (unsigned int iMat = 0; iMat < pScene->mNumMaterials; ++iMat) {
- aiMaterial* pcMat = new aiMaterial();
- ai_assert( nullptr != pcMat );
- pScene->mMaterials[iMat] = pcMat;
-
- aiString szName;
- szName.length = (size_t)ai_snprintf(szName.data,MAXLEN,"Texture_%u",iMat);
- pcMat->AddProperty(&szName,AI_MATKEY_NAME);
-
- if (aszTextures[iMat].length())
- {
- ::strncpy(szName.data, aszTextures[iMat].c_str(),MAXLEN-1);
- szName.length = aszTextures[iMat].length();
- pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
-
- // create a default material if necessary
- if (0 == pScene->mNumMaterials)
- {
- pScene->mNumMaterials = 1;
-
- aiMaterial* pcHelper = new aiMaterial();
- pScene->mMaterials[0] = pcHelper;
-
- int iMode = (int)aiShadingMode_Gouraud;
- pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
-
- aiColor3D clr;
- clr.b = clr.g = clr.r = 0.7f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_DIFFUSE);
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_SPECULAR);
-
- clr.b = clr.g = clr.r = 0.05f;
- pcHelper->AddProperty<aiColor3D>(&clr, 1,AI_MATKEY_COLOR_AMBIENT);
-
- aiString szName;
- szName.Set(AI_DEFAULT_MATERIAL_NAME);
- pcHelper->AddProperty(&szName,AI_MATKEY_NAME);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the file
-void SMDImporter::ParseFile()
-{
- const char* szCurrent = &mBuffer[0];
-
- // read line per line ...
- for ( ;; )
- {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "version <n> \n", <n> should be 1 for hl and hl2 SMD files
- if (TokenMatch(szCurrent,"version",7))
- {
- if(!SkipSpaces(szCurrent,&szCurrent)) break;
- if (1 != strtoul10(szCurrent,&szCurrent))
- {
- DefaultLogger::get()->warn("SMD.version is not 1. This "
- "file format is not known. Continuing happily ...");
- }
- continue;
- }
- // "nodes\n" - Starts the node section
- if (TokenMatch(szCurrent,"nodes",5))
- {
- ParseNodesSection(szCurrent,&szCurrent);
- continue;
- }
- // "triangles\n" - Starts the triangle section
- if (TokenMatch(szCurrent,"triangles",9))
- {
- ParseTrianglesSection(szCurrent,&szCurrent);
- continue;
- }
- // "vertexanimation\n" - Starts the vertex animation section
- if (TokenMatch(szCurrent,"vertexanimation",15))
- {
- bHasUVs = false;
- ParseVASection(szCurrent,&szCurrent);
- continue;
- }
- // "skeleton\n" - Starts the skeleton section
- if (TokenMatch(szCurrent,"skeleton",8))
- {
- ParseSkeletonSection(szCurrent,&szCurrent);
- continue;
- }
- SkipLine(szCurrent,&szCurrent);
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int SMDImporter::GetTextureIndex(const std::string& filename)
-{
- unsigned int iIndex = 0;
- for (std::vector<std::string>::const_iterator
- i = aszTextures.begin();
- i != aszTextures.end();++i,++iIndex)
- {
- // case-insensitive ... it's a path
- if (0 == ASSIMP_stricmp ( filename.c_str(),(*i).c_str()))return iIndex;
- }
- iIndex = (unsigned int)aszTextures.size();
- aszTextures.push_back(filename);
- return iIndex;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the nodes section of the file
-void SMDImporter::ParseNodesSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- for ( ;; )
- {
- // "end\n" - Ends the nodes section
- if (0 == ASSIMP_strincmp(szCurrent,"end",3) &&
- IsSpaceOrNewLine(*(szCurrent+3)))
- {
- szCurrent += 4;
- break;
- }
- ParseNodeInfo(szCurrent,&szCurrent);
- }
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse the triangles section of the file
-void SMDImporter::ParseTrianglesSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- // Parse a triangle, parse another triangle, parse the next triangle ...
- // and so on until we reach a token that looks quite similar to "end"
- for ( ;; )
- {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the triangles section
- if (TokenMatch(szCurrent,"end",3))
- break;
- ParseTriangle(szCurrent,&szCurrent);
- }
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-// ------------------------------------------------------------------------------------------------
-// Parse the vertex animation section of the file
-void SMDImporter::ParseVASection(const char* szCurrent,
- const char** szCurrentOut)
-{
- unsigned int iCurIndex = 0;
- for ( ;; )
- {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the "vertexanimation" section
- if (TokenMatch(szCurrent,"end",3))
- break;
-
- // "time <n>\n"
- if (TokenMatch(szCurrent,"time",4))
- {
- // NOTE: The doc says that time values COULD be negative ...
- // NOTE2: this is the shape key -> valve docs
- int iTime = 0;
- if(!ParseSignedInt(szCurrent,&szCurrent,iTime) || configFrameID != (unsigned int)iTime)break;
- SkipLine(szCurrent,&szCurrent);
- }
- else
- {
- if(0 == iCurIndex)
- {
- asTriangles.push_back(SMD::Face());
- }
- if (++iCurIndex == 3)iCurIndex = 0;
- ParseVertex(szCurrent,&szCurrent,asTriangles.back().avVertices[iCurIndex],true);
- }
- }
-
- if (iCurIndex != 2 && !asTriangles.empty())
- {
- // we want to no degenerates, so throw this triangle away
- asTriangles.pop_back();
- }
-
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- *szCurrentOut = szCurrent;
-}
-// ------------------------------------------------------------------------------------------------
-// Parse the skeleton section of the file
-void SMDImporter::ParseSkeletonSection(const char* szCurrent,
- const char** szCurrentOut)
-{
- int iTime = 0;
- for ( ;; )
- {
- if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
-
- // "end\n" - Ends the skeleton section
- if (TokenMatch(szCurrent,"end",3))
- break;
-
- // "time <n>\n" - Specifies the current animation frame
- else if (TokenMatch(szCurrent,"time",4))
- {
- // NOTE: The doc says that time values COULD be negative ...
- if(!ParseSignedInt(szCurrent,&szCurrent,iTime))break;
-
- iSmallestFrame = std::min(iSmallestFrame,iTime);
- SkipLine(szCurrent,&szCurrent);
- }
- else ParseSkeletonElement(szCurrent,&szCurrent,iTime);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-#define SMDI_PARSE_RETURN { \
- SkipLine(szCurrent,&szCurrent); \
- *szCurrentOut = szCurrent; \
- return; \
-}
-// ------------------------------------------------------------------------------------------------
-// Parse a node line
-void SMDImporter::ParseNodeInfo(const char* szCurrent,
- const char** szCurrentOut)
-{
- unsigned int iBone = 0;
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone) || !SkipSpaces(szCurrent,&szCurrent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone index");
- SMDI_PARSE_RETURN;
- }
- // add our bone to the list
- if (iBone >= asBones.size())asBones.resize(iBone+1);
- SMD::Bone& bone = asBones[iBone];
-
- bool bQuota = true;
- if ('\"' != *szCurrent)
- {
- LogWarning("Bone name is expcted to be enclosed in "
- "double quotation marks. ");
- bQuota = false;
- }
- else ++szCurrent;
-
- const char* szEnd = szCurrent;
- for ( ;; )
- {
- if (bQuota && '\"' == *szEnd)
- {
- iBone = (unsigned int)(szEnd - szCurrent);
- ++szEnd;
- break;
- }
- else if (IsSpaceOrNewLine(*szEnd))
- {
- iBone = (unsigned int)(szEnd - szCurrent);
- break;
- }
- else if (!(*szEnd))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone name");
- SMDI_PARSE_RETURN;
- }
- ++szEnd;
- }
- bone.mName = std::string(szCurrent,iBone);
- szCurrent = szEnd;
-
- // the only negative bone parent index that could occur is -1 AFAIK
- if(!ParseSignedInt(szCurrent,&szCurrent,(int&)bone.iParent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone parent index. Assuming -1");
- SMDI_PARSE_RETURN;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a skeleton element
-void SMDImporter::ParseSkeletonElement(const char* szCurrent,
- const char** szCurrentOut,int iTime)
-{
- aiVector3D vPos;
- aiVector3D vRot;
-
- unsigned int iBone = 0;
- if(!ParseUnsignedInt(szCurrent,&szCurrent,iBone))
- {
- DefaultLogger::get()->error("Unexpected EOF/EOL while parsing bone index");
- SMDI_PARSE_RETURN;
- }
- if (iBone >= asBones.size())
- {
- LogErrorNoThrow("Bone index in skeleton section is out of range");
- SMDI_PARSE_RETURN;
- }
- SMD::Bone& bone = asBones[iBone];
-
- bone.sAnim.asKeys.push_back(SMD::Bone::Animation::MatrixKey());
- SMD::Bone::Animation::MatrixKey& key = bone.sAnim.asKeys.back();
-
- key.dTime = (double)iTime;
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.x");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.y");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vPos.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.pos.z");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.x");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.y");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vRot.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing bone.rot.z");
- SMDI_PARSE_RETURN;
- }
- // build the transformation matrix of the key
- key.matrix.FromEulerAnglesXYZ(vRot.x,vRot.y,vRot.z);
- {
- aiMatrix4x4 mTemp;
- mTemp.a4 = vPos.x;
- mTemp.b4 = vPos.y;
- mTemp.c4 = vPos.z;
- key.matrix = key.matrix * mTemp;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a triangle
-void SMDImporter::ParseTriangle(const char* szCurrent,
- const char** szCurrentOut)
-{
- asTriangles.push_back(SMD::Face());
- SMD::Face& face = asTriangles.back();
-
- if(!SkipSpaces(szCurrent,&szCurrent))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing a triangle");
- return;
- }
-
- // read the texture file name
- const char* szLast = szCurrent;
- while (!IsSpaceOrNewLine(*++szCurrent));
-
- // ... and get the index that belongs to this file name
- face.iTexture = GetTextureIndex(std::string(szLast,(uintptr_t)szCurrent-(uintptr_t)szLast));
-
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
-
- // load three vertices
- for (unsigned int iVert = 0; iVert < 3;++iVert)
- {
- ParseVertex(szCurrent,&szCurrent,
- face.avVertices[iVert]);
- }
- *szCurrentOut = szCurrent;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a float
-bool SMDImporter::ParseFloat(const char* szCurrent,
- const char** szCurrentOut, float& out)
-{
- if(!SkipSpaces(&szCurrent))
- return false;
-
- *szCurrentOut = fast_atoreal_move<float>(szCurrent,out);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse an unsigned int
-bool SMDImporter::ParseUnsignedInt(const char* szCurrent,
- const char** szCurrentOut, unsigned int& out)
-{
- if(!SkipSpaces(&szCurrent))
- return false;
-
- out = strtoul10(szCurrent,szCurrentOut);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a signed int
-bool SMDImporter::ParseSignedInt(const char* szCurrent,
- const char** szCurrentOut, int& out)
-{
- if(!SkipSpaces(&szCurrent))
- return false;
-
- out = strtol10(szCurrent,szCurrentOut);
- return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Parse a vertex
-void SMDImporter::ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
- bool bVASection /*= false*/)
-{
- if (SkipSpaces(&szCurrent) && IsLineEnd(*szCurrent))
- {
- SkipSpacesAndLineEnd(szCurrent,&szCurrent);
- return ParseVertex(szCurrent,szCurrentOut,vertex,bVASection);
- }
- if(!ParseSignedInt(szCurrent,&szCurrent,(int&)vertex.iParentNode))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.parent");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.x");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.y");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.pos.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.pos.z");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.x");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.y");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.nor.z))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.nor.z");
- SMDI_PARSE_RETURN;
- }
-
- if (bVASection)SMDI_PARSE_RETURN;
-
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.x))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.x");
- SMDI_PARSE_RETURN;
- }
- if(!ParseFloat(szCurrent,&szCurrent,(float&)vertex.uv.y))
- {
- LogErrorNoThrow("Unexpected EOF/EOL while parsing vertex.uv.y");
- SMDI_PARSE_RETURN;
- }
-
- // now read the number of bones affecting this vertex
- // all elements from now are fully optional, we don't need them
- unsigned int iSize = 0;
- if(!ParseUnsignedInt(szCurrent,&szCurrent,iSize))SMDI_PARSE_RETURN;
- vertex.aiBoneLinks.resize(iSize,std::pair<unsigned int, float>(0,0.0f));
-
- for (std::vector<std::pair<unsigned int, float> >::iterator
- i = vertex.aiBoneLinks.begin();
- i != vertex.aiBoneLinks.end();++i)
- {
- if(!ParseUnsignedInt(szCurrent,&szCurrent,(*i).first))
- SMDI_PARSE_RETURN;
- if(!ParseFloat(szCurrent,&szCurrent,(*i).second))
- SMDI_PARSE_RETURN;
- }
-
- // go to the beginning of the next line
- SMDI_PARSE_RETURN;
-}
-
-#endif // !! ASSIMP_BUILD_NO_SMD_IMPORTER
diff --git a/src/3rdparty/assimp/code/SMDLoader.h b/src/3rdparty/assimp/code/SMDLoader.h
deleted file mode 100644
index c50b327e3..000000000
--- a/src/3rdparty/assimp/code/SMDLoader.h
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SMDLoader.h
- * @brief Definition of the Valve SMD file format
- */
-
-#ifndef AI_SMDLOADER_H_INCLUDED
-#define AI_SMDLOADER_H_INCLUDED
-
-// internal headers
-#include "BaseImporter.h"
-#include "ParsingUtils.h"
-
-// public Assimp headers
-#include <assimp/types.h>
-#include <assimp/texture.h>
-#include <assimp/anim.h>
-#include <assimp/material.h>
-
-struct aiNode;
-
-// STL headers
-#include <vector>
-
-namespace Assimp {
-
-namespace SMD {
-
-// ---------------------------------------------------------------------------
-/** Data structure for a vertex in a SMD file
-*/
-struct Vertex
-{
- Vertex() : iParentNode(UINT_MAX)
- {}
-
- //! Vertex position, normal and texture coordinate
- aiVector3D pos,nor,uv;
-
- //! Vertex parent node
- unsigned int iParentNode;
-
- //! Links to bones: pair.first is the bone index,
- //! pair.second is the vertex weight.
- //! WARN: The remaining weight (to reach 1.0f) is assigned
- //! to the parent node/bone
- std::vector<std::pair<unsigned int, float> > aiBoneLinks;
-};
-
-// ---------------------------------------------------------------------------
-/** Data structure for a face in a SMD file
-*/
-struct Face
-{
- Face() : iTexture(0x0)
- {}
-
- //! Texture index for the face
- unsigned int iTexture;
-
- //! The three vertices of the face
- Vertex avVertices[3];
-};
-
-// ---------------------------------------------------------------------------
-/** Data structure for a bone in a SMD file
-*/
-struct Bone
-{
- //! Default constructor
- Bone() : iParent(UINT_MAX), bIsUsed(false)
- {
- }
-
- //! Destructor
- ~Bone()
- {
- }
-
- //! Name of the bone
- std::string mName;
-
- //! Parent of the bone
- uint32_t iParent;
-
- //! Animation of the bone
- struct Animation
- {
- //! Public default constructor
- Animation()
- : iFirstTimeKey()
- {
- asKeys.reserve(20);
- }
-
- //! Data structure for a matrix key
- struct MatrixKey
- {
- //! Matrix at this time
- aiMatrix4x4 matrix;
-
- //! Absolute transformation matrix
- aiMatrix4x4 matrixAbsolute;
-
- //! Position
- aiVector3D vPos;
-
- //! Rotation (euler angles)
- aiVector3D vRot;
-
- //! Current time. may be negative, this
- //! will be fixed later
- double dTime;
- };
-
- //! Index of the key with the smallest time value
- uint32_t iFirstTimeKey;
-
- //! Array of matrix keys
- std::vector<MatrixKey> asKeys;
-
- } sAnim;
-
- //! Offset matrix of the bone
- aiMatrix4x4 mOffsetMatrix;
-
- //! true if the bone is referenced by at least one mesh
- bool bIsUsed;
-};
-
-} //! namespace SMD
-
-// ---------------------------------------------------------------------------
-/** Used to load Half-life 1 and 2 SMD models
-*/
-class ASSIMP_API SMDImporter : public BaseImporter
-{
-public:
- SMDImporter();
- ~SMDImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ReadFile().
- * The function is a request to the importer to update its configuration
- * basing on the Importer's configuration property list.
- */
- void SetupProperties(const Importer* pImp);
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Parse the SMD file and create the output scene
- */
- void ParseFile();
-
- // -------------------------------------------------------------------
- /** Parse the triangles section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseTrianglesSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the vertex animation section in VTA files
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseVASection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the nodes section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseNodesSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse the skeleton section of the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives a pointer to the heading line of
- * the next section (or to EOF)
- */
- void ParseSkeletonSection(const char* szCurrent,
- const char** szCurrentOut);
-
- // -------------------------------------------------------------------
- /** Parse a single triangle in the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives the output cursor position
- */
- void ParseTriangle(const char* szCurrent,
- const char** szCurrentOut);
-
-
- // -------------------------------------------------------------------
- /** Parse a single vertex in the SMD file
- * \param szCurrent Current position in the file. Points to the first
- * data line of the section.
- * \param szCurrentOut Receives the output cursor position
- * \param vertex Vertex to be filled
- */
- void ParseVertex(const char* szCurrent,
- const char** szCurrentOut, SMD::Vertex& vertex,
- bool bVASection = false);
-
- // -------------------------------------------------------------------
- /** Get the index of a texture. If the texture was not yet known
- * it will be added to the internal texture list.
- * \param filename Name of the texture
- * \return Value texture index
- */
- unsigned int GetTextureIndex(const std::string& filename);
-
- // -------------------------------------------------------------------
- /** Computes absolute bone transformations
- * All output transformations are in worldspace.
- */
- void ComputeAbsoluteBoneTransformations();
-
-
- // -------------------------------------------------------------------
- /** Parse a line in the skeleton section
- */
- void ParseSkeletonElement(const char* szCurrent,
- const char** szCurrentOut,int iTime);
-
- // -------------------------------------------------------------------
- /** Parse a line in the nodes section
- */
- void ParseNodeInfo(const char* szCurrent,
- const char** szCurrentOut);
-
-
- // -------------------------------------------------------------------
- /** Parse a floating-point value
- */
- bool ParseFloat(const char* szCurrent,
- const char** szCurrentOut, float& out);
-
- // -------------------------------------------------------------------
- /** Parse an unsigned integer. There may be no sign!
- */
- bool ParseUnsignedInt(const char* szCurrent,
- const char** szCurrentOut, unsigned int& out);
-
- // -------------------------------------------------------------------
- /** Parse a signed integer. Signs (+,-) are handled.
- */
- bool ParseSignedInt(const char* szCurrent,
- const char** szCurrentOut, int& out);
-
- // -------------------------------------------------------------------
- /** Fix invalid time values in the file
- */
- void FixTimeValues();
-
- // -------------------------------------------------------------------
- /** Add all children of a bone as subnodes to a node
- * \param pcNode Parent node
- * \param iParent Parent bone index
- */
- void AddBoneChildren(aiNode* pcNode, uint32_t iParent);
-
- // -------------------------------------------------------------------
- /** Build output meshes/materials/nodes/animations
- */
- void CreateOutputMeshes();
- void CreateOutputNodes();
- void CreateOutputAnimations();
- void CreateOutputMaterials();
-
-
- // -------------------------------------------------------------------
- /** Print a log message together with the current line number
- */
- void LogErrorNoThrow(const char* msg);
- void LogWarning(const char* msg);
-
-
- // -------------------------------------------------------------------
- inline bool SkipLine( const char* in, const char** out)
- {
- Assimp::SkipLine(in,out);
- ++iLineNumber;
- return true;
- }
- // -------------------------------------------------------------------
- inline bool SkipSpacesAndLineEnd( const char* in, const char** out)
- {
- ++iLineNumber;
- return Assimp::SkipSpacesAndLineEnd(in,out);
- }
-
-private:
-
- /** Configuration option: frame to be loaded */
- unsigned int configFrameID;
-
- /** Buffer to hold the loaded file */
- std::vector<char> mBuffer;
-
- /** Output scene to be filled
- */
- aiScene* pScene;
-
- /** Size of the input file in bytes
- */
- unsigned int iFileSize;
-
- /** Array of textures found in the file
- */
- std::vector<std::string> aszTextures;
-
- /** Array of triangles found in the file
- */
- std::vector<SMD::Face> asTriangles;
-
- /** Array of bones found in the file
- */
- std::vector<SMD::Bone> asBones;
-
- /** Smallest frame index found in the skeleton
- */
- int iSmallestFrame;
-
- /** Length of the whole animation, in frames
- */
- double dLengthOfAnim;
-
- /** Do we have texture coordinates?
- */
- bool bHasUVs;
-
- /** Current line numer
- */
- unsigned int iLineNumber;
-
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SMDIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/STEPFile.h b/src/3rdparty/assimp/code/STEPFile.h
deleted file mode 100644
index 8a30beb3f..000000000
--- a/src/3rdparty/assimp/code/STEPFile.h
+++ /dev/null
@@ -1,1019 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_STEPFILE_H
-#define INCLUDED_AI_STEPFILE_H
-
-#include <bitset>
-#include <memory>
-#include <typeinfo>
-#include <vector>
-#include <map>
-#include <set>
-
-#include "FBXDocument.h" //ObjectMap::value_type
-#include <assimp/DefaultLogger.hpp>
-
-//
-#if _MSC_VER > 1500 || (defined __GNUC___)
-# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
-#else
-# define step_unordered_map map
-# define step_unordered_multimap multimap
-#endif
-
-#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
-# include <unordered_map>
-# if _MSC_VER > 1600
-# define step_unordered_map unordered_map
-# define step_unordered_multimap unordered_multimap
-# else
-# define step_unordered_map tr1::unordered_map
-# define step_unordered_multimap tr1::unordered_multimap
-# endif
-#endif
-
-#include "LineSplitter.h"
-
-// uncomment this to have the loader evaluate all entities upon loading.
-// this is intended as stress test - by default, entities are evaluated
-// lazily and therefore not unless needed.
-
-//#define ASSIMP_IFC_TEST
-
-namespace Assimp {
-
-// ********************************************************************************
-// before things get complicated, this is the basic outline:
-
-
-namespace STEP {
-
- namespace EXPRESS {
-
- // base data types known by EXPRESS schemata - any custom data types will derive one of those
- class DataType;
- class UNSET; /*: public DataType */
- class ISDERIVED; /*: public DataType */
- // class REAL; /*: public DataType */
- class ENUM; /*: public DataType */
- // class STRING; /*: public DataType */
- // class INTEGER; /*: public DataType */
- class ENTITY; /*: public DataType */
- class LIST; /*: public DataType */
- // class SELECT; /*: public DataType */
-
- // a conversion schema is not exactly an EXPRESS schema, rather it
- // is a list of pointers to conversion functions to build up the
- // object tree from an input file.
- class ConversionSchema;
- }
-
- struct HeaderInfo;
- class Object;
- class LazyObject;
- class DB;
-
-
- typedef Object* (*ConvertObjectProc)(const DB& db, const EXPRESS::LIST& params);
-}
-
-// ********************************************************************************
-
-namespace STEP {
-
- // -------------------------------------------------------------------------------
- /** Exception class used by the STEP loading & parsing code. It is typically
- * coupled with a line number. */
- // -------------------------------------------------------------------------------
- struct SyntaxError : DeadlyImportError {
- enum {
- LINE_NOT_SPECIFIED = 0xffffffffffffffffLL
- };
-
- SyntaxError (const std::string& s,uint64_t line = LINE_NOT_SPECIFIED);
- };
-
-
- // -------------------------------------------------------------------------------
- /** Exception class used by the STEP loading & parsing code when a type
- * error (i.e. an entity expects a string but receives a bool) occurs.
- * It is typically coupled with both an entity id and a line number.*/
- // -------------------------------------------------------------------------------
- struct TypeError : DeadlyImportError
- {
- enum {
- ENTITY_NOT_SPECIFIED = 0xffffffffffffffffLL
- };
-
- TypeError (const std::string& s,uint64_t entity = ENTITY_NOT_SPECIFIED, uint64_t line = SyntaxError::LINE_NOT_SPECIFIED);
- };
-
-
- // hack to make a given member template-dependent
- template <typename T, typename T2>
- T2& Couple(T2& in) {
- return in;
- }
-
-
- namespace EXPRESS {
-
- // -------------------------------------------------------------------------------
- //** Base class for all STEP data types */
- // -------------------------------------------------------------------------------
- class DataType
- {
- public:
-
- typedef std::shared_ptr<const DataType> Out;
-
- public:
-
- virtual ~DataType() {
- }
-
- public:
-
- template <typename T>
- const T& To() const {
- return dynamic_cast<const T&>(*this);
- }
-
- template <typename T>
- T& To() {
- return dynamic_cast<T&>(*this);
- }
-
-
- template <typename T>
- const T* ToPtr() const {
- return dynamic_cast<const T*>(this);
- }
-
- template <typename T>
- T* ToPtr() {
- return dynamic_cast<T*>(this);
- }
-
- // utilities to deal with SELECT entities, which currently lack automatic
- // conversion support.
- template <typename T>
- const T& ResolveSelect(const DB& db) const {
- 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;
- }
-
- public:
-
- /** parse a variable from a string and set 'inout' to the character
- * behind the last consumed character. An optional schema enables,
- * if specified, automatic conversion of custom data types.
- *
- * @throw SyntaxError
- */
- static std::shared_ptr<const EXPRESS::DataType> Parse(const char*& inout,
- uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
- const EXPRESS::ConversionSchema* schema = NULL);
-
- public:
- };
-
- typedef DataType SELECT;
- typedef DataType LOGICAL;
-
- // -------------------------------------------------------------------------------
- /** Sentinel class to represent explicitly unset (optional) fields ($) */
- // -------------------------------------------------------------------------------
- class UNSET : public DataType
- {
- public:
- private:
- };
-
- // -------------------------------------------------------------------------------
- /** Sentinel class to represent explicitly derived fields (*) */
- // -------------------------------------------------------------------------------
- class ISDERIVED : public DataType
- {
- public:
- private:
- };
-
- // -------------------------------------------------------------------------------
- /** Shared implementation for some of the primitive data type, i.e. int, float */
- // -------------------------------------------------------------------------------
- template <typename T>
- class PrimitiveDataType : public DataType
- {
- public:
-
- // This is the type that will cd ultimatively be used to
- // expose this data type to the user.
- typedef T Out;
-
- public:
-
- PrimitiveDataType() {}
- PrimitiveDataType(const T& val)
- : val(val)
- {}
-
- PrimitiveDataType(const PrimitiveDataType& o) {
- (*this) = o;
- }
-
-
- public:
-
- operator const T& () const {
- return val;
- }
-
- PrimitiveDataType& operator=(const PrimitiveDataType& o) {
- val = o.val;
- return *this;
- }
-
- protected:
- T val;
-
- };
-
- typedef PrimitiveDataType<int64_t> INTEGER;
- typedef PrimitiveDataType<double> REAL;
- typedef PrimitiveDataType<double> NUMBER;
- typedef PrimitiveDataType<std::string> STRING;
-
-
-
- // -------------------------------------------------------------------------------
- /** Generic base class for all enumerated types */
- // -------------------------------------------------------------------------------
- class ENUMERATION : public STRING
- {
- public:
-
- ENUMERATION (const std::string& val)
- : STRING(val)
- {}
-
- private:
- };
-
- typedef ENUMERATION BOOLEAN;
-
- // -------------------------------------------------------------------------------
- /** This is just a reference to an entity/object somewhere else */
- // -------------------------------------------------------------------------------
- class ENTITY : public PrimitiveDataType<uint64_t>
- {
- public:
-
- ENTITY(uint64_t val)
- : PrimitiveDataType<uint64_t>(val)
- {
- ai_assert(val!=0);
- }
-
- ENTITY()
- : PrimitiveDataType<uint64_t>(TypeError::ENTITY_NOT_SPECIFIED)
- {
- }
-
- private:
- };
-
- // -------------------------------------------------------------------------------
- /** Wrap any STEP aggregate: LIST, SET, ... */
- // -------------------------------------------------------------------------------
- class LIST : public DataType
- {
- public:
-
- // access a particular list index, throw std::range_error for wrong indices
- std::shared_ptr<const DataType> operator[] (size_t index) const {
- return members[index];
- }
-
- size_t GetSize() const {
- return members.size();
- }
-
- public:
-
- /** @see DaraType::Parse */
- static std::shared_ptr<const EXPRESS::LIST> Parse(const char*& inout,
- uint64_t line = SyntaxError::LINE_NOT_SPECIFIED,
- const EXPRESS::ConversionSchema* schema = NULL);
-
-
- private:
- typedef std::vector< std::shared_ptr<const DataType> > MemberList;
- MemberList members;
- };
-
-
- // -------------------------------------------------------------------------------
- /* Not exactly a full EXPRESS schema but rather a list of conversion functions
- * to extract valid C++ objects out of a STEP file. Those conversion functions
- * may, however, perform further schema validations. */
- // -------------------------------------------------------------------------------
- class ConversionSchema
- {
-
- public:
-
- struct SchemaEntry {
- SchemaEntry(const char* name,ConvertObjectProc func)
- : name(name)
- , func(func)
- {}
-
- const char* name;
- ConvertObjectProc func;
- };
-
- typedef std::map<std::string,ConvertObjectProc> ConverterMap;
-
- public:
-
- template <size_t N>
- explicit ConversionSchema( const SchemaEntry (& schemas)[N]) {
- *this = schemas;
- }
-
- ConversionSchema() {}
-
- public:
-
- ConvertObjectProc GetConverterProc(const std::string& name) const {
- ConverterMap::const_iterator it = converters.find(name);
- return it == converters.end() ? NULL : (*it).second;
- }
-
-
- bool IsKnownToken(const std::string& name) const {
- return converters.find(name) != converters.end();
- }
-
- const char* GetStaticStringForToken(const std::string& token) const {
- ConverterMap::const_iterator it = converters.find(token);
- return it == converters.end() ? NULL : (*it).first.c_str();
- }
-
-
- template <size_t N>
- const ConversionSchema& operator=( const SchemaEntry (& schemas)[N]) {
- for(size_t i = 0; i < N; ++i ) {
- const SchemaEntry& schema = schemas[i];
- converters[schema.name] = schema.func;
- }
- return *this;
- }
-
- private:
-
- ConverterMap converters;
- };
- }
-
-
-
- // ------------------------------------------------------------------------------
- /** Bundle all the relevant info from a STEP header, parts of which may later
- * be plainly dumped to the logfile, whereas others may help the caller pick an
- * appropriate loading strategy.*/
- // ------------------------------------------------------------------------------
- struct HeaderInfo
- {
- std::string timestamp;
- std::string app;
- std::string fileSchema;
- };
-
-
- // ------------------------------------------------------------------------------
- /** Base class for all concrete object instances */
- // ------------------------------------------------------------------------------
- class Object {
- public:
- Object(const char* classname = "unknown")
- : id( 0 )
- , classname(classname) {
- // empty
- }
-
- virtual ~Object() {
- // empty
- }
-
- public:
-
- // utilities to simplify casting to concrete types
- template <typename T>
- const T& To() const {
- return dynamic_cast<const T&>(*this);
- }
-
- template <typename T>
- T& To() {
- return dynamic_cast<T&>(*this);
- }
-
- template <typename T>
- const T* ToPtr() const {
- return dynamic_cast<const T*>(this);
- }
-
- template <typename T>
- T* ToPtr() {
- return dynamic_cast<T*>(this);
- }
-
- public:
- uint64_t GetID() const {
- return id;
- }
-
- std::string GetClassName() const {
- return classname;
- }
-
- void SetID(uint64_t newval) {
- id = newval;
- }
-
- private:
- uint64_t id;
- const char* const classname;
- };
-
- template <typename T>
- size_t GenericFill(const STEP::DB& db, const EXPRESS::LIST& params, T* in);
- // (intentionally undefined)
-
-
- // ------------------------------------------------------------------------------
- /** CRTP shared base class for use by concrete entity implementation classes */
- // ------------------------------------------------------------------------------
- template <typename TDerived, size_t arg_count>
- struct ObjectHelper : virtual Object
- {
- ObjectHelper() : aux_is_derived(0) {}
-
- static Object* Construct(const STEP::DB& db, const EXPRESS::LIST& params) {
- // make sure we don't leak if Fill() throws an exception
- std::unique_ptr<TDerived> impl(new TDerived());
-
- // GenericFill<T> is undefined so we need to have a specialization
- const size_t num_args = GenericFill<TDerived>(db,params,&*impl);
- (void)num_args;
-
- // the following check is commented because it will always trigger if
- // parts of the entities are generated with dummy wrapper code.
- // This is currently done to reduce the size of the loader
- // code.
- //if (num_args != params.GetSize() && impl->GetClassName() != "NotImplemented") {
- // DefaultLogger::get()->debug("STEP: not all parameters consumed");
- //}
- return impl.release();
- }
-
- // note that this member always exists multiple times within the hierarchy
- // of an individual object, so any access to it must be disambiguated.
- std::bitset<arg_count> aux_is_derived;
- };
-
- // ------------------------------------------------------------------------------
- /** Class template used to represent OPTIONAL data members in the converted schema */
- // ------------------------------------------------------------------------------
- template <typename T>
- struct Maybe
- {
- Maybe() : have() {}
- explicit Maybe(const T& ptr) : ptr(ptr), have(true) {
- }
-
-
- void flag_invalid() {
- have = false;
- }
-
- void flag_valid() {
- have = true;
- }
-
-
- bool operator! () const {
- return !have;
- }
-
- operator bool() const {
- return have;
- }
-
- operator const T&() const {
- return Get();
- }
-
- const T& Get() const {
- ai_assert(have);
- return ptr;
- }
-
- Maybe& operator=(const T& _ptr) {
- ptr = _ptr;
- have = true;
- return *this;
- }
-
- private:
-
- template <typename T2> friend struct InternGenericConvert;
-
- operator T&() {
- return ptr;
- }
-
- T ptr;
- bool have;
- };
-
- // ------------------------------------------------------------------------------
- /** A LazyObject is created when needed. Before this happens, we just keep
- the text line that contains the object definition. */
- // -------------------------------------------------------------------------------
- class LazyObject
- {
- friend class DB;
- public:
-
- LazyObject(DB& db, uint64_t id, uint64_t line, const char* type,const char* args);
- ~LazyObject();
-
- public:
-
- Object& operator * () {
- if (!obj) {
- LazyInit();
- ai_assert(obj);
- }
- return *obj;
- }
-
- const Object& operator * () const {
- if (!obj) {
- LazyInit();
- ai_assert(obj);
- }
- return *obj;
- }
-
- template <typename T>
- const T& To() const {
- return dynamic_cast<const T&>( **this );
- }
-
- template <typename T>
- T& To() {
- return dynamic_cast<T&>( **this );
- }
-
- template <typename T>
- const T* ToPtr() const {
- return dynamic_cast<const T*>( &**this );
- }
-
- template <typename T>
- T* ToPtr() {
- return dynamic_cast<T*>( &**this );
- }
-
- Object* operator -> () {
- return &**this;
- }
-
- const Object* operator -> () const {
- return &**this;
- }
-
- bool operator== (const std::string& atype) const {
- return type == atype;
- }
-
- bool operator!= (const std::string& atype) const {
- return type != atype;
- }
-
- uint64_t GetID() const {
- return id;
- }
-
- private:
-
- void LazyInit() const;
-
- private:
-
- mutable uint64_t id;
- const char* const type;
- DB& db;
-
- mutable const char* args;
- mutable Object* obj;
- };
-
- template <typename T>
- inline bool operator==( std::shared_ptr<LazyObject> lo, T whatever ) {
- return *lo == whatever; // XXX use std::forward if we have 0x
- }
-
- template <typename T>
- inline bool operator==( const std::pair<uint64_t, std::shared_ptr<LazyObject> >& lo, T whatever ) {
- return *(lo.second) == whatever; // XXX use std::forward if we have 0x
- }
-
-
- // ------------------------------------------------------------------------------
- /** Class template used to represent lazily evaluated object references in the converted schema */
- // ------------------------------------------------------------------------------
- template <typename T>
- struct Lazy
- {
- typedef Lazy Out;
- Lazy(const LazyObject* obj = NULL) : obj(obj) {
- }
-
- operator const T*() const {
- return obj->ToPtr<T>();
- }
-
- operator const T&() const {
- return obj->To<T>();
- }
-
- const T& operator * () const {
- return obj->To<T>();
- }
-
- const T* operator -> () const {
- return &obj->To<T>();
- }
-
- const LazyObject* obj;
- };
-
- // ------------------------------------------------------------------------------
- /** Class template used to represent LIST and SET data members in the converted schema */
- // ------------------------------------------------------------------------------
- template <typename T, uint64_t min_cnt, uint64_t max_cnt=0uL>
- struct ListOf : public std::vector<typename T::Out>
- {
- typedef typename T::Out OutScalar;
- typedef ListOf Out;
-
-
- ListOf() {
- static_assert(min_cnt <= max_cnt || !max_cnt, "min_cnt <= max_cnt || !max_cnt");
- }
-
- };
-
-
- // ------------------------------------------------------------------------------
- template <typename TOut>
- struct PickBaseType {
- typedef EXPRESS::PrimitiveDataType<TOut> Type;
- };
-
- template <typename TOut>
- struct PickBaseType< Lazy<TOut> > {
- typedef EXPRESS::ENTITY Type;
- };
-
- template <> struct PickBaseType< std::shared_ptr< const EXPRESS::DataType > >;
-
- // ------------------------------------------------------------------------------
- template <typename T>
- struct InternGenericConvert {
- void operator()(T& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& /*db*/) {
- try{
- out = dynamic_cast< const typename PickBaseType<T>::Type& > ( *in );
- }
- catch(std::bad_cast&) {
- throw TypeError("type error reading literal field");
- }
- }
- };
-
- template <>
- struct InternGenericConvert< std::shared_ptr< const EXPRESS::DataType > > {
- void operator()(std::shared_ptr< const EXPRESS::DataType >& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& /*db*/) {
- out = in;
- }
- };
-
- template <typename T>
- struct InternGenericConvert< Maybe<T> > {
- void operator()(Maybe<T>& out, const std::shared_ptr< const EXPRESS::DataType >& in, const STEP::DB& db) {
- GenericConvert((T&)out,in,db);
- out.flag_valid();
- }
- };
-
- template <typename T,uint64_t min_cnt, uint64_t max_cnt>
- struct InternGenericConvertList {
- void operator()(ListOf<T, min_cnt, max_cnt>& out, const std::shared_ptr< const EXPRESS::DataType >& inp_base, const STEP::DB& db) {
-
- const EXPRESS::LIST* inp = dynamic_cast<const EXPRESS::LIST*>(inp_base.get());
- if (!inp) {
- throw TypeError("type error reading aggregate");
- }
-
- // XXX is this really how the EXPRESS notation ([?:3],[1:3]) is intended?
- if (max_cnt && inp->GetSize() > max_cnt) {
- DefaultLogger::get()->warn("too many aggregate elements");
- }
- else if (inp->GetSize() < min_cnt) {
- DefaultLogger::get()->warn("too few aggregate elements");
- }
-
- out.reserve(inp->GetSize());
- for(size_t i = 0; i < inp->GetSize(); ++i) {
-
- out.push_back( typename ListOf<T, min_cnt, max_cnt>::OutScalar() );
- try{
- GenericConvert(out.back(),(*inp)[i], db);
- }
- catch(const TypeError& t) {
- throw TypeError(t.what() +std::string(" of aggregate"));
- }
- }
- }
- };
-
- template <typename T>
- struct InternGenericConvert< Lazy<T> > {
- void operator()(Lazy<T>& out, const std::shared_ptr< const EXPRESS::DataType >& in_base, const STEP::DB& db) {
- const EXPRESS::ENTITY* in = dynamic_cast<const EXPRESS::ENTITY*>(in_base.get());
- if (!in) {
- throw TypeError("type error reading entity");
- }
- out = Couple<T>(db).GetObject(*in);
- }
- };
-
- template <typename T1>
- inline void GenericConvert(T1& a, const std::shared_ptr< const EXPRESS::DataType >& b, const STEP::DB& db) {
- return InternGenericConvert<T1>()(a,b,db);
- }
-
- template <typename T1,uint64_t N1, uint64_t N2>
- inline void GenericConvert(ListOf<T1,N1,N2>& a, const std::shared_ptr< const EXPRESS::DataType >& b, const STEP::DB& db) {
- return InternGenericConvertList<T1,N1,N2>()(a,b,db);
- }
-
-
- // ------------------------------------------------------------------------------
- /** Lightweight manager class that holds the map of all objects in a
- * STEP file. DB's are exclusively maintained by the functions in
- * STEPFileReader.h*/
- // -------------------------------------------------------------------------------
- class DB
- {
- friend DB* ReadFileHeader(std::shared_ptr<IOStream> stream);
- friend void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
- const char* const* types_to_track, size_t len,
- const char* const* inverse_indices_to_track, size_t len2
- );
-
- friend class LazyObject;
-
- public:
-
- // objects indexed by ID - this can grow pretty large (i.e some hundred million
- // entries), so use raw pointers to avoid *any* overhead.
- typedef std::map<uint64_t,const LazyObject* > ObjectMap;
-
- // objects indexed by their declarative type, but only for those that we truly want
- typedef std::set< const LazyObject*> ObjectSet;
- typedef std::map<std::string, ObjectSet > ObjectMapByType;
-
- // list of types for which to keep inverse indices for all references
- // that the respective objects keep.
- // the list keeps pointers to strings in static storage
- typedef std::set<const char*> InverseWhitelist;
-
- // references - for each object id the ids of all objects which reference it
- // this is used to simulate STEP inverse indices for selected types.
- typedef std::step_unordered_multimap<uint64_t, uint64_t > RefMap;
- typedef std::pair<RefMap::const_iterator,RefMap::const_iterator> RefMapRange;
-
- private:
-
- DB(std::shared_ptr<StreamReaderLE> reader)
- : reader(reader)
- , splitter(*reader,true,true)
- , evaluated_count()
- , schema( NULL )
- {}
-
- public:
-
- ~DB() {
- for(ObjectMap::value_type& o : objects) {
- delete o.second;
- }
- }
-
- public:
-
- uint64_t GetObjectCount() const {
- return objects.size();
- }
-
- uint64_t GetEvaluatedObjectCount() const {
- return evaluated_count;
- }
-
- const HeaderInfo& GetHeader() const {
- return header;
- }
-
- const EXPRESS::ConversionSchema& GetSchema() const {
- return *schema;
- }
-
- const ObjectMap& GetObjects() const {
- return objects;
- }
-
- const ObjectMapByType& GetObjectsByType() const {
- return objects_bytype;
- }
-
- const RefMap& GetRefs() const {
- return refs;
- }
-
-
- bool KeepInverseIndicesForType(const char* const type) const {
- return inv_whitelist.find(type) != inv_whitelist.end();
- }
-
-
- // get the yet unevaluated object record with a given id
- const LazyObject* GetObject(uint64_t id) const {
- const ObjectMap::const_iterator it = objects.find(id);
- if (it != objects.end()) {
- return (*it).second;
- }
- return NULL;
- }
-
-
- // get an arbitrary object out of the soup with the only restriction being its type.
- const LazyObject* GetObject(const std::string& type) const {
- const ObjectMapByType::const_iterator it = objects_bytype.find(type);
- if (it != objects_bytype.end() && (*it).second.size()) {
- return *(*it).second.begin();
- }
- return NULL;
- }
-
- // same, but raise an exception if the object doesn't exist and return a reference
- const LazyObject& MustGetObject(uint64_t id) const {
- const LazyObject* o = GetObject(id);
- if (!o) {
- throw TypeError("requested entity is not present",id);
- }
- return *o;
- }
-
- const LazyObject& MustGetObject(const std::string& type) const {
- const LazyObject* o = GetObject(type);
- if (!o) {
- throw TypeError("requested entity of type "+type+"is not present");
- }
- return *o;
- }
-
-
-#ifdef ASSIMP_IFC_TEST
-
- // evaluate *all* entities in the file. this is a power test for the loader
- void EvaluateAll() {
- for(ObjectMap::value_type& e :objects) {
- **e.second;
- }
- ai_assert(evaluated_count == objects.size());
- }
-
-#endif
-
- private:
-
- // full access only offered to close friends - they should
- // use the provided getters rather than messing around with
- // the members directly.
- LineSplitter& GetSplitter() {
- return splitter;
- }
-
- void InternInsert(const LazyObject* lz) {
- objects[lz->GetID()] = lz;
-
- const ObjectMapByType::iterator it = objects_bytype.find( lz->type );
- if (it != objects_bytype.end()) {
- (*it).second.insert(lz);
- }
- }
-
- void SetSchema(const EXPRESS::ConversionSchema& _schema) {
- schema = &_schema;
- }
-
-
- void SetTypesToTrack(const char* const* types, size_t N) {
- for(size_t i = 0; i < N;++i) {
- objects_bytype[types[i]] = ObjectSet();
- }
- }
-
- void SetInverseIndicesToTrack( const char* const* types, size_t N ) {
- for(size_t i = 0; i < N;++i) {
- const char* const sz = schema->GetStaticStringForToken(types[i]);
- ai_assert(sz);
- inv_whitelist.insert(sz);
- }
- }
-
- HeaderInfo& GetHeader() {
- return header;
- }
-
- void MarkRef(uint64_t who, uint64_t by_whom) {
- refs.insert(std::make_pair(who,by_whom));
- }
-
- private:
- HeaderInfo header;
- ObjectMap objects;
- ObjectMapByType objects_bytype;
- RefMap refs;
- InverseWhitelist inv_whitelist;
- std::shared_ptr<StreamReaderLE> reader;
- LineSplitter splitter;
- uint64_t evaluated_count;
- const EXPRESS::ConversionSchema* schema;
- };
-
-}
-
-} // end Assimp
-
-#endif // INCLUDED_AI_STEPFILE_H
diff --git a/src/3rdparty/assimp/code/STEPFileEncoding.cpp b/src/3rdparty/assimp/code/STEPFileEncoding.cpp
deleted file mode 100644
index 7204f802b..000000000
--- a/src/3rdparty/assimp/code/STEPFileEncoding.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 un-escaping
- */
-#include "STEPFileEncoding.h"
-#include "fast_atof.h"
-#include <contrib/utf8cpp/source/utf8.h>
-
-#include <memory>
-
-using namespace Assimp;
-
-// roman1 to utf16 table
-static const uint16_t 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 uint32_t unival = mac_codetable[macval - 0x20], *univalp = &unival;
-
- unsigned char temp[5], *tempp = temp;
- ai_assert(sizeof( unsigned char ) == 1);
-
- utf8::utf32to8( univalp, univalp + 1, tempp );
-
- 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()-3;
-
- for (; j < jend; ++j) {
- if (s[j] == '\\' && s[j+1] == 'X' && s[j+2] == '0' && s[j+3] == '\\') {
- 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;
- std::unique_ptr<uint16_t[]> src(new uint16_t[count]);
-
- const char* cur = s.c_str() + basei;
- for (size_t k = 0; k < count; ++k, cur += 4) {
- src[k] = (static_cast<uint16_t>(HexOctetToDecimal(cur)) << 8u) |
- static_cast<uint16_t>(HexOctetToDecimal(cur+2));
- }
-
- const size_t dcount = count * 3; // this is enough to hold all possible outputs
- std::unique_ptr<unsigned char[]> dest(new unsigned char[dcount]);
-
- const uint16_t* srct = src.get();
- unsigned char* destt = dest.get();
- utf8::utf16to8( srct, srct + count, destt );
-
- const size_t outcount = static_cast<size_t>(destt-dest.get());
-
- s.erase(i,(j+4-i));
-
- ai_assert(sizeof(unsigned char) == 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;
- std::unique_ptr<uint32_t[]> src(new uint32_t[count]);
-
- const char* cur = s.c_str() + basei;
- for (size_t k = 0; k < count; ++k, cur += 8) {
- src[k] = (static_cast<uint32_t>(HexOctetToDecimal(cur )) << 24u) |
- (static_cast<uint32_t>(HexOctetToDecimal(cur+2)) << 16u) |
- (static_cast<uint32_t>(HexOctetToDecimal(cur+4)) << 8u) |
- (static_cast<uint32_t>(HexOctetToDecimal(cur+6)));
- }
-
- const size_t dcount = count * 5; // this is enough to hold all possible outputs
- std::unique_ptr<unsigned char[]> dest(new unsigned char[dcount]);
-
- const uint32_t* srct = src.get();
- unsigned char* destt = dest.get();
- utf8::utf32to8( srct, srct + count, destt );
-
- const size_t outcount = static_cast<size_t>(destt-dest.get());
-
- s.erase(i,(j+4-i));
-
- ai_assert(sizeof(unsigned char) == 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
deleted file mode 100644
index 56615c8f6..000000000
--- a/src/3rdparty/assimp/code/STEPFileEncoding.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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
deleted file mode 100644
index d014c1a5d..000000000
--- a/src/3rdparty/assimp/code/STEPFileReader.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 STEPFileReader.cpp
- * @brief Implementation of the STEP file parser, which fills a
- * STEP::DB with data read from a file.
- */
-
-#include "STEPFileReader.h"
-#include "STEPFileEncoding.h"
-#include "TinyFormatter.h"
-#include "fast_atof.h"
-#include <memory>
-
-
-using namespace Assimp;
-namespace EXPRESS = STEP::EXPRESS;
-
-#include <functional>
-
-// ------------------------------------------------------------------------------------------------
-std::string AddLineNumber(const std::string& s,uint64_t line /*= LINE_NOT_SPECIFIED*/, const std::string& prefix = "")
-{
- return line == STEP::SyntaxError::LINE_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(line ",line,") ",s) );
-}
-
-
-// ------------------------------------------------------------------------------------------------
-std::string AddEntityID(const std::string& s,uint64_t entity /*= ENTITY_NOT_SPECIFIED*/, const std::string& prefix = "")
-{
- return entity == STEP::TypeError::ENTITY_NOT_SPECIFIED ? prefix+s : static_cast<std::string>( (Formatter::format(),prefix,"(entity #",entity,") ",s));
-}
-
-
-// ------------------------------------------------------------------------------------------------
-STEP::SyntaxError::SyntaxError (const std::string& s,uint64_t line /* = LINE_NOT_SPECIFIED */)
-: DeadlyImportError(AddLineNumber(s,line))
-{
-
-}
-
-// ------------------------------------------------------------------------------------------------
-STEP::TypeError::TypeError (const std::string& s,uint64_t entity /* = ENTITY_NOT_SPECIFIED */,uint64_t line /*= LINE_NOT_SPECIFIED*/)
-: DeadlyImportError(AddLineNumber(AddEntityID(s,entity),line))
-{
-
-}
-
-
-// ------------------------------------------------------------------------------------------------
-STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream)
-{
- std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
- std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader));
-
- LineSplitter& splitter = db->GetSplitter();
- if (!splitter || *splitter != "ISO-10303-21;") {
- throw STEP::SyntaxError("expected magic token: ISO-10303-21",1);
- }
-
- HeaderInfo& head = db->GetHeader();
- for(++splitter; splitter; ++splitter) {
- const std::string& s = *splitter;
- if (s == "DATA;") {
- // here we go, header done, start of data section
- ++splitter;
- break;
- }
-
- // want one-based line numbers for human readers, so +1
- const uint64_t line = splitter.get_index()+1;
-
- if (s.substr(0,11) == "FILE_SCHEMA") {
- const char* sz = s.c_str()+11;
- SkipSpaces(sz,&sz);
- std::shared_ptr< const EXPRESS::DataType > schema = EXPRESS::DataType::Parse(sz);
-
- // the file schema should be a regular list entity, although it usually contains exactly one entry
- // since the list itself is contained in a regular parameter list, we actually have
- // two nested lists.
- const EXPRESS::LIST* list = dynamic_cast<const EXPRESS::LIST*>(schema.get());
- if (list && list->GetSize()) {
- list = dynamic_cast<const EXPRESS::LIST*>( (*list)[0].get() );
- if (!list) {
- throw STEP::SyntaxError("expected FILE_SCHEMA to be a list",line);
- }
-
- // XXX need support for multiple schemas?
- if (list->GetSize() > 1) {
- DefaultLogger::get()->warn(AddLineNumber("multiple schemas currently not supported",line));
- }
- const EXPRESS::STRING* string( nullptr );
- if (!list->GetSize() || !(string=dynamic_cast<const EXPRESS::STRING*>( (*list)[0].get() ))) {
- throw STEP::SyntaxError("expected FILE_SCHEMA to contain a single string literal",line);
- }
- head.fileSchema = *string;
- }
- }
-
- // XXX handle more header fields
- }
-
- return db.release();
-}
-
-
-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,
- const char* const* inverse_indices_to_track, size_t len2)
-{
- db.SetSchema(scheme);
- db.SetTypesToTrack(types_to_track,len);
- db.SetInverseIndicesToTrack(inverse_indices_to_track,len2);
-
- const DB::ObjectMap& map = db.GetObjects();
- LineSplitter& splitter = db.GetSplitter();
-
- 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;
- }
- std::string::size_type n1 = s.find_first_of('(',n0);
- if (n1 == std::string::npos) {
- 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;
- }
- }
-
- 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()) {
- DefaultLogger::get()->warn(AddLineNumber((Formatter::format(),"an object with the id #",id," already exists"),line));
- }
-
- 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()){
- DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ",
- db.GetRefs().size()," inverse index entries"));
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-std::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);
- }
-
- // just skip over constructions such as IFCPLANEANGLEMEASURE(0.01) and read only the value
- if (schema) {
- bool ok = false;
- for(const char* t = cur; *t && *t != ')' && *t != ','; ++t) {
- if (*t=='(') {
- if (!ok) {
- break;
- }
- for(--t;IsSpace(*t);--t);
- std::string s(cur,static_cast<size_t>(t-cur+1));
- std::transform(s.begin(),s.end(),s.begin(),&ToLower<char> );
- if (schema->IsKnownToken(s)) {
- for(cur = t+1;*cur++ != '(';);
- const std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur);
- inout = *cur ? cur+1 : cur;
- return dt;
- }
- break;
- }
- else if (!IsSpace(*t)) {
- ok = true;
- }
- }
- }
-
- if (*cur == '*' ) {
- inout = cur+1;
- return std::make_shared<EXPRESS::ISDERIVED>();
- }
- else if (*cur == '$' ) {
- inout = cur+1;
- return std::make_shared<EXPRESS::UNSET>();
- }
- else if (*cur == '(' ) {
- // start of an aggregate, further parsing is done by the LIST factory constructor
- inout = cur;
- return EXPRESS::LIST::Parse(inout,line,schema);
- }
- else if (*cur == '.' ) {
- // enum (includes boolean)
- const char* start = ++cur;
- for(;*cur != '.';++cur) {
- if (*cur == '\0') {
- throw STEP::SyntaxError("enum not closed",line);
- }
- }
- inout = cur+1;
- return std::make_shared<EXPRESS::ENUMERATION>(std::string(start, static_cast<size_t>(cur-start) ));
- }
- else if (*cur == '#' ) {
- // object reference
- return std::make_shared<EXPRESS::ENTITY>(strtoul10_64(++cur,&inout));
- }
- else if (*cur == '\'' ) {
- // string literal
- const char* start = ++cur;
-
- for(;*cur != '\'';++cur) {
- if (*cur == '\0') {
- throw STEP::SyntaxError("string literal not closed",line);
- }
- }
-
- if (cur[1] == '\'') {
- // Vesanen: more than 2 escaped ' in one literal!
- do {
- for(cur += 2;*cur != '\'';++cur) {
- if (*cur == '\0') {
- throw STEP::SyntaxError("string literal not closed",line);
- }
- }
- }
- while(cur[1] == '\'');
- }
-
- inout = cur + 1;
-
- // 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 std::make_shared<EXPRESS::STRING>(stemp);
- }
- else if (*cur == '\"' ) {
- throw STEP::SyntaxError("binary data not supported yet",line);
- }
-
- // else -- must be a number. if there is a decimal dot in it,
- // parse it as real value, otherwise as integer.
- const char* start = cur;
- for(;*cur && *cur != ',' && *cur != ')' && !IsSpace(*cur);++cur) {
- if (*cur == '.') {
- double f;
- inout = fast_atoreal_move<double>(start,f);
- return std::make_shared<EXPRESS::REAL>(f);
- }
- }
-
- bool neg = false;
- if (*start == '-') {
- neg = true;
- ++start;
- }
- else if (*start == '+') {
- ++start;
- }
- int64_t num = static_cast<int64_t>( strtoul10_64(start,&inout) );
- return std::make_shared<EXPRESS::INTEGER>(neg?-num:num);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-std::shared_ptr<const EXPRESS::LIST> EXPRESS::LIST::Parse(const char*& inout,uint64_t line, const EXPRESS::ConversionSchema* schema /*= NULL*/)
-{
- const std::shared_ptr<EXPRESS::LIST> list = std::make_shared<EXPRESS::LIST>();
- EXPRESS::LIST::MemberList& members = list->members;
-
- const char* cur = inout;
- if (*cur++ != '(') {
- throw STEP::SyntaxError("unexpected token, expected \'(\' token at beginning of list",line);
- }
-
- // estimate the number of items upfront - lists can grow large
- size_t count = 1;
- for(const char* c=cur; *c && *c != ')'; ++c) {
- count += (*c == ',' ? 1 : 0);
- }
-
- members.reserve(count);
-
- for(;;++cur) {
- if (!*cur) {
- throw STEP::SyntaxError("unexpected end of line while reading list");
- }
- SkipSpaces(cur,&cur);
- if (*cur == ')') {
- break;
- }
-
- members.push_back( EXPRESS::DataType::Parse(cur,line,schema));
- SkipSpaces(cur,&cur);
-
- if (*cur != ',') {
- if (*cur == ')') {
- break;
- }
- throw STEP::SyntaxError("unexpected token, expected \',\' or \')\' token after list element",line);
- }
- }
-
- inout = cur+1;
- return list;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t /*line*/, const char* const type,const char* args)
- : id(id)
- , type(type)
- , db(db)
- , args(args)
- , obj()
-{
- // find any external references and store them in the database.
- // this helps us emulate STEPs INVERSE fields.
- if (db.KeepInverseIndicesForType(type)) {
- const char* a = args;
-
- // do a quick scan through the argument tuple and watch out for entity references
- int64_t skip_depth = 0;
- while(*a) {
- if (*a == '(') {
- ++skip_depth;
- }
- else if (*a == ')') {
- --skip_depth;
- }
-
- 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);
- }
- ++a;
- }
-
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-STEP::LazyObject::~LazyObject()
-{
- // make sure the right dtor/operator delete get called
- if (obj) {
- delete obj;
- }
- else delete[] args;
-}
-
-// ------------------------------------------------------------------------------------------------
-void STEP::LazyObject::LazyInit() const
-{
- const EXPRESS::ConversionSchema& schema = db.GetSchema();
- STEP::ConvertObjectProc proc = schema.GetConverterProc(type);
-
- if (!proc) {
- throw STEP::TypeError("unknown object type: " + std::string(type),id);
- }
-
- const char* acopy = args;
- std::shared_ptr<const EXPRESS::LIST> conv_args = EXPRESS::LIST::Parse(acopy,STEP::SyntaxError::LINE_NOT_SPECIFIED,&db.GetSchema());
- delete[] args;
- args = NULL;
-
- // if the converter fails, it should throw an exception, but it should never return NULL
- try {
- obj = proc(db,*conv_args);
- }
- catch(const TypeError& t) {
- // augment line and entity information
- throw TypeError(t.what(),id);
- }
- ++db.evaluated_count;
- ai_assert(obj);
-
- // store the original id in the object instance
- obj->SetID(id);
-}
-
diff --git a/src/3rdparty/assimp/code/STEPFileReader.h b/src/3rdparty/assimp/code/STEPFileReader.h
deleted file mode 100644
index fb8c86f59..000000000
--- a/src/3rdparty/assimp/code/STEPFileReader.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_STEPFILEREADER_H
-#define INCLUDED_AI_STEPFILEREADER_H
-
-#include "STEPFile.h"
-
-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(std::shared_ptr<IOStream> stream);
- // --------------------------------------------------------------------------
- // 2) read the actual file contents using a user-supplied set of
- // conversion functions to interpret the data.
- void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2);
- 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
-
-#endif
diff --git a/src/3rdparty/assimp/code/STLExporter.cpp b/src/3rdparty/assimp/code/STLExporter.cpp
deleted file mode 100644
index 60b5d8bf3..000000000
--- a/src/3rdparty/assimp/code/STLExporter.cpp
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-
-
-#if !defined(ASSIMP_BUILD_NO_EXPORT) && !defined(ASSIMP_BUILD_NO_STL_EXPORTER)
-
-#include "STLExporter.h"
-#include <assimp/version.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/Exporter.hpp>
-#include <memory>
-#include "Exceptional.h"
-#include "ByteSwapper.h"
-
-using namespace Assimp;
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
-void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
-{
- // invoke the exporter
- STLExporter exporter(pFile, pScene);
-
- if (exporter.mOutput.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write the file.
- std::unique_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, const ExportProperties* /*pProperties*/)
-{
- // invoke the exporter
- STLExporter exporter(pFile, pScene, true);
-
- if (exporter.mOutput.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write the file.
- std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wb"));
- 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);
-}
-
-} // end of namespace Assimp
-
-
-// ------------------------------------------------------------------------------------------------
-STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary)
-: filename(_filename)
-, endl("\n")
-{
- // 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);
- mOutput.precision(16);
- 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 << "endsolid " << name << endl;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void STLExporter :: WriteMesh(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();
- }
- mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
- mOutput << " outer loop" << endl;
- for(unsigned int a = 0; a < f.mNumIndices; ++a) {
- const aiVector3D& v = m->mVertices[f.mIndices[a]];
- mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
- }
-
- mOutput << " endloop" << endl;
- mOutput << " endfacet" << endl << endl;
- }
-}
-
-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();
- }
- ai_real 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]];
- ai_real 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
deleted file mode 100644
index 7fb6a3e75..000000000
--- a/src/3rdparty/assimp/code/STLExporter.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 STLExporter.h
- * Declares the exporter class to write a scene to a Stereolithography (STL) file
- */
-#ifndef AI_STLEXPORTER_H_INC
-#define AI_STLEXPORTER_H_INC
-
-#include <sstream>
-
-struct aiScene;
-struct aiNode;
-struct aiMesh;
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-/** Helper class to export a given scene to a STL file. */
-// ------------------------------------------------------------------------------------------------
-class STLExporter
-{
-public:
- /// Constructor for a specific scene to export
- STLExporter(const char* filename, const aiScene* pScene, bool binary = false);
-
-public:
-
- /// public stringstreams to write all output into
- std::ostringstream mOutput;
-
-private:
-
- void WriteMesh(const aiMesh* m);
- void WriteMeshBinary(const aiMesh* m);
-
-private:
-
- const std::string filename;
-
- // this endl() doesn't flush() the stream
- const std::string endl;
-};
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/STLLoader.cpp b/src/3rdparty/assimp/code/STLLoader.cpp
deleted file mode 100644
index be4c7584d..000000000
--- a/src/3rdparty/assimp/code/STLLoader.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the STL importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_STL_IMPORTER
-
-// internal headers
-#include "STLLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-namespace {
-
-static const aiImporterDesc desc = {
- "Stereolithography (STL) Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "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
-static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
- if( fileSize < 84 ) {
- return false;
- }
-
- const char *facecount_pos = buffer + 80;
- uint32_t faceCount( 0 );
- ::memcpy( &faceCount, facecount_pos, sizeof( uint32_t ) );
- 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".
-static 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;
-
- bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
- if( isASCII ) {
- // A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
- if( fileSize >= 500 ) {
- isASCII = true;
- for( unsigned int i = 0; i < 500; i++ ) {
- if( buffer[ i ] > 127 ) {
- isASCII = false;
- break;
- }
- }
- }
- }
- return isASCII;
-}
-} // namespace
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-STLImporter::STLImporter()
- : mBuffer(),
- fileSize(),
- pScene()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-STLImporter::~STLImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if( extension == "stl" ) {
- return true;
- } else if (!extension.length() || checkSig) {
- if( !pIOHandler ) {
- return true;
- }
- const char* tokens[] = {"STL","solid"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* STLImporter::GetInfo () const {
- return &desc;
-}
-
-void addFacesToMesh(aiMesh* pMesh)
-{
- pMesh->mFaces = new aiFace[pMesh->mNumFaces];
- for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
-
- aiFace& face = pMesh->mFaces[i];
- face.mIndices = new unsigned int[face.mNumIndices = 3];
- for (unsigned int o = 0; o < 3;++o,++p) {
- face.mIndices[o] = p;
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler )
-{
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
-
- // Check whether we can read from the file
- if( file.get() == NULL) {
- throw DeadlyImportError( "Failed to open STL file " + pFile + ".");
- }
-
- fileSize = (unsigned int)file->FileSize();
-
- // allocate storage and copy the contents of the file to a memory buffer
- // (terminate it with zero)
- std::vector<char> mBuffer2;
- TextFileToBuffer(file.get(),mBuffer2);
-
- this->pScene = pScene;
- this->mBuffer = &mBuffer2[0];
-
- // the default vertex color is light gray.
- clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = (ai_real) 0.6;
-
- // allocate a single node
- pScene->mRootNode = new aiNode();
-
- bool bMatClr = false;
-
- if (IsBinarySTL(mBuffer, fileSize)) {
- bMatClr = LoadBinaryFile();
- } else if (IsAsciiSTL(mBuffer, fileSize)) {
- LoadASCIIFile( pScene->mRootNode );
- } else {
- throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
- }
-
- // create a single default material, using a white 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(ai_real(1.0),ai_real(1.0),ai_real(1.0),ai_real(1.0));
- if (bMatClr) {
- clrDiffuse = clrColorDefault;
- }
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
- clrDiffuse = aiColor4D( ai_real(1.0), ai_real(1.0), ai_real(1.0), ai_real(1.0));
- pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
-
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = pcMat;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read an ASCII STL file
-void STLImporter::LoadASCIIFile( aiNode *root ) {
- std::vector<aiMesh*> meshes;
- std::vector<aiNode*> nodes;
- const char* sz = mBuffer;
- const char* bufferEnd = mBuffer + fileSize;
- std::vector<aiVector3D> positionBuffer;
- std::vector<aiVector3D> normalBuffer;
-
- // try to guess how many vertices we could have
- // assume we'll need 160 bytes for each face
- size_t sizeEstimate = std::max(1u, fileSize / 160u ) * 3;
- positionBuffer.reserve(sizeEstimate);
- normalBuffer.reserve(sizeEstimate);
-
- while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
- std::vector<unsigned int> meshIndices;
- aiMesh* pMesh = new aiMesh();
- pMesh->mMaterialIndex = 0;
- meshIndices.push_back((unsigned int) meshes.size() );
- meshes.push_back(pMesh);
- aiNode *node = new aiNode;
- node->mParent = root;
- nodes.push_back( node );
- SkipSpaces(&sz);
- ai_assert(!IsLineEnd(sz));
-
- sz += 5; // skip the "solid"
- SkipSpaces(&sz);
- const char* szMe = sz;
- while (!::IsSpaceOrNewLine(*sz)) {
- sz++;
- }
-
- size_t temp;
- // setup the name of the node
- if ((temp = (size_t)(sz-szMe))) {
- if (temp >= MAXLEN) {
- throw DeadlyImportError( "STL: Node name too long" );
- }
- std::string name( szMe, temp );
- node->mName.Set( name.c_str() );
- //pScene->mRootNode->mName.length = temp;
- //memcpy(pScene->mRootNode->mName.data,szMe,temp);
- //pScene->mRootNode->mName.data[temp] = '\0';
- } else {
- pScene->mRootNode->mName.Set("<STL_ASCII>");
- }
-
- unsigned int faceVertexCounter = 3;
- for ( ;; ) {
- // go to the next token
- if(!SkipSpacesAndLineEnd(&sz))
- {
- // seems we're finished although there was no end marker
- DefaultLogger::get()->warn("STL: unexpected EOF. \'endsolid\' keyword was expected");
- break;
- }
- // facet normal -0.13 -0.13 -0.98
- if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5)) && *(sz + 5) != '\0') {
-
- if (faceVertexCounter != 3) {
- DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
- }
- faceVertexCounter = 0;
- normalBuffer.push_back(aiVector3D());
- aiVector3D* vn = &normalBuffer.back();
-
- sz += 6;
- SkipSpaces(&sz);
- if (strncmp(sz,"normal",6)) {
- DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
- } else {
- if (sz[6] == '\0') {
- throw DeadlyImportError("STL: unexpected EOF while parsing facet");
- }
- sz += 7;
- SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->x );
- SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->y );
- SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
- normalBuffer.push_back(*vn);
- normalBuffer.push_back(*vn);
- }
- } else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
- if (faceVertexCounter >= 3) {
- DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
- ++sz;
- } else {
- if (sz[6] == '\0') {
- throw DeadlyImportError("STL: unexpected EOF while parsing facet");
- }
- sz += 7;
- SkipSpaces(&sz);
- positionBuffer.push_back(aiVector3D());
- aiVector3D* vn = &positionBuffer.back();
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->x );
- SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->y );
- SkipSpaces(&sz);
- sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
- faceVertexCounter++;
- }
- } else if (!::strncmp(sz,"endsolid",8)) {
- do {
- ++sz;
- } while (!::IsLineEnd(*sz));
- SkipSpacesAndLineEnd(&sz);
- // finished!
- break;
- } else { // else skip the whole identifier
- do {
- ++sz;
- } while (!::IsSpaceOrNewLine(*sz));
- }
- }
-
- if (positionBuffer.empty()) {
- pMesh->mNumFaces = 0;
- throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
- }
- if (positionBuffer.size() % 3 != 0) {
- pMesh->mNumFaces = 0;
- throw DeadlyImportError("STL: Invalid number of vertices");
- }
- if (normalBuffer.size() != positionBuffer.size()) {
- pMesh->mNumFaces = 0;
- throw DeadlyImportError("Normal buffer size does not match position buffer size");
- }
- pMesh->mNumFaces = static_cast<unsigned int>(positionBuffer.size() / 3);
- pMesh->mNumVertices = static_cast<unsigned int>(positionBuffer.size());
- pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
- positionBuffer.clear();
- pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
- normalBuffer.clear();
-
- // now copy faces
- addFacesToMesh(pMesh);
-
- // assign the meshes to the current node
- pushMeshesToNode( meshIndices, node );
- }
-
- // now add the loaded meshes
- pScene->mNumMeshes = (unsigned int)meshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for (size_t i = 0; i < meshes.size(); i++) {
- pScene->mMeshes[ i ] = meshes[i];
- }
-
- root->mNumChildren = (unsigned int) nodes.size();
- root->mChildren = new aiNode*[ root->mNumChildren ];
- for ( size_t i=0; i<nodes.size(); ++i ) {
- root->mChildren[ i ] = nodes[ i ];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Read a binary STL file
-bool STLImporter::LoadBinaryFile()
-{
- // allocate one mesh
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
- pMesh->mMaterialIndex = 0;
-
- // skip the first 80 bytes
- if (fileSize < 84) {
- throw DeadlyImportError("STL: file is too small for the header");
- }
- bool bIsMaterialise = false;
-
- // search for an occurrence of "COLOR=" in the header
- const unsigned char* sz2 = (const unsigned char*)mBuffer;
- const unsigned char* const szEnd = sz2+80;
- while (sz2 < szEnd) {
-
- if ('C' == *sz2++ && 'O' == *sz2++ && 'L' == *sz2++ &&
- 'O' == *sz2++ && 'R' == *sz2++ && '=' == *sz2++) {
-
- // read the default vertex color for facets
- bIsMaterialise = true;
- DefaultLogger::get()->info("STL: Taking code path for Materialise files");
- const ai_real invByte = (ai_real)1.0 / ( ai_real )255.0;
- clrColorDefault.r = (*sz2++) * invByte;
- clrColorDefault.g = (*sz2++) * invByte;
- clrColorDefault.b = (*sz2++) * invByte;
- clrColorDefault.a = (*sz2++) * invByte;
- break;
- }
- }
- const unsigned char* sz = (const unsigned char*)mBuffer + 80;
-
- // now read the number of facets
- pScene->mRootNode->mName.Set("<STL_BINARY>");
-
- pMesh->mNumFaces = *((uint32_t*)sz);
- sz += 4;
-
- if (fileSize < 84 + pMesh->mNumFaces*50) {
- throw DeadlyImportError("STL: file is too small to hold all facets");
- }
-
- if (!pMesh->mNumFaces) {
- throw DeadlyImportError("STL: file is empty. There are no facets defined");
- }
-
- pMesh->mNumVertices = pMesh->mNumFaces*3;
-
- aiVector3D* vp,*vn;
- vp = pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
- vn = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-
- for (unsigned int i = 0; i < pMesh->mNumFaces;++i) {
-
- // NOTE: Blender sometimes writes empty normals ... this is not
- // our fault ... the RemoveInvalidData helper step should fix that
- *vn = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
- *(vn+1) = *vn;
- *(vn+2) = *vn;
- vn += 3;
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- *vp++ = *((aiVector3D*)sz);
- sz += sizeof(aiVector3D);
-
- uint16_t color = *((uint16_t*)sz);
- sz += 2;
-
- if (color & (1 << 15))
- {
- // seems we need to take the color
- if (!pMesh->mColors[0])
- {
- pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
- for (unsigned int i = 0; i <pMesh->mNumVertices;++i)
- *pMesh->mColors[0]++ = this->clrColorDefault;
- pMesh->mColors[0] -= pMesh->mNumVertices;
-
- DefaultLogger::get()->info("STL: Mesh has vertex colors");
- }
- aiColor4D* clr = &pMesh->mColors[0][i*3];
- clr->a = 1.0;
- const ai_real invVal( (ai_real)1.0 / ( ai_real )31.0 );
- if (bIsMaterialise) // this is reversed
- {
- clr->r = (color & 0x31u) *invVal;
- clr->g = ((color & (0x31u<<5))>>5u) *invVal;
- clr->b = ((color & (0x31u<<10))>>10u) *invVal;
- }
- else
- {
- clr->b = (color & 0x31u) *invVal;
- clr->g = ((color & (0x31u<<5))>>5u) *invVal;
- clr->r = ((color & (0x31u<<10))>>10u) *invVal;
- }
- // assign the color to all vertices of the face
- *(clr+1) = *clr;
- *(clr+2) = *clr;
- }
- }
-
- // now copy faces
- addFacesToMesh(pMesh);
-
- // add all created meshes to the single node
- pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
- pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
- pScene->mRootNode->mMeshes[i] = i;
-
- if (bIsMaterialise && !pMesh->mColors[0])
- {
- // use the color as diffuse material color
- return true;
- }
- return false;
-}
-
-void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
- ai_assert( nullptr != node );
- if ( meshIndices.empty() ) {
- return;
- }
-
- node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
- node->mMeshes = new unsigned int[ meshIndices.size() ];
- for ( size_t i=0; i<meshIndices.size(); ++i ) {
- node->mMeshes[ i ] = meshIndices[ i ];
- }
- meshIndices.clear();
-}
-
-#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER
diff --git a/src/3rdparty/assimp/code/STLLoader.h b/src/3rdparty/assimp/code/STLLoader.h
deleted file mode 100644
index c51604861..000000000
--- a/src/3rdparty/assimp/code/STLLoader.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 STLLoader.h
- * Declaration of the STL importer class.
- */
-#ifndef AI_STLLOADER_H_INCLUDED
-#define AI_STLLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include <assimp/types.h>
-
-// Forward declarations
-struct aiNode;
-
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/**
- * @brief Importer class for the sterolithography STL file format.
- */
-class STLImporter : public BaseImporter {
-public:
- /**
- * @brief STLImporter, the class default constructor.
- */
- STLImporter();
-
- /**
- * @brief The class destructor.
- */
- ~STLImporter();
-
- /**
- * @brief Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details.
- */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-protected:
-
- /**
- * @brief Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- /**
- * @brief Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- /**
- * @brief Loads a binary .stl file
- * @return true if the default vertex color must be used as material color
- */
- bool LoadBinaryFile();
-
- /**
- * @brief Loads a ASCII text .stl file
- */
- void LoadASCIIFile( aiNode *root );
-
- void pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node );
-
-protected:
-
- /** Buffer to hold the loaded file */
- const char* mBuffer;
-
- /** Size of the file, in bytes */
- unsigned int fileSize;
-
- /** Output scene */
- aiScene* pScene;
-
- /** Default vertex color */
- aiColor4D clrColorDefault;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_3DSIMPORTER_H_IN
diff --git a/src/3rdparty/assimp/code/ScaleProcess.cpp b/src/3rdparty/assimp/code/ScaleProcess.cpp
deleted file mode 100644
index ada978e82..000000000
--- a/src/3rdparty/assimp/code/ScaleProcess.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#include "ScaleProcess.h"
-
-#include <assimp/scene.h>
-#include <assimp/postprocess.h>
-
-namespace Assimp {
-
-ScaleProcess::ScaleProcess()
-: BaseProcess()
-, mScale( AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT ) {
- // empty
-}
-
-ScaleProcess::~ScaleProcess() {
- // empty
-}
-
-void ScaleProcess::setScale( ai_real scale ) {
- mScale = scale;
-}
-
-ai_real ScaleProcess::getScale() const {
- return mScale;
-}
-
-bool ScaleProcess::IsActive( unsigned int pFlags ) const {
- return ( pFlags & aiProcess_GlobalScale ) != 0;
-}
-
-void ScaleProcess::SetupProperties( const Importer* pImp ) {
- mScale = pImp->GetPropertyFloat( AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY, 0 );
-}
-
-void ScaleProcess::Execute( aiScene* pScene ) {
- if ( nullptr == pScene ) {
- return;
- }
-
- if ( nullptr == pScene->mRootNode ) {
- return;
- }
-
- traverseNodes( pScene->mRootNode );
-}
-
-void ScaleProcess::traverseNodes( aiNode *node ) {
- applyScaling( node );
-
- /*for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
- aiNode *currentNode = currentNode->mChildren[ i ];
- if ( nullptr != currentNode ) {
- traverseNodes( currentNode );
- }
- }*/
-}
-
-void ScaleProcess::applyScaling( aiNode *currentNode ) {
- if ( nullptr != currentNode ) {
- currentNode->mTransformation.a1 = currentNode->mTransformation.a1 * mScale;
- currentNode->mTransformation.b2 = currentNode->mTransformation.b2 * mScale;
- currentNode->mTransformation.c3 = currentNode->mTransformation.c3 * mScale;
- }
-}
-
-} // Namespace Assimp
diff --git a/src/3rdparty/assimp/code/ScaleProcess.h b/src/3rdparty/assimp/code/ScaleProcess.h
deleted file mode 100644
index 7eb91fd5c..000000000
--- a/src/3rdparty/assimp/code/ScaleProcess.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include "BaseProcess.h"
-
-struct aiNode;
-
-#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT)
-# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
-#endif // !! AI_DEBONE_THRESHOLD
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** ScaleProcess: Class to rescale the whole model.
-*/
-class ASSIMP_API ScaleProcess : public BaseProcess {
-public:
- /// The default class constructor.
- ScaleProcess();
-
- /// The class destructor.
- virtual ~ScaleProcess();
-
- /// Will set the scale manually.
- void setScale( ai_real scale );
-
- /// Returns the current scaling value.
- ai_real getScale() const;
-
- /// Overwritten, @see BaseProcess
- virtual bool IsActive( unsigned int pFlags ) const;
-
- /// Overwritten, @see BaseProcess
- virtual void SetupProperties( const Importer* pImp );
-
- /// Overwritten, @see BaseProcess
- virtual void Execute( aiScene* pScene );
-
-private:
- void traverseNodes( aiNode *currentNode );
- void applyScaling( aiNode *currentNode );
-
-private:
- ai_real mScale;
-};
-
-} // Namespace Assimp
diff --git a/src/3rdparty/assimp/code/SceneCombiner.cpp b/src/3rdparty/assimp/code/SceneCombiner.cpp
deleted file mode 100644
index 4b77bb2db..000000000
--- a/src/3rdparty/assimp/code/SceneCombiner.cpp
+++ /dev/null
@@ -1,1286 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-// TODO: refactor entire file to get rid of the "flat-copy" first approach
-// to copying structures. This easily breaks in the most unintuitive way
-// possible as new fields are added to assimp structures.
-
-// ----------------------------------------------------------------------------
-/**
- * @file Implements Assimp::SceneCombiner. This is a smart utility
- * class that combines multiple scenes, meshes, ... into one. Currently
- * these utilities are used by the IRR and LWS loaders and the
- * OptimizeGraph step.
- */
-// ----------------------------------------------------------------------------
-#include <assimp/SceneCombiner.h>
-#include "StringUtils.h"
-#include "fast_atof.h"
-#include "Hash.h"
-#include "time.h"
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-#include <assimp/mesh.h>
-#include <stdio.h>
-#include "ScenePrivate.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-// Add a prefix to a string
-inline
-void PrefixString(aiString& string,const char* prefix, unsigned int len) {
- // If the string is already prefixed, we won't prefix it a second time
- if (string.length >= 1 && string.data[0] == '$')
- return;
-
- if (len+string.length>=MAXLEN-1) {
- DefaultLogger::get()->debug("Can't add an unique prefix because the string is too long");
- ai_assert(false);
- return;
- }
-
- // Add the prefix
- ::memmove(string.data+len,string.data,string.length+1);
- ::memcpy (string.data, prefix, len);
-
- // And update the string's length
- string.length += len;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add node identifiers to a hashing set
-void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes) {
- // Add node name to hashing set if it is non-empty - empty nodes are allowed
- // and they can't have any anims assigned so its absolutely safe to duplicate them.
- if (node->mName.length) {
- hashes.insert( SuperFastHash(node->mName.data, static_cast<uint32_t>(node->mName.length)) );
- }
-
- // Process all children recursively
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- AddNodeHashes(node->mChildren[i],hashes);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a name prefix to all nodes in a hierarchy
-void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len) {
- ai_assert(NULL != prefix);
- PrefixString(node->mName,prefix,len);
-
- // Process all children recursively
- for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
- AddNodePrefixes( node->mChildren[ i ], prefix, len );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Search for matching names
-bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur) {
- const unsigned int hash = SuperFastHash(name.data, static_cast<uint32_t>(name.length));
-
- // Check whether we find a positive match in one of the given sets
- for (unsigned int i = 0; i < input.size(); ++i) {
- if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
- return true;
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add a name prefix to all nodes in a hierarchy if a hash match is found
-void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, unsigned int len,
- std::vector<SceneHelper>& input, unsigned int cur) {
- ai_assert(NULL != prefix);
- const unsigned int hash = SuperFastHash(node->mName.data, static_cast<uint32_t>(node->mName.length));
-
- // Check whether we find a positive match in one of the given sets
- for (unsigned int i = 0; i < input.size(); ++i) {
- if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
- PrefixString(node->mName,prefix,len);
- break;
- }
- }
-
- // Process all children recursively
- for (unsigned int i = 0; i < node->mNumChildren;++i)
- AddNodePrefixesChecked(node->mChildren[i],prefix,len,input,cur);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Add an offset to all mesh indices in a node graph
-void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset) {
- for (unsigned int i = 0; i < node->mNumMeshes;++i)
- node->mMeshes[i] += offset;
-
- for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
- OffsetNodeMeshIndices( node->mChildren[ i ], offset );
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merges two scenes. Currently only used by the LWS loader.
-void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src, unsigned int flags) {
- if ( nullptr == _dest ) {
- return;
- }
-
- // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
- if (src.empty()) {
- if (*_dest) {
- (*_dest)->~aiScene();
- SceneCombiner::CopySceneFlat(_dest,src[0]);
- }
- else *_dest = src[0];
- return;
- }
- if (*_dest)(*_dest)->~aiScene();
- else *_dest = new aiScene();
-
- // Create a dummy scene to serve as master for the others
- aiScene* master = new aiScene();
- master->mRootNode = new aiNode();
- master->mRootNode->mName.Set("<MergeRoot>");
-
- std::vector<AttachmentInfo> srcList (src.size());
- for (unsigned int i = 0; i < srcList.size();++i) {
- srcList[i] = AttachmentInfo(src[i],master->mRootNode);
- }
-
- // 'master' will be deleted afterwards
- MergeScenes (_dest, master, srcList, flags);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList) {
- unsigned int cnt;
- for ( cnt = 0; cnt < attach->mNumChildren; ++cnt ) {
- AttachToGraph( attach->mChildren[ cnt ], srcList );
- }
-
- cnt = 0;
- for (std::vector<NodeAttachmentInfo>::iterator it = srcList.begin();
- it != srcList.end(); ++it)
- {
- if ((*it).attachToNode == attach && !(*it).resolved)
- ++cnt;
- }
-
- if (cnt) {
- aiNode** n = new aiNode*[cnt+attach->mNumChildren];
- if (attach->mNumChildren) {
- ::memcpy(n,attach->mChildren,sizeof(void*)*attach->mNumChildren);
- delete[] attach->mChildren;
- }
- attach->mChildren = n;
-
- n += attach->mNumChildren;
- attach->mNumChildren += cnt;
-
- for (unsigned int i = 0; i < srcList.size();++i) {
- NodeAttachmentInfo& att = srcList[i];
- if (att.attachToNode == attach && !att.resolved) {
- *n = att.node;
- (**n).mParent = attach;
- ++n;
-
- // mark this attachment as resolved
- att.resolved = true;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::AttachToGraph ( aiScene* master, std::vector<NodeAttachmentInfo>& src) {
- ai_assert(NULL != master);
- AttachToGraph(master->mRootNode,src);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master, std::vector<AttachmentInfo>& srcList, unsigned int flags) {
- if ( nullptr == _dest ) {
- return;
- }
-
- // if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
- if (srcList.empty()) {
- if (*_dest) {
- SceneCombiner::CopySceneFlat(_dest,master);
- }
- else *_dest = master;
- return;
- }
- if (*_dest) {
- (*_dest)->~aiScene();
- new (*_dest) aiScene();
- }
- else *_dest = new aiScene();
-
- aiScene* dest = *_dest;
-
- std::vector<SceneHelper> src (srcList.size()+1);
- src[0].scene = master;
- for (unsigned int i = 0; i < srcList.size();++i) {
- src[i+1] = SceneHelper( srcList[i].scene );
- }
-
- // this helper array specifies which scenes are duplicates of others
- std::vector<unsigned int> duplicates(src.size(),UINT_MAX);
-
- // this helper array is used as lookup table several times
- std::vector<unsigned int> offset(src.size());
-
- // Find duplicate scenes
- for (unsigned int i = 0; i < src.size();++i) {
- if (duplicates[i] != i && duplicates[i] != UINT_MAX) {
- continue;
- }
-
- duplicates[i] = i;
- for ( unsigned int a = i+1; a < src.size(); ++a) {
- if (src[i].scene == src[a].scene) {
- duplicates[a] = i;
- }
- }
- }
-
- // Generate unique names for all named stuff?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES)
- {
-#if 0
- // Construct a proper random number generator
- boost::mt19937 rng( );
- boost::uniform_int<> dist(1u,1 << 24u);
- boost::variate_generator<boost::mt19937&, boost::uniform_int<> > rndGen(rng, dist);
-#endif
- for (unsigned int i = 1; i < src.size();++i)
- {
- //if (i != duplicates[i])
- //{
- // // duplicate scenes share the same UID
- // ::strcpy( src[i].id, src[duplicates[i]].id );
- // src[i].idlen = src[duplicates[i]].idlen;
-
- // continue;
- //}
-
- src[i].idlen = ai_snprintf(src[i].id, 32, "$%.6X$_",i);
-
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
-
- // Compute hashes for all identifiers in this scene and store them
- // in a sorted table (for convenience I'm using std::set). We hash
- // just the node and animation channel names, all identifiers except
- // the material names should be caught by doing this.
- AddNodeHashes(src[i]->mRootNode,src[i].hashes);
-
- for (unsigned int a = 0; a < src[i]->mNumAnimations;++a) {
- aiAnimation* anim = src[i]->mAnimations[a];
- src[i].hashes.insert(SuperFastHash(anim->mName.data,static_cast<uint32_t>(anim->mName.length)));
- }
- }
- }
- }
-
- unsigned int cnt;
-
- // First find out how large the respective output arrays must be
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
-
- if (n == duplicates[n] || flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
- dest->mNumTextures += (*cur)->mNumTextures;
- dest->mNumMaterials += (*cur)->mNumMaterials;
- dest->mNumMeshes += (*cur)->mNumMeshes;
- }
-
- dest->mNumLights += (*cur)->mNumLights;
- dest->mNumCameras += (*cur)->mNumCameras;
- dest->mNumAnimations += (*cur)->mNumAnimations;
-
- // Combine the flags of all scenes
- // We need to process them flag-by-flag here to get correct results
- // dest->mFlags ; //|= (*cur)->mFlags;
- if ((*cur)->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) {
- dest->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- }
- }
-
- // generate the output texture list + an offset table for all texture indices
- if (dest->mNumTextures)
- {
- aiTexture** pip = dest->mTextures = new aiTexture*[dest->mNumMaterials];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumTextures;++i)
- {
- if (n != duplicates[n])
- {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip,(*cur)->mTextures[i]);
-
- else continue;
- }
- else *pip = (*cur)->mTextures[i];
- ++pip;
- }
-
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mTextures);
- }
- }
-
- // generate the output material list + an offset table for all material indices
- if (dest->mNumMaterials)
- {
- aiMaterial** pip = dest->mMaterials = new aiMaterial*[dest->mNumMaterials];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n ) {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumMaterials;++i)
- {
- if (n != duplicates[n])
- {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip,(*cur)->mMaterials[i]);
-
- else continue;
- }
- else *pip = (*cur)->mMaterials[i];
-
- if ((*cur)->mNumTextures != dest->mNumTextures) {
- // We need to update all texture indices of the mesh. So we need to search for
- // a material property called '$tex.file'
-
- for (unsigned int a = 0; a < (*pip)->mNumProperties;++a)
- {
- aiMaterialProperty* prop = (*pip)->mProperties[a];
- if (!strncmp(prop->mKey.data,"$tex.file",9))
- {
- // Check whether this texture is an embedded texture.
- // In this case the property looks like this: *<n>,
- // where n is the index of the texture.
- aiString& s = *((aiString*)prop->mData);
- if ('*' == s.data[0]) {
- // Offset the index and write it back ..
- const unsigned int idx = strtoul10(&s.data[1]) + offset[n];
- ASSIMP_itoa10(&s.data[1],sizeof(s.data)-1,idx);
- }
- }
-
- // Need to generate new, unique material names?
- else if (!::strcmp( prop->mKey.data,"$mat.name" ) && flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES)
- {
- aiString* pcSrc = (aiString*) prop->mData;
- PrefixString(*pcSrc, (*cur).id, (*cur).idlen);
- }
- }
- }
- ++pip;
- }
-
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mMaterials);
- }
- }
-
- // generate the output mesh list + again an offset table for all mesh indices
- if (dest->mNumMeshes)
- {
- aiMesh** pip = dest->mMeshes = new aiMesh*[dest->mNumMeshes];
- cnt = 0;
- for ( unsigned int n = 0; n < src.size();++n )
- {
- SceneHelper* cur = &src[n];
- for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i)
- {
- if (n != duplicates[n]) {
- if ( flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY)
- Copy(pip, (*cur)->mMeshes[i]);
-
- else continue;
- }
- else *pip = (*cur)->mMeshes[i];
-
- // update the material index of the mesh
- (*pip)->mMaterialIndex += offset[n];
- ++pip;
- }
-
- // reuse the offset array - store now the mesh offset in it
- offset[n] = cnt;
- cnt = (unsigned int)(pip - dest->mMeshes);
- }
- }
-
- std::vector <NodeAttachmentInfo> nodes;
- nodes.reserve(srcList.size());
-
- // ----------------------------------------------------------------------------
- // Now generate the output node graph. We need to make those
- // names in the graph that are referenced by anims or lights
- // or cameras unique. So we add a prefix to them ... $<rand>_
- // We could also use a counter, but using a random value allows us to
- // use just one prefix if we are joining multiple scene hierarchies recursively.
- // Chances are quite good we don't collide, so we try that ...
- // ----------------------------------------------------------------------------
-
- // Allocate space for light sources, cameras and animations
- aiLight** ppLights = dest->mLights = (dest->mNumLights
- ? new aiLight*[dest->mNumLights] : NULL);
-
- aiCamera** ppCameras = dest->mCameras = (dest->mNumCameras
- ? new aiCamera*[dest->mNumCameras] : NULL);
-
- aiAnimation** ppAnims = dest->mAnimations = (dest->mNumAnimations
- ? new aiAnimation*[dest->mNumAnimations] : NULL);
-
- for ( int n = static_cast<int>(src.size()-1); n >= 0 ;--n ) /* !!! important !!! */
- {
- SceneHelper* cur = &src[n];
- aiNode* node;
-
- // To offset or not to offset, this is the question
- if (n != (int)duplicates[n])
- {
- // Get full scene-graph copy
- Copy( &node, (*cur)->mRootNode );
- OffsetNodeMeshIndices(node,offset[duplicates[n]]);
-
- if (flags & AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY) {
- // (note:) they are already 'offseted' by offset[duplicates[n]]
- OffsetNodeMeshIndices(node,offset[n] - offset[duplicates[n]]);
- }
- }
- else // if (n == duplicates[n])
- {
- node = (*cur)->mRootNode;
- OffsetNodeMeshIndices(node,offset[n]);
- }
- if (n) // src[0] is the master node
- nodes.push_back(NodeAttachmentInfo( node,srcList[n-1].attachToNode,n ));
-
- // add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
-
- // or the whole scenegraph
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- AddNodePrefixesChecked(node,(*cur).id,(*cur).idlen,src,n);
- }
- else AddNodePrefixes(node,(*cur).id,(*cur).idlen);
-
- // meshes
- for (unsigned int i = 0; i < (*cur)->mNumMeshes;++i) {
- aiMesh* mesh = (*cur)->mMeshes[i];
-
- // rename all bones
- for (unsigned int a = 0; a < mesh->mNumBones;++a) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch(mesh->mBones[a]->mName,src,n))
- continue;
- }
- PrefixString(mesh->mBones[a]->mName,(*cur).id,(*cur).idlen);
- }
- }
- }
-
- // --------------------------------------------------------------------
- // Copy light sources
- for (unsigned int i = 0; i < (*cur)->mNumLights;++i,++ppLights)
- {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppLights, (*cur)->mLights[i]);
- }
- else *ppLights = (*cur)->mLights[i];
-
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppLights)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppLights)->mName,(*cur).id,(*cur).idlen);
- }
- }
-
- // --------------------------------------------------------------------
- // Copy cameras
- for (unsigned int i = 0; i < (*cur)->mNumCameras;++i,++ppCameras) {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppCameras, (*cur)->mCameras[i]);
- }
- else *ppCameras = (*cur)->mCameras[i];
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppCameras)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppCameras)->mName,(*cur).id,(*cur).idlen);
- }
- }
-
- // --------------------------------------------------------------------
- // Copy animations
- for (unsigned int i = 0; i < (*cur)->mNumAnimations;++i,++ppAnims) {
- if (n != (int)duplicates[n]) // duplicate scene?
- {
- Copy(ppAnims, (*cur)->mAnimations[i]);
- }
- else *ppAnims = (*cur)->mAnimations[i];
-
- // Add name prefixes?
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppAnims)->mName,src,n))
- continue;
- }
-
- PrefixString((*ppAnims)->mName,(*cur).id,(*cur).idlen);
-
- // don't forget to update all node animation channels
- for (unsigned int a = 0; a < (*ppAnims)->mNumChannels;++a) {
- if (flags & AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY) {
- if (!FindNameMatch((*ppAnims)->mChannels[a]->mNodeName,src,n))
- continue;
- }
-
- PrefixString((*ppAnims)->mChannels[a]->mNodeName,(*cur).id,(*cur).idlen);
- }
- }
- }
- }
-
- // Now build the output graph
- AttachToGraph ( master, nodes);
- dest->mRootNode = master->mRootNode;
-
- // Check whether we succeeded at building the output graph
- for (std::vector <NodeAttachmentInfo> ::iterator it = nodes.begin();
- it != nodes.end(); ++it)
- {
- if (!(*it).resolved) {
- if (flags & AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS) {
- // search for this attachment point in all other imported scenes, too.
- for ( unsigned int n = 0; n < src.size();++n ) {
- if (n != (*it).src_idx) {
- AttachToGraph(src[n].scene,nodes);
- if ((*it).resolved)
- break;
- }
- }
- }
- if (!(*it).resolved) {
- DefaultLogger::get()->error(std::string("SceneCombiner: Failed to resolve attachment ")
- + (*it).node->mName.data + " " + (*it).attachToNode->mName.data);
- }
- }
- }
-
- // now delete all input scenes. Make sure duplicate scenes aren't
- // deleted more than one time
- for ( unsigned int n = 0; n < src.size();++n ) {
- if (n != duplicates[n]) // duplicate scene?
- continue;
-
- aiScene* deleteMe = src[n].scene;
-
- // We need to delete the arrays before the destructor is called -
- // we are reusing the array members
- delete[] deleteMe->mMeshes; deleteMe->mMeshes = NULL;
- delete[] deleteMe->mCameras; deleteMe->mCameras = NULL;
- delete[] deleteMe->mLights; deleteMe->mLights = NULL;
- delete[] deleteMe->mMaterials; deleteMe->mMaterials = NULL;
- delete[] deleteMe->mAnimations; deleteMe->mAnimations = NULL;
-
- deleteMe->mRootNode = NULL;
-
- // Now we can safely delete the scene
- delete deleteMe;
- }
-
- // Check flags
- if (!dest->mNumMeshes || !dest->mNumMaterials) {
- dest->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-
- // We're finished
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a list of unique bones
-void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
- std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end)
-{
- unsigned int iOffset = 0;
- for (; it != end;++it) {
- for (unsigned int l = 0; l < (*it)->mNumBones;++l) {
- aiBone* p = (*it)->mBones[l];
- uint32_t itml = SuperFastHash(p->mName.data,(unsigned int)p->mName.length);
-
- std::list<BoneWithHash>::iterator it2 = asBones.begin();
- std::list<BoneWithHash>::iterator end2 = asBones.end();
-
- for (;it2 != end2;++it2) {
- if ((*it2).first == itml) {
- (*it2).pSrcBones.push_back(BoneSrcIndex(p,iOffset));
- break;
- }
- }
- if (end2 == it2) {
- // need to begin a new bone entry
- asBones.push_back(BoneWithHash());
- BoneWithHash& btz = asBones.back();
-
- // setup members
- btz.first = itml;
- btz.second = &p->mName;
- btz.pSrcBones.push_back(BoneSrcIndex(p,iOffset));
- }
- }
- iOffset += (*it)->mNumVertices;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merge a list of bones
-void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end)
-{
- if ( nullptr == out || out->mNumBones == 0 ) {
- return;
- }
-
- // find we need to build an unique list of all bones.
- // we work with hashes to make the comparisons MUCH faster,
- // at least if we have many bones.
- std::list<BoneWithHash> asBones;
- BuildUniqueBoneList(asBones, it,end);
-
- // now create the output bones
- out->mNumBones = 0;
- out->mBones = new aiBone*[asBones.size()];
-
- for (std::list<BoneWithHash>::const_iterator it = asBones.begin(),end = asBones.end(); it != end;++it) {
- // Allocate a bone and setup it's name
- aiBone* pc = out->mBones[out->mNumBones++] = new aiBone();
- pc->mName = aiString( *((*it).second ));
-
- std::vector< BoneSrcIndex >::const_iterator wend = (*it).pSrcBones.end();
-
- // Loop through all bones to be joined for this bone
- for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
- pc->mNumWeights += (*wmit).first->mNumWeights;
-
- // NOTE: different offset matrices for bones with equal names
- // are - at the moment - not handled correctly.
- if (wmit != (*it).pSrcBones.begin() && pc->mOffsetMatrix != (*wmit).first->mOffsetMatrix) {
- DefaultLogger::get()->warn("Bones with equal names but different offset matrices can't be joined at the moment");
- continue;
- }
- pc->mOffsetMatrix = (*wmit).first->mOffsetMatrix;
- }
-
- // Allocate the vertex weight array
- aiVertexWeight* avw = pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- // And copy the final weights - adjust the vertex IDs by the
- // face index offset of the corresponding mesh.
- for (std::vector< BoneSrcIndex >::const_iterator wmit = (*it).pSrcBones.begin(); wmit != wend; ++wmit) {
- aiBone* pip = (*wmit).first;
- for (unsigned int mp = 0; mp < pip->mNumWeights;++mp,++avw) {
- const aiVertexWeight& vfi = pip->mWeights[mp];
- avw->mWeight = vfi.mWeight;
- avw->mVertexId = vfi.mVertexId + (*wmit).second;
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Merge a list of meshes
-void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
- std::vector<aiMesh*>::const_iterator begin,
- std::vector<aiMesh*>::const_iterator end)
-{
- if ( nullptr == _out ) {
- return;
- }
-
- if (begin == end) {
- *_out = NULL; // no meshes ...
- return;
- }
-
- // Allocate the output mesh
- aiMesh* out = *_out = new aiMesh();
- out->mMaterialIndex = (*begin)->mMaterialIndex;
-
- std::string name;
- // Find out how much output storage we'll need
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) {
- const char *meshName( (*it)->mName.C_Str() );
- name += std::string( meshName );
- if ( it != end - 1 ) {
- name += ".";
- }
- out->mNumVertices += (*it)->mNumVertices;
- out->mNumFaces += (*it)->mNumFaces;
- out->mNumBones += (*it)->mNumBones;
-
- // combine primitive type flags
- out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
- }
- out->mName.Set( name.c_str() );
-
- if (out->mNumVertices) {
- aiVector3D* pv2;
-
- // copy vertex positions
- if ((**begin).HasPositions()) {
-
- pv2 = out->mVertices = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end; ++it) {
- if ((*it)->mVertices) {
- ::memcpy(pv2,(*it)->mVertices,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Positions expected but input mesh contains no positions");
- pv2 += (*it)->mNumVertices;
- }
- }
- // copy normals
- if ((**begin).HasNormals()) {
-
- pv2 = out->mNormals = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- if ((*it)->mNormals) {
- ::memcpy(pv2,(*it)->mNormals,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Normals expected but input mesh contains no normals");
- pv2 += (*it)->mNumVertices;
- }
- }
- // copy tangents and bi-tangents
- if ((**begin).HasTangentsAndBitangents()) {
-
- pv2 = out->mTangents = new aiVector3D[out->mNumVertices];
- aiVector3D* pv2b = out->mBitangents = new aiVector3D[out->mNumVertices];
-
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- if ((*it)->mTangents) {
- ::memcpy(pv2, (*it)->mTangents, (*it)->mNumVertices*sizeof(aiVector3D));
- ::memcpy(pv2b,(*it)->mBitangents,(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: Tangents expected but input mesh contains no tangents");
- pv2 += (*it)->mNumVertices;
- pv2b += (*it)->mNumVertices;
- }
- }
- // copy texture coordinates
- unsigned int n = 0;
- while ((**begin).HasTextureCoords(n)) {
- out->mNumUVComponents[n] = (*begin)->mNumUVComponents[n];
-
- pv2 = out->mTextureCoords[n] = new aiVector3D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
-
- if ((*it)->mTextureCoords[n]) {
- ::memcpy(pv2,(*it)->mTextureCoords[n],(*it)->mNumVertices*sizeof(aiVector3D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: UVs expected but input mesh contains no UVs");
- pv2 += (*it)->mNumVertices;
- }
- ++n;
- }
- // copy vertex colors
- n = 0;
- while ((**begin).HasVertexColors(n)) {
- aiColor4D* pv2 = out->mColors[n] = new aiColor4D[out->mNumVertices];
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
-
- if ((*it)->mColors[n]) {
- ::memcpy(pv2,(*it)->mColors[n],(*it)->mNumVertices*sizeof(aiColor4D));
- }
- else DefaultLogger::get()->warn("JoinMeshes: VCs expected but input mesh contains no VCs");
- pv2 += (*it)->mNumVertices;
- }
- ++n;
- }
- }
-
- if (out->mNumFaces) // just for safety
- {
- // copy faces
- out->mFaces = new aiFace[out->mNumFaces];
- aiFace* pf2 = out->mFaces;
-
- unsigned int ofs = 0;
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it) {
- for (unsigned int m = 0; m < (*it)->mNumFaces;++m,++pf2) {
- aiFace& face = (*it)->mFaces[m];
- pf2->mNumIndices = face.mNumIndices;
- pf2->mIndices = face.mIndices;
-
- if (ofs) {
- // add the offset to the vertex
- for (unsigned int q = 0; q < face.mNumIndices; ++q)
- face.mIndices[q] += ofs;
- }
- face.mIndices = NULL;
- }
- ofs += (*it)->mNumVertices;
- }
- }
-
- // bones - as this is quite lengthy, I moved the code to a separate function
- if (out->mNumBones)
- MergeBones(out,begin,end);
-
- // delete all source meshes
- for (std::vector<aiMesh*>::const_iterator it = begin; it != end;++it)
- delete *it;
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::MergeMaterials(aiMaterial** dest,
- std::vector<aiMaterial*>::const_iterator begin,
- std::vector<aiMaterial*>::const_iterator end)
-{
- if ( nullptr == dest ) {
- return;
- }
-
- 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->mSemantic, 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, ai_uint num) {
- if (!num) {
- dest = NULL;
- return;
- }
- dest = new Type*[num];
- for (ai_uint i = 0; i < num;++i) {
- SceneCombiner::Copy(&dest[i],src[i]);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename Type>
-inline
-void GetArrayCopy(Type*& dest, ai_uint num ) {
- if ( !dest ) {
- return;
- }
- Type* old = dest;
-
- dest = new Type[num];
- ::memcpy(dest, old, sizeof(Type) * num);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- // reuse the old scene or allocate a new?
- if (*_dest) {
- (*_dest)->~aiScene();
- new (*_dest) aiScene();
- } else {
- *_dest = new aiScene();
- }
-
- ::memcpy(*_dest,src,sizeof(aiScene));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- if (allocate) {
- *_dest = new aiScene();
- }
- aiScene* dest = *_dest;
- ai_assert(dest);
-
- // copy animations
- dest->mNumAnimations = src->mNumAnimations;
- CopyPtrArray(dest->mAnimations,src->mAnimations,
- dest->mNumAnimations);
-
- // copy textures
- dest->mNumTextures = src->mNumTextures;
- CopyPtrArray(dest->mTextures,src->mTextures,
- dest->mNumTextures);
-
- // copy materials
- dest->mNumMaterials = src->mNumMaterials;
- CopyPtrArray(dest->mMaterials,src->mMaterials,
- dest->mNumMaterials);
-
- // copy lights
- dest->mNumLights = src->mNumLights;
- CopyPtrArray(dest->mLights,src->mLights,
- dest->mNumLights);
-
- // copy cameras
- dest->mNumCameras = src->mNumCameras;
- CopyPtrArray(dest->mCameras,src->mCameras,
- dest->mNumCameras);
-
- // copy meshes
- dest->mNumMeshes = src->mNumMeshes;
- CopyPtrArray(dest->mMeshes,src->mMeshes,
- dest->mNumMeshes);
-
- // now - copy the root node of the scene (deep copy, too)
- Copy( &dest->mRootNode, src->mRootNode);
-
- // and keep the flags ...
- dest->mFlags = src->mFlags;
-
- // source private data might be NULL if the scene is user-allocated (i.e. for use with the export API)
- if (dest->mPrivate != NULL) {
- ScenePriv(dest)->mPPStepsApplied = ScenePriv(src) ? ScenePriv(src)->mPPStepsApplied : 0;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiMesh* dest = *_dest = new aiMesh();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiMesh));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mVertices, dest->mNumVertices );
- GetArrayCopy( dest->mNormals , dest->mNumVertices );
- GetArrayCopy( dest->mTangents, dest->mNumVertices );
- GetArrayCopy( dest->mBitangents, dest->mNumVertices );
-
- unsigned int n = 0;
- while (dest->HasTextureCoords(n))
- GetArrayCopy( dest->mTextureCoords[n++], dest->mNumVertices );
-
- n = 0;
- while (dest->HasVertexColors(n))
- GetArrayCopy( dest->mColors[n++], dest->mNumVertices );
-
- // make a deep copy of all bones
- CopyPtrArray(dest->mBones,dest->mBones,dest->mNumBones);
-
- // make a deep copy of all faces
- GetArrayCopy(dest->mFaces,dest->mNumFaces);
- for (unsigned int i = 0; i < dest->mNumFaces;++i) {
- aiFace& f = dest->mFaces[i];
- GetArrayCopy(f.mIndices,f.mNumIndices);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- 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];
-
- for (unsigned int i = 0; i < dest->mNumProperties;++i)
- {
- aiMaterialProperty* prop = dest->mProperties[i] = new aiMaterialProperty();
- aiMaterialProperty* sprop = src->mProperties[i];
-
- 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;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy(aiTexture** _dest, const aiTexture* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiTexture* dest = *_dest = new aiTexture();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiTexture));
-
- // and reallocate all arrays. We must do it manually here
- const char* old = (const char*)dest->pcData;
- if (old)
- {
- unsigned int cpy;
- if (!dest->mHeight)cpy = dest->mWidth;
- else cpy = dest->mHeight * dest->mWidth * sizeof(aiTexel);
-
- if (!cpy)
- {
- dest->pcData = NULL;
- return;
- }
- // the cast is legal, the aiTexel c'tor does nothing important
- dest->pcData = (aiTexel*) new char[cpy];
- ::memcpy(dest->pcData, old, cpy);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiAnimation* dest = *_dest = new aiAnimation();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiAnimation));
-
- // and reallocate all arrays
- CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiNodeAnim* dest = *_dest = new aiNodeAnim();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiNodeAnim));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys );
- GetArrayCopy( dest->mScalingKeys, dest->mNumScalingKeys );
- GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiCamera* dest = *_dest = new aiCamera();
-
- // get a flat copy, that's already OK
- ::memcpy(dest,src,sizeof(aiCamera));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy(aiLight** _dest, const aiLight* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiLight* dest = *_dest = new aiLight();
-
- // get a flat copy, that's already OK
- ::memcpy(dest,src,sizeof(aiLight));
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy(aiBone** _dest, const aiBone* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- aiBone* dest = *_dest = new aiBone();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiBone));
-
- // and reallocate all arrays
- GetArrayCopy( dest->mWeights, dest->mNumWeights );
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
-{
- ai_assert(NULL != _dest && NULL != src);
-
- aiNode* dest = *_dest = new aiNode();
-
- // get a flat copy
- ::memcpy(dest,src,sizeof(aiNode));
-
- if (src->mMetaData) {
- Copy(&dest->mMetaData, src->mMetaData);
- }
-
- // and reallocate all arrays
- GetArrayCopy( dest->mMeshes, dest->mNumMeshes );
- CopyPtrArray( dest->mChildren, src->mChildren,dest->mNumChildren);
-
- // need to set the mParent fields to the created aiNode.
- for( unsigned int i = 0; i < dest->mNumChildren; i ++ ) {
- dest->mChildren[i]->mParent = dest;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src) {
- if ( nullptr == _dest || nullptr == src ) {
- return;
- }
-
- if ( 0 == src->mNumProperties ) {
- return;
- }
-
- aiMetadata* dest = *_dest = aiMetadata::Alloc( src->mNumProperties );
- std::copy(src->mKeys, src->mKeys + src->mNumProperties, dest->mKeys);
-
- dest->mValues = new aiMetadataEntry[src->mNumProperties];
- for (unsigned int i = 0; i < src->mNumProperties; ++i) {
- aiMetadataEntry& in = src->mValues[i];
- aiMetadataEntry& out = dest->mValues[i];
- out.mType = in.mType;
- switch (dest->mValues[i].mType) {
- case AI_BOOL:
- out.mData = new bool(*static_cast<bool*>(in.mData));
- break;
- case AI_INT32:
- out.mData = new int32_t(*static_cast<int32_t*>(in.mData));
- break;
- case AI_UINT64:
- out.mData = new uint64_t(*static_cast<uint64_t*>(in.mData));
- break;
- case AI_FLOAT:
- out.mData = new float(*static_cast<float*>(in.mData));
- break;
- case AI_DOUBLE:
- out.mData = new double(*static_cast<double*>(in.mData));
- break;
- case AI_AISTRING:
- out.mData = new aiString(*static_cast<aiString*>(in.mData));
- break;
- case AI_AIVECTOR3D:
- out.mData = new aiVector3D(*static_cast<aiVector3D*>(in.mData));
- break;
- default:
- ai_assert(false);
- }
- }
-}
-
-} // Namespace Assimp
-
diff --git a/src/3rdparty/assimp/code/ScenePreprocessor.cpp b/src/3rdparty/assimp/code/ScenePreprocessor.cpp
deleted file mode 100644
index 0a6366b7d..000000000
--- a/src/3rdparty/assimp/code/ScenePreprocessor.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "ScenePreprocessor.h"
-#include <assimp/ai_assert.h>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-
-
-using namespace Assimp;
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessScene ()
-{
- ai_assert(scene != NULL);
-
- // Process all meshes
- for (unsigned int i = 0; i < scene->mNumMeshes;++i)
- ProcessMesh(scene->mMeshes[i]);
-
- // - nothing to do for nodes for the moment
- // - nothing to do for textures for the moment
- // - nothing to do for lights for the moment
- // - nothing to do for cameras for the moment
-
- // Process all animations
- for (unsigned int i = 0; i < scene->mNumAnimations;++i)
- ProcessAnimation(scene->mAnimations[i]);
-
- // Generate a default material if none was specified
- if (!scene->mNumMaterials && scene->mNumMeshes) {
- scene->mMaterials = new aiMaterial*[2];
- aiMaterial* helper;
-
- aiString name;
-
- scene->mMaterials[scene->mNumMaterials] = helper = new aiMaterial();
- aiColor3D clr(0.6f,0.6f,0.6f);
- helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
-
- // setup the default name to make this material identifiable
- name.Set(AI_DEFAULT_MATERIAL_NAME);
- helper->AddProperty(&name,AI_MATKEY_NAME);
-
- DefaultLogger::get()->debug("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME "\'");
-
- for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
- scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials;
- }
-
- scene->mNumMaterials++;
- }
-}
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
-{
- // If aiMesh::mNumUVComponents is *not* set assign the default value of 2
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- if (!mesh->mTextureCoords[i]) {
- mesh->mNumUVComponents[i] = 0;
- } else {
- if (!mesh->mNumUVComponents[i])
- mesh->mNumUVComponents[i] = 2;
-
- aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
-
- // Ensure unsued components are zeroed. This will make 1D texture channels work
- // as if they were 2D channels .. just in case an application doesn't handle
- // this case
- if (2 == mesh->mNumUVComponents[i]) {
- for (; p != end; ++p)
- p->z = 0.f;
- }
- else if (1 == mesh->mNumUVComponents[i]) {
- for (; p != end; ++p)
- p->z = p->y = 0.f;
- }
- else if (3 == mesh->mNumUVComponents[i]) {
- // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
- for (; p != end; ++p) {
- if (p->z != 0)
- break;
- }
- if (p == end) {
- DefaultLogger::get()->warn("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
- mesh->mNumUVComponents[i] = 2;
- }
- }
- }
- }
-
- // If the information which primitive types are there in the
- // mesh is currently not available, compute it.
- if (!mesh->mPrimitiveTypes) {
- for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
- aiFace& face = mesh->mFaces[a];
- switch (face.mNumIndices)
- {
- case 3u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
-
- case 2u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
-
- case 1u:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
-
- default:
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- break;
- }
- }
- }
-
- // If tangents and normals are given but no bitangents compute them
- if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
-
- mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
- for (unsigned int i = 0; i < mesh->mNumVertices;++i) {
- mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
- }
- }
-}
-
-// ---------------------------------------------------------------------------------------------
-void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
-{
- double first = 10e10, last = -10e10;
- for (unsigned int i = 0; i < anim->mNumChannels;++i) {
- aiNodeAnim* channel = anim->mChannels[i];
-
- /* If the exact duration of the animation is not given
- * compute it now.
- */
- if (anim->mDuration == -1.) {
-
- // Position keys
- for (unsigned int j = 0; j < channel->mNumPositionKeys;++j) {
- aiVectorKey& key = channel->mPositionKeys[j];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
-
- // Scaling keys
- for (unsigned int j = 0; j < channel->mNumScalingKeys;++j ) {
- aiVectorKey& key = channel->mScalingKeys[j];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
-
- // Rotation keys
- for (unsigned int j = 0; j < channel->mNumRotationKeys;++j ) {
- aiQuatKey& key = channel->mRotationKeys[ j ];
- first = std::min (first, key.mTime);
- last = std::max (last, key.mTime);
- }
- }
-
- /* Check whether the animation channel has no rotation
- * or position tracks. In this case we generate a dummy
- * track from the information we have in the transformation
- * matrix of the corresponding node.
- */
- if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys) {
- // Find the node that belongs to this animation
- aiNode* node = scene->mRootNode->FindNode(channel->mNodeName);
- if (node) // ValidateDS will complain later if 'node' is NULL
- {
- // Decompose the transformation matrix of the node
- aiVector3D scaling, position;
- aiQuaternion rotation;
-
- node->mTransformation.Decompose(scaling, rotation,position);
-
- // No rotation keys? Generate a dummy track
- if (!channel->mNumRotationKeys) {
- channel->mNumRotationKeys = 1;
- channel->mRotationKeys = new aiQuatKey[1];
- aiQuatKey& q = channel->mRotationKeys[0];
-
- q.mTime = 0.;
- q.mValue = rotation;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy rotation track has been generated");
- }
-
- // No scaling keys? Generate a dummy track
- if (!channel->mNumScalingKeys) {
- channel->mNumScalingKeys = 1;
- channel->mScalingKeys = new aiVectorKey[1];
- aiVectorKey& q = channel->mScalingKeys[0];
-
- q.mTime = 0.;
- q.mValue = scaling;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy scaling track has been generated");
- }
-
- // No position keys? Generate a dummy track
- if (!channel->mNumPositionKeys) {
- channel->mNumPositionKeys = 1;
- channel->mPositionKeys = new aiVectorKey[1];
- aiVectorKey& q = channel->mPositionKeys[0];
-
- q.mTime = 0.;
- q.mValue = position;
-
- DefaultLogger::get()->debug("ScenePreprocessor: Dummy position track has been generated");
- }
- }
- }
- }
-
- if (anim->mDuration == -1.) {
- DefaultLogger::get()->debug("ScenePreprocessor: Setting animation duration");
- anim->mDuration = last - std::min( first, 0. );
- }
-}
diff --git a/src/3rdparty/assimp/code/ScenePreprocessor.h b/src/3rdparty/assimp/code/ScenePreprocessor.h
deleted file mode 100644
index 3311036c3..000000000
--- a/src/3rdparty/assimp/code/ScenePreprocessor.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to search all meshes for
- degenerated faces */
-#ifndef AI_SCENE_PREPROCESSOR_H_INC
-#define AI_SCENE_PREPROCESSOR_H_INC
-
-#include <assimp/defs.h>
-#include <stddef.h>
-
-struct aiScene;
-struct aiAnimation;
-struct aiMesh;
-
-class ScenePreprocessorTest;
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** ScenePreprocessor: Preprocess a scene before any post-processing
- * steps are executed.
- *
- * The step computes data that needn't necessarily be provided by the
- * importer, such as aiMesh::mPrimitiveTypes.
-*/
-// ----------------------------------------------------------------------------------
-class ASSIMP_API ScenePreprocessor
-{
- // Make ourselves a friend of the corresponding test unit.
- friend class ::ScenePreprocessorTest;
-public:
-
- // ----------------------------------------------------------------
- /** Default c'tpr. Use SetScene() to assign a scene to the object.
- */
- ScenePreprocessor()
- : scene (NULL)
- {}
-
- /** Constructs the object and assigns a specific scene to it
- */
- ScenePreprocessor(aiScene* _scene)
- : scene (_scene)
- {}
-
- // ----------------------------------------------------------------
- /** Assign a (new) scene to the object.
- *
- * One 'SceneProcessor' can be used for multiple scenes.
- * Call ProcessScene to have the scene preprocessed.
- * @param sc Scene to be processed.
- */
- void SetScene (aiScene* sc) {
- scene = sc;
- }
-
- // ----------------------------------------------------------------
- /** Preprocess the current scene
- */
- void ProcessScene ();
-
-protected:
-
- // ----------------------------------------------------------------
- /** Preprocess an animation in the scene
- * @param anim Anim to be preprocessed.
- */
- void ProcessAnimation (aiAnimation* anim);
-
-
- // ----------------------------------------------------------------
- /** Preprocess a mesh in the scene
- * @param mesh Mesh to be preprocessed.
- */
- void ProcessMesh (aiMesh* mesh);
-
-protected:
-
- //! Scene we're currently working on
- aiScene* scene;
-};
-
-
-} // ! end namespace Assimp
-
-#endif // include guard
diff --git a/src/3rdparty/assimp/code/ScenePrivate.h b/src/3rdparty/assimp/code/ScenePrivate.h
deleted file mode 100644
index 90d34bade..000000000
--- a/src/3rdparty/assimp/code/ScenePrivate.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Stuff to deal with aiScene::mPrivate
- */
-#ifndef AI_SCENEPRIVATE_H_INCLUDED
-#define AI_SCENEPRIVATE_H_INCLUDED
-
-#include <assimp/scene.h>
-
-namespace Assimp {
-
-class Importer;
-
-struct ScenePrivateData {
-
- ScenePrivateData()
- : mOrigImporter()
- , mPPStepsApplied()
- , mIsCopy()
- {}
-
- // Importer that originally loaded the scene though the C-API
- // If set, this object is owned by this private data instance.
- Assimp::Importer* mOrigImporter;
-
- // List of post-processing 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
-inline ScenePrivateData* ScenePriv(aiScene* in) {
- return static_cast<ScenePrivateData*>(in->mPrivate);
-}
-
-inline const ScenePrivateData* ScenePriv(const aiScene* in) {
- return static_cast<const ScenePrivateData*>(in->mPrivate);
-}
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp b/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp
deleted file mode 100644
index e9f427113..000000000
--- a/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SkeletonMeshBuilder.cpp
- * @brief Implementation of a little class to construct a dummy mesh for a skeleton
- */
-
-#include <assimp/scene.h>
-#include "SkeletonMeshBuilder.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// The constructor processes the given scene and adds a mesh there.
-SkeletonMeshBuilder::SkeletonMeshBuilder( aiScene* pScene, aiNode* root, bool bKnobsOnly)
-{
- // nothing to do if there's mesh data already present at the scene
- if( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL)
- return;
-
- if (!root)
- root = pScene->mRootNode;
-
- mKnobsOnly = bKnobsOnly;
-
- // build some faces around each node
- CreateGeometry( root );
-
- // create a mesh to hold all the generated faces
- pScene->mNumMeshes = 1;
- pScene->mMeshes = new aiMesh*[1];
- pScene->mMeshes[0] = CreateMesh();
- // and install it at the root node
- root->mNumMeshes = 1;
- root->mMeshes = new unsigned int[1];
- root->mMeshes[0] = 0;
-
- // create a dummy material for the mesh
- if(pScene->mNumMaterials==0){
- pScene->mNumMaterials = 1;
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = CreateMaterial();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively builds a simple mesh representation for the given node
-void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode)
-{
- // add a joint entry for the node.
- const unsigned int vertexStartIndex = static_cast<unsigned int>(mVertices.size());
-
- // now build the geometry.
- if( pNode->mNumChildren > 0 && !mKnobsOnly)
- {
- // If the node has children, we build little pointers to each of them
- for( unsigned int a = 0; a < pNode->mNumChildren; a++)
- {
- // find a suitable coordinate system
- const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation;
- aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4);
- ai_real distanceToChild = childpos.Length();
- if( distanceToChild < 0.0001)
- continue;
- aiVector3D up = aiVector3D( childpos).Normalize();
-
- aiVector3D orth( 1.0, 0.0, 0.0);
- if( std::fabs( orth * up) > 0.99)
- orth.Set( 0.0, 1.0, 0.0);
-
- aiVector3D front = (up ^ orth).Normalize();
- aiVector3D side = (front ^ up).Normalize();
-
- unsigned int localVertexStart = static_cast<unsigned int>(mVertices.size());
- mVertices.push_back( -front * distanceToChild * (ai_real)0.1);
- mVertices.push_back( childpos);
- mVertices.push_back( -side * distanceToChild * (ai_real)0.1);
- mVertices.push_back( -side * distanceToChild * (ai_real)0.1);
- mVertices.push_back( childpos);
- mVertices.push_back( front * distanceToChild * (ai_real)0.1);
- mVertices.push_back( front * distanceToChild * (ai_real)0.1);
- mVertices.push_back( childpos);
- mVertices.push_back( side * distanceToChild * (ai_real)0.1);
- mVertices.push_back( side * distanceToChild * (ai_real)0.1);
- mVertices.push_back( childpos);
- mVertices.push_back( -front * distanceToChild * (ai_real)0.1);
-
- mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2));
- mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5));
- mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8));
- mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11));
- }
- }
- else
- {
- // if the node has no children, it's an end node. Put a little knob there instead
- aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4);
- ai_real sizeEstimate = ownpos.Length() * ai_real( 0.18 );
-
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, -sizeEstimate));
-
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( sizeEstimate, 0.0, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate));
- mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, -sizeEstimate, 0.0));
- mVertices.push_back( aiVector3D( 0.0, 0.0, sizeEstimate));
- mVertices.push_back( aiVector3D( -sizeEstimate, 0.0, 0.0));
-
- mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2));
- mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5));
- mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8));
- mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11));
- mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14));
- mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17));
- mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20));
- mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23));
- }
-
- unsigned int numVertices = static_cast<unsigned int>(mVertices.size() - vertexStartIndex);
- if( numVertices > 0)
- {
- // create a bone affecting all the newly created vertices
- aiBone* bone = new aiBone;
- mBones.push_back( bone);
- bone->mName = pNode->mName;
-
- // calculate the bone offset matrix by concatenating the inverse transformations of all parents
- bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse();
- for( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent)
- bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix;
-
- // add all the vertices to the bone's influences
- bone->mNumWeights = numVertices;
- bone->mWeights = new aiVertexWeight[numVertices];
- for( unsigned int a = 0; a < numVertices; a++)
- bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0);
-
- // HACK: (thom) transform all vertices to the bone's local space. Should be done before adding
- // them to the array, but I'm tired now and I'm annoyed.
- aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse();
- for( unsigned int a = vertexStartIndex; a < mVertices.size(); a++)
- mVertices[a] = boneToMeshTransform * mVertices[a];
- }
-
- // and finally recurse into the children list
- for( unsigned int a = 0; a < pNode->mNumChildren; a++)
- CreateGeometry( pNode->mChildren[a]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the mesh from the internally accumulated stuff and returns it.
-aiMesh* SkeletonMeshBuilder::CreateMesh()
-{
- aiMesh* mesh = new aiMesh();
-
- // add points
- mesh->mNumVertices = static_cast<unsigned int>(mVertices.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices);
-
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
-
- // add faces
- mesh->mNumFaces = static_cast<unsigned int>(mFaces.size());
- mesh->mFaces = new aiFace[mesh->mNumFaces];
- for( unsigned int a = 0; a < mesh->mNumFaces; a++)
- {
- const Face& inface = mFaces[a];
- aiFace& outface = mesh->mFaces[a];
- outface.mNumIndices = 3;
- outface.mIndices = new unsigned int[3];
- outface.mIndices[0] = inface.mIndices[0];
- outface.mIndices[1] = inface.mIndices[1];
- outface.mIndices[2] = inface.mIndices[2];
-
- // Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize
- // the skeleton, so it's good if there's a visual difference to the rest of the geometry
- aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^
- (mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]]));
-
- if (nor.Length() < 1e-5) /* ensure that FindInvalidData won't remove us ...*/
- nor = aiVector3D(1.0,0.0,0.0);
-
- for (unsigned int n = 0; n < 3; ++n)
- mesh->mNormals[inface.mIndices[n]] = nor;
- }
-
- // add the bones
- mesh->mNumBones = static_cast<unsigned int>(mBones.size());
- mesh->mBones = new aiBone*[mesh->mNumBones];
- std::copy( mBones.begin(), mBones.end(), mesh->mBones);
-
- // default
- mesh->mMaterialIndex = 0;
-
- return mesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates a dummy material and returns it.
-aiMaterial* SkeletonMeshBuilder::CreateMaterial()
-{
- aiMaterial* matHelper = new aiMaterial;
-
- // Name
- aiString matName( std::string( "SkeletonMaterial"));
- matHelper->AddProperty( &matName, AI_MATKEY_NAME);
-
- // Prevent backface culling
- const int no_cull = 1;
- matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED);
-
- return matHelper;
-}
diff --git a/src/3rdparty/assimp/code/SkeletonMeshBuilder.h b/src/3rdparty/assimp/code/SkeletonMeshBuilder.h
deleted file mode 100644
index 7a7e7b8ff..000000000
--- a/src/3rdparty/assimp/code/SkeletonMeshBuilder.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/** Helper class to construct a dummy mesh for file formats containing only motion data */
-
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SkeletonMeshBuilder.h
- * Declares SkeletonMeshBuilder, a tiny utility to build dummy meshes
- * for animation skeletons.
- */
-
-#ifndef AI_SKELETONMESHBUILDER_H_INC
-#define AI_SKELETONMESHBUILDER_H_INC
-
-#include <vector>
-#include <assimp/mesh.h>
-
-struct aiMaterial;
-struct aiScene;
-struct aiNode;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/**
- * This little helper class constructs a dummy mesh for a given scene
- * the resembles the node hierarchy. This is useful for file formats
- * that don't carry any mesh data but only animation data.
- */
-class SkeletonMeshBuilder
-{
-public:
-
- // -------------------------------------------------------------------
- /** The constructor processes the given scene and adds a mesh there.
- *
- * Does nothing if the scene already has mesh data.
- * @param pScene The scene for which a skeleton mesh should be constructed.
- * @param root The node to start with. NULL is the scene root
- * @param bKnobsOnly Set this to true if you don't want the connectors
- * between the knobs representing the nodes.
- */
- SkeletonMeshBuilder( aiScene* pScene, aiNode* root = NULL,
- bool bKnobsOnly = false);
-
-protected:
-
- // -------------------------------------------------------------------
- /** Recursively builds a simple mesh representation for the given node
- * and also creates a joint for the node that affects this part of
- * the mesh.
- * @param pNode The node to build geometry for.
- */
- void CreateGeometry( const aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** Creates the mesh from the internally accumulated stuff and returns it.
- */
- aiMesh* CreateMesh();
-
- // -------------------------------------------------------------------
- /** Creates a dummy material and returns it. */
- aiMaterial* CreateMaterial();
-
-protected:
- /** space to assemble the mesh data: points */
- std::vector<aiVector3D> mVertices;
-
- /** faces */
- struct Face
- {
- unsigned int mIndices[3];
- Face();
- Face( unsigned int p0, unsigned int p1, unsigned int p2)
- { mIndices[0] = p0; mIndices[1] = p1; mIndices[2] = p2; }
- };
- std::vector<Face> mFaces;
-
- /** bones */
- std::vector<aiBone*> mBones;
-
- bool mKnobsOnly;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SKELETONMESHBUILDER_H_INC
diff --git a/src/3rdparty/assimp/code/SmoothingGroups.h b/src/3rdparty/assimp/code/SmoothingGroups.h
deleted file mode 100644
index 7a7e2e429..000000000
--- a/src/3rdparty/assimp/code/SmoothingGroups.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the helper data structures for importing 3DS files.
-http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
-
-#ifndef AI_SMOOTHINGGROUPS_H_INC
-#define AI_SMOOTHINGGROUPS_H_INC
-
-#include <assimp/vector3.h>
-#include <stdint.h>
-#include <vector>
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a face with smoothing groups assigned */
-struct FaceWithSmoothingGroup
-{
- FaceWithSmoothingGroup()
- : mIndices(),
- iSmoothGroup(0)
- {
- // in debug builds set all indices to a common magic value
-#ifdef ASSIMP_BUILD_DEBUG
- this->mIndices[0] = 0xffffffff;
- this->mIndices[1] = 0xffffffff;
- this->mIndices[2] = 0xffffffff;
-#endif
- }
-
-
- //! Indices. .3ds is using uint16. However, after
- //! an unique vertex set has been generated,
- //! individual index values might exceed 2^16
- uint32_t mIndices[3];
-
- //! specifies to which smoothing group the face belongs to
- uint32_t iSmoothGroup;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure representing a mesh whose faces have smoothing
- groups assigned. This allows us to reuse the code for normal computations
- from smoothings groups for several loaders (3DS, ASE). All of them
- use face structures which inherit from #FaceWithSmoothingGroup,
- but as they add extra members and need to be copied by value we
- need to use a template here.
- */
-template <class T>
-struct MeshWithSmoothingGroups
-{
- //! Vertex positions
- std::vector<aiVector3D> mPositions;
-
- //! Face lists
- std::vector<T> mFaces;
-
- //! List of normal vectors
- std::vector<aiVector3D> mNormals;
-};
-
-// ---------------------------------------------------------------------------
-/** Computes normal vectors for the mesh
- */
-template <class T>
-void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh);
-
-
-// include implementations
-#include "SmoothingGroups.inl"
-
-#endif // !! AI_SMOOTHINGGROUPS_H_INC
diff --git a/src/3rdparty/assimp/code/SmoothingGroups.inl b/src/3rdparty/assimp/code/SmoothingGroups.inl
deleted file mode 100644
index 42c500070..000000000
--- a/src/3rdparty/assimp/code/SmoothingGroups.inl
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
----------------------------------------------------------------------------
-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 Generation of normal vectors basing on smoothing groups */
-
-#ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
-#define AI_SMOOTHINGGROUPS_INL_INCLUDED
-
-// internal headers
-#include "SGSpatialSort.h"
-
-// CRT header
-#include <algorithm>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-void ComputeNormalsWithSmoothingsGroups(MeshWithSmoothingGroups<T>& sMesh)
-{
- // First generate face normals
- sMesh.mNormals.resize(sMesh.mPositions.size(),aiVector3D());
- for( unsigned int a = 0; a < sMesh.mFaces.size(); a++)
- {
- T& face = sMesh.mFaces[a];
-
- aiVector3D* pV1 = &sMesh.mPositions[face.mIndices[0]];
- aiVector3D* pV2 = &sMesh.mPositions[face.mIndices[1]];
- aiVector3D* pV3 = &sMesh.mPositions[face.mIndices[2]];
-
- aiVector3D pDelta1 = *pV2 - *pV1;
- aiVector3D pDelta2 = *pV3 - *pV1;
- aiVector3D vNor = pDelta1 ^ pDelta2;
-
- for (unsigned int c = 0; c < 3;++c)
- sMesh.mNormals[face.mIndices[c]] = vNor;
- }
-
- // calculate the position bounds so we have a reliable epsilon to check position differences against
- aiVector3D minVec( 1e10f, 1e10f, 1e10f), maxVec( -1e10f, -1e10f, -1e10f);
- for( unsigned int a = 0; a < sMesh.mPositions.size(); a++)
- {
- minVec.x = std::min( minVec.x, sMesh.mPositions[a].x);
- minVec.y = std::min( minVec.y, sMesh.mPositions[a].y);
- minVec.z = std::min( minVec.z, sMesh.mPositions[a].z);
- maxVec.x = std::max( maxVec.x, sMesh.mPositions[a].x);
- maxVec.y = std::max( maxVec.y, sMesh.mPositions[a].y);
- maxVec.z = std::max( maxVec.z, sMesh.mPositions[a].z);
- }
- const float posEpsilon = (maxVec - minVec).Length() * 1e-5f;
- std::vector<aiVector3D> avNormals;
- avNormals.resize(sMesh.mNormals.size());
-
- // now generate the spatial sort tree
- SGSpatialSort sSort;
- for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
- i != sMesh.mFaces.end();++i)
- {
- for (unsigned int c = 0; c < 3;++c)
- sSort.Add(sMesh.mPositions[(*i).mIndices[c]],(*i).mIndices[c],(*i).iSmoothGroup);
- }
- sSort.Prepare();
-
- std::vector<bool> vertexDone(sMesh.mPositions.size(),false);
- for( typename std::vector<T>::iterator i = sMesh.mFaces.begin();
- i != sMesh.mFaces.end();++i)
- {
- std::vector<unsigned int> poResult;
- for (unsigned int c = 0; c < 3;++c)
- {
- unsigned int idx = (*i).mIndices[c];
- if (vertexDone[idx])continue;
-
- sSort.FindPositions(sMesh.mPositions[idx],(*i).iSmoothGroup,
- posEpsilon,poResult);
-
- aiVector3D vNormals;
- for (std::vector<unsigned int>::const_iterator
- a = poResult.begin();
- a != poResult.end();++a)
- {
- vNormals += sMesh.mNormals[(*a)];
- }
- vNormals.NormalizeSafe();
-
- // write back into all affected normals
- for (std::vector<unsigned int>::const_iterator
- a = poResult.begin();
- a != poResult.end();++a)
- {
- idx = *a;
- avNormals [idx] = vNormals;
- vertexDone[idx] = true;
- }
- }
- }
- sMesh.mNormals = avNormals;
-}
-
-#endif // !! AI_SMOOTHINGGROUPS_INL_INCLUDED
diff --git a/src/3rdparty/assimp/code/SortByPTypeProcess.cpp b/src/3rdparty/assimp/code/SortByPTypeProcess.cpp
deleted file mode 100644
index e4b314e02..000000000
--- a/src/3rdparty/assimp/code/SortByPTypeProcess.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the DeterminePTypeHelperProcess and
- * SortByPTypeProcess post-process steps.
-*/
-
-
-
-// internal headers
-#include "ProcessHelper.h"
-#include "SortByPTypeProcess.h"
-#include "Exceptional.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-SortByPTypeProcess::SortByPTypeProcess()
-{
- configRemoveMeshes = 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-SortByPTypeProcess::~SortByPTypeProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SortByPType) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void SortByPTypeProcess::SetupProperties(const Importer* pImp)
-{
- configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update changed meshes in all nodes
-void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
-{
-// std::vector<unsigned int>::const_iterator it;
-
- if (node->mNumMeshes)
- {
- unsigned int newSize = 0;
- for (unsigned int m = 0; m< node->mNumMeshes; ++m)
- {
- unsigned int add = node->mMeshes[m]<<2;
- for (unsigned int i = 0; i < 4;++i)
- {
- if (UINT_MAX != replaceMeshIndex[add+i])++newSize;
- }
- }
- if (!newSize)
- {
- delete[] node->mMeshes;
- node->mNumMeshes = 0;
- node->mMeshes = NULL;
- }
- else
- {
- // Try to reuse the old array if possible
- unsigned int* newMeshes = (newSize > node->mNumMeshes
- ? new unsigned int[newSize] : node->mMeshes);
-
- for (unsigned int m = 0; m< node->mNumMeshes; ++m)
- {
- unsigned int add = node->mMeshes[m]<<2;
- for (unsigned int i = 0; i < 4;++i)
- {
- if (UINT_MAX != replaceMeshIndex[add+i])
- *newMeshes++ = replaceMeshIndex[add+i];
- }
- }
- if (newSize > node->mNumMeshes)
- delete[] node->mMeshes;
-
- node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
- }
- }
-
- // call all subnodes recursively
- for (unsigned int m = 0; m < node->mNumChildren; ++m)
- UpdateNodes(replaceMeshIndex,node->mChildren[m]);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SortByPTypeProcess::Execute( aiScene* pScene)
-{
- if (!pScene->mNumMeshes)
- {
- DefaultLogger::get()->debug("SortByPTypeProcess skipped, there are no meshes");
- return;
- }
-
- DefaultLogger::get()->debug("SortByPTypeProcess begin");
-
- unsigned int aiNumMeshesPerPType[4] = {0,0,0,0};
-
- std::vector<aiMesh*> outMeshes;
- outMeshes.reserve(pScene->mNumMeshes<<1u);
-
- bool bAnyChanges = false;
-
- std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,UINT_MAX);
- std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
- for (unsigned int i = 0; i < pScene->mNumMeshes;++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
- unsigned int num = 0;
- if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT)
- {
- ++aiNumMeshesPerPType[0];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE)
- {
- ++aiNumMeshesPerPType[1];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)
- {
- ++aiNumMeshesPerPType[2];
- ++num;
- }
- if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)
- {
- ++aiNumMeshesPerPType[3];
- ++num;
- }
-
- if (1 == num)
- {
- if (!(configRemoveMeshes & mesh->mPrimitiveTypes))
- {
- *meshIdx = (unsigned int) outMeshes.size();
- outMeshes.push_back(mesh);
- }
- else bAnyChanges = true;
-
- meshIdx += 4;
- continue;
- }
- bAnyChanges = true;
-
- // reuse our current mesh arrays for the submesh
- // with the largest numer of primitives
- unsigned int aiNumPerPType[4] = {0,0,0,0};
- aiFace* pFirstFace = mesh->mFaces;
- aiFace* const pLastFace = pFirstFace + mesh->mNumFaces;
-
- unsigned int numPolyVerts = 0;
- for (;pFirstFace != pLastFace; ++pFirstFace)
- {
- if (pFirstFace->mNumIndices <= 3)
- ++aiNumPerPType[pFirstFace->mNumIndices-1];
- else
- {
- ++aiNumPerPType[3];
- numPolyVerts += pFirstFace-> mNumIndices;
- }
- }
-
- VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
- for (unsigned int real = 0; real < 4; ++real,++meshIdx)
- {
- if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
- {
- continue;
- }
-
- *meshIdx = (unsigned int) outMeshes.size();
- outMeshes.push_back(new aiMesh());
- aiMesh* out = outMeshes.back();
-
- // the name carries the adjacency information between the meshes
- out->mName = mesh->mName;
-
- // copy data members
- out->mPrimitiveTypes = 1u << real;
- out->mMaterialIndex = mesh->mMaterialIndex;
-
- // allocate output storage
- out->mNumFaces = aiNumPerPType[real];
- aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces];
-
- out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));
-
- aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
- aiVector3D *uv [AI_MAX_NUMBER_OF_TEXTURECOORDS];
- aiColor4D *cols [AI_MAX_NUMBER_OF_COLOR_SETS];
-
- if (mesh->mVertices)
- vert = out->mVertices = new aiVector3D[out->mNumVertices];
-
- if (mesh->mNormals)
- nor = out->mNormals = new aiVector3D[out->mNumVertices];
-
- if (mesh->mTangents)
- {
- tan = out->mTangents = new aiVector3D[out->mNumVertices];
- bit = out->mBitangents = new aiVector3D[out->mNumVertices];
- }
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- if (mesh->mTextureCoords[i])
- uv[i] = out->mTextureCoords[i] = new aiVector3D[out->mNumVertices];
- else uv[i] = NULL;
-
- out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
- }
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- {
- if (mesh->mColors[i])
- cols[i] = out->mColors[i] = new aiColor4D[out->mNumVertices];
- else cols[i] = NULL;
- }
-
- typedef std::vector< aiVertexWeight > TempBoneInfo;
- std::vector< TempBoneInfo > tempBones(mesh->mNumBones);
-
- // try to guess how much storage we'll need
- for (unsigned int q = 0; q < mesh->mNumBones;++q)
- {
- tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1));
- }
-
- unsigned int outIdx = 0;
- for (unsigned int m = 0; m < mesh->mNumFaces; ++m)
- {
- aiFace& in = mesh->mFaces[m];
- if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1))
- {
- continue;
- }
-
- outFaces->mNumIndices = in.mNumIndices;
- outFaces->mIndices = in.mIndices;
-
- for (unsigned int q = 0; q < in.mNumIndices; ++q)
- {
- unsigned int idx = in.mIndices[q];
-
- // process all bones of this index
- if (avw)
- {
- VertexWeightTable& tbl = avw[idx];
- for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
- it != end; ++it)
- {
- tempBones[ (*it).first ].push_back( aiVertexWeight(outIdx, (*it).second) );
- }
- }
-
- if (vert)
- {
- *vert++ = mesh->mVertices[idx];
- //mesh->mVertices[idx].x = get_qnan();
- }
- if (nor )*nor++ = mesh->mNormals[idx];
- if (tan )
- {
- *tan++ = mesh->mTangents[idx];
- *bit++ = mesh->mBitangents[idx];
- }
-
- for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp)
- {
- if (!uv[pp])break;
- *uv[pp]++ = mesh->mTextureCoords[pp][idx];
- }
-
- for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp)
- {
- if (!cols[pp])break;
- *cols[pp]++ = mesh->mColors[pp][idx];
- }
-
- in.mIndices[q] = outIdx++;
- }
-
- in.mIndices = NULL;
- ++outFaces;
- }
- ai_assert(outFaces == out->mFaces + out->mNumFaces);
-
- // now generate output bones
- for (unsigned int q = 0; q < mesh->mNumBones;++q)
- if (!tempBones[q].empty())++out->mNumBones;
-
- if (out->mNumBones)
- {
- out->mBones = new aiBone*[out->mNumBones];
- for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q)
- {
- TempBoneInfo& in = tempBones[q];
- if (in.empty())continue;
-
- aiBone* srcBone = mesh->mBones[q];
- aiBone* bone = out->mBones[real] = new aiBone();
-
- bone->mName = srcBone->mName;
- bone->mOffsetMatrix = srcBone->mOffsetMatrix;
-
- bone->mNumWeights = (unsigned int)in.size();
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
-
- ::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(aiVertexWeight));
-
- ++real;
- }
- }
- }
-
- // delete the per-vertex bone weights table
- delete[] avw;
-
- // delete the input mesh
- delete mesh;
-
- // avoid invalid pointer
- pScene->mMeshes[i] = NULL;
- }
-
- if (outMeshes.empty())
- {
- // This should not occur
- throw DeadlyImportError("No meshes remaining");
- }
-
- // If we added at least one mesh process all nodes in the node
- // graph and update their respective mesh indices.
- if (bAnyChanges)
- {
- UpdateNodes(replaceMeshIndex,pScene->mRootNode);
- }
-
- if (outMeshes.size() != pScene->mNumMeshes)
- {
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)outMeshes.size();
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- }
- ::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
-
- if (!DefaultLogger::isNullLogger())
- {
- char buffer[1024];
- ::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
- aiNumMeshesPerPType[0], ((configRemoveMeshes & aiPrimitiveType_POINT) ? "X" : ""),
- aiNumMeshesPerPType[1], ((configRemoveMeshes & aiPrimitiveType_LINE) ? "X" : ""),
- aiNumMeshesPerPType[2], ((configRemoveMeshes & aiPrimitiveType_TRIANGLE) ? "X" : ""),
- aiNumMeshesPerPType[3], ((configRemoveMeshes & aiPrimitiveType_POLYGON) ? "X" : ""));
- DefaultLogger::get()->info(buffer);
- DefaultLogger::get()->debug("SortByPTypeProcess finished");
- }
-}
-
diff --git a/src/3rdparty/assimp/code/SortByPTypeProcess.h b/src/3rdparty/assimp/code/SortByPTypeProcess.h
deleted file mode 100644
index 0be7925ff..000000000
--- a/src/3rdparty/assimp/code/SortByPTypeProcess.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to sort meshes by the types
- of primitives they contain */
-#ifndef AI_SORTBYPTYPEPROCESS_H_INC
-#define AI_SORTBYPTYPEPROCESS_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/mesh.h>
-
-class SortByPTypeProcessTest;
-namespace Assimp {
-
-
-// ---------------------------------------------------------------------------
-/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
- * A mesh with 5 lines, 3 points and 145 triangles would be split in 3
- * submeshes.
-*/
-class ASSIMP_API SortByPTypeProcess : public BaseProcess
-{
-public:
-
- SortByPTypeProcess();
- ~SortByPTypeProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-private:
-
- int configRemoveMeshes;
-};
-
-
-} // end of namespace Assimp
-
-#endif // !!AI_SORTBYPTYPEPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/SpatialSort.cpp b/src/3rdparty/assimp/code/SpatialSort.cpp
deleted file mode 100644
index 35724c2cd..000000000
--- a/src/3rdparty/assimp/code/SpatialSort.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the helper class to quickly find vertices close to a given position */
-
-#include "SpatialSort.h"
-#include <assimp/ai_assert.h>
-
-using namespace Assimp;
-
-// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8.
-#ifndef CHAR_BIT
-# define CHAR_BIT 8
-#endif
-
-// ------------------------------------------------------------------------------------------------
-// Constructs a spatially sorted representation from the given position array.
-SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset)
-
- // define the reference plane. We choose some arbitrary vector away from all basic axises
- // in the hope that no model spreads all its vertices along this plane.
- : mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
-{
- mPlaneNormal.Normalize();
- Fill(pPositions,pNumPositions,pElementOffset);
-}
-
-// ------------------------------------------------------------------------------------------------
-SpatialSort :: SpatialSort()
-: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
-{
- mPlaneNormal.Normalize();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SpatialSort::~SpatialSort()
-{
- // nothing to do here, everything destructs automatically
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize /*= true */)
-{
- mPositions.clear();
- Append(pPositions,pNumPositions,pElementOffset,pFinalize);
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort :: Finalize()
-{
- std::sort( mPositions.begin(), mPositions.end());
-}
-
-// ------------------------------------------------------------------------------------------------
-void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize /*= true */)
-{
- // store references to all given positions along with their distance to the reference plane
- const size_t initial = mPositions.size();
- mPositions.reserve(initial + (pFinalize?pNumPositions:pNumPositions*2));
- for( unsigned int a = 0; a < pNumPositions; a++)
- {
- const char* tempPointer = reinterpret_cast<const char*> (pPositions);
- const aiVector3D* vec = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset);
-
- // store position by index and distance
- ai_real distance = *vec * mPlaneNormal;
- mPositions.push_back( Entry( static_cast<unsigned int>(a+initial), *vec, distance));
- }
-
- if (pFinalize) {
- // now sort the array ascending by distance.
- Finalize();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns an iterator for all positions close to the given position.
-void SpatialSort::FindPositions( const aiVector3D& pPosition,
- ai_real pRadius, std::vector<unsigned int>& poResults) const
-{
- const ai_real dist = pPosition * mPlaneNormal;
- const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
-
- // clear the array
- poResults.clear();
-
- // quick check for positions outside the range
- if( mPositions.size() == 0)
- return;
- if( maxDist < mPositions.front().mDistance)
- return;
- if( minDist > mPositions.back().mDistance)
- return;
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while( binaryStepSize > 1)
- {
- if( mPositions[index].mDistance < minDist)
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while( index > 0 && mPositions[index].mDistance > minDist)
- index--;
- while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
- index++;
-
- // Mow start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the given radius to the result aray
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- const ai_real pSquared = pRadius*pRadius;
- while( it->mDistance < maxDist)
- {
- if( (it->mPosition - pPosition).SquareLength() < pSquared)
- poResults.push_back( it->mIndex);
- ++it;
- if( it == mPositions.end())
- break;
- }
-
- // that's it
-}
-
-namespace {
-
- // Binary, signed-integer representation of a single-precision floating-point value.
- // IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are
- // ordered the same way when their bits are reinterpreted as sign-magnitude integers."
- // This allows us to convert all floating-point numbers to signed integers of arbitrary size
- // and then use them to work with ULPs (Units in the Last Place, for high-precision
- // computations) or to compare them (integer comparisons are faster than floating-point
- // comparisons on many platforms).
- typedef ai_int BinFloat;
-
- // --------------------------------------------------------------------------------------------
- // Converts the bit pattern of a floating-point number to its signed integer representation.
- BinFloat ToBinary( const ai_real & pValue) {
-
- // If this assertion fails, signed int is not big enough to store a float on your platform.
- // Please correct the declaration of BinFloat a few lines above - but do it in a portable,
- // #ifdef'd manner!
- static_assert( sizeof(BinFloat) >= sizeof(ai_real), "sizeof(BinFloat) >= sizeof(ai_real)");
-
- #if defined( _MSC_VER)
- // If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
- // code has just become legacy code! Find out the current value of _MSC_VER and modify
- // the #if above so it evaluates false on the current and all upcoming VC versions (or
- // on the current platform, if LP64 or LLP64 are still used on other platforms).
- static_assert( sizeof(BinFloat) == sizeof(ai_real), "sizeof(BinFloat) == sizeof(ai_real)");
-
- // This works best on Visual C++, but other compilers have their problems with it.
- const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
- #else
- // On many compilers, reinterpreting a float address as an integer causes aliasing
- // problems. This is an ugly but more or less safe way of doing it.
- union {
- ai_real asFloat;
- BinFloat asBin;
- } conversion;
- conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
- conversion.asFloat = pValue;
- const BinFloat binValue = conversion.asBin;
- #endif
-
- // floating-point numbers are of sign-magnitude format, so find out what signed number
- // representation we must convert negative values to.
- // See http://en.wikipedia.org/wiki/Signed_number_representations.
-
- // Two's complement?
- if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
- return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
- // One's complement?
- else if( (-42 == ~42) && (binValue & 0x80000000))
- return BinFloat(-0) - binValue;
- // Sign-magnitude?
- else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
- return binValue;
- else
- return binValue;
- }
-
-} // namespace
-
-// ------------------------------------------------------------------------------------------------
-// Fills an array with indices of all positions identical to the given position. In opposite to
-// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
-void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
- std::vector<unsigned int>& poResults) const
-{
- // Epsilons have a huge disadvantage: they are of constant precision, while floating-point
- // values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
- // if you apply it to 0.001, it is enormous.
-
- // The best way to overcome this is the unit in the last place (ULP). A precision of 2 ULPs
- // tells us that a float does not differ more than 2 bits from the "real" value. ULPs are of
- // logarithmic precision - around 1, they are 1*(2^24) and around 10000, they are 0.00125.
-
- // For standard C math, we can assume a precision of 0.5 ULPs according to IEEE 754. The
- // incoming vertex positions might have already been transformed, probably using rather
- // inaccurate SSE instructions, so we assume a tolerance of 4 ULPs to safely identify
- // identical vertex positions.
- static const int toleranceInULPs = 4;
- // An interesting point is that the inaccuracy grows linear with the number of operations:
- // multiplying to numbers, each inaccurate to four ULPs, results in an inaccuracy of four ULPs
- // plus 0.5 ULPs for the multiplication.
- // To compute the distance to the plane, a dot product is needed - that is a multiplication and
- // an addition on each number.
- static const int distanceToleranceInULPs = toleranceInULPs + 1;
- // The squared distance between two 3D vectors is computed the same way, but with an additional
- // subtraction.
- static const int distance3DToleranceInULPs = distanceToleranceInULPs + 1;
-
- // Convert the plane distance to its signed integer representation so the ULPs tolerance can be
- // applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
- const BinFloat minDistBinary = ToBinary( pPosition * mPlaneNormal) - distanceToleranceInULPs;
- const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
-
- // clear the array in this strange fashion because a simple clear() would also deallocate
- // the array which we want to avoid
- poResults.resize( 0 );
-
- // do a binary search for the minimal distance to start the iteration there
- unsigned int index = (unsigned int)mPositions.size() / 2;
- unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
- while( binaryStepSize > 1)
- {
- // Ugly, but conditional jumps are faster with integers than with floats
- if( minDistBinary > ToBinary(mPositions[index].mDistance))
- index += binaryStepSize;
- else
- index -= binaryStepSize;
-
- binaryStepSize /= 2;
- }
-
- // depending on the direction of the last step we need to single step a bit back or forth
- // to find the actual beginning element of the range
- while( index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance) )
- index--;
- while( index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance))
- index++;
-
- // Now start iterating from there until the first position lays outside of the distance range.
- // Add all positions inside the distance range within the tolerance to the result aray
- std::vector<Entry>::const_iterator it = mPositions.begin() + index;
- while( ToBinary(it->mDistance) < maxDistBinary)
- {
- if( distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength()))
- poResults.push_back(it->mIndex);
- ++it;
- if( it == mPositions.end())
- break;
- }
-
- // that's it
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill, ai_real pRadius) const
-{
- fill.resize(mPositions.size(),UINT_MAX);
- ai_real dist, maxDist;
-
- unsigned int t=0;
- const ai_real pSquared = pRadius*pRadius;
- for (size_t i = 0; i < mPositions.size();) {
- dist = mPositions[i].mPosition * mPlaneNormal;
- maxDist = dist + pRadius;
-
- fill[mPositions[i].mIndex] = t;
- const aiVector3D& oldpos = mPositions[i].mPosition;
- for (++i; i < fill.size() && mPositions[i].mDistance < maxDist
- && (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i)
- {
- fill[mPositions[i].mIndex] = t;
- }
- ++t;
- }
-
-#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) {
- ai_assert(fill[i]<mPositions.size());
- }
-
-#endif
- return t;
-}
diff --git a/src/3rdparty/assimp/code/SpatialSort.h b/src/3rdparty/assimp/code/SpatialSort.h
deleted file mode 100644
index 36b7a2767..000000000
--- a/src/3rdparty/assimp/code/SpatialSort.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-/** Small helper classes to optimise finding vertizes close to a given location */
-#ifndef AI_SPATIALSORT_H_INC
-#define AI_SPATIALSORT_H_INC
-
-#include <vector>
-#include <assimp/types.h>
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-/** A little helper class to quickly find all vertices in the epsilon environment of a given
- * position. Construct an instance with an array of positions. The class stores the given positions
- * by their indices and sorts them by their distance to an arbitrary chosen plane.
- * You can then query the instance for all vertices close to a given position in an average O(log n)
- * time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen
- * so that it avoids common planes in usual data sets. */
-// ------------------------------------------------------------------------------------------------
-class SpatialSort
-{
-public:
-
- SpatialSort();
-
- // ------------------------------------------------------------------------------------
- /** Constructs a spatially sorted representation from the given position array.
- * Supply the positions in its layout in memory, the class will only refer to them
- * by index.
- * @param pPositions Pointer to the first position vector of the array.
- * @param pNumPositions Number of vectors to expect in that array.
- * @param pElementOffset Offset in bytes from the beginning of one vector in memory
- * to the beginning of the next vector. */
- SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset);
-
- /** Destructor */
- ~SpatialSort();
-
-public:
-
- // ------------------------------------------------------------------------------------
- /** Sets the input data for the SpatialSort. This replaces existing data, if any.
- * The new data receives new indices in ascending order.
- *
- * @param pPositions Pointer to the first position vector of the array.
- * @param pNumPositions Number of vectors to expect in that array.
- * @param pElementOffset Offset in bytes from the beginning of one vector in memory
- * to the beginning of the next vector.
- * @param pFinalize Specifies whether the SpatialSort's internal representation
- * is finalized after the new data has been added. Finalization is
- * required in order to use #FindPosition() or #GenerateMappingTable().
- * If you don't finalize yet, you can use #Append() to add data from
- * other sources.*/
- void Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize = true);
-
-
- // ------------------------------------------------------------------------------------
- /** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */
- void Append( const aiVector3D* pPositions, unsigned int pNumPositions,
- unsigned int pElementOffset,
- bool pFinalize = true);
-
-
- // ------------------------------------------------------------------------------------
- /** Finalize the spatial hash data structure. This can be useful after
- * multiple calls to #Append() with the pFinalize parameter set to false.
- * This is finally required before one of #FindPositions() and #GenerateMappingTable()
- * can be called to query the spatial sort.*/
- void Finalize();
-
- // ------------------------------------------------------------------------------------
- /** Returns an iterator for all positions close to the given position.
- * @param pPosition The position to look for vertices.
- * @param pRadius Maximal distance from the position a vertex may have to be counted in.
- * @param poResults The container to store the indices of the found positions.
- * Will be emptied by the call so it may contain anything.
- * @return An iterator to iterate over all vertices in the given area.*/
- void FindPositions( const aiVector3D& pPosition, ai_real pRadius,
- std::vector<unsigned int>& poResults) const;
-
- // ------------------------------------------------------------------------------------
- /** Fills an array with indices of all positions identical to the given position. In
- * opposite to FindPositions(), not an epsilon is used but a (very low) tolerance of
- * four floating-point units.
- * @param pPosition The position to look for vertices.
- * @param poResults The container to store the indices of the found positions.
- * Will be emptied by the call so it may contain anything.*/
- void FindIdenticalPositions( const aiVector3D& pPosition,
- std::vector<unsigned int>& poResults) const;
-
- // ------------------------------------------------------------------------------------
- /** Compute a table that maps each vertex ID referring to a spatially close
- * enough position to the same output ID. Output IDs are assigned in ascending order
- * from 0...n.
- * @param fill Will be filled with numPositions entries.
- * @param pRadius Maximal distance from the position a vertex may have to
- * be counted in.
- * @return Number of unique vertices (n). */
- unsigned int GenerateMappingTable(std::vector<unsigned int>& fill,
- ai_real pRadius) const;
-
-protected:
- /** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
- aiVector3D mPlaneNormal;
-
- /** An entry in a spatially sorted position array. Consists of a vertex index,
- * its position and its precalculated distance from the reference plane */
- struct Entry
- {
- unsigned int mIndex; ///< The vertex referred by this entry
- aiVector3D mPosition; ///< Position
- ai_real mDistance; ///< Distance of this vertex to the sorting plane
-
- Entry() { /** intentionally not initialized.*/ }
- Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance)
- : mIndex( pIndex), mPosition( pPosition), mDistance( pDistance)
- { }
-
- bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
- };
-
- // all positions, sorted by distance to the sorting plane
- std::vector<Entry> mPositions;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_SPATIALSORT_H_INC
diff --git a/src/3rdparty/assimp/code/SplitByBoneCountProcess.cpp b/src/3rdparty/assimp/code/SplitByBoneCountProcess.cpp
deleted file mode 100644
index a73dfe81e..000000000
--- a/src/3rdparty/assimp/code/SplitByBoneCountProcess.cpp
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SplitByBoneCountProcess.cpp
-/// Implementation of the SplitByBoneCount postprocessing step
-
-// internal headers of the post-processing framework
-#include "SplitByBoneCountProcess.h"
-#include <assimp/postprocess.h>
-#include <assimp/DefaultLogger.hpp>
-
-#include <limits>
-#include "TinyFormatter.h"
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor
-SplitByBoneCountProcess::SplitByBoneCountProcess()
-{
- // set default, might be overridden by importer config
- mMaxBoneCount = AI_SBBC_DEFAULT_MAX_BONES;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor
-SplitByBoneCountProcess::~SplitByBoneCountProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag.
-bool SplitByBoneCountProcess::IsActive( unsigned int pFlags) const
-{
- return !!(pFlags & aiProcess_SplitByBoneCount);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Updates internal properties
-void SplitByBoneCountProcess::SetupProperties(const Importer* pImp)
-{
- mMaxBoneCount = pImp->GetPropertyInteger(AI_CONFIG_PP_SBBC_MAX_BONES,AI_SBBC_DEFAULT_MAX_BONES);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitByBoneCountProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("SplitByBoneCountProcess begin");
-
- // early out
- bool isNecessary = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
- if( pScene->mMeshes[a]->mNumBones > mMaxBoneCount )
- isNecessary = true;
-
- if( !isNecessary )
- {
- DefaultLogger::get()->debug( format() << "SplitByBoneCountProcess early-out: no meshes with more than " << mMaxBoneCount << " bones." );
- return;
- }
-
- // we need to do something. Let's go.
- mSubMeshIndices.clear();
- mSubMeshIndices.resize( pScene->mNumMeshes);
-
- // build a new array of meshes for the scene
- std::vector<aiMesh*> meshes;
-
- for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
- {
- aiMesh* srcMesh = pScene->mMeshes[a];
-
- std::vector<aiMesh*> newMeshes;
- SplitMesh( pScene->mMeshes[a], newMeshes);
-
- // mesh was split
- if( !newMeshes.empty() )
- {
- // store new meshes and indices of the new meshes
- for( unsigned int b = 0; b < newMeshes.size(); ++b)
- {
- mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
- meshes.push_back( newMeshes[b]);
- }
-
- // and destroy the source mesh. It should be completely contained inside the new submeshes
- delete srcMesh;
- }
- else
- {
- // Mesh is kept unchanged - store it's new place in the mesh array
- mSubMeshIndices[a].push_back( static_cast<unsigned int>(meshes.size()));
- meshes.push_back( srcMesh);
- }
- }
-
- // rebuild the scene's mesh array
- pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- delete [] pScene->mMeshes;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
-
- // recurse through all nodes and translate the node's mesh indices to fit the new mesh array
- UpdateNode( pScene->mRootNode);
-
- DefaultLogger::get()->debug( format() << "SplitByBoneCountProcess end: split " << mSubMeshIndices.size() << " meshes into " << meshes.size() << " submeshes." );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Splits the given mesh by bone count.
-void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const
-{
- // skip if not necessary
- if( pMesh->mNumBones <= mMaxBoneCount )
- return;
-
- // necessary optimisation: build a list of all affecting bones for each vertex
- // TODO: (thom) maybe add a custom allocator here to avoid allocating tens of thousands of small arrays
- typedef std::pair<unsigned int, float> BoneWeight;
- std::vector< std::vector<BoneWeight> > vertexBones( pMesh->mNumVertices);
- for( unsigned int a = 0; a < pMesh->mNumBones; ++a)
- {
- const aiBone* bone = pMesh->mBones[a];
- for( unsigned int b = 0; b < bone->mNumWeights; ++b)
- vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
- }
-
- unsigned int numFacesHandled = 0;
- std::vector<bool> isFaceHandled( pMesh->mNumFaces, false);
- while( numFacesHandled < pMesh->mNumFaces )
- {
- // which bones are used in the current submesh
- unsigned int numBones = 0;
- std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
- // indices of the faces which are going to go into this submesh
- std::vector<unsigned int> subMeshFaces;
- subMeshFaces.reserve( pMesh->mNumFaces);
- // accumulated vertex count of all the faces in this submesh
- unsigned int numSubMeshVertices = 0;
- // a small local array of new bones for the current face. State of all used bones for that face
- // can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
- std::vector<unsigned int> newBonesAtCurrentFace;
-
- // add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
- for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
- {
- // skip if the face is already stored in a submesh
- if( isFaceHandled[a] )
- continue;
-
- const aiFace& face = pMesh->mFaces[a];
- // check every vertex if its bones would still fit into the current submesh
- for( unsigned int b = 0; b < face.mNumIndices; ++b )
- {
- const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
- for( unsigned int c = 0; c < vb.size(); ++c)
- {
- unsigned int boneIndex = vb[c].first;
- // if the bone is already used in this submesh, it's ok
- if( isBoneUsed[boneIndex] )
- continue;
-
- // if it's not used, yet, we would need to add it. Store its bone index
- if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() )
- newBonesAtCurrentFace.push_back( boneIndex);
- }
- }
-
- // leave out the face if the new bones required for this face don't fit the bone count limit anymore
- if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
- continue;
-
- // mark all new bones as necessary
- while( !newBonesAtCurrentFace.empty() )
- {
- unsigned int newIndex = newBonesAtCurrentFace.back();
- newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear()
- if( isBoneUsed[newIndex] )
- continue;
-
- isBoneUsed[newIndex] = true;
- numBones++;
- }
-
- // store the face index and the vertex count
- subMeshFaces.push_back( a);
- numSubMeshVertices += face.mNumIndices;
-
- // remember that this face is handled
- isFaceHandled[a] = true;
- numFacesHandled++;
- }
-
- // create a new mesh to hold this subset of the source mesh
- aiMesh* newMesh = new aiMesh;
- if( pMesh->mName.length > 0 )
- newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size());
- newMesh->mMaterialIndex = pMesh->mMaterialIndex;
- newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
- poNewMeshes.push_back( newMesh);
-
- // create all the arrays for this mesh if the old mesh contained them
- newMesh->mNumVertices = numSubMeshVertices;
- newMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
- newMesh->mVertices = new aiVector3D[newMesh->mNumVertices];
- if( pMesh->HasNormals() )
- newMesh->mNormals = new aiVector3D[newMesh->mNumVertices];
- if( pMesh->HasTangentsAndBitangents() )
- {
- newMesh->mTangents = new aiVector3D[newMesh->mNumVertices];
- newMesh->mBitangents = new aiVector3D[newMesh->mNumVertices];
- }
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
- {
- if( pMesh->HasTextureCoords( a) )
- newMesh->mTextureCoords[a] = new aiVector3D[newMesh->mNumVertices];
- newMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
- }
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a )
- {
- if( pMesh->HasVertexColors( a) )
- newMesh->mColors[a] = new aiColor4D[newMesh->mNumVertices];
- }
-
- // and copy over the data, generating faces with linear indices along the way
- newMesh->mFaces = new aiFace[subMeshFaces.size()];
- unsigned int nvi = 0; // next vertex index
- std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
- for( unsigned int a = 0; a < subMeshFaces.size(); ++a )
- {
- const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
- aiFace& dstFace = newMesh->mFaces[a];
- dstFace.mNumIndices = srcFace.mNumIndices;
- dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
-
- // accumulate linearly all the vertices of the source face
- for( unsigned int b = 0; b < dstFace.mNumIndices; ++b )
- {
- unsigned int srcIndex = srcFace.mIndices[b];
- dstFace.mIndices[b] = nvi;
- previousVertexIndices[nvi] = srcIndex;
-
- newMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
- if( pMesh->HasNormals() )
- newMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
- if( pMesh->HasTangentsAndBitangents() )
- {
- newMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
- newMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
- }
- for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++c )
- {
- if( pMesh->HasTextureCoords( c) )
- newMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
- }
- for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; ++c )
- {
- if( pMesh->HasVertexColors( c) )
- newMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
- }
-
- nvi++;
- }
- }
-
- ai_assert( nvi == numSubMeshVertices );
-
- // Create the bones for the new submesh: first create the bone array
- newMesh->mNumBones = 0;
- newMesh->mBones = new aiBone*[numBones];
-
- std::vector<unsigned int> mappedBoneIndex( pMesh->mNumBones, std::numeric_limits<unsigned int>::max());
- for( unsigned int a = 0; a < pMesh->mNumBones; ++a )
- {
- if( !isBoneUsed[a] )
- continue;
-
- // create the new bone
- const aiBone* srcBone = pMesh->mBones[a];
- aiBone* dstBone = new aiBone;
- mappedBoneIndex[a] = newMesh->mNumBones;
- newMesh->mBones[newMesh->mNumBones++] = dstBone;
- dstBone->mName = srcBone->mName;
- dstBone->mOffsetMatrix = srcBone->mOffsetMatrix;
- dstBone->mNumWeights = 0;
- }
-
- ai_assert( newMesh->mNumBones == numBones );
-
- // iterate over all new vertices and count which bones affected its old vertex in the source mesh
- for( unsigned int a = 0; a < numSubMeshVertices; ++a )
- {
- unsigned int oldIndex = previousVertexIndices[a];
- const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[oldIndex];
-
- for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b )
- {
- unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
- if( newBoneIndex != std::numeric_limits<unsigned int>::max() )
- newMesh->mBones[newBoneIndex]->mNumWeights++;
- }
- }
-
- // allocate all bone weight arrays accordingly
- for( unsigned int a = 0; a < newMesh->mNumBones; ++a )
- {
- aiBone* bone = newMesh->mBones[a];
- ai_assert( bone->mNumWeights > 0 );
- bone->mWeights = new aiVertexWeight[bone->mNumWeights];
- bone->mNumWeights = 0; // for counting up in the next step
- }
-
- // now copy all the bone vertex weights for all the vertices which made it into the new submesh
- for( unsigned int a = 0; a < numSubMeshVertices; ++a)
- {
- // find the source vertex for it in the source mesh
- unsigned int previousIndex = previousVertexIndices[a];
- // these bones were affecting it
- const std::vector<BoneWeight>& bonesOnThisVertex = vertexBones[previousIndex];
- // all of the bones affecting it should be present in the new submesh, or else
- // the face it comprises shouldn't be present
- for( unsigned int b = 0; b < bonesOnThisVertex.size(); ++b)
- {
- unsigned int newBoneIndex = mappedBoneIndex[ bonesOnThisVertex[b].first ];
- ai_assert( newBoneIndex != std::numeric_limits<unsigned int>::max() );
- aiVertexWeight* dstWeight = newMesh->mBones[newBoneIndex]->mWeights + newMesh->mBones[newBoneIndex]->mNumWeights;
- newMesh->mBones[newBoneIndex]->mNumWeights++;
-
- dstWeight->mVertexId = a;
- dstWeight->mWeight = bonesOnThisVertex[b].second;
- }
- }
-
- // I have the strange feeling that this will break apart at some point in time...
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively updates the node's mesh list to account for the changed mesh list
-void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const
-{
- // rebuild the node's mesh index list
- if( pNode->mNumMeshes > 0 )
- {
- std::vector<unsigned int> newMeshList;
- for( unsigned int a = 0; a < pNode->mNumMeshes; ++a)
- {
- unsigned int srcIndex = pNode->mMeshes[a];
- const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
- newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
- }
-
- delete pNode->mMeshes;
- pNode->mNumMeshes = static_cast<unsigned int>(newMeshList.size());
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
- std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
- }
-
- // do that also recursively for all children
- for( unsigned int a = 0; a < pNode->mNumChildren; ++a )
- {
- UpdateNode( pNode->mChildren[a]);
- }
-}
diff --git a/src/3rdparty/assimp/code/SplitByBoneCountProcess.h b/src/3rdparty/assimp/code/SplitByBoneCountProcess.h
deleted file mode 100644
index 434ef9866..000000000
--- a/src/3rdparty/assimp/code/SplitByBoneCountProcess.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 SplitByBoneCountProcess.h
-/// Defines a post processing step to split meshes with many bones into submeshes
-#ifndef AI_SPLITBYBONECOUNTPROCESS_H_INC
-#define AI_SPLITBYBONECOUNTPROCESS_H_INC
-
-#include <vector>
-#include "BaseProcess.h"
-
-#include <assimp/mesh.h>
-#include <assimp/scene.h>
-
-namespace Assimp
-{
-
-
-/** Postprocessing filter to split meshes with many bones into submeshes
- * so that each submesh has a certain max bone count.
- *
- * Applied BEFORE the JoinVertices-Step occurs.
- * Returns NON-UNIQUE vertices, splits by bone count.
-*/
-class SplitByBoneCountProcess : public BaseProcess
-{
-public:
-
- SplitByBoneCountProcess();
- ~SplitByBoneCountProcess();
-
-public:
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with. A
- * bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
-protected:
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- /// Splits the given mesh by bone count.
- /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
- /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
- void SplitMesh( const aiMesh* pMesh, std::vector<aiMesh*>& poNewMeshes) const;
-
- /// Recursively updates the node's mesh list to account for the changed mesh list
- void UpdateNode( aiNode* pNode) const;
-
-public:
- /// Max bone count. Splitting occurs if a mesh has more than that number of bones.
- size_t mMaxBoneCount;
-
- /// Per mesh index: Array of indices of the new submeshes.
- std::vector< std::vector<unsigned int> > mSubMeshIndices;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/SplitLargeMeshes.cpp b/src/3rdparty/assimp/code/SplitLargeMeshes.cpp
deleted file mode 100644
index 2066f7989..000000000
--- a/src/3rdparty/assimp/code/SplitLargeMeshes.cpp
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the SplitLargeMeshes postprocessing step
-*/
-
-
-
-// internal headers of the post-processing framework
-#include "SplitLargeMeshes.h"
-#include "ProcessHelper.h"
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Triangle::SplitLargeMeshesProcess_Triangle()
-{
- LIMIT = AI_SLM_DEFAULT_MAX_TRIANGLES;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Triangle::~SplitLargeMeshesProcess_Triangle()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SplitLargeMeshesProcess_Triangle::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SplitLargeMeshes) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene)
-{
- if (0xffffffff == this->LIMIT)return;
-
- DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle begin");
- std::vector<std::pair<aiMesh*, unsigned int> > avList;
-
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- this->SplitMesh(a, pScene->mMeshes[a],avList);
-
- if (avList.size() != pScene->mNumMeshes)
- {
- // it seems something has been split. rebuild the mesh list
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)avList.size();
- pScene->mMeshes = new aiMesh*[avList.size()];
-
- for (unsigned int i = 0; i < avList.size();++i)
- pScene->mMeshes[i] = avList[i].first;
-
- // now we need to update all nodes
- this->UpdateNode(pScene->mRootNode,avList);
- DefaultLogger::get()->info("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
- }
- else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp)
-{
- // get the current value of the split property
- this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_TRIANGLE_LIMIT,AI_SLM_DEFAULT_MAX_TRIANGLES);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Update a node after some meshes have been split
-void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
- const std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- // for every index in out list build a new entry
- std::vector<unsigned int> aiEntries;
- aiEntries.reserve(pcNode->mNumMeshes + 1);
- for (unsigned int i = 0; i < pcNode->mNumMeshes;++i)
- {
- for (unsigned int a = 0; a < avList.size();++a)
- {
- if (avList[a].second == pcNode->mMeshes[i])
- {
- aiEntries.push_back(a);
- }
- }
- }
-
- // now build the new list
- delete[] pcNode->mMeshes;
- pcNode->mNumMeshes = (unsigned int)aiEntries.size();
- pcNode->mMeshes = new unsigned int[pcNode->mNumMeshes];
-
- for (unsigned int b = 0; b < pcNode->mNumMeshes;++b)
- pcNode->mMeshes[b] = aiEntries[b];
-
- // recusively update all other nodes
- for (unsigned int i = 0; i < pcNode->mNumChildren;++i)
- {
- UpdateNode ( pcNode->mChildren[i], avList );
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Triangle::SplitMesh(
- unsigned int a,
- aiMesh* pMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- if (pMesh->mNumFaces > SplitLargeMeshesProcess_Triangle::LIMIT)
- {
- DefaultLogger::get()->info("Mesh exceeds the triangle limit. It will be split ...");
-
- // we need to split this mesh into sub meshes
- // determine the size of a submesh
- const unsigned int iSubMeshes = (pMesh->mNumFaces / LIMIT) + 1;
-
- const unsigned int iOutFaceNum = pMesh->mNumFaces / iSubMeshes;
- const unsigned int iOutVertexNum = iOutFaceNum * 3;
-
- // now generate all submeshes
- for (unsigned int i = 0; i < iSubMeshes;++i)
- {
- aiMesh* pcMesh = new aiMesh;
- pcMesh->mNumFaces = iOutFaceNum;
- pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
-
- // the name carries the adjacency information between the meshes
- pcMesh->mName = pMesh->mName;
-
- if (i == iSubMeshes-1)
- {
- pcMesh->mNumFaces = iOutFaceNum + (
- pMesh->mNumFaces - iOutFaceNum * iSubMeshes);
- }
- // copy the list of faces
- pcMesh->mFaces = new aiFace[pcMesh->mNumFaces];
-
- const unsigned int iBase = iOutFaceNum * i;
-
- // get the total number of indices
- unsigned int iCnt = 0;
- for (unsigned int p = iBase; p < pcMesh->mNumFaces + iBase;++p)
- {
- iCnt += pMesh->mFaces[p].mNumIndices;
- }
- pcMesh->mNumVertices = iCnt;
-
- // allocate storage
- if (pMesh->mVertices != NULL)
- pcMesh->mVertices = new aiVector3D[iCnt];
-
- if (pMesh->HasNormals())
- pcMesh->mNormals = new aiVector3D[iCnt];
-
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents = new aiVector3D[iCnt];
- pcMesh->mBitangents = new aiVector3D[iCnt];
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
- if (pMesh->HasTextureCoords( c))
- {
- pcMesh->mTextureCoords[c] = new aiVector3D[iCnt];
- }
- }
-
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- {
- pcMesh->mColors[c] = new aiColor4D[iCnt];
- }
- }
-
- if (pMesh->HasBones())
- {
- // assume the number of bones won't change in most cases
- pcMesh->mBones = new aiBone*[pMesh->mNumBones];
-
- // iterate through all bones of the mesh and find those which
- // need to be copied to the split mesh
- std::vector<aiVertexWeight> avTempWeights;
- for (unsigned int p = 0; p < pcMesh->mNumBones;++p)
- {
- aiBone* const bone = pcMesh->mBones[p];
- avTempWeights.clear();
- avTempWeights.reserve(bone->mNumWeights / iSubMeshes);
-
- for (unsigned int q = 0; q < bone->mNumWeights;++q)
- {
- aiVertexWeight& weight = bone->mWeights[q];
- if(weight.mVertexId >= iBase && weight.mVertexId < iBase + iOutVertexNum)
- {
- avTempWeights.push_back(weight);
- weight = avTempWeights.back();
- weight.mVertexId -= iBase;
- }
- }
-
- if (!avTempWeights.empty())
- {
- // we'll need this bone. Copy it ...
- aiBone* pc = new aiBone();
- pcMesh->mBones[pcMesh->mNumBones++] = pc;
- pc->mName = aiString(bone->mName);
- pc->mNumWeights = (unsigned int)avTempWeights.size();
- pc->mOffsetMatrix = bone->mOffsetMatrix;
-
- // no need to reallocate the array for the last submesh.
- // Here we can reuse the (large) source array, although
- // we'll waste some memory
- if (iSubMeshes-1 == i)
- {
- pc->mWeights = bone->mWeights;
- bone->mWeights = NULL;
- }
- else pc->mWeights = new aiVertexWeight[pc->mNumWeights];
-
- // copy the weights
- ::memcpy(pc->mWeights,&avTempWeights[0],sizeof(aiVertexWeight)*pc->mNumWeights);
- }
- }
- }
-
- // (we will also need to copy the array of indices)
- unsigned int iCurrent = 0;
- for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
- {
- pcMesh->mFaces[p].mNumIndices = 3;
- // allocate a new array
- const unsigned int iTemp = p + iBase;
- const unsigned int iNumIndices = pMesh->mFaces[iTemp].mNumIndices;
-
- // setup face type and number of indices
- pcMesh->mFaces[p].mNumIndices = iNumIndices;
- unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
- unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
-
- // need to update the output primitive types
- switch (iNumIndices)
- {
- case 1:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
-
- // and copy the contents of the old array, offset by current base
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pi[v];
- unsigned int iIndexOut = iCurrent++;
- piOut[v] = iIndexOut;
-
- // copy positions
- if (pMesh->mVertices != NULL)
- pcMesh->mVertices[iIndexOut] = pMesh->mVertices[iIndex];
-
- // copy normals
- if (pMesh->HasNormals())
- pcMesh->mNormals[iIndexOut] = pMesh->mNormals[iIndex];
-
- // copy tangents/bitangents
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents[iIndexOut] = pMesh->mTangents[iIndex];
- pcMesh->mBitangents[iIndexOut] = pMesh->mBitangents[iIndex];
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- if (pMesh->HasTextureCoords( c))
- pcMesh->mTextureCoords[c][iIndexOut] = pMesh->mTextureCoords[c][iIndex];
- }
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- pcMesh->mColors[c][iIndexOut] = pMesh->mColors[c][iIndex];
- }
- }
- }
-
- // add the newly created mesh to the list
- avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
- }
-
- // now delete the old mesh data
- delete pMesh;
- }
- else avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Vertex::SplitLargeMeshesProcess_Vertex()
-{
- LIMIT = AI_SLM_DEFAULT_MAX_VERTICES;
-}
-
-// ------------------------------------------------------------------------------------------------
-SplitLargeMeshesProcess_Vertex::~SplitLargeMeshesProcess_Vertex()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool SplitLargeMeshesProcess_Vertex::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_SplitLargeMeshes) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Vertex::Execute( aiScene* pScene)
-{
- std::vector<std::pair<aiMesh*, unsigned int> > avList;
-
- if (0xffffffff == this->LIMIT)return;
-
- DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex begin");
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- this->SplitMesh(a, pScene->mMeshes[a],avList);
-
- if (avList.size() != pScene->mNumMeshes)
- {
- // it seems something has been split. rebuild the mesh list
- delete[] pScene->mMeshes;
- pScene->mNumMeshes = (unsigned int)avList.size();
- pScene->mMeshes = new aiMesh*[avList.size()];
-
- for (unsigned int i = 0; i < avList.size();++i)
- pScene->mMeshes[i] = avList[i].first;
-
- // now we need to update all nodes
- SplitLargeMeshesProcess_Triangle::UpdateNode(pScene->mRootNode,avList);
- DefaultLogger::get()->info("SplitLargeMeshesProcess_Vertex finished. Meshes have been split");
- }
- else DefaultLogger::get()->debug("SplitLargeMeshesProcess_Vertex finished. There was nothing to do");
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void SplitLargeMeshesProcess_Vertex::SetupProperties( const Importer* pImp)
-{
- this->LIMIT = pImp->GetPropertyInteger(AI_CONFIG_PP_SLM_VERTEX_LIMIT,AI_SLM_DEFAULT_MAX_VERTICES);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void SplitLargeMeshesProcess_Vertex::SplitMesh(
- unsigned int a,
- aiMesh* pMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList)
-{
- if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
- {
- typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
-
- // build a per-vertex weight list if necessary
- VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);
-
- // we need to split this mesh into sub meshes
- // determine the estimated size of a submesh
- // (this could be too large. Max waste is a single digit percentage)
- const unsigned int iSubMeshes = (pMesh->mNumVertices / SplitLargeMeshesProcess_Vertex::LIMIT) + 1;
- //const unsigned int iOutVertexNum2 = pMesh->mNumVertices /iSubMeshes;
-
- // create a std::vector<unsigned int> to indicate which vertices
- // have already been copied
- std::vector<unsigned int> avWasCopied;
- avWasCopied.resize(pMesh->mNumVertices,0xFFFFFFFF);
-
- // try to find a good estimate for the number of output faces
- // per mesh. Add 12.5% as buffer
- unsigned int iEstimatedSize = pMesh->mNumFaces / iSubMeshes;
- iEstimatedSize += iEstimatedSize >> 3;
-
- // now generate all submeshes
- unsigned int iBase = 0;
- while (true)
- {
- const unsigned int iOutVertexNum = SplitLargeMeshesProcess_Vertex::LIMIT;
-
- aiMesh* pcMesh = new aiMesh;
- pcMesh->mNumVertices = 0;
- pcMesh->mMaterialIndex = pMesh->mMaterialIndex;
-
- // the name carries the adjacency information between the meshes
- pcMesh->mName = pMesh->mName;
-
- typedef std::vector<aiVertexWeight> BoneWeightList;
- if (pMesh->HasBones())
- {
- pcMesh->mBones = new aiBone*[pMesh->mNumBones];
- ::memset(pcMesh->mBones,0,sizeof(void*)*pMesh->mNumBones);
- }
-
- // clear the temporary helper array
- if (iBase)
- {
- // we can't use memset here we unsigned int needn' be 32 bits
- for (auto &elem : avWasCopied)
- {
- elem = 0xffffffff;
- }
- }
-
- // output vectors
- std::vector<aiFace> vFaces;
-
- // reserve enough storage for most cases
- if (pMesh->HasPositions())
- {
- pcMesh->mVertices = new aiVector3D[iOutVertexNum];
- }
- if (pMesh->HasNormals())
- {
- pcMesh->mNormals = new aiVector3D[iOutVertexNum];
- }
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents = new aiVector3D[iOutVertexNum];
- pcMesh->mBitangents = new aiVector3D[iOutVertexNum];
- }
- for (unsigned int c = 0; pMesh->HasVertexColors(c);++c)
- {
- pcMesh->mColors[c] = new aiColor4D[iOutVertexNum];
- }
- for (unsigned int c = 0; pMesh->HasTextureCoords(c);++c)
- {
- pcMesh->mNumUVComponents[c] = pMesh->mNumUVComponents[c];
- pcMesh->mTextureCoords[c] = new aiVector3D[iOutVertexNum];
- }
- vFaces.reserve(iEstimatedSize);
-
- // (we will also need to copy the array of indices)
- while (iBase < pMesh->mNumFaces)
- {
- // allocate a new array
- const unsigned int iNumIndices = pMesh->mFaces[iBase].mNumIndices;
-
- // doesn't catch degenerates but is quite fast
- unsigned int iNeed = 0;
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
-
- // check whether we do already have this vertex
- if (0xFFFFFFFF == avWasCopied[iIndex])
- {
- iNeed++;
- }
- }
- if (pcMesh->mNumVertices + iNeed > iOutVertexNum)
- {
- // don't use this face
- break;
- }
-
- vFaces.push_back(aiFace());
- aiFace& rFace = vFaces.back();
-
- // setup face type and number of indices
- rFace.mNumIndices = iNumIndices;
- rFace.mIndices = new unsigned int[iNumIndices];
-
- // need to update the output primitive types
- switch (rFace.mNumIndices)
- {
- case 1:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
- case 2:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
- case 3:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- default:
- pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- }
-
- // and copy the contents of the old array, offset by current base
- for (unsigned int v = 0; v < iNumIndices;++v)
- {
- unsigned int iIndex = pMesh->mFaces[iBase].mIndices[v];
-
- // check whether we do already have this vertex
- if (0xFFFFFFFF != avWasCopied[iIndex])
- {
- rFace.mIndices[v] = avWasCopied[iIndex];
- continue;
- }
-
- // copy positions
- pcMesh->mVertices[pcMesh->mNumVertices] = (pMesh->mVertices[iIndex]);
-
- // copy normals
- if (pMesh->HasNormals())
- {
- pcMesh->mNormals[pcMesh->mNumVertices] = (pMesh->mNormals[iIndex]);
- }
-
- // copy tangents/bitangents
- if (pMesh->HasTangentsAndBitangents())
- {
- pcMesh->mTangents[pcMesh->mNumVertices] = (pMesh->mTangents[iIndex]);
- pcMesh->mBitangents[pcMesh->mNumVertices] = (pMesh->mBitangents[iIndex]);
- }
-
- // texture coordinates
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
- {
- if (pMesh->HasTextureCoords( c))
- {
- pcMesh->mTextureCoords[c][pcMesh->mNumVertices] = pMesh->mTextureCoords[c][iIndex];
- }
- }
- // vertex colors
- for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS;++c)
- {
- if (pMesh->HasVertexColors( c))
- {
- pcMesh->mColors[c][pcMesh->mNumVertices] = pMesh->mColors[c][iIndex];
- }
- }
- // check whether we have bone weights assigned to this vertex
- rFace.mIndices[v] = pcMesh->mNumVertices;
- if (avPerVertexWeights)
- {
- VertexWeightTable& table = avPerVertexWeights[ pcMesh->mNumVertices ];
- if( !table.empty() )
- {
- for (VertexWeightTable::const_iterator
- iter = table.begin();
- iter != table.end();++iter)
- {
- // allocate the bone weight array if necessary
- BoneWeightList* pcWeightList = (BoneWeightList*)pcMesh->mBones[(*iter).first];
- if (!pcWeightList)
- {
- pcMesh->mBones[(*iter).first] = (aiBone*)(pcWeightList = new BoneWeightList());
- }
- pcWeightList->push_back(aiVertexWeight(pcMesh->mNumVertices,(*iter).second));
- }
- }
- }
-
- avWasCopied[iIndex] = pcMesh->mNumVertices;
- pcMesh->mNumVertices++;
- }
- iBase++;
- if(pcMesh->mNumVertices == iOutVertexNum)
- {
- // break here. The face is only added if it was complete
- break;
- }
- }
-
- // check which bones we'll need to create for this submesh
- if (pMesh->HasBones())
- {
- aiBone** ppCurrent = pcMesh->mBones;
- for (unsigned int k = 0; k < pMesh->mNumBones;++k)
- {
- // check whether the bone is existing
- BoneWeightList* pcWeightList;
- if ((pcWeightList = (BoneWeightList*)pcMesh->mBones[k]))
- {
- aiBone* pcOldBone = pMesh->mBones[k];
- aiBone* pcOut;
- *ppCurrent++ = pcOut = new aiBone();
- pcOut->mName = aiString(pcOldBone->mName);
- pcOut->mOffsetMatrix = pcOldBone->mOffsetMatrix;
- pcOut->mNumWeights = (unsigned int)pcWeightList->size();
- pcOut->mWeights = new aiVertexWeight[pcOut->mNumWeights];
-
- // copy the vertex weights
- ::memcpy(pcOut->mWeights,&pcWeightList->operator[](0),
- pcOut->mNumWeights * sizeof(aiVertexWeight));
-
- // delete the temporary bone weight list
- delete pcWeightList;
- pcMesh->mNumBones++;
- }
- }
- }
-
- // copy the face list to the mesh
- pcMesh->mFaces = new aiFace[vFaces.size()];
- pcMesh->mNumFaces = (unsigned int)vFaces.size();
-
- for (unsigned int p = 0; p < pcMesh->mNumFaces;++p)
- pcMesh->mFaces[p] = vFaces[p];
-
- // add the newly created mesh to the list
- avList.push_back(std::pair<aiMesh*, unsigned int>(pcMesh,a));
-
- if (iBase == pMesh->mNumFaces)
- {
- // have all faces ... finish the outer loop, too
- break;
- }
- }
-
- // delete the per-vertex weight list again
- delete[] avPerVertexWeights;
-
- // now delete the old mesh data
- delete pMesh;
- return;
- }
- avList.push_back(std::pair<aiMesh*, unsigned int>(pMesh,a));
- return;
-}
diff --git a/src/3rdparty/assimp/code/SplitLargeMeshes.h b/src/3rdparty/assimp/code/SplitLargeMeshes.h
deleted file mode 100644
index 7556e9fe8..000000000
--- a/src/3rdparty/assimp/code/SplitLargeMeshes.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to split large meshes into submeshes
- */
-#ifndef AI_SPLITLARGEMESHES_H_INC
-#define AI_SPLITLARGEMESHES_H_INC
-
-#include <vector>
-#include "BaseProcess.h"
-
-#include <assimp/mesh.h>
-#include <assimp/scene.h>
-
-class SplitLargeMeshesTest;
-
-namespace Assimp
-{
-
-class SplitLargeMeshesProcess_Triangle;
-class SplitLargeMeshesProcess_Vertex;
-
-// NOTE: If you change these limits, don't forget to change the
-// corresponding values in all Assimp ports
-
-// **********************************************************
-// Java: ConfigProperty.java,
-// ConfigProperty.DEFAULT_VERTEX_SPLIT_LIMIT
-// ConfigProperty.DEFAULT_TRIANGLE_SPLIT_LIMIT
-// **********************************************************
-
-// default limit for vertices
-#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
-# define AI_SLM_DEFAULT_MAX_VERTICES 1000000
-#endif
-
-// default limit for triangles
-#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
-# define AI_SLM_DEFAULT_MAX_TRIANGLES 1000000
-#endif
-
-// ---------------------------------------------------------------------------
-/** 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 ASSIMP_API SplitLargeMeshesProcess_Triangle : public BaseProcess
-{
- friend class SplitLargeMeshesProcess_Vertex;
-
-public:
-
- SplitLargeMeshesProcess_Triangle();
- ~SplitLargeMeshesProcess_Triangle();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag.
- * @param pFlags The processing flags the importer was called with. A
- * bitwise combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields,
- * false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
-
- //! Set the split limit - needed for unit testing
- inline void SetLimit(unsigned int l)
- {LIMIT = l;}
-
- //! Get the split limit
- inline unsigned int GetLimit() const
- {return LIMIT;}
-
-public:
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- //! Apply the algorithm to a given mesh
- void SplitMesh (unsigned int a, aiMesh* pcMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
- // -------------------------------------------------------------------
- //! Update a node in the asset after a few of its meshes
- //! have been split
- static void UpdateNode(aiNode* pcNode,
- const std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
-public:
- //! Triangle limit
- unsigned int LIMIT;
-};
-
-
-// ---------------------------------------------------------------------------
-/** Post-processing filter to split large meshes into sub-meshes
- *
- * Applied AFTER the JoinVertices-Step occurs.
- * Returns UNIQUE vertices, splits by vertex number.
-*/
-class ASSIMP_API SplitLargeMeshesProcess_Vertex : public BaseProcess
-{
-public:
-
- SplitLargeMeshesProcess_Vertex();
- ~SplitLargeMeshesProcess_Vertex();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Called prior to ExecuteOnScene().
- * The function is a request to the process to update its configuration
- * basing on the Importer's configuration property list.
- */
- virtual void SetupProperties(const Importer* pImp);
-
-
- //! Set the split limit - needed for unit testing
- inline void SetLimit(unsigned int l)
- {LIMIT = l;}
-
- //! Get the split limit
- inline unsigned int GetLimit() const
- {return LIMIT;}
-
-public:
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- //! Apply the algorithm to a given mesh
- void SplitMesh (unsigned int a, aiMesh* pcMesh,
- std::vector<std::pair<aiMesh*, unsigned int> >& avList);
-
- // NOTE: Reuse SplitLargeMeshesProcess_Triangle::UpdateNode()
-
-public:
- //! Triangle limit
- unsigned int LIMIT;
-};
-
-} // end of namespace Assimp
-
-#endif // !!AI_SPLITLARGEMESHES_H_INC
diff --git a/src/3rdparty/assimp/code/StandardShapes.cpp b/src/3rdparty/assimp/code/StandardShapes.cpp
deleted file mode 100644
index 4346a8d76..000000000
--- a/src/3rdparty/assimp/code/StandardShapes.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 StandardShapes.cpp
- * @brief Implementation of the StandardShapes class
- *
- * The primitive geometry data comes from
- * http://geometrictools.com/Documentation/PlatonicSolids.pdf.
- */
-
-#include "StandardShapes.h"
-#include "StringComparison.h"
-#include <stddef.h>
-#include <assimp/Defines.h>
-#include <assimp/mesh.h>
-
-namespace Assimp {
-
-
-# define ADD_TRIANGLE(n0,n1,n2) \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2);
-
-# define ADD_PENTAGON(n0,n1,n2,n3,n4) \
- if (polygons) \
- { \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2); \
- positions.push_back(n3); \
- positions.push_back(n4); \
- } \
- else \
- { \
- ADD_TRIANGLE(n0, n1, n2) \
- ADD_TRIANGLE(n0, n2, n3) \
- ADD_TRIANGLE(n0, n3, n4) \
- }
-
-# define ADD_QUAD(n0,n1,n2,n3) \
- if (polygons) \
- { \
- positions.push_back(n0); \
- positions.push_back(n1); \
- positions.push_back(n2); \
- positions.push_back(n3); \
- } \
- else \
- { \
- ADD_TRIANGLE(n0, n1, n2) \
- ADD_TRIANGLE(n0, n2, n3) \
- }
-
-
-// ------------------------------------------------------------------------------------------------
-// Fast subdivision for a mesh whose verts have a magnitude of 1
-void Subdivide(std::vector<aiVector3D>& positions)
-{
- // assume this to be constant - (fixme: must be 1.0? I think so)
- const ai_real fl1 = positions[0].Length();
-
- unsigned int origSize = (unsigned int)positions.size();
- for (unsigned int i = 0 ; i < origSize ; i+=3)
- {
- aiVector3D& tv0 = positions[i];
- aiVector3D& tv1 = positions[i+1];
- aiVector3D& tv2 = positions[i+2];
-
- aiVector3D a = tv0, b = tv1, c = tv2;
- aiVector3D v1 = aiVector3D(a.x+b.x, a.y+b.y, a.z+b.z).Normalize()*fl1;
- aiVector3D v2 = aiVector3D(a.x+c.x, a.y+c.y, a.z+c.z).Normalize()*fl1;
- aiVector3D v3 = aiVector3D(b.x+c.x, b.y+c.y, b.z+c.z).Normalize()*fl1;
-
- tv0 = v1; tv1 = v3; tv2 = v2; // overwrite the original
- ADD_TRIANGLE(v1, v2, a);
- ADD_TRIANGLE(v2, v3, c);
- ADD_TRIANGLE(v3, v1, b);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh from given vertex positions
-aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
- unsigned int numIndices)
-{
- if (positions.empty() || !numIndices) return NULL;
-
- // Determine which kinds of primitives the mesh consists of
- aiMesh* out = new aiMesh();
- switch (numIndices)
- {
- case 1:
- out->mPrimitiveTypes = aiPrimitiveType_POINT;
- break;
- case 2:
- out->mPrimitiveTypes = aiPrimitiveType_LINE;
- break;
- case 3:
- out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- break;
- default:
- out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- break;
- };
-
- out->mNumFaces = (unsigned int)positions.size() / numIndices;
- out->mFaces = new aiFace[out->mNumFaces];
- for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
- {
- aiFace& f = out->mFaces[i];
- f.mNumIndices = numIndices;
- f.mIndices = new unsigned int[numIndices];
- for (unsigned int i = 0; i < numIndices;++i,++a)
- f.mIndices[i] = a;
- }
- out->mNumVertices = (unsigned int)positions.size();
- out->mVertices = new aiVector3D[out->mNumVertices];
- ::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
- std::vector<aiVector3D>&))
-{
- std::vector<aiVector3D> temp;
- unsigned num = (*GenerateFunc)(temp);
- return MakeMesh(temp,num);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh ( unsigned int (*GenerateFunc)(
- std::vector<aiVector3D>&, bool))
-{
- std::vector<aiVector3D> temp;
- unsigned num = (*GenerateFunc)(temp,true);
- return MakeMesh(temp,num);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Construct a mesh with a specific shape (callback)
-aiMesh* StandardShapes::MakeMesh (unsigned int num, void (*GenerateFunc)(
- unsigned int,std::vector<aiVector3D>&))
-{
- std::vector<aiVector3D> temp;
- (*GenerateFunc)(num,temp);
- return MakeMesh(temp,3);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build an incosahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeIcosahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+60);
-
- const ai_real t = ( ai_real( 1.0 )+ ai_real( 2.236067977 ) ) / ai_real( 2.0 );
- const ai_real s = std::sqrt(ai_real(1.0) + t*t);
-
- const aiVector3D v0 = aiVector3D(t,1.0, 0.0)/s;
- const aiVector3D v1 = aiVector3D(-t,1.0, 0.0)/s;
- const aiVector3D v2 = aiVector3D(t,-1.0, 0.0)/s;
- const aiVector3D v3 = aiVector3D(-t,-1.0, 0.0)/s;
- const aiVector3D v4 = aiVector3D(1.0, 0.0, t)/s;
- const aiVector3D v5 = aiVector3D(1.0, 0.0,-t)/s;
- const aiVector3D v6 = aiVector3D(-1.0, 0.0,t)/s;
- const aiVector3D v7 = aiVector3D(-1.0, 0.0,-t)/s;
- const aiVector3D v8 = aiVector3D(0.0, t, 1.0)/s;
- const aiVector3D v9 = aiVector3D(0.0,-t, 1.0)/s;
- const aiVector3D v10 = aiVector3D(0.0, t,-1.0)/s;
- const aiVector3D v11 = aiVector3D(0.0,-t,-1.0)/s;
-
- ADD_TRIANGLE(v0,v8,v4);
- ADD_TRIANGLE(v0,v5,v10);
- ADD_TRIANGLE(v2,v4,v9);
- ADD_TRIANGLE(v2,v11,v5);
-
- ADD_TRIANGLE(v1,v6,v8);
- ADD_TRIANGLE(v1,v10,v7);
- ADD_TRIANGLE(v3,v9,v6);
- ADD_TRIANGLE(v3,v7,v11);
-
- ADD_TRIANGLE(v0,v10,v8);
- ADD_TRIANGLE(v1,v8,v10);
- ADD_TRIANGLE(v2,v9,v11);
- ADD_TRIANGLE(v3,v11,v9);
-
- ADD_TRIANGLE(v4,v2,v0);
- ADD_TRIANGLE(v5,v0,v2);
- ADD_TRIANGLE(v6,v1,v3);
- ADD_TRIANGLE(v7,v3,v1);
-
- ADD_TRIANGLE(v8,v6,v4);
- ADD_TRIANGLE(v9,v4,v6);
- ADD_TRIANGLE(v10,v5,v7);
- ADD_TRIANGLE(v11,v7,v5);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a dodecahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeDodecahedron(std::vector<aiVector3D>& positions,
- bool polygons /*= false*/)
-{
- positions.reserve(positions.size()+108);
-
- const ai_real a = ai_real( 1.0 ) / ai_real(1.7320508);
- const ai_real b = std::sqrt(( ai_real( 3.0 )- ai_real( 2.23606797))/ ai_real( 6.0) );
- const ai_real c = std::sqrt(( ai_real( 3.0 )+ ai_real( 2.23606797f))/ ai_real( 6.0) );
-
- const aiVector3D v0 = aiVector3D(a,a,a);
- const aiVector3D v1 = aiVector3D(a,a,-a);
- const aiVector3D v2 = aiVector3D(a,-a,a);
- const aiVector3D v3 = aiVector3D(a,-a,-a);
- const aiVector3D v4 = aiVector3D(-a,a,a);
- const aiVector3D v5 = aiVector3D(-a,a,-a);
- const aiVector3D v6 = aiVector3D(-a,-a,a);
- const aiVector3D v7 = aiVector3D(-a,-a,-a);
- const aiVector3D v8 = aiVector3D(b,c,0.0);
- const aiVector3D v9 = aiVector3D(-b,c,0.0);
- const aiVector3D v10 = aiVector3D(b,-c,0.0);
- const aiVector3D v11 = aiVector3D(-b,-c,0.0);
- const aiVector3D v12 = aiVector3D(c, 0.0, b);
- const aiVector3D v13 = aiVector3D(c, 0.0, -b);
- const aiVector3D v14 = aiVector3D(-c, 0.0, b);
- const aiVector3D v15 = aiVector3D(-c, 0.0, -b);
- const aiVector3D v16 = aiVector3D(0.0, b, c);
- const aiVector3D v17 = aiVector3D(0.0, -b, c);
- const aiVector3D v18 = aiVector3D(0.0, b, -c);
- const aiVector3D v19 = aiVector3D(0.0, -b, -c);
-
- ADD_PENTAGON(v0, v8, v9, v4, v16);
- ADD_PENTAGON(v0, v12, v13, v1, v8);
- ADD_PENTAGON(v0, v16, v17, v2, v12);
- ADD_PENTAGON(v8, v1, v18, v5, v9);
- ADD_PENTAGON(v12, v2, v10, v3, v13);
- ADD_PENTAGON(v16, v4, v14, v6, v17);
- ADD_PENTAGON(v9, v5, v15, v14, v4);
-
- ADD_PENTAGON(v6, v11, v10, v2, v17);
- ADD_PENTAGON(v3, v19, v18, v1, v13);
- ADD_PENTAGON(v7, v15, v5, v18, v19);
- ADD_PENTAGON(v7, v11, v6, v14, v15);
- ADD_PENTAGON(v7, v19, v3, v10, v11);
- return (polygons ? 5 : 3);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build an octahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeOctahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+24);
-
- const aiVector3D v0 = aiVector3D(1.0, 0.0, 0.0) ;
- const aiVector3D v1 = aiVector3D(-1.0, 0.0, 0.0);
- const aiVector3D v2 = aiVector3D(0.0, 1.0, 0.0);
- const aiVector3D v3 = aiVector3D(0.0, -1.0, 0.0);
- const aiVector3D v4 = aiVector3D(0.0, 0.0, 1.0);
- const aiVector3D v5 = aiVector3D(0.0, 0.0, -1.0);
-
- ADD_TRIANGLE(v4,v0,v2);
- ADD_TRIANGLE(v4,v2,v1);
- ADD_TRIANGLE(v4,v1,v3);
- ADD_TRIANGLE(v4,v3,v0);
-
- ADD_TRIANGLE(v5,v2,v0);
- ADD_TRIANGLE(v5,v1,v2);
- ADD_TRIANGLE(v5,v3,v1);
- ADD_TRIANGLE(v5,v0,v3);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a tetrahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeTetrahedron(std::vector<aiVector3D>& positions)
-{
- positions.reserve(positions.size()+9);
-
- const ai_real invThree = ai_real( 1.0 ) / ai_real( 3.0 );
- const ai_real a = ai_real( 1.41421 ) * invThree;
- const ai_real b = ai_real( 2.4494 ) * invThree;
-
- const aiVector3D v0 = aiVector3D(0.0,0.0,1.0);
- const aiVector3D v1 = aiVector3D(2*a,0,-invThree );
- const aiVector3D v2 = aiVector3D(-a,b,-invThree );
- const aiVector3D v3 = aiVector3D(-a,-b,-invThree );
-
- ADD_TRIANGLE(v0,v1,v2);
- ADD_TRIANGLE(v0,v2,v3);
- ADD_TRIANGLE(v0,v3,v1);
- ADD_TRIANGLE(v1,v3,v2);
- return 3;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a hexahedron with points.magnitude == 1
-unsigned int StandardShapes::MakeHexahedron(std::vector<aiVector3D>& positions,
- bool polygons /*= false*/)
-{
- positions.reserve(positions.size()+36);
- const ai_real length = ai_real(1.0)/ai_real(1.73205080);
-
- const aiVector3D v0 = aiVector3D(-1.0,-1.0,-1.0)*length;
- const aiVector3D v1 = aiVector3D(1.0,-1.0,-1.0)*length;
- const aiVector3D v2 = aiVector3D(1.0,1.0,-1.0)*length;
- const aiVector3D v3 = aiVector3D(-1.0,1.0,-1.0)*length;
- const aiVector3D v4 = aiVector3D(-1.0,-1.0,1.0)*length;
- const aiVector3D v5 = aiVector3D(1.0,-1.0,1.0)*length;
- const aiVector3D v6 = aiVector3D(1.0,1.0,1.0)*length;
- const aiVector3D v7 = aiVector3D(-1.0,1.0,1.0)*length;
-
- ADD_QUAD(v0,v3,v2,v1);
- ADD_QUAD(v0,v1,v5,v4);
- ADD_QUAD(v0,v4,v7,v3);
- ADD_QUAD(v6,v5,v1,v2);
- ADD_QUAD(v6,v2,v3,v7);
- ADD_QUAD(v6,v7,v4,v5);
- return (polygons ? 4 : 3);
-}
-
-// Cleanup ...
-#undef ADD_TRIANGLE
-#undef ADD_QUAD
-#undef ADD_PENTAGON
-
-// ------------------------------------------------------------------------------------------------
-// Create a subdivision sphere
-void StandardShapes::MakeSphere(unsigned int tess,
- std::vector<aiVector3D>& positions)
-{
- // Reserve enough storage. Every subdivision
- // splits each triangle in 4, the icosahedron consists of 60 verts
- positions.reserve(positions.size()+60 * integer_pow(4, tess));
-
- // Construct an icosahedron to start with
- MakeIcosahedron(positions);
-
- // ... and subdivide it until the requested output
- // tesselation is reached
- for (unsigned int i = 0; i<tess;++i)
- Subdivide(positions);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a cone
-void StandardShapes::MakeCone(ai_real height,ai_real radius1,
- ai_real radius2,unsigned int tess,
- std::vector<aiVector3D>& positions,bool bOpen /*= false */)
-{
- // Sorry, a cone with less than 3 segments makes ABSOLUTELY NO SENSE
- if (tess < 3 || !height)
- return;
-
- size_t old = positions.size();
-
- // No negative radii
- radius1 = std::fabs(radius1);
- radius2 = std::fabs(radius2);
-
- ai_real halfHeight = height / ai_real(2.0);
-
- // radius1 is always the smaller one
- if (radius2 > radius1)
- {
- std::swap(radius2,radius1);
- halfHeight = -halfHeight;
- }
- else old = SIZE_MAX;
-
- // Use a large epsilon to check whether the cone is pointy
- if (radius1 < (radius2-radius1)*10e-3)radius1 = 0.0;
-
- // We will need 3*2 verts per segment + 3*2 verts per segment
- // if the cone is closed
- const unsigned int mem = tess*6 + (!bOpen ? tess*3 * (radius1 ? 2 : 1) : 0);
- positions.reserve(positions.size () + mem);
-
- // Now construct all segments
- const ai_real angle_delta = (ai_real)AI_MATH_TWO_PI / tess;
- const ai_real angle_max = (ai_real)AI_MATH_TWO_PI;
-
- ai_real s = 1.0; // std::cos(angle == 0);
- ai_real t = 0.0; // std::sin(angle == 0);
-
- for (ai_real angle = 0.0; angle < angle_max; )
- {
- const aiVector3D v1 = aiVector3D (s * radius1, -halfHeight, t * radius1 );
- const aiVector3D v2 = aiVector3D (s * radius2, halfHeight, t * radius2 );
-
- const ai_real next = angle + angle_delta;
- ai_real s2 = std::cos(next);
- ai_real t2 = std::sin(next);
-
- const aiVector3D v3 = aiVector3D (s2 * radius2, halfHeight, t2 * radius2 );
- const aiVector3D v4 = aiVector3D (s2 * radius1, -halfHeight, t2 * radius1 );
-
- positions.push_back(v1);
- positions.push_back(v2);
- positions.push_back(v3);
- positions.push_back(v4);
- positions.push_back(v1);
- positions.push_back(v3);
-
- if (!bOpen)
- {
- // generate the end 'cap'
- positions.push_back(aiVector3D(s * radius2, halfHeight, t * radius2 ));
- positions.push_back(aiVector3D(s2 * radius2, halfHeight, t2 * radius2 ));
- positions.push_back(aiVector3D(0.0, halfHeight, 0.0));
-
-
- if (radius1)
- {
- // generate the other end 'cap'
- positions.push_back(aiVector3D(s * radius1, -halfHeight, t * radius1 ));
- positions.push_back(aiVector3D(s2 * radius1, -halfHeight, t2 * radius1 ));
- positions.push_back(aiVector3D(0.0, -halfHeight, 0.0));
-
- }
- }
- s = s2;
- t = t2;
- angle = next;
- }
-
- // Need to flip face order?
- if ( SIZE_MAX != old ) {
- for (size_t s = old; s < positions.size();s += 3) {
- std::swap(positions[s],positions[s+1]);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a circle
-void StandardShapes::MakeCircle(ai_real radius, unsigned int tess,
- std::vector<aiVector3D>& positions)
-{
- // Sorry, a circle with less than 3 segments makes ABSOLUTELY NO SENSE
- if (tess < 3 || !radius)
- return;
-
- radius = std::fabs(radius);
-
- // We will need 3 vertices per segment
- positions.reserve(positions.size()+tess*3);
-
- const ai_real angle_delta = (ai_real)AI_MATH_TWO_PI / tess;
- const ai_real angle_max = (ai_real)AI_MATH_TWO_PI;
-
- ai_real s = 1.0; // std::cos(angle == 0);
- ai_real t = 0.0; // std::sin(angle == 0);
-
- for (ai_real angle = 0.0; angle < angle_max; )
- {
- positions.push_back(aiVector3D(s * radius,0.0,t * radius));
- angle += angle_delta;
- s = std::cos(angle);
- t = std::sin(angle);
- positions.push_back(aiVector3D(s * radius,0.0,t * radius));
-
- positions.push_back(aiVector3D(0.0,0.0,0.0));
- }
-}
-
-} // ! Assimp
diff --git a/src/3rdparty/assimp/code/StandardShapes.h b/src/3rdparty/assimp/code/StandardShapes.h
deleted file mode 100644
index a31de566c..000000000
--- a/src/3rdparty/assimp/code/StandardShapes.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Declares a helper class, "StandardShapes" which generates
- * vertices for standard shapes, such as cylnders, cones, spheres ..
- */
-#ifndef AI_STANDARD_SHAPES_H_INC
-#define AI_STANDARD_SHAPES_H_INC
-
-#include <assimp/vector3.h>
-#include <vector>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper class to generate vertex buffers for standard geometric
- * shapes, such as cylinders, cones, boxes, spheres, elipsoids ... .
- */
-class StandardShapes
-{
- // class cannot be instanced
- StandardShapes() {}
-
-public:
-
-
- // ----------------------------------------------------------------
- /** Generates a mesh from an array of vertex positions.
- *
- * @param positions List of vertex positions
- * @param numIndices Number of indices per primitive
- * @return Output mesh
- */
- static aiMesh* MakeMesh(const std::vector<aiVector3D>& positions,
- unsigned int numIndices);
-
-
- static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
- (std::vector<aiVector3D>&));
-
- static aiMesh* MakeMesh ( unsigned int (*GenerateFunc)
- (std::vector<aiVector3D>&, bool));
-
- static aiMesh* MakeMesh ( unsigned int n, void (*GenerateFunc)
- (unsigned int,std::vector<aiVector3D>&));
-
- // ----------------------------------------------------------------
- /** @brief Generates a hexahedron (cube)
- *
- * Hexahedrons can be scaled on all axes.
- * @param positions Receives output triangles.
- * @param polygons If you pass true here quads will be returned
- * @return Number of vertices per face
- */
- static unsigned int MakeHexahedron(
- std::vector<aiVector3D>& positions,
- bool polygons = false);
-
- // ----------------------------------------------------------------
- /** @brief Generates an icosahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeIcosahedron(
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a dodecahedron
- *
- * @param positions Receives output triangles
- * @param polygons If you pass true here pentagons will be returned
- * @return Number of vertices per face
- */
- static unsigned int MakeDodecahedron(
- std::vector<aiVector3D>& positions,
- bool polygons = false);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates an octahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeOctahedron(
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a tetrahedron
- *
- * @param positions Receives output triangles.
- * @return Number of vertices per face
- */
- static unsigned int MakeTetrahedron(
- std::vector<aiVector3D>& positions);
-
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a sphere
- *
- * @param tess Number of subdivions - 0 generates a octahedron
- * @param positions Receives output triangles.
- */
- static void MakeSphere(unsigned int tess,
- std::vector<aiVector3D>& positions);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a cone or a cylinder, either open or closed.
- *
- * @code
- *
- * |-----| <- radius 1
- *
- * __x__ <- ] ^
- * / \ | height |
- * / \ | Y
- * / \ |
- * / \ |
- * /______x______\ <- ] <- end cap
- *
- * |-------------| <- radius 2
- *
- * @endcode
- *
- * @param height Height of the cone
- * @param radius1 First radius
- * @param radius2 Second radius
- * @param tess Number of triangles.
- * @param bOpened true for an open cone/cylinder. An open shape has
- * no 'end caps'
- * @param positions Receives output triangles
- */
- static void MakeCone(ai_real height,ai_real radius1,
- ai_real radius2,unsigned int tess,
- std::vector<aiVector3D>& positions,bool bOpen= false);
-
-
- // ----------------------------------------------------------------
- /** @brief Generates a flat circle
- *
- * The circle is constructed in the planned formed by the x,z
- * axes of the cartesian coordinate system.
- *
- * @param radius Radius of the circle
- * @param tess Number of segments.
- * @param positions Receives output triangles.
- */
- static void MakeCircle(ai_real radius, unsigned int tess,
- std::vector<aiVector3D>& positions);
-
-};
-} // ! Assimp
-
-#endif // !! AI_STANDARD_SHAPES_H_INC
diff --git a/src/3rdparty/assimp/code/StdOStreamLogStream.h b/src/3rdparty/assimp/code/StdOStreamLogStream.h
deleted file mode 100644
index d9993b246..000000000
--- a/src/3rdparty/assimp/code/StdOStreamLogStream.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 StdOStreamLogStream.h
-* @brief Implementation of StdOStreamLogStream
-*/
-
-#ifndef AI_STROSTREAMLOGSTREAM_H_INC
-#define AI_STROSTREAMLOGSTREAM_H_INC
-
-#include <assimp/LogStream.hpp>
-#include <ostream>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @class StdOStreamLogStream
- * @brief Logs into a std::ostream
- */
-class StdOStreamLogStream : public LogStream {
-public:
- /** @brief Construction from an existing std::ostream
- * @param _ostream Output stream to be used
- */
- explicit StdOStreamLogStream(std::ostream& _ostream);
-
- /** @brief Destructor */
- ~StdOStreamLogStream();
-
- /** @brief Writer */
- void write(const char* message);
-
-private:
- std::ostream& mOstream;
-};
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline StdOStreamLogStream::StdOStreamLogStream(std::ostream& _ostream)
-: mOstream (_ostream){
- // empty
-}
-
-// ---------------------------------------------------------------------------
-// Default constructor
-inline StdOStreamLogStream::~StdOStreamLogStream() {
- // empty
-}
-
-// ---------------------------------------------------------------------------
-// Write method
-inline void StdOStreamLogStream::write(const char* message) {
- mOstream << message;
- mOstream.flush();
-}
-
-// ---------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // guard
diff --git a/src/3rdparty/assimp/code/StepExporter.cpp b/src/3rdparty/assimp/code/StepExporter.cpp
deleted file mode 100644
index acf1b6dad..000000000
--- a/src/3rdparty/assimp/code/StepExporter.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-@author: Richard Steffen, 2015
-----------------------------------------------------------------------
-*/
-
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
-
-#include "StepExporter.h"
-#include "ConvertToLHProcess.h"
-#include "Bitmap.h"
-#include "BaseImporter.h"
-#include "fast_atof.h"
-#include <assimp/SceneCombiner.h>
-#include <iostream>
-#include <ctime>
-#include <set>
-#include <map>
-#include <list>
-#include <memory>
-#include "Exceptional.h"
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/light.h>
-
-//
-#if _MSC_VER > 1500 || (defined __GNUC___)
-# define ASSIMP_STEP_USE_UNORDERED_MULTIMAP
-# else
-# define step_unordered_map map
-# define step_unordered_multimap multimap
-#endif
-
-#ifdef ASSIMP_STEP_USE_UNORDERED_MULTIMAP
-# include <unordered_map>
-# if _MSC_VER > 1600
-# define step_unordered_map unordered_map
-# define step_unordered_multimap unordered_multimap
-# else
-# define step_unordered_map tr1::unordered_map
-# define step_unordered_multimap tr1::unordered_multimap
-# endif
-#endif
-
-typedef std::step_unordered_map<aiVector3D*, int> VectorIndexUMap;
-
-/* Tested with Step viewer v4 from www.ida-step.net */
-
-using namespace Assimp;
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneStep(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
-{
- std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
- std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
-
- // create/copy Properties
- ExportProperties props(*pProperties);
-
- // invoke the exporter
- StepExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
-
- // we're still here - export successfully completed. Write result to the given IOSYstem
- std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
- if(outfile == NULL) {
- throw DeadlyExportError("could not open output .stp 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);
-}
-
-} // end of namespace Assimp
-
-
-namespace {
- // Collect world transformations for each node
- void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
- const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
- trafos[node] = parent * node->mTransformation;
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectTrafos(node->mChildren[i], trafos);
- }
- }
-
- // Generate a flat list of the meshes (by index) assigned to each node
- void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
- for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
- meshes.insert(std::make_pair(node, node->mMeshes[i]));
- }
- for (unsigned int i = 0; i < node->mNumChildren; ++i) {
- CollectMeshes(node->mChildren[i], meshes);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructor for a specific scene to export
-StepExporter::StepExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path,
- const std::string& file, const ExportProperties* pProperties):
- mProperties(pProperties),mIOSystem(pIOSystem),mFile(file), mPath(path),
- mScene(pScene), endstr(";\n") {
- CollectTrafos(pScene->mRootNode, trafos);
- CollectMeshes(pScene->mRootNode, meshes);
-
- // make sure that all formatting happens using the standard, C locale and not the user's current locale
- mOutput.imbue( std::locale("C") );
- mOutput.precision(16);
-
- // start writing
- WriteFile();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Starts writing the contents
-void StepExporter::WriteFile()
-{
- // see http://shodhganga.inflibnet.ac.in:8080/jspui/bitstream/10603/14116/11/11_chapter%203.pdf
- // note, that all realnumber values must be comma separated in x files
- mOutput.setf(std::ios::fixed);
- // precission for double
- // see http://stackoverflow.com/questions/554063/how-do-i-print-a-double-value-with-full-precision-using-cout
- mOutput.precision(16);
-
- // standard color
- aiColor4D fColor;
- fColor.r = 0.8f;
- fColor.g = 0.8f;
- fColor.b = 0.8f;
-
- int ind = 100; // the start index to be used
- int faceEntryLen = 30; // number of entries for a triangle/face
- // prepare unique (count triangles and vertices)
-
- VectorIndexUMap uniqueVerts; // use a map to reduce find complexity to log(n)
- VectorIndexUMap::iterator it;
- int countFace = 0;
-
- for (unsigned int i=0; i<mScene->mNumMeshes; ++i)
- {
- aiMesh* mesh = mScene->mMeshes[i];
- for (unsigned int j=0; j<mesh->mNumFaces; ++j)
- {
- aiFace* face = &(mesh->mFaces[j]);
-
- if (face->mNumIndices == 3) countFace++;
- }
- for (unsigned int j=0; j<mesh->mNumVertices; ++j)
- {
- aiVector3D* v = &(mesh->mVertices[j]);
- it =uniqueVerts.find(v);
- if (it == uniqueVerts.end())
- {
- uniqueVerts[v] = -1; // first mark the vector as not transformed
- }
- }
- }
-
- 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));
-
- // write the header
- mOutput << "ISO-10303-21" << endstr;
- mOutput << "HEADER" << endstr;
- mOutput << "FILE_DESCRIPTION(('STEP AP214'),'1')" << endstr;
- mOutput << "FILE_NAME('" << mFile << ".stp','" << date_str << "',(' '),(' '),'Spatial InterOp 3D',' ',' ')" << endstr;
- mOutput << "FILE_SCHEMA(('automotive_design'))" << endstr;
- mOutput << "ENDSEC" << endstr;
-
- // write the top of data
- mOutput << "DATA" << endstr;
- mOutput << "#1=MECHANICAL_DESIGN_GEOMETRIC_PRESENTATION_REPRESENTATION(' ',(";
- for (int i=0; i<countFace; ++i)
- {
- mOutput << "#" << i*faceEntryLen + ind + 2*uniqueVerts.size();
- if (i!=countFace-1) mOutput << ",";
- }
- mOutput << "),#6)" << endstr;
-
- mOutput << "#2=PRODUCT_DEFINITION_CONTEXT('',#7,'design')" << endstr;
- mOutput << "#3=APPLICATION_PROTOCOL_DEFINITION('INTERNATIONAL STANDARD','automotive_design',1994,#7)" << endstr;
- mOutput << "#4=PRODUCT_CATEGORY_RELATIONSHIP('NONE','NONE',#8,#9)" << endstr;
- mOutput << "#5=SHAPE_DEFINITION_REPRESENTATION(#10,#11)" << endstr;
- mOutput << "#6= (GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#12))GLOBAL_UNIT_ASSIGNED_CONTEXT((#13,#14,#15))REPRESENTATION_CONTEXT('NONE','WORKSPACE'))" << endstr;
- mOutput << "#7=APPLICATION_CONTEXT(' ')" << endstr;
- mOutput << "#8=PRODUCT_CATEGORY('part','NONE')" << endstr;
- mOutput << "#9=PRODUCT_RELATED_PRODUCT_CATEGORY('detail',' ',(#17))" << endstr;
- mOutput << "#10=PRODUCT_DEFINITION_SHAPE('NONE','NONE',#18)" << endstr;
- mOutput << "#11=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('Root',(#16,#19),#6)" << endstr;
- mOutput << "#12=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0E-006),#13,'','')" << endstr;
- mOutput << "#13=(CONVERSION_BASED_UNIT('METRE',#20)LENGTH_UNIT()NAMED_UNIT(#21))" << endstr;
- mOutput << "#14=(NAMED_UNIT(#22)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.))" << endstr;
- mOutput << "#15=(NAMED_UNIT(#22)SOLID_ANGLE_UNIT()SI_UNIT($,.STERADIAN.))" << endstr;
- mOutput << "#16=SHELL_BASED_SURFACE_MODEL('Root',(#29))" << endstr;
- mOutput << "#17=PRODUCT('Root','Root','Root',(#23))" << endstr;
- mOutput << "#18=PRODUCT_DEFINITION('NONE','NONE',#24,#2)" << endstr;
- mOutput << "#19=AXIS2_PLACEMENT_3D('',#25,#26,#27)" << endstr;
- mOutput << "#20=LENGTH_MEASURE_WITH_UNIT(LENGTH_MEASURE(1.0),#28)" << endstr;
- mOutput << "#21=DIMENSIONAL_EXPONENTS(1.0,0.0,0.0,0.0,0.0,0.0,0.0)" << endstr;
- mOutput << "#22=DIMENSIONAL_EXPONENTS(0.0,0.0,0.0,0.0,0.0,0.0,0.0)" << endstr;
- mOutput << "#23=PRODUCT_CONTEXT('',#7,'mechanical')" << endstr;
- mOutput << "#24=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE(' ','NONE',#17,.NOT_KNOWN.)" << endstr;
- mOutput << "#25=CARTESIAN_POINT('',(0.0,0.0,0.0))" << endstr;
- mOutput << "#26=DIRECTION('',(0.0,0.0,1.0))" << endstr;
- mOutput << "#27=DIRECTION('',(1.0,0.0,0.0))" << endstr;
- mOutput << "#28= (NAMED_UNIT(#21)LENGTH_UNIT()SI_UNIT(.MILLI.,.METRE.))" << endstr;
- mOutput << "#29=CLOSED_SHELL('',(";
- for (int i=0; i<countFace; ++i)
- {
- mOutput << "#" << i*faceEntryLen + ind + 2*uniqueVerts.size() + 8;
- if (i!=countFace-1) mOutput << ",";
- }
- mOutput << "))" << endstr;
-
- // write all the unique transformed CARTESIAN and VERTEX
- for (MeshesByNodeMap::const_iterator it2 = meshes.begin(); it2 != meshes.end(); ++it2)
- {
- const aiNode& node = *(*it2).first;
- unsigned int mesh_idx = (*it2).second;
-
- const aiMesh* mesh = mScene->mMeshes[mesh_idx];
- aiMatrix4x4& trafo = trafos[&node];
- for (unsigned int i = 0; i < mesh->mNumVertices; ++i)
- {
- aiVector3D* v = &(mesh->mVertices[i]);
- it = uniqueVerts.find(v);
- if (it->second >=0 ) continue;
- it->second = ind; // this one is new, so set the index (ind)
- aiVector3D vt = trafo * (*v); // transform the coordinate
- mOutput << "#" << it->second << "=CARTESIAN_POINT('',(" << vt.x << "," << vt.y << "," << vt.z << "))" << endstr;
- mOutput << "#" << it->second+1 << "=VERTEX_POINT('',#" << it->second << ")" << endstr;
- ind += 2;
- }
- }
-
- // write the triangles
- for (unsigned int i=0; i<mScene->mNumMeshes; ++i)
- {
- aiMesh* mesh = mScene->mMeshes[i];
- for (unsigned int j=0; j<mesh->mNumFaces; ++j)
- {
- aiFace* face = &(mesh->mFaces[j]);
-
- if (face->mNumIndices != 3) continue;
-
- aiVector3D* v1 = &(mesh->mVertices[face->mIndices[0]]);
- aiVector3D* v2 = &(mesh->mVertices[face->mIndices[1]]);
- aiVector3D* v3 = &(mesh->mVertices[face->mIndices[2]]);
- aiVector3D dv12 = *v2 - *v1;
- aiVector3D dv23 = *v3 - *v2;
- aiVector3D dv31 = *v1 - *v3;
- aiVector3D dv13 = *v3 - *v1;
- dv12.Normalize();
- dv23.Normalize();
- dv31.Normalize();
- dv13.Normalize();
-
- int pid1 = uniqueVerts.find(v1)->second;
- int pid2 = uniqueVerts.find(v2)->second;
- int pid3 = uniqueVerts.find(v3)->second;
-
- // mean vertex color for the face if available
- if (mesh->HasVertexColors(0))
- {
- fColor.r = 0.0;
- fColor.g = 0.0;
- fColor.b = 0.0;
- fColor += mesh->mColors[0][face->mIndices[0]];
- fColor += mesh->mColors[0][face->mIndices[1]];
- fColor += mesh->mColors[0][face->mIndices[2]];
- fColor /= 3.0f;
- }
-
- int sid = ind; // the sub index
- mOutput << "#" << sid << "=STYLED_ITEM('',(#" << sid+1 << "),#" << sid+8 << ")" << endstr; /* the item that must be referenced in #1 */
- /* This is the color information of the Triangle */
- mOutput << "#" << sid+1 << "=PRESENTATION_STYLE_ASSIGNMENT((#" << sid+2 << "))" << endstr;
- mOutput << "#" << sid+2 << "=SURFACE_STYLE_USAGE(.BOTH.,#" << sid+3 << ")" << endstr;
- mOutput << "#" << sid+3 << "=SURFACE_SIDE_STYLE('',(#" << sid+4 << "))" << endstr;
- mOutput << "#" << sid+4 << "=SURFACE_STYLE_FILL_AREA(#" << sid+5 << ")" << endstr;
- mOutput << "#" << sid+5 << "=FILL_AREA_STYLE('',(#" << sid+6 << "))" << endstr;
- mOutput << "#" << sid+6 << "=FILL_AREA_STYLE_COLOUR('',#" << sid+7 << ")" << endstr;
- mOutput << "#" << sid+7 << "=COLOUR_RGB(''," << fColor.r << "," << fColor.g << "," << fColor.b << ")" << endstr;
-
- /* this is the geometry */
- mOutput << "#" << sid+8 << "=FACE_SURFACE('',(#" << sid+13 << "),#" << sid+9<< ",.T.)" << endstr; /* the face that must be referenced in 29 */
-
- /* 2 directions of the plane */
- mOutput << "#" << sid+9 << "=PLANE('',#" << sid+10 << ")" << endstr;
- mOutput << "#" << sid+10 << "=AXIS2_PLACEMENT_3D('',#" << pid1 << ", #" << sid+11 << ",#" << sid+12 << ")" << endstr;
-
- mOutput << "#" << sid+11 << "=DIRECTION('',(" << dv12.x << "," << dv12.y << "," << dv12.z << "))" << endstr;
- mOutput << "#" << sid+12 << "=DIRECTION('',(" << dv13.x << "," << dv13.y << "," << dv13.z << "))" << endstr;
-
- mOutput << "#" << sid+13 << "=FACE_BOUND('',#" << sid+14 << ",.T.)" << endstr;
- mOutput << "#" << sid+14 << "=EDGE_LOOP('',(#" << sid+15 << ",#" << sid+16 << ",#" << sid+17 << "))" << endstr;
-
- /* edge loop */
- mOutput << "#" << sid+15 << "=ORIENTED_EDGE('',*,*,#" << sid+18 << ",.T.)" << endstr;
- mOutput << "#" << sid+16 << "=ORIENTED_EDGE('',*,*,#" << sid+19 << ",.T.)" << endstr;
- mOutput << "#" << sid+17 << "=ORIENTED_EDGE('',*,*,#" << sid+20 << ",.T.)" << endstr;
-
- /* oriented edges */
- mOutput << "#" << sid+18 << "=EDGE_CURVE('',#" << pid1+1 << ",#" << pid2+1 << ",#" << sid+21 << ",.F.)" << endstr;
- mOutput << "#" << sid+19 << "=EDGE_CURVE('',#" << pid2+1 << ",#" << pid3+1 << ",#" << sid+22 << ",.T.)" << endstr;
- mOutput << "#" << sid+20 << "=EDGE_CURVE('',#" << pid3+1 << ",#" << pid1+1 << ",#" << sid+23 << ",.T.)" << endstr;
-
- /* 3 lines and 3 vectors for the lines for the 3 edge curves */
- mOutput << "#" << sid+21 << "=LINE('',#" << pid1 << ",#" << sid+24 << ")" << endstr;
- mOutput << "#" << sid+22 << "=LINE('',#" << pid2 << ",#" << sid+25 << ")" << endstr;
- mOutput << "#" << sid+23 << "=LINE('',#" << pid3 << ",#" << sid+26 << ")" << endstr;
- mOutput << "#" << sid+24 << "=VECTOR('',#" << sid+27 << ",1.0)" << endstr;
- mOutput << "#" << sid+25 << "=VECTOR('',#" << sid+28 << ",1.0)" << endstr;
- mOutput << "#" << sid+26 << "=VECTOR('',#" << sid+29 << ",1.0)" << endstr;
- mOutput << "#" << sid+27 << "=DIRECTION('',(" << dv12.x << "," << dv12.y << "," << dv12.z << "))" << endstr;
- mOutput << "#" << sid+28 << "=DIRECTION('',(" << dv23.x << "," << dv23.y << "," << dv23.z << "))" << endstr;
- mOutput << "#" << sid+29 << "=DIRECTION('',(" << dv31.x << "," << dv31.y << "," << dv31.z << "))" << endstr;
- ind += faceEntryLen; // increase counter
- }
- }
-
- mOutput << "ENDSEC" << endstr; // end of data section
- mOutput << "END-ISO-10303-21" << endstr; // end of file
-}
-
-#endif
-#endif
diff --git a/src/3rdparty/assimp/code/StepExporter.h b/src/3rdparty/assimp/code/StepExporter.h
deleted file mode 100644
index e5cdda7a1..000000000
--- a/src/3rdparty/assimp/code/StepExporter.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-@author: Richard Steffen, 2014
-
-----------------------------------------------------------------------
-*/
-
-/** @file StepExporter.h
- * Declares the exporter class to write a scene to a Collada file
- */
-#ifndef AI_STEPEXPORTER_H_INC
-#define AI_STEPEXPORTER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/matrix4x4.h>
-#include <assimp/Exporter.hpp>
-#include <sstream>
-
-
-struct aiScene;
-struct aiNode;
-
-namespace Assimp
-{
-
-/// Helper class to export a given scene to a StepFile.
-/// Note: an StepFile uses a left hand system. Assimp used a right hand system (OpenGL), therefore we have to transform everything
-class StepExporter
-{
-public:
- /// Constructor for a specific scene to export
- StepExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
-
-protected:
- /// Starts writing the contents
- void WriteFile();
-
-public:
-
- /// Stringstream to write all output into
- std::stringstream mOutput;
-
-protected:
-
- /// hold the properties pointer
- const ExportProperties* mProperties;
-
- /// The IOSystem for output
- IOSystem* mIOSystem;
-
- /// Name of the file (without extension) where the scene will be exported
- std::string mFile;
-
- /// Path of the directory where the scene will be exported
- std::string mPath;
-
- /// The scene to be written
- const aiScene* mScene;
-
- /// current line end string for simple stream insertion
- std::string endstr;
-
- /// accumultated transformations for nodes
- std::map<const aiNode*, aiMatrix4x4> trafos;
-
- /// map to all meshed of nodes
- typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
- MeshesByNodeMap meshes;
-
-};
-
-}
-
-#endif // !! AI_STEPEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/StreamReader.h b/src/3rdparty/assimp/code/StreamReader.h
deleted file mode 100644
index 6220de9a8..000000000
--- a/src/3rdparty/assimp/code/StreamReader.h
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the StreamReader class which reads data from
- * a binary stream with a well-defined endianness.
- */
-
-#ifndef AI_STREAMREADER_H_INCLUDED
-#define AI_STREAMREADER_H_INCLUDED
-
-#include "ByteSwapper.h"
-#include "Exceptional.h"
-#include <memory>
-#include <assimp/IOStream.hpp>
-#include <assimp/Defines.h>
-
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------------
-/** Wrapper class around IOStream to allow for consistent reading of binary data in both
- * little and big endian format. Don't attempt to instance the template directly. Use
- * StreamReaderLE to read from a little-endian stream and StreamReaderBE to read from a
- * BE stream. The class expects that the endianness of any input data is known at
- * compile-time, which should usually be true (#BaseImporter::ConvertToUTF8 implements
- * runtime endianness conversions for text files).
- *
- * XXX switch from unsigned int for size types to size_t? or ptrdiff_t?*/
-// --------------------------------------------------------------------------------------------
-template <bool SwapEndianess = false, bool RuntimeSwitch = false>
-class StreamReader
-{
-public:
- // FIXME: use these data types throughout the whole library,
- // then change them to 64 bit values :-)
-
- typedef int diff;
- typedef unsigned int pos;
-
-public:
- // ---------------------------------------------------------------------
- /** Construction from a given stream with a well-defined endianness.
- *
- * The StreamReader holds a permanent strong reference to the
- * stream, which is released upon destruction.
- * @param stream Input stream. The stream is not restarted if
- * its file pointer is not at 0. Instead, the stream reader
- * reads from the current position to the end of the stream.
- * @param le If @c RuntimeSwitch is true: specifies whether the
- * stream is in little endian byte order. Otherwise the
- * endianness information is contained in the @c SwapEndianess
- * template parameter and this parameter is meaningless. */
- StreamReader(std::shared_ptr<IOStream> stream, bool le = false)
- : stream(stream)
- , le(le)
- {
- ai_assert(stream);
- InternBegin();
- }
-
- // ---------------------------------------------------------------------
- StreamReader(IOStream* stream, bool le = false)
- : stream(std::shared_ptr<IOStream>(stream))
- , le(le)
- {
- ai_assert(stream);
- InternBegin();
- }
-
- // ---------------------------------------------------------------------
- ~StreamReader() {
- delete[] buffer;
- }
-
-public:
-
- // deprecated, use overloaded operator>> instead
-
- // ---------------------------------------------------------------------
- /** Read a float from the stream */
- float GetF4()
- {
- return Get<float>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a double from the stream */
- double GetF8() {
- return Get<double>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 16 bit integer from the stream */
- int16_t GetI2() {
- return Get<int16_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 8 bit integer from the stream */
- int8_t GetI1() {
- return Get<int8_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read an signed 32 bit integer from the stream */
- int32_t GetI4() {
- return Get<int32_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a signed 64 bit integer from the stream */
- int64_t GetI8() {
- return Get<int64_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 16 bit integer from the stream */
- uint16_t GetU2() {
- return Get<uint16_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 8 bit integer from the stream */
- uint8_t GetU1() {
- return Get<uint8_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read an unsigned 32 bit integer from the stream */
- uint32_t GetU4() {
- return Get<uint32_t>();
- }
-
- // ---------------------------------------------------------------------
- /** Read a unsigned 64 bit integer from the stream */
- uint64_t GetU8() {
- return Get<uint64_t>();
- }
-
-public:
- // ---------------------------------------------------------------------
- /** Get the remaining stream size (to the end of the stream) */
- unsigned int GetRemainingSize() const {
- return (unsigned int)(end - current);
- }
-
- // ---------------------------------------------------------------------
- /** Get the remaining stream size (to the current read limit). The
- * return value is the remaining size of the stream if no custom
- * read limit has been set. */
- unsigned int GetRemainingSizeToLimit() const {
- return (unsigned int)(limit - current);
- }
-
- // ---------------------------------------------------------------------
- /** Increase the file pointer (relative seeking) */
- void IncPtr(size_t plus) {
- current += plus;
- if (current > limit) {
- throw DeadlyImportError("End of file or read limit was reached");
- }
- }
-
- // ---------------------------------------------------------------------
- /** Get the current file pointer */
- int8_t* GetPtr() const {
- return current;
- }
-
- // ---------------------------------------------------------------------
- /** Set current file pointer (Get it from #GetPtr). This is if you
- * prefer to do pointer arithmetics on your own or want to copy
- * large chunks of data at once.
- * @param p The new pointer, which is validated against the size
- * limit and buffer boundaries. */
- void SetPtr(int8_t* p) {
- current = p;
- if (current > limit || current < buffer) {
- throw DeadlyImportError("End of file or read limit was reached");
- }
- }
-
- // ---------------------------------------------------------------------
- /** Copy n bytes to an external buffer
- * @param out Destination for copying
- * @param bytes Number of bytes to copy */
- void CopyAndAdvance(void* out, size_t bytes) {
- int8_t* ur = GetPtr();
- SetPtr(ur+bytes); // fire exception if eof
-
- ::memcpy(out,ur,bytes);
- }
-
- // ---------------------------------------------------------------------
- /** Get the current offset from the beginning of the file */
- int GetCurrentPos() const {
- return (unsigned int)(current - buffer);
- }
-
- void SetCurrentPos(size_t pos) {
- SetPtr(buffer + pos);
- }
-
- // ---------------------------------------------------------------------
- /** Setup a temporary read limit
- *
- * @param limit Maximum number of bytes to be read from
- * the beginning of the file. Specifying UINT_MAX
- * resets the limit to the original end of the stream.
- * Returns the previously set limit. */
- unsigned int SetReadLimit(unsigned int _limit) {
- unsigned int prev = GetReadLimit();
- if (UINT_MAX == _limit) {
- limit = end;
- return prev;
- }
-
- limit = buffer + _limit;
- if (limit > end) {
- throw DeadlyImportError("StreamReader: Invalid read limit");
- }
- return prev;
- }
-
- // ---------------------------------------------------------------------
- /** Get the current read limit in bytes. Reading over this limit
- * accidentally raises an exception. */
- unsigned int GetReadLimit() const {
- return (unsigned int)(limit - buffer);
- }
-
- // ---------------------------------------------------------------------
- /** Skip to the read limit in bytes. Reading over this limit
- * accidentally raises an exception. */
- void SkipToReadLimit() {
- current = limit;
- }
-
- // ---------------------------------------------------------------------
- /** overload operator>> and allow chaining of >> ops. */
- template <typename T>
- StreamReader& operator >> (T& f) {
- f = Get<T>();
- return *this;
- }
-
-private:
- // ---------------------------------------------------------------------
- /** Generic read method. ByteSwap::Swap(T*) *must* be defined */
- template <typename T>
- T Get() {
- if ( current + sizeof(T) > limit) {
- throw DeadlyImportError("End of file or stream limit was reached");
- }
-
- T f;
- ::memcpy (&f, current, sizeof(T));
- Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
- current += sizeof(T);
-
- return f;
- }
-
- // ---------------------------------------------------------------------
- void InternBegin() {
- if (!stream) {
- // in case someone wonders: StreamReader is frequently invoked with
- // no prior validation whether the input stream is valid. Since
- // no one bothers changing the error message, this message here
- // is passed down to the caller and 'unable to open file'
- // simply describes best what happened.
- throw DeadlyImportError("StreamReader: Unable to open file");
- }
-
- const size_t s = stream->FileSize() - stream->Tell();
- if (!s) {
- throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
- }
-
- current = buffer = new int8_t[s];
- const size_t read = stream->Read(current,1,s);
- // (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
- ai_assert(read <= s);
- end = limit = &buffer[read];
- }
-
-private:
- std::shared_ptr<IOStream> stream;
- int8_t *buffer, *current, *end, *limit;
- bool le;
-};
-
-// --------------------------------------------------------------------------------------------
-// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
-#ifdef AI_BUILD_BIG_ENDIAN
- typedef StreamReader<true> StreamReaderLE;
- typedef StreamReader<false> StreamReaderBE;
-#else
- typedef StreamReader<true> StreamReaderBE;
- typedef StreamReader<false> StreamReaderLE;
-#endif
-
-// `dynamic` StreamReader. The byte order of the input data is specified in the
-// c'tor. This involves runtime branching and might be a little bit slower.
-typedef StreamReader<true,true> StreamReaderAny;
-
-} // end namespace Assimp
-
-#endif // !! AI_STREAMREADER_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/StreamWriter.h b/src/3rdparty/assimp/code/StreamWriter.h
deleted file mode 100644
index 26873fb5b..000000000
--- a/src/3rdparty/assimp/code/StreamWriter.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the StreamWriter class which writes data to
- * a binary stream with a well-defined endianness. */
-
-#ifndef AI_STREAMWRITER_H_INCLUDED
-#define AI_STREAMWRITER_H_INCLUDED
-
-#include "ByteSwapper.h"
-#include <assimp/IOStream.hpp>
-
-#include <memory>
-#include <vector>
-
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------------
-/** Wrapper class around IOStream to allow for consistent writing of binary data in both
- * little and big endian format. Don't attempt to instance the template directly. Use
- * StreamWriterLE to read from a little-endian stream and StreamWriterBE to read from a
- * BE stream. Alternatively, there is StreamWriterAny if the endianness of the output
- * stream is to be determined at runtime.
- */
-// --------------------------------------------------------------------------------------------
-template <bool SwapEndianess = false, bool RuntimeSwitch = false>
-class StreamWriter
-{
- enum {
- INITIAL_CAPACITY = 1024
- };
-
-public:
-
- // ---------------------------------------------------------------------
- /** Construction from a given stream with a well-defined endianness.
- *
- * The StreamReader holds a permanent strong reference to the
- * stream, which is released upon destruction.
- * @param stream Input stream. The stream is not re-seeked and writing
- continues at the current position of the stream cursor.
- * @param le If @c RuntimeSwitch is true: specifies whether the
- * stream is in little endian byte order. Otherwise the
- * endianness information is defined by the @c SwapEndianess
- * template parameter and this parameter is meaningless. */
- StreamWriter(std::shared_ptr<IOStream> stream, bool le = false)
- : stream(stream)
- , le(le)
- , cursor()
- {
- ai_assert(stream);
- buffer.reserve(INITIAL_CAPACITY);
- }
-
- // ---------------------------------------------------------------------
- StreamWriter(IOStream* stream, bool le = false)
- : stream(std::shared_ptr<IOStream>(stream))
- , le(le)
- , cursor()
- {
- ai_assert(stream);
- buffer.reserve(INITIAL_CAPACITY);
- }
-
- // ---------------------------------------------------------------------
- ~StreamWriter() {
- stream->Write(&buffer[0], 1, buffer.size());
- stream->Flush();
- }
-
-public:
-
- // ---------------------------------------------------------------------
- /** Write a float to the stream */
- void PutF4(float f)
- {
- Put(f);
- }
-
- // ---------------------------------------------------------------------
- /** Write a double to the stream */
- void PutF8(double d) {
- Put(d);
- }
-
- // ---------------------------------------------------------------------
- /** Write a signed 16 bit integer to the stream */
- void PutI2(int16_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write a signed 8 bit integer to the stream */
- void PutI1(int8_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write an signed 32 bit integer to the stream */
- void PutI4(int32_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write a signed 64 bit integer to the stream */
- void PutI8(int64_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write a unsigned 16 bit integer to the stream */
- void PutU2(uint16_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write a unsigned 8 bit integer to the stream */
- void PutU1(uint8_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write an unsigned 32 bit integer to the stream */
- void PutU4(uint32_t n) {
- Put(n);
- }
-
- // ---------------------------------------------------------------------
- /** Write a unsigned 64 bit integer to the stream */
- void PutU8(uint64_t n) {
- Put(n);
- }
-
-public:
-
- // ---------------------------------------------------------------------
- /** overload operator<< and allow chaining of MM ops. */
- template <typename T>
- StreamWriter& operator << (T f) {
- Put(f);
- return *this;
- }
-
- // ---------------------------------------------------------------------
- std::size_t GetCurrentPos() const {
- return cursor;
- }
-
- // ---------------------------------------------------------------------
- void SetCurrentPos(std::size_t new_cursor) {
- cursor = new_cursor;
- }
-
-private:
-
- // ---------------------------------------------------------------------
- /** Generic write method. ByteSwap::Swap(T*) *must* be defined */
- template <typename T>
- void Put(T f) {
- Intern :: Getter<SwapEndianess,T,RuntimeSwitch>() (&f, le);
-
- if (cursor + sizeof(T) >= buffer.size()) {
- buffer.resize(cursor + sizeof(T));
- }
-
- void* dest = &buffer[cursor];
-
- // reinterpret_cast + assignment breaks strict aliasing rules
- // and generally causes trouble on platforms such as ARM that
- // do not silently ignore alignment faults.
- ::memcpy(dest, &f, sizeof(T));
- cursor += sizeof(T);
- }
-
-private:
-
- std::shared_ptr<IOStream> stream;
- bool le;
-
- std::vector<uint8_t> buffer;
- std::size_t cursor;
-};
-
-
-// --------------------------------------------------------------------------------------------
-// `static` StreamWriter. Their byte order is fixed and they might be a little bit faster.
-#ifdef AI_BUILD_BIG_ENDIAN
- typedef StreamWriter<true> StreamWriterLE;
- typedef StreamWriter<false> StreamWriterBE;
-#else
- typedef StreamWriter<true> StreamWriterBE;
- typedef StreamWriter<false> StreamWriterLE;
-#endif
-
-// `dynamic` StreamWriter. The byte order of the input data is specified in the
-// c'tor. This involves runtime branching and might be a little bit slower.
-typedef StreamWriter<true,true> StreamWriterAny;
-
-} // end namespace Assimp
-
-#endif // !! AI_STREAMWriter_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/StringComparison.h b/src/3rdparty/assimp/code/StringComparison.h
deleted file mode 100644
index ed5f4bd6a..000000000
--- a/src/3rdparty/assimp/code/StringComparison.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Definition of platform independent string workers:
-
- ASSIMP_itoa10
- ASSIMP_stricmp
- ASSIMP_strincmp
-
- These functions are not consistently available on all platforms,
- or the provided implementations behave too differently.
-*/
-#ifndef INCLUDED_AI_STRING_WORKERS_H
-#define INCLUDED_AI_STRING_WORKERS_H
-
-#include <assimp/ai_assert.h>
-#include "StringComparison.h"
-
-#include <string.h>
-#include <stdint.h>
-#include <string>
-
-namespace Assimp {
-
-// -------------------------------------------------------------------------------
-/** @brief itoa with a fixed base 10
- * 'itoa' is not consistently available on all platforms so it is quite useful
- * to have a small replacement function here. No need to use a full sprintf()
- * if we just want to print a number ...
- * @param out Output buffer
- * @param max Maximum number of characters to be written, including '\0'.
- * This parameter may not be 0.
- * @param number Number to be written
- * @return Length of the output string, excluding the '\0'
- */
-inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
-{
- ai_assert(NULL != out);
-
- // write the unary minus to indicate we have a negative number
- unsigned int written = 1u;
- if (number < 0 && written < max) {
- *out++ = '-';
- ++written;
- number = -number;
- }
-
- // We begin with the largest number that is not zero.
- int32_t cur = 1000000000; // 2147483648
- bool mustPrint = false;
- while (written < max) {
-
- const unsigned int digit = number / cur;
- if (mustPrint || digit > 0 || 1 == cur) {
- // print all future zeroes from now
- mustPrint = true;
-
- *out++ = '0'+static_cast<char>(digit);
-
- ++written;
- number -= digit*cur;
- if (1 == cur) {
- break;
- }
- }
- cur /= 10;
- }
-
- // append a terminal zero
- *out++ = '\0';
- return written-1;
-}
-
-// -------------------------------------------------------------------------------
-/** @brief itoa with a fixed base 10 (Secure template overload)
- * The compiler should choose this function if he or she is able to determine the
- * size of the array automatically.
- */
-template <size_t length>
-inline unsigned int ASSIMP_itoa10( char(& out)[length], int32_t number)
-{
- return ASSIMP_itoa10(out,length,number);
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to do platform independent string comparison.
- *
- * This is required since stricmp() is not consistently available on
- * all platforms. Some platforms use the '_' prefix, others don't even
- * have such a function.
- *
- * @param s1 First input string
- * @param s2 Second input string
- * @return 0 if the given strings are identical
- */
-inline int ASSIMP_stricmp(const char *s1, const char *s2)
-{
- ai_assert(NULL != s1 && NULL != s2);
-
-#if (defined _MSC_VER)
-
- return ::_stricmp(s1,s2);
-#elif defined( __GNUC__ )
-
- return ::strcasecmp(s1,s2);
-#else
-
- char c1, c2;
- do {
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- }
- while ( c1 && (c1 == c2) );
- return c1 - c2;
-#endif
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Case independent comparison of two std::strings
- *
- * @param a First string
- * @param b Second string
- * @return 0 if a == b
- */
-inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
-{
- int i = (int)b.length()-(int)a.length();
- return (i ? i : ASSIMP_stricmp(a.c_str(),b.c_str()));
-}
-
-// -------------------------------------------------------------------------------
-/** @brief Helper function to do platform independent string comparison.
- *
- * This is required since strincmp() is not consistently available on
- * all platforms. Some platforms use the '_' prefix, others don't even
- * have such a function.
- *
- * @param s1 First input string
- * @param s2 Second input string
- * @param n Macimum number of characters to compare
- * @return 0 if the given strings are identical
- */
-inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n)
-{
- ai_assert(NULL != s1 && NULL != s2);
- if (!n)return 0;
-
-#if (defined _MSC_VER)
-
- return ::_strnicmp(s1,s2,n);
-
-#elif defined( __GNUC__ )
-
- return ::strncasecmp(s1,s2, n);
-
-#else
- char c1, c2;
- unsigned int p = 0;
- do
- {
- if (p++ >= n)return 0;
- c1 = tolower(*s1++);
- c2 = tolower(*s2++);
- }
- while ( c1 && (c1 == c2) );
-
- return c1 - c2;
-#endif
-}
-
-
-// -------------------------------------------------------------------------------
-/** @brief Evaluates an integer power
- *
- * todo: move somewhere where it fits better in than here
- */
-inline unsigned int integer_pow (unsigned int base, unsigned int power)
-{
- unsigned int res = 1;
- for (unsigned int i = 0; i < power;++i)
- res *= base;
-
- return res;
-}
-} // end of namespace
-
-#endif // ! AI_STRINGCOMPARISON_H_INC
diff --git a/src/3rdparty/assimp/code/StringUtils.h b/src/3rdparty/assimp/code/StringUtils.h
deleted file mode 100644
index 64f66e6b9..000000000
--- a/src/3rdparty/assimp/code/StringUtils.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_STRINGUTILS_H
-#define INCLUDED_AI_STRINGUTILS_H
-
-#include <sstream>
-#include <stdarg.h>
-#include <cstdlib>
-
-/// @fn ai_snprintf
-/// @brief The portable version of the function snprintf ( C99 standard ), which works on visual studio compilers 2013 and earlier.
-/// @param outBuf The buffer to write in
-/// @param size The buffer size
-/// @param format The format string
-/// @param ap The additional arguments.
-/// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned.
-#if defined(_MSC_VER) && _MSC_VER < 1900
-
- inline int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
- int count(-1);
- if (0 != size) {
- count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
- }
- if (count == -1) {
- count = _vscprintf(format, ap);
- }
-
- return count;
- }
-
- inline int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
- int count;
- va_list ap;
-
- va_start(ap, format);
- count = c99_ai_vsnprintf(outBuf, size, format, ap);
- va_end(ap);
-
- return count;
- }
-
-#else
-# define ai_snprintf snprintf
-#endif
-
-template <typename T>
-inline
-std::string to_string( T value ) {
- std::ostringstream os;
- os << value;
- return os.str();
-}
-
-inline
-float ai_strtof( const char *begin, const char *end ) {
- if ( nullptr == begin ) {
- return 0.0f;
- }
- float val( 0.0f );
- if ( nullptr == end ) {
- val = static_cast< float >( ::atof( begin ) );
- } else {
- std::string::size_type len( end - begin );
- std::string token( begin, len );
- val = static_cast< float >( ::atof( token.c_str() ) );
- }
-
- return val;
-}
-
-#endif // INCLUDED_AI_STRINGUTILS_H
-
diff --git a/src/3rdparty/assimp/code/Subdivision.cpp b/src/3rdparty/assimp/code/Subdivision.cpp
deleted file mode 100644
index bc5292dbe..000000000
--- a/src/3rdparty/assimp/code/Subdivision.cpp
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "Subdivision.h"
-#include <assimp/SceneCombiner.h>
-#include "SpatialSort.h"
-#include "ProcessHelper.h"
-#include "Vertex.h"
-#include <assimp/ai_assert.h>
-#include <stdio.h>
-
-using namespace Assimp;
-void mydummy() {}
-
-// ------------------------------------------------------------------------------------------------
-/** Subdivider stub class to implement the Catmull-Clarke subdivision algorithm. The
- * implementation is basing on recursive refinement. Directly evaluating the result is also
- * possible and much quicker, but it depends on lengthy matrix lookup tables. */
-// ------------------------------------------------------------------------------------------------
-class CatmullClarkSubdivider : public Subdivider
-{
-public:
- void Subdivide (aiMesh* mesh, aiMesh*& out, unsigned int num, bool discard_input);
- void Subdivide (aiMesh** smesh, size_t nmesh,
- aiMesh** out, unsigned int num, bool discard_input);
-
- // ---------------------------------------------------------------------------
- /** Intermediate description of an edge between two corners of a polygon*/
- // ---------------------------------------------------------------------------
- struct Edge
- {
- Edge()
- : ref(0)
- {}
- Vertex edge_point, midpoint;
- unsigned int ref;
- };
-
- typedef std::vector<unsigned int> UIntVector;
- typedef std::map<uint64_t,Edge> EdgeMap;
-
- // ---------------------------------------------------------------------------
- // Hashing function to derive an index into an #EdgeMap from two given
- // 'unsigned int' vertex coordinates (!!distinct coordinates - same
- // vertex position == same index!!).
- // NOTE - this leads to rare hash collisions if a) sizeof(unsigned int)>4
- // and (id[0]>2^32-1 or id[0]>2^32-1).
- // MAKE_EDGE_HASH() uses temporaries, so INIT_EDGE_HASH() needs to be put
- // at the head of every function which is about to use MAKE_EDGE_HASH().
- // Reason is that the hash is that hash construction needs to hold the
- // invariant id0<id1 to identify an edge - else two hashes would refer
- // to the same edge.
- // ---------------------------------------------------------------------------
-#define MAKE_EDGE_HASH(id0,id1) (eh_tmp0__=id0,eh_tmp1__=id1,\
- (eh_tmp0__<eh_tmp1__?std::swap(eh_tmp0__,eh_tmp1__):mydummy()),(uint64_t)eh_tmp0__^((uint64_t)eh_tmp1__<<32u))
-
-
-#define INIT_EDGE_HASH_TEMPORARIES()\
- unsigned int eh_tmp0__, eh_tmp1__;
-
-private:
- void InternSubdivide (const aiMesh* const * smesh,
- size_t nmesh,aiMesh** out, unsigned int num);
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Construct a subdivider of a specific type
-Subdivider* Subdivider::Create (Algorithm algo)
-{
- switch (algo)
- {
- case CATMULL_CLARKE:
- return new CatmullClarkSubdivider();
- };
-
- ai_assert(false);
- return NULL; // shouldn't happen
-}
-
-// ------------------------------------------------------------------------------------------------
-// Call the Catmull Clark subdivision algorithm for one mesh
-void CatmullClarkSubdivider::Subdivide (
- aiMesh* mesh,
- aiMesh*& out,
- unsigned int num,
- bool discard_input
- )
-{
- ai_assert(mesh != out);
-
- Subdivide(&mesh,1,&out,num,discard_input);
-}
-
-// ------------------------------------------------------------------------------------------------
-// Call the Catmull Clark subdivision algorithm for multiple meshes
-void CatmullClarkSubdivider::Subdivide (
- aiMesh** smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num,
- bool discard_input
- )
-{
- ai_assert( NULL != smesh );
- ai_assert( NULL != out );
-
- // course, both regions may not overlap
- ai_assert(smesh<out || smesh+nmesh>out+nmesh);
- if (!num) {
- // No subdivision at all. Need to copy all the meshes .. argh.
- if (discard_input) {
- for (size_t s = 0; s < nmesh; ++s) {
- out[s] = smesh[s];
- smesh[s] = NULL;
- }
- }
- else {
- for (size_t s = 0; s < nmesh; ++s) {
- SceneCombiner::Copy(out+s,smesh[s]);
- }
- }
- return;
- }
-
- std::vector<aiMesh*> inmeshes;
- std::vector<aiMesh*> outmeshes;
- std::vector<unsigned int> maptbl;
-
- inmeshes.reserve(nmesh);
- outmeshes.reserve(nmesh);
- maptbl.reserve(nmesh);
-
- // Remove pure line and point meshes from the working set to reduce the
- // number of edge cases the subdivider is forced to deal with. Line and
- // point meshes are simply passed through.
- for (size_t s = 0; s < nmesh; ++s) {
- aiMesh* i = smesh[s];
- // FIX - mPrimitiveTypes might not yet be initialized
- if (i->mPrimitiveTypes && (i->mPrimitiveTypes & (aiPrimitiveType_LINE|aiPrimitiveType_POINT))==i->mPrimitiveTypes) {
- DefaultLogger::get()->debug("Catmull-Clark Subdivider: Skipping pure line/point mesh");
-
- if (discard_input) {
- out[s] = i;
- smesh[s] = NULL;
- }
- else {
- SceneCombiner::Copy(out+s,i);
- }
- continue;
- }
-
- outmeshes.push_back(NULL);inmeshes.push_back(i);
- maptbl.push_back(static_cast<unsigned int>(s));
- }
-
- // Do the actual subdivision on the preallocated storage. InternSubdivide
- // *always* assumes that enough storage is available, it does not bother
- // checking any ranges.
- ai_assert(inmeshes.size()==outmeshes.size()&&inmeshes.size()==maptbl.size());
- if (inmeshes.empty()) {
- DefaultLogger::get()->warn("Catmull-Clark Subdivider: Pure point/line scene, I can't do anything");
- return;
- }
- InternSubdivide(&inmeshes.front(),inmeshes.size(),&outmeshes.front(),num);
- for (unsigned int i = 0; i < maptbl.size(); ++i) {
- ai_assert(outmeshes[i]);
- out[maptbl[i]] = outmeshes[i];
- }
-
- if (discard_input) {
- for (size_t s = 0; s < nmesh; ++s) {
- delete smesh[s];
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Note - this is an implementation of the standard (recursive) Cm-Cl algorithm without further
-// optimizations (except we're using some nice LUTs). A description of the algorithm can be found
-// here: http://en.wikipedia.org/wiki/Catmull-Clark_subdivision_surface
-//
-// The code is mostly O(n), however parts are O(nlogn) which is therefore the algorithm's
-// expected total runtime complexity. The implementation is able to work in-place on the same
-// mesh arrays. Calling #InternSubdivide() directly is not encouraged. The code can operate
-// in-place unless 'smesh' and 'out' are equal (no strange overlaps or reorderings).
-// Previous data is replaced/deleted then.
-// ------------------------------------------------------------------------------------------------
-void CatmullClarkSubdivider::InternSubdivide (
- const aiMesh* const * smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num
- )
-{
- ai_assert(NULL != smesh && NULL != out);
- INIT_EDGE_HASH_TEMPORARIES();
-
- // no subdivision requested or end of recursive refinement
- if (!num) {
- return;
- }
-
- UIntVector maptbl;
- SpatialSort spatial;
-
- // ---------------------------------------------------------------------
- // 0. Offset table to index all meshes continuously, generate a spatially
- // sorted representation of all vertices in all meshes.
- // ---------------------------------------------------------------------
- typedef std::pair<unsigned int,unsigned int> IntPair;
- std::vector<IntPair> moffsets(nmesh);
- unsigned int totfaces = 0, totvert = 0;
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
-
- spatial.Append(mesh->mVertices,mesh->mNumVertices,sizeof(aiVector3D),false);
- moffsets[t] = IntPair(totfaces,totvert);
-
- totfaces += mesh->mNumFaces;
- totvert += mesh->mNumVertices;
- }
-
- spatial.Finalize();
- const unsigned int num_unique = spatial.GenerateMappingTable(maptbl,ComputePositionEpsilon(smesh,nmesh));
-
-
-#define FLATTEN_VERTEX_IDX(mesh_idx, vert_idx) (moffsets[mesh_idx].second+vert_idx)
-#define FLATTEN_FACE_IDX(mesh_idx, face_idx) (moffsets[mesh_idx].first+face_idx)
-
- // ---------------------------------------------------------------------
- // 1. Compute the centroid point for all faces
- // ---------------------------------------------------------------------
- std::vector<Vertex> centroids(totfaces);
- unsigned int nfacesout = 0;
- for (size_t t = 0, n = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
- for (unsigned int i = 0; i < mesh->mNumFaces;++i,++n)
- {
- const aiFace& face = mesh->mFaces[i];
- Vertex& c = centroids[n];
-
- for (unsigned int a = 0; a < face.mNumIndices;++a) {
- c += Vertex(mesh,face.mIndices[a]);
- }
-
- c /= static_cast<float>(face.mNumIndices);
- nfacesout += face.mNumIndices;
- }
- }
-
- {
- // we want edges to go away before the recursive calls so begin a new scope
- EdgeMap edges;
-
- // ---------------------------------------------------------------------
- // 2. Set each edge point to be the average of all neighbouring
- // face points and original points. Every edge exists twice
- // if there is a neighboring face.
- // ---------------------------------------------------------------------
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* mesh = smesh[t];
-
- for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
- const aiFace& face = mesh->mFaces[i];
-
- for (unsigned int p =0; p< face.mNumIndices; ++p) {
- const unsigned int id[] = {
- face.mIndices[p],
- face.mIndices[p==face.mNumIndices-1?0:p+1]
- };
- const unsigned int mp[] = {
- maptbl[FLATTEN_VERTEX_IDX(t,id[0])],
- maptbl[FLATTEN_VERTEX_IDX(t,id[1])]
- };
-
- Edge& e = edges[MAKE_EDGE_HASH(mp[0],mp[1])];
- e.ref++;
- if (e.ref<=2) {
- if (e.ref==1) { // original points (end points) - add only once
- e.edge_point = e.midpoint = Vertex(mesh,id[0])+Vertex(mesh,id[1]);
- e.midpoint *= 0.5f;
- }
- e.edge_point += centroids[FLATTEN_FACE_IDX(t,i)];
- }
- }
- }
- }
-
- // ---------------------------------------------------------------------
- // 3. Normalize edge points
- // ---------------------------------------------------------------------
- {unsigned int bad_cnt = 0;
- for (EdgeMap::iterator it = edges.begin(); it != edges.end(); ++it) {
- if ((*it).second.ref < 2) {
- ai_assert((*it).second.ref);
- ++bad_cnt;
- }
- (*it).second.edge_point *= 1.f/((*it).second.ref+2.f);
- }
-
- if (bad_cnt) {
- // Report the number of bad edges. bad edges are referenced by less than two
- // faces in the mesh. They occur at outer model boundaries in non-closed
- // shapes.
- char tmp[512];
- ai_snprintf(tmp, 512, "Catmull-Clark Subdivider: got %u bad edges touching only one face (totally %u edges). ",
- bad_cnt,static_cast<unsigned int>(edges.size()));
-
- DefaultLogger::get()->debug(tmp);
- }}
-
- // ---------------------------------------------------------------------
- // 4. Compute a vertex-face adjacency table. We can't reuse the code
- // from VertexTriangleAdjacency because we need the table for multiple
- // meshes and out vertex indices need to be mapped to distinct values
- // first.
- // ---------------------------------------------------------------------
- UIntVector faceadjac(nfacesout), cntadjfac(maptbl.size(),0), ofsadjvec(maptbl.size()+1,0); {
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
-
- const aiFace& f = minp->mFaces[i];
- for (unsigned int n = 0; n < f.mNumIndices; ++n) {
- ++cntadjfac[maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]];
- }
- }
- }
- unsigned int cur = 0;
- for (size_t i = 0; i < cntadjfac.size(); ++i) {
- ofsadjvec[i+1] = cur;
- cur += cntadjfac[i];
- }
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- for (unsigned int i = 0; i < minp->mNumFaces; ++i) {
-
- const aiFace& f = minp->mFaces[i];
- for (unsigned int n = 0; n < f.mNumIndices; ++n) {
- faceadjac[ofsadjvec[1+maptbl[FLATTEN_VERTEX_IDX(t,f.mIndices[n])]]++] = FLATTEN_FACE_IDX(t,i);
- }
- }
- }
-
- // check the other way round for consistency
-#ifdef ASSIMP_BUILD_DEBUG
-
- for (size_t t = 0; t < ofsadjvec.size()-1; ++t) {
- for (unsigned int m = 0; m < cntadjfac[t]; ++m) {
- const unsigned int fidx = faceadjac[ofsadjvec[t]+m];
- ai_assert(fidx < totfaces);
- for (size_t n = 1; n < nmesh; ++n) {
-
- if (moffsets[n].first > fidx) {
- const aiMesh* msh = smesh[--n];
- const aiFace& f = msh->mFaces[fidx-moffsets[n].first];
-
- bool haveit = false;
- for (unsigned int i = 0; i < f.mNumIndices; ++i) {
- if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) {
- haveit = true;
- break;
- }
- }
- ai_assert(haveit);
- if (!haveit) {
- DefaultLogger::get()->debug("Catmull-Clark Subdivider: Index not used");
- }
- break;
- }
- }
- }
- }
-
-#endif
- }
-
-#define GET_ADJACENT_FACES_AND_CNT(vidx,fstartout,numout) \
- fstartout = &faceadjac[ofsadjvec[vidx]], numout = cntadjfac[vidx]
-
- typedef std::pair<bool,Vertex> TouchedOVertex;
- std::vector<TouchedOVertex > new_points(num_unique,TouchedOVertex(false,Vertex()));
- // ---------------------------------------------------------------------
- // 5. Spawn a quad from each face point to the corresponding edge points
- // the original points being the fourth quad points.
- // ---------------------------------------------------------------------
- for (size_t t = 0; t < nmesh; ++t) {
- const aiMesh* const minp = smesh[t];
- aiMesh* const mout = out[t] = new aiMesh();
-
- for (unsigned int a = 0; a < minp->mNumFaces; ++a) {
- mout->mNumFaces += minp->mFaces[a].mNumIndices;
- }
-
- // We need random access to the old face buffer, so reuse is not possible.
- mout->mFaces = new aiFace[mout->mNumFaces];
-
- mout->mNumVertices = mout->mNumFaces*4;
- mout->mVertices = new aiVector3D[mout->mNumVertices];
-
- // quads only, keep material index
- mout->mPrimitiveTypes = aiPrimitiveType_POLYGON;
- mout->mMaterialIndex = minp->mMaterialIndex;
-
- if (minp->HasNormals()) {
- mout->mNormals = new aiVector3D[mout->mNumVertices];
- }
-
- if (minp->HasTangentsAndBitangents()) {
- mout->mTangents = new aiVector3D[mout->mNumVertices];
- mout->mBitangents = new aiVector3D[mout->mNumVertices];
- }
-
- for(unsigned int i = 0; minp->HasTextureCoords(i); ++i) {
- mout->mTextureCoords[i] = new aiVector3D[mout->mNumVertices];
- mout->mNumUVComponents[i] = minp->mNumUVComponents[i];
- }
-
- for(unsigned int i = 0; minp->HasVertexColors(i); ++i) {
- mout->mColors[i] = new aiColor4D[mout->mNumVertices];
- }
-
- mout->mNumVertices = mout->mNumFaces<<2u;
- for (unsigned int i = 0, v = 0, n = 0; i < minp->mNumFaces;++i) {
-
- const aiFace& face = minp->mFaces[i];
- for (unsigned int a = 0; a < face.mNumIndices;++a) {
-
- // Get a clean new face.
- aiFace& faceOut = mout->mFaces[n++];
- faceOut.mIndices = new unsigned int [faceOut.mNumIndices = 4];
-
- // Spawn a new quadrilateral (ccw winding) for this original point between:
- // a) face centroid
- centroids[FLATTEN_FACE_IDX(t,i)].SortBack(mout,faceOut.mIndices[0]=v++);
-
- // b) adjacent edge on the left, seen from the centroid
- const Edge& e0 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
- maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a==face.mNumIndices-1?0:a+1])
- ])]; // fixme: replace with mod face.mNumIndices?
-
- // c) adjacent edge on the right, seen from the centroid
- const Edge& e1 = edges[MAKE_EDGE_HASH(maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])],
- maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[!a?face.mNumIndices-1:a-1])
- ])]; // fixme: replace with mod face.mNumIndices?
-
- e0.edge_point.SortBack(mout,faceOut.mIndices[3]=v++);
- e1.edge_point.SortBack(mout,faceOut.mIndices[1]=v++);
-
- // d= original point P with distinct index i
- // F := 0
- // R := 0
- // n := 0
- // for each face f containing i
- // F := F+ centroid of f
- // R := R+ midpoint of edge of f from i to i+1
- // n := n+1
- //
- // (F+2R+(n-3)P)/n
- const unsigned int org = maptbl[FLATTEN_VERTEX_IDX(t,face.mIndices[a])];
- TouchedOVertex& ov = new_points[org];
-
- if (!ov.first) {
- ov.first = true;
-
- const unsigned int* adj; unsigned int cnt;
- GET_ADJACENT_FACES_AND_CNT(org,adj,cnt);
-
- if (cnt < 3) {
- ov.second = Vertex(minp,face.mIndices[a]);
- }
- else {
-
- Vertex F,R;
- for (unsigned int o = 0; o < cnt; ++o) {
- ai_assert(adj[o] < totfaces);
- F += centroids[adj[o]];
-
- // adj[0] is a global face index - search the face in the mesh list
- const aiMesh* mp = NULL;
- size_t nidx;
-
- if (adj[o] < moffsets[0].first) {
- mp = smesh[nidx=0];
- }
- else {
- for (nidx = 1; nidx<= nmesh; ++nidx) {
- if (nidx == nmesh ||moffsets[nidx].first > adj[o]) {
- mp = smesh[--nidx];
- break;
- }
- }
- }
-
- ai_assert(adj[o]-moffsets[nidx].first < mp->mNumFaces);
- const aiFace& f = mp->mFaces[adj[o]-moffsets[nidx].first];
- bool haveit = false;
-
- // find our original point in the face
- for (unsigned int m = 0; m < f.mNumIndices; ++m) {
- if (maptbl[FLATTEN_VERTEX_IDX(nidx,f.mIndices[m])] == org) {
-
- // add *both* edges. this way, we can be sure that we add
- // *all* adjacent edges to R. In a closed shape, every
- // edge is added twice - so we simply leave out the
- // factor 2.f in the amove formula and get the right
- // result.
-
- const Edge& c0 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
- nidx,f.mIndices[!m?f.mNumIndices-1:m-1])])];
- // fixme: replace with mod face.mNumIndices?
-
- const Edge& c1 = edges[MAKE_EDGE_HASH(org,maptbl[FLATTEN_VERTEX_IDX(
- nidx,f.mIndices[m==f.mNumIndices-1?0:m+1])])];
- // fixme: replace with mod face.mNumIndices?
- R += c0.midpoint+c1.midpoint;
-
- haveit = true;
- break;
- }
- }
-
- // this invariant *must* hold if the vertex-to-face adjacency table is valid
- ai_assert(haveit);
- if ( !haveit ) {
- DefaultLogger::get()->warn( "OBJ: no name for material library specified." );
- }
- }
-
- const float div = static_cast<float>(cnt), divsq = 1.f/(div*div);
- ov.second = Vertex(minp,face.mIndices[a])*((div-3.f) / div) + R*divsq + F*divsq;
- }
- }
- ov.second.SortBack(mout,faceOut.mIndices[2]=v++);
- }
- }
- }
- } // end of scope for edges, freeing its memory
-
- // ---------------------------------------------------------------------
- // 7. Apply the next subdivision step.
- // ---------------------------------------------------------------------
- if (num != 1) {
- std::vector<aiMesh*> tmp(nmesh);
- InternSubdivide (out,nmesh,&tmp.front(),num-1);
- for (size_t i = 0; i < nmesh; ++i) {
- delete out[i];
- out[i] = tmp[i];
- }
- }
-}
diff --git a/src/3rdparty/assimp/code/Subdivision.h b/src/3rdparty/assimp/code/Subdivision.h
deleted file mode 100644
index d06bc09d6..000000000
--- a/src/3rdparty/assimp/code/Subdivision.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a helper class to evaluate subdivision surfaces.*/
-#pragma once
-#ifndef AI_SUBDISIVION_H_INC
-#define AI_SUBDISIVION_H_INC
-
-#include <cstddef>
-#include <assimp/types.h>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------
-/** Helper class to evaluate subdivision surfaces. Different algorithms
- * are provided for choice. */
-// ------------------------------------------------------------------------------
-class ASSIMP_API Subdivider {
-public:
-
- /** Enumerates all supported subvidision algorithms */
- enum Algorithm {
- CATMULL_CLARKE = 0x1
- };
-
- virtual ~Subdivider();
-
- // ---------------------------------------------------------------
- /** Create a subdivider of a specific type
- *
- * @param algo Algorithm to be used for subdivision
- * @return Subdivider instance. */
- static Subdivider* Create (Algorithm algo);
-
- // ---------------------------------------------------------------
- /** Subdivide a mesh using the selected algorithm
- *
- * @param mesh First mesh to be subdivided. Must be in verbose
- * format.
- * @param out Receives the output mesh, allocated by me.
- * @param num Number of subdivisions to perform.
- * @param discard_input If true is passed, the input mesh is
- * deleted after the subdivision is complete. This can
- * improve performance because it allows the optimization
- * to reuse the existing mesh for intermediate results.
- * @pre out!=mesh*/
- virtual void Subdivide ( aiMesh* mesh,
- aiMesh*& out, unsigned int num,
- bool discard_input = false) = 0;
-
- // ---------------------------------------------------------------
- /** Subdivide multiple meshes using the selected algorithm. This
- * avoids erroneous smoothing on objects consisting of multiple
- * per-material meshes. Usually, most 3d modellers smooth on a
- * per-object base, regardless the materials assigned to the
- * meshes.
- *
- * @param smesh Array of meshes to be subdivided. Must be in
- * verbose format.
- * @param nmesh Number of meshes in smesh.
- * @param out Receives the output meshes. The array must be
- * sufficiently large (at least @c nmesh elements) and may not
- * overlap the input array. Output meshes map one-to-one to
- * their corresponding input meshes. The meshes are allocated
- * by the function.
- * @param discard_input If true is passed, input meshes are
- * deleted after the subdivision is complete. This can
- * improve performance because it allows the optimization
- * of reusing existing meshes for intermediate results.
- * @param num Number of subdivisions to perform.
- * @pre nmesh != 0, smesh and out may not overlap*/
- virtual void Subdivide (
- aiMesh** smesh,
- size_t nmesh,
- aiMesh** out,
- unsigned int num,
- bool discard_input = false) = 0;
-
-};
-
-inline
-Subdivider::~Subdivider() {
- // empty
-}
-
-} // end namespace Assimp
-
-
-#endif // !! AI_SUBDISIVION_H_INC
-
diff --git a/src/3rdparty/assimp/code/TargetAnimation.cpp b/src/3rdparty/assimp/code/TargetAnimation.cpp
deleted file mode 100644
index ab6b3d12f..000000000
--- a/src/3rdparty/assimp/code/TargetAnimation.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "TargetAnimation.h"
-#include <algorithm>
-#include <assimp/ai_assert.h>
-
-using namespace Assimp;
-
-
-// ------------------------------------------------------------------------------------------------
-KeyIterator::KeyIterator(const std::vector<aiVectorKey>* _objPos,
- const std::vector<aiVectorKey>* _targetObjPos,
- const aiVector3D* defaultObjectPos /*= NULL*/,
- const aiVector3D* defaultTargetPos /*= NULL*/)
-
- : reachedEnd (false)
- , curTime (-1.)
- , objPos (_objPos)
- , targetObjPos (_targetObjPos)
- , nextObjPos (0)
- , nextTargetObjPos(0)
-{
- // Generate default transformation tracks if necessary
- if (!objPos || objPos->empty())
- {
- defaultObjPos.resize(1);
- defaultObjPos.front().mTime = 10e10;
-
- if (defaultObjectPos)
- defaultObjPos.front().mValue = *defaultObjectPos;
-
- objPos = & defaultObjPos;
- }
- if (!targetObjPos || targetObjPos->empty())
- {
- defaultTargetObjPos.resize(1);
- defaultTargetObjPos.front().mTime = 10e10;
-
- if (defaultTargetPos)
- defaultTargetObjPos.front().mValue = *defaultTargetPos;
-
- targetObjPos = & defaultTargetObjPos;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <class T>
-inline T Interpolate(const T& one, const T& two, ai_real val)
-{
- return one + (two-one)*val;
-}
-
-// ------------------------------------------------------------------------------------------------
-void KeyIterator::operator ++()
-{
- // If we are already at the end of all keyframes, return
- if (reachedEnd) {
- return;
- }
-
- // Now search in all arrays for the time value closest
- // to our current position on the time line
- double d0,d1;
-
- d0 = objPos->at ( std::min ( nextObjPos, static_cast<unsigned int>(objPos->size()-1)) ).mTime;
- d1 = targetObjPos->at( std::min ( nextTargetObjPos, static_cast<unsigned int>(targetObjPos->size()-1)) ).mTime;
-
- // Easiest case - all are identical. In this
- // case we don't need to interpolate so we can
- // return earlier
- if ( d0 == d1 )
- {
- curTime = d0;
- curPosition = objPos->at(nextObjPos).mValue;
- curTargetPosition = targetObjPos->at(nextTargetObjPos).mValue;
-
- // increment counters
- if (objPos->size() != nextObjPos-1)
- ++nextObjPos;
-
- if (targetObjPos->size() != nextTargetObjPos-1)
- ++nextTargetObjPos;
- }
-
- // An object position key is closest to us
- else if (d0 < d1)
- {
- curTime = d0;
-
- // interpolate the other
- if (1 == targetObjPos->size() || !nextTargetObjPos) {
- curTargetPosition = targetObjPos->at(0).mValue;
- }
- else
- {
- const aiVectorKey& last = targetObjPos->at(nextTargetObjPos);
- const aiVectorKey& first = targetObjPos->at(nextTargetObjPos-1);
-
- curTargetPosition = Interpolate(first.mValue, last.mValue, (ai_real) (
- (curTime-first.mTime) / (last.mTime-first.mTime) ));
- }
-
- if (objPos->size() != nextObjPos-1)
- ++nextObjPos;
- }
- // A target position key is closest to us
- else
- {
- curTime = d1;
-
- // interpolate the other
- if (1 == objPos->size() || !nextObjPos) {
- curPosition = objPos->at(0).mValue;
- }
- else
- {
- const aiVectorKey& last = objPos->at(nextObjPos);
- const aiVectorKey& first = objPos->at(nextObjPos-1);
-
- curPosition = Interpolate(first.mValue, last.mValue, (ai_real) (
- (curTime-first.mTime) / (last.mTime-first.mTime)));
- }
-
- if (targetObjPos->size() != nextTargetObjPos-1)
- ++nextTargetObjPos;
- }
-
- if (nextObjPos >= objPos->size()-1 &&
- nextTargetObjPos >= targetObjPos->size()-1)
- {
- // We reached the very last keyframe
- reachedEnd = true;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetTargetAnimationChannel (
- const std::vector<aiVectorKey>* _targetPositions)
-{
- ai_assert(NULL != _targetPositions);
- targetPositions = _targetPositions;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetMainAnimationChannel (
- const std::vector<aiVectorKey>* _objectPositions)
-{
- ai_assert(NULL != _objectPositions);
- objectPositions = _objectPositions;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::SetFixedMainAnimationChannel(
- const aiVector3D& fixed)
-{
- objectPositions = NULL; // just to avoid confusion
- fixedMain = fixed;
-}
-
-// ------------------------------------------------------------------------------------------------
-void TargetAnimationHelper::Process(std::vector<aiVectorKey>* distanceTrack)
-{
- ai_assert(NULL != targetPositions && NULL != distanceTrack);
-
- // TODO: in most cases we won't need the extra array
- std::vector<aiVectorKey> real;
-
- std::vector<aiVectorKey>* fill = (distanceTrack == objectPositions ? &real : distanceTrack);
- fill->reserve(std::max( objectPositions->size(), targetPositions->size() ));
-
- // Iterate through all object keys and interpolate their values if necessary.
- // Then get the corresponding target position, compute the difference
- // vector between object and target position. Then compute a rotation matrix
- // that rotates the base vector of the object coordinate system at that time
- // to match the diff vector.
-
- KeyIterator iter(objectPositions,targetPositions,&fixedMain);
- for (;!iter.Finished();++iter)
- {
- const aiVector3D& position = iter.GetCurPosition();
- const aiVector3D& tposition = iter.GetCurTargetPosition();
-
- // diff vector
- aiVector3D diff = tposition - position;
- ai_real f = diff.Length();
-
- // output distance vector
- if (f)
- {
- fill->push_back(aiVectorKey());
- aiVectorKey& v = fill->back();
- v.mTime = iter.GetCurTime();
- v.mValue = diff;
-
- diff /= f;
- }
- else
- {
- // FIXME: handle this
- }
-
- // diff is now the vector in which our camera is pointing
- }
-
- if (real.size()) {
- *distanceTrack = real;
- }
-}
diff --git a/src/3rdparty/assimp/code/TargetAnimation.h b/src/3rdparty/assimp/code/TargetAnimation.h
deleted file mode 100644
index 21b66e591..000000000
--- a/src/3rdparty/assimp/code/TargetAnimation.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a helper class for the ASE and 3DS loaders to
- help them compute camera and spot light animation channels */
-#ifndef AI_TARGET_ANIMATION_H_INC
-#define AI_TARGET_ANIMATION_H_INC
-
-#include <assimp/anim.h>
-#include <vector>
-
-namespace Assimp {
-
-
-
-// ---------------------------------------------------------------------------
-/** Helper class to iterate through all keys in an animation channel.
- *
- * Missing tracks are interpolated. This is a helper class for
- * TargetAnimationHelper, but it can be freely used for other purposes.
-*/
-class KeyIterator
-{
-public:
-
-
- // ------------------------------------------------------------------
- /** Constructs a new key iterator
- *
- * @param _objPos Object position track. May be NULL.
- * @param _targetObjPos Target object position track. May be NULL.
- * @param defaultObjectPos Default object position to be used if
- * no animated track is available. May be NULL.
- * @param defaultTargetPos Default target position to be used if
- * no animated track is available. May be NULL.
- */
- KeyIterator(const std::vector<aiVectorKey>* _objPos,
- const std::vector<aiVectorKey>* _targetObjPos,
- const aiVector3D* defaultObjectPos = NULL,
- const aiVector3D* defaultTargetPos = NULL);
-
- // ------------------------------------------------------------------
- /** Returns true if all keys have been processed
- */
- bool Finished() const
- {return reachedEnd;}
-
- // ------------------------------------------------------------------
- /** Increment the iterator
- */
- void operator++();
- inline void operator++(int)
- {return ++(*this);}
-
-
-
- // ------------------------------------------------------------------
- /** Getters to retrieve the current state of the iterator
- */
- inline const aiVector3D& GetCurPosition() const
- {return curPosition;}
-
- inline const aiVector3D& GetCurTargetPosition() const
- {return curTargetPosition;}
-
- inline double GetCurTime() const
- {return curTime;}
-
-private:
-
- //! Did we reach the end?
- bool reachedEnd;
-
- //! Represents the current position of the iterator
- aiVector3D curPosition, curTargetPosition;
-
- double curTime;
-
- //! Input tracks and the next key to process
- const std::vector<aiVectorKey>* objPos,*targetObjPos;
-
- unsigned int nextObjPos, nextTargetObjPos;
- std::vector<aiVectorKey> defaultObjPos,defaultTargetObjPos;
-};
-
-// ---------------------------------------------------------------------------
-/** Helper class for the 3DS and ASE loaders to compute camera and spot light
- * animations.
- *
- * 3DS and ASE store the differently to Assimp - there is an animation
- * channel for the camera/spot light itself and a separate position
- * animation channels specifying the position of the camera/spot light
- * look-at target */
-class TargetAnimationHelper
-{
-public:
-
- TargetAnimationHelper()
- : targetPositions (NULL)
- , objectPositions (NULL)
- {}
-
-
- // ------------------------------------------------------------------
- /** Sets the target animation channel
- *
- * This channel specifies the position of the camera/spot light
- * target at a specific position.
- *
- * @param targetPositions Translation channel*/
- void SetTargetAnimationChannel (const
- std::vector<aiVectorKey>* targetPositions);
-
-
- // ------------------------------------------------------------------
- /** Sets the main animation channel
- *
- * @param objectPositions Translation channel */
- void SetMainAnimationChannel ( const
- std::vector<aiVectorKey>* objectPositions);
-
- // ------------------------------------------------------------------
- /** Sets the main animation channel to a fixed value
- *
- * @param fixed Fixed value for the main animation channel*/
- void SetFixedMainAnimationChannel(const aiVector3D& fixed);
-
-
- // ------------------------------------------------------------------
- /** Computes final animation channels
- * @param distanceTrack Receive camera translation keys ... != NULL. */
- void Process( std::vector<aiVectorKey>* distanceTrack );
-
-
-private:
-
- const std::vector<aiVectorKey>* targetPositions,*objectPositions;
- aiVector3D fixedMain;
-};
-
-
-} // ! end namespace Assimp
-
-#endif // include guard
diff --git a/src/3rdparty/assimp/code/TerragenLoader.cpp b/src/3rdparty/assimp/code/TerragenLoader.cpp
deleted file mode 100644
index 0126229ac..000000000
--- a/src/3rdparty/assimp/code/TerragenLoader.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the Terragen importer class */
-
-
-
-#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
-
-#include "TerragenLoader.h"
-#include "StreamReader.h"
-#include <assimp/Importer.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Terragen Heightmap Importer",
- "",
- "",
- "http://www.planetside.co.uk/",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "ter"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TerragenImporter::TerragenImporter()
-: configComputeUVs (false)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TerragenImporter::~TerragenImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- // check file extension
- std::string extension = GetExtension(pFile);
-
- if( extension == "ter")
- return true;
-
- if( !extension.length() || checkSig) {
- /* If CanRead() is called in order to check whether we
- * support a specific file extension in general pIOHandler
- * might be NULL and it's our duty to return true here.
- */
- if (!pIOHandler)return true;
- const char* tokens[] = {"terragen"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-const aiImporterDesc* TerragenImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup import properties
-void TerragenImporter::SetupProperties(const Importer* pImp)
-{
- // AI_CONFIG_IMPORT_TER_MAKE_UVS
- configComputeUVs = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,0) );
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void TerragenImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- IOStream* file = pIOHandler->Open( pFile, "rb");
-
- // Check whether we can read from the file
- if( file == NULL)
- throw DeadlyImportError( "Failed to open TERRAGEN TERRAIN file " + pFile + ".");
-
- // Construct a stream reader to read all data in the correct endianness
- StreamReaderLE reader(file);
- if(reader.GetRemainingSize() < 16)
- throw DeadlyImportError( "TER: file is too small" );
-
- // Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
- if (::strncmp((const char*)reader.GetPtr(),AI_TERR_BASE_STRING,8))
- throw DeadlyImportError( "TER: Magic string \'TERRAGEN\' not found" );
-
- if (::strncmp((const char*)reader.GetPtr()+8,AI_TERR_TERRAIN_STRING,8))
- throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
-
- unsigned int x = 0,y = 0,mode = 0;
-
- aiNode* root = pScene->mRootNode = new aiNode();
- root->mName.Set("<TERRAGEN.TERRAIN>");
-
- // Default scaling is 30
- root->mTransformation.a1 = root->mTransformation.b2 = root->mTransformation.c3 = 30.f;
-
- // Now read all chunks until we're finished or an EOF marker is encountered
- reader.IncPtr(16);
- while (reader.GetRemainingSize() >= 4)
- {
- const char* head = (const char*)reader.GetPtr();
- reader.IncPtr(4);
-
- // EOF, break in every case
- if (!::strncmp(head,AI_TERR_EOF_STRING,4))
- break;
-
- // Number of x-data points
- if (!::strncmp(head,AI_TERR_CHUNK_XPTS,4))
- {
- x = (uint16_t)reader.GetI2();
- }
- // Number of y-data points
- else if (!::strncmp(head,AI_TERR_CHUNK_YPTS,4))
- {
- y = (uint16_t)reader.GetI2();
- }
- // Squared terrains width-1.
- else if (!::strncmp(head,AI_TERR_CHUNK_SIZE,4))
- {
- x = y = (uint16_t)reader.GetI2()+1;
- }
- // terrain scaling
- else if (!::strncmp(head,AI_TERR_CHUNK_SCAL,4))
- {
- root->mTransformation.a1 = reader.GetF4();
- root->mTransformation.b2 = reader.GetF4();
- root->mTransformation.c3 = reader.GetF4();
- }
- // mapping == 1: earth radius
- else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
- {
- reader.GetF4();
- }
- // mapping mode
- else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
- {
- mode = reader.GetI1();
- if (0 != mode)
- DefaultLogger::get()->error("TER: Unsupported mapping mode, a flat terrain is returned");
- }
- // actual terrain data
- else if (!::strncmp(head,AI_TERR_CHUNK_ALTW,4))
- {
- float hscale = (float)reader.GetI2() / 65536;
- float bheight = (float)reader.GetI2();
-
- if (!hscale)hscale = 1;
-
- // Ensure we have enough data
- if (reader.GetRemainingSize() < x*y*2)
- throw DeadlyImportError("TER: ALTW chunk is too small");
-
- if (x <= 1 || y <= 1)
- throw DeadlyImportError("TER: Invalid terrain size");
-
- // Allocate the output mesh
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = 1];
- aiMesh* m = pScene->mMeshes[0] = new aiMesh();
-
- // We return quads
- aiFace* f = m->mFaces = new aiFace[m->mNumFaces = (x-1)*(y-1)];
- aiVector3D* pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces*4];
-
- aiVector3D *uv( NULL );
- float step_y( 0.0f ), step_x( 0.0f );
- if (configComputeUVs) {
- uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
- step_y = 1.f/y;
- step_x = 1.f/x;
- }
- const int16_t* data = (const int16_t*)reader.GetPtr();
-
- for (unsigned int yy = 0, t = 0; yy < y-1;++yy) {
- for (unsigned int xx = 0; xx < x-1;++xx,++f) {
-
- // make verts
- const float fy = (float)yy, fx = (float)xx;
- unsigned tmp,tmp2;
- *pv++ = aiVector3D(fx,fy, (float)data[(tmp2=x*yy) + xx] * hscale + bheight);
- *pv++ = aiVector3D(fx,fy+1, (float)data[(tmp=x*(yy+1)) + xx] * hscale + bheight);
- *pv++ = aiVector3D(fx+1,fy+1,(float)data[tmp + xx+1] * hscale + bheight);
- *pv++ = aiVector3D(fx+1,fy, (float)data[tmp2 + xx+1] * hscale + bheight);
-
- // also make texture coordinates, if necessary
- if (configComputeUVs) {
- *uv++ = aiVector3D( step_x*xx, step_y*yy, 0.f );
- *uv++ = aiVector3D( step_x*xx, step_y*(yy+1), 0.f );
- *uv++ = aiVector3D( step_x*(xx+1), step_y*(yy+1), 0.f );
- *uv++ = aiVector3D( step_x*(xx+1), step_y*yy, 0.f );
- }
-
- // make indices
- f->mIndices = new unsigned int[f->mNumIndices = 4];
- for (unsigned int i = 0; i < 4;++i)
- f->mIndices[i] = t++;
- }
- }
-
- // Add the mesh to the root node
- root->mMeshes = new unsigned int[root->mNumMeshes = 1];
- root->mMeshes[0] = 0;
- }
-
- // Get to the next chunk (4 byte aligned)
- unsigned dtt;
- if ((dtt = reader.GetCurrentPos() & 0x3))
- reader.IncPtr(4-dtt);
- }
-
- // Check whether we have a mesh now
- if (pScene->mNumMeshes != 1)
- throw DeadlyImportError("TER: Unable to load terrain");
-
- // Set the AI_SCENE_FLAGS_TERRAIN bit
- pScene->mFlags |= AI_SCENE_FLAGS_TERRAIN;
-}
-
-#endif // !! ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
diff --git a/src/3rdparty/assimp/code/TerragenLoader.h b/src/3rdparty/assimp/code/TerragenLoader.h
deleted file mode 100644
index a95bd6bff..000000000
--- a/src/3rdparty/assimp/code/TerragenLoader.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 TerragenLoader.h
- * @brief Declaration of the .ter importer class.
- */
-#ifndef INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
-#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
-
-#include "BaseImporter.h"
-namespace Assimp {
-
-// Magic strings
-#define AI_TERR_BASE_STRING "TERRAGEN"
-#define AI_TERR_TERRAIN_STRING "TERRAIN "
-#define AI_TERR_EOF_STRING "EOF "
-
-// Chunka
-#define AI_TERR_CHUNK_XPTS "XPTS"
-#define AI_TERR_CHUNK_YPTS "YPTS"
-#define AI_TERR_CHUNK_SIZE "SIZE"
-#define AI_TERR_CHUNK_SCAL "SCAL"
-#define AI_TERR_CHUNK_CRAD "CRAD"
-#define AI_TERR_CHUNK_CRVM "CRVM"
-#define AI_TERR_CHUNK_ALTW "ALTW"
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load Terragen (0.9) terrain files.
- *
- * The loader is basing on the information found here:
- * http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
-*/
-class TerragenImporter : public BaseImporter
-{
-public:
- TerragenImporter();
- ~TerragenImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-private:
-
- bool configComputeUVs;
-
-}; //! class TerragenImporter
-
-} // end of namespace Assimp
-
-#endif // AI_AC3DIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/TextureTransform.cpp b/src/3rdparty/assimp/code/TextureTransform.cpp
deleted file mode 100644
index 30953113e..000000000
--- a/src/3rdparty/assimp/code/TextureTransform.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 A helper class that processes texture transformations */
-
-
-
-#include <assimp/Importer.hpp>
-#include <assimp/postprocess.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/scene.h>
-
-#include "TextureTransform.h"
-#include "StringUtils.h"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TextureTransformStep::TextureTransformStep() :
- configFlags()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TextureTransformStep::~TextureTransformStep()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool TextureTransformStep::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_TransformUVCoords) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup properties
-void TextureTransformStep::SetupProperties(const Importer* pImp)
-{
- configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
-}
-
-// ------------------------------------------------------------------------------------------------
-void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
-{
- /* This function tries to simplify the input UV transformation.
- * That's very important as it allows us to reduce the number
- * of output UV channels. The oder in which the transformations
- * are applied is - as always - scaling, rotation, translation.
- */
-
- char szTemp[512];
- int rounded = 0;
-
-
- /* Optimize the rotation angle. That's slightly difficult as
- * we have an inprecise floating-point number (when comparing
- * UV transformations we'll take that into account by using
- * an epsilon of 5 degrees). If there is a rotation value, we can't
- * perform any further optimizations.
- */
- if (info.mRotation)
- {
- float out = info.mRotation;
- if ((rounded = (int)(info.mRotation / (float)AI_MATH_TWO_PI)))
- {
- out -= rounded*(float)AI_MATH_PI;
-
- ai_snprintf(szTemp, 512, "Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
- DefaultLogger::get()->info(szTemp);
- }
-
- // Next step - convert negative rotation angles to positives
- if (out < 0.f)
- out = (float)AI_MATH_TWO_PI * 2 + out;
-
- info.mRotation = out;
- return;
- }
-
-
- /* Optimize UV translation in the U direction. To determine whether
- * or not we can optimize we need to look at the requested mapping
- * type (e.g. if mirroring is active there IS a difference between
- * offset 2 and 3)
- */
- if ((rounded = (int)info.mTranslation.x)) {
- float out = 0.0f;
- szTemp[0] = 0;
- if (aiTextureMapMode_Wrap == info.mapU) {
- // Wrap - simple take the fraction of the field
- out = info.mTranslation.x-(float)rounded;
- ai_snprintf(szTemp, 512, "[w] UV U offset %f can be simplified to %f", info.mTranslation.x, out);
- }
- else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded) {
- // Mirror
- if (rounded % 2)
- rounded--;
- out = info.mTranslation.x-(float)rounded;
-
- ai_snprintf(szTemp,512,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
- }
- else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU) {
- // Clamp - translations beyond 1,1 are senseless
- ai_snprintf(szTemp,512,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);
-
- out = 1.f;
- }
- if (szTemp[0]) {
- DefaultLogger::get()->info(szTemp);
- info.mTranslation.x = out;
- }
- }
-
- /* Optimize UV translation in the V direction. To determine whether
- * or not we can optimize we need to look at the requested mapping
- * type (e.g. if mirroring is active there IS a difference between
- * offset 2 and 3)
- */
- if ((rounded = (int)info.mTranslation.y)) {
- float out = 0.0f;
- szTemp[0] = 0;
- if (aiTextureMapMode_Wrap == info.mapV) {
- // Wrap - simple take the fraction of the field
- out = info.mTranslation.y-(float)rounded;
- ::ai_snprintf(szTemp,512,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
- }
- else if (aiTextureMapMode_Mirror == info.mapV && 1 != rounded) {
- // Mirror
- if (rounded % 2)
- rounded--;
- out = info.mTranslation.x-(float)rounded;
-
- ::ai_snprintf(szTemp,512,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
- }
- else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV) {
- // Clamp - translations beyond 1,1 are senseless
- ::ai_snprintf(szTemp,512,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);
-
- out = 1.f;
- }
- if (szTemp[0]) {
- DefaultLogger::get()->info(szTemp);
- info.mTranslation.y = out;
- }
- }
- return;
-}
-
-// ------------------------------------------------------------------------------------------------
-void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
-{
- // Don't set if == 0 && wasn't set before
- for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
- const TTUpdateInfo& info = *it;
-
- if (info.directShortcut)
- *info.directShortcut = n;
- else if (!n)
- {
- info.mat->AddProperty<int>((int*)&n,1,AI_MATKEY_UVWSRC(info.semantic,info.index));
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-inline const char* MappingModeToChar(aiTextureMapMode map)
-{
- if (aiTextureMapMode_Wrap == map)
- return "-w";
-
- if (aiTextureMapMode_Mirror == map)
- return "-m";
-
- return "-c";
-}
-
-// ------------------------------------------------------------------------------------------------
-void TextureTransformStep::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("TransformUVCoordsProcess begin");
-
-
- /* We build a per-mesh list of texture transformations we'll need
- * to apply. To achieve this, we iterate through all materials,
- * find all textures and get their transformations and UV indices.
- * Then we search for all meshes using this material.
- */
- typedef std::list<STransformVecInfo> MeshTrafoList;
- std::vector<MeshTrafoList> meshLists(pScene->mNumMeshes);
-
- for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
-
- aiMaterial* mat = pScene->mMaterials[i];
- for (unsigned int a = 0; a < mat->mNumProperties;++a) {
-
- aiMaterialProperty* prop = mat->mProperties[a];
- if (!::strcmp( prop->mKey.data, "$tex.file")) {
- STransformVecInfo info;
-
- // Setup a shortcut structure to allow for a fast updating
- // of the UV index later
- TTUpdateInfo update;
- update.mat = (aiMaterial*) mat;
- update.semantic = prop->mSemantic;
- update.index = prop->mIndex;
-
- // Get textured properties and transform
- for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2) {
- aiMaterialProperty* prop2 = mat->mProperties[a2];
- if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) {
- continue;
- }
-
- if ( !::strcmp( prop2->mKey.data, "$tex.uvwsrc")) {
- info.uvIndex = *((int*)prop2->mData);
-
- // Store a direct pointer for later use
- update.directShortcut = (unsigned int*) prop2->mData;
- }
-
- else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodeu")) {
- info.mapU = *((aiTextureMapMode*)prop2->mData);
- }
- else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodev")) {
- info.mapV = *((aiTextureMapMode*)prop2->mData);
- }
- else if ( !::strcmp( prop2->mKey.data, "$tex.uvtrafo")) {
- // ValidateDS should check this
- ai_assert(prop2->mDataLength >= 20);
- ::memcpy(&info.mTranslation.x,prop2->mData,sizeof(float)*5);
-
- // Directly remove this property from the list
- mat->mNumProperties--;
- for (unsigned int a3 = a2; a3 < mat->mNumProperties;++a3) {
- mat->mProperties[a3] = mat->mProperties[a3+1];
- }
-
- delete prop2;
-
- // Warn: could be an underflow, but this does not invoke undefined behaviour
- --a2;
- }
- }
-
- // Find out which transformations are to be evaluated
- if (!(configFlags & AI_UVTRAFO_ROTATION)) {
- info.mRotation = 0.f;
- }
- if (!(configFlags & AI_UVTRAFO_SCALING)) {
- info.mScaling = aiVector2D(1.f,1.f);
- }
- if (!(configFlags & AI_UVTRAFO_TRANSLATION)) {
- info.mTranslation = aiVector2D(0.f,0.f);
- }
-
- // Do some preprocessing
- PreProcessUVTransform(info);
- info.uvIndex = std::min(info.uvIndex,AI_MAX_NUMBER_OF_TEXTURECOORDS -1u);
-
- // Find out whether this material is used by more than
- // one mesh. This will make our task much, much more difficult!
- unsigned int cnt = 0;
- for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
- if (pScene->mMeshes[n]->mMaterialIndex == i)
- ++cnt;
- }
-
- if (!cnt)
- continue;
- else if (1 != cnt) {
- // This material is referenced by more than one mesh!
- // So we need to make sure the UV index for the texture
- // is identical for each of it ...
- info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
- }
-
- // Get all corresponding meshes
- for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
- aiMesh* mesh = pScene->mMeshes[n];
- if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
- continue;
-
- unsigned int uv = info.uvIndex;
- if (!mesh->mTextureCoords[uv]) {
- // If the requested UV index is not available, take the first one instead.
- uv = 0;
- }
-
- if (mesh->mNumUVComponents[info.uvIndex] >= 3){
- DefaultLogger::get()->warn("UV transformations on 3D mapping channels are not supported");
- continue;
- }
-
- MeshTrafoList::iterator it;
-
- // Check whether we have this transform setup already
- for (it = meshLists[n].begin();it != meshLists[n].end(); ++it) {
-
- if ((*it) == info && (*it).uvIndex == uv) {
- (*it).updateList.push_back(update);
- break;
- }
- }
-
- if (it == meshLists[n].end()) {
- meshLists[n].push_back(info);
- meshLists[n].back().uvIndex = uv;
- meshLists[n].back().updateList.push_back(update);
- }
- }
- }
- }
- }
-
- char buffer[1024]; // should be sufficiently large
- unsigned int outChannels = 0, inChannels = 0, transformedChannels = 0;
-
- // Now process all meshes. Important: we don't remove unreferenced UV channels.
- // This is a job for the RemoveUnreferencedData-Step.
- for (unsigned int q = 0; q < pScene->mNumMeshes;++q) {
-
- aiMesh* mesh = pScene->mMeshes[q];
- MeshTrafoList& trafo = meshLists[q];
-
- inChannels += mesh->GetNumUVChannels();
-
- if (!mesh->mTextureCoords[0] || trafo.empty() || (trafo.size() == 1 && trafo.begin()->IsUntransformed())) {
- outChannels += mesh->GetNumUVChannels();
- continue;
- }
-
- // Move untransformed UV channels to the first position in the list ....
- // except if we need a new locked index which should be as small as possible
- bool veto = false, need = false;
- unsigned int cnt = 0;
- unsigned int untransformed = 0;
-
- MeshTrafoList::iterator it,it2;
- for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
-
- if (!(*it).IsUntransformed()) {
- need = true;
- }
-
- if ((*it).lockedPos == AI_TT_UV_IDX_LOCK_TBD) {
- // Lock this index and make sure it won't be changed
- (*it).lockedPos = cnt;
- veto = true;
- continue;
- }
-
- if (!veto && it != trafo.begin() && (*it).IsUntransformed()) {
- for (it2 = trafo.begin();it2 != it; ++it2) {
- if (!(*it2).IsUntransformed())
- break;
- }
- trafo.insert(it2,*it);
- trafo.erase(it);
- break;
- }
- }
- if (!need)
- continue;
-
- // Find all that are not at their 'locked' position and move them to it.
- // Conflicts are possible but quite unlikely.
- cnt = 0;
- for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
- if ((*it).lockedPos != AI_TT_UV_IDX_LOCK_NONE && (*it).lockedPos != cnt) {
- it2 = trafo.begin();unsigned int t = 0;
- while (t != (*it).lockedPos)
- ++it2;
-
- if ((*it2).lockedPos != AI_TT_UV_IDX_LOCK_NONE) {
- DefaultLogger::get()->error("Channel mismatch, can't compute all transformations properly [design bug]");
- continue;
- }
-
- std::swap(*it2,*it);
- if ((*it).lockedPos == untransformed)
- untransformed = cnt;
- }
- }
-
- // ... and add dummies for all unreferenced channels
- // at the end of the list
- bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
- ref[n] = (!mesh->mTextureCoords[n] ? true : false);
-
- for (it = trafo.begin();it != trafo.end(); ++it)
- ref[(*it).uvIndex] = true;
-
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
- if (ref[n])
- continue;
- trafo.push_back(STransformVecInfo());
- trafo.back().uvIndex = n;
- }
-
- // Then check whether this list breaks the channel limit.
- // The unimportant ones are at the end of the list, so
- // it shouldn't be too worse if we remove them.
- unsigned int size = (unsigned int)trafo.size();
- if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) {
-
- if (!DefaultLogger::isNullLogger()) {
- ::ai_snprintf(buffer,1024,"%u UV channels required but just %u available",
- static_cast<unsigned int>(trafo.size()),AI_MAX_NUMBER_OF_TEXTURECOORDS);
-
- DefaultLogger::get()->error(buffer);
- }
- size = AI_MAX_NUMBER_OF_TEXTURECOORDS;
- }
-
-
- aiVector3D* old[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
- old[n] = mesh->mTextureCoords[n];
-
- // Now continue and generate the output channels. Channels
- // that we're not going to need later can be overridden.
- it = trafo.begin();
- for (unsigned int n = 0; n < trafo.size();++n,++it) {
-
- if (n >= size) {
- // Try to use an untransformed channel for all channels we threw over board
- UpdateUVIndex((*it).updateList,untransformed);
- continue;
- }
-
- outChannels++;
-
- // Write to the log
- if (!DefaultLogger::isNullLogger()) {
- ::ai_snprintf(buffer,1024,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
- q,n,
- (*it).mTranslation.x,
- (*it).mTranslation.y,
- (*it).mScaling.x,
- (*it).mScaling.y,
- AI_RAD_TO_DEG( (*it).mRotation),
- MappingModeToChar ((*it).mapU),
- MappingModeToChar ((*it).mapV));
-
- DefaultLogger::get()->info(buffer);
- }
-
- // Check whether we need a new buffer here
- if (mesh->mTextureCoords[n]) {
-
- it2 = it;++it2;
- for (unsigned int m = n+1; m < size;++m, ++it2) {
-
- if ((*it2).uvIndex == n){
- it2 = trafo.begin();
- break;
- }
- }
- if (it2 == trafo.begin()){
- mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
- }
- }
- else mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
-
- aiVector3D* src = old[(*it).uvIndex];
- aiVector3D* dest, *end;
- dest = mesh->mTextureCoords[n];
-
- ai_assert(NULL != src);
-
- // Copy the data to the destination array
- if (dest != src)
- ::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
-
- end = dest + mesh->mNumVertices;
-
- // Build a transformation matrix and transform all UV coords with it
- if (!(*it).IsUntransformed()) {
- const aiVector2D& trl = (*it).mTranslation;
- const aiVector2D& scl = (*it).mScaling;
-
- // fixme: simplify ..
- ++transformedChannels;
- aiMatrix3x3 matrix;
-
- aiMatrix3x3 m2,m3,m4,m5;
-
- m4.a1 = scl.x;
- m4.b2 = scl.y;
-
- m2.a3 = m2.b3 = 0.5f;
- m3.a3 = m3.b3 = -0.5f;
-
- if ((*it).mRotation > AI_TT_ROTATION_EPSILON )
- aiMatrix3x3::RotationZ((*it).mRotation,matrix);
-
- m5.a3 += trl.x; m5.b3 += trl.y;
- matrix = m2 * m4 * matrix * m3 * m5;
-
- for (src = dest; src != end; ++src) { /* manual homogenious divide */
- src->z = 1.f;
- *src = matrix * *src;
- src->x /= src->z;
- src->y /= src->z;
- src->z = 0.f;
- }
- }
-
- // Update all UV indices
- UpdateUVIndex((*it).updateList,n);
- }
- }
-
- // Print some detailed statistics into the log
- if (!DefaultLogger::isNullLogger()) {
-
- if (transformedChannels) {
- ::ai_snprintf(buffer,1024,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
- outChannels,inChannels,transformedChannels);
-
- DefaultLogger::get()->info(buffer);
- }
- else DefaultLogger::get()->debug("TransformUVCoordsProcess finished");
- }
-}
-
-
diff --git a/src/3rdparty/assimp/code/TextureTransform.h b/src/3rdparty/assimp/code/TextureTransform.h
deleted file mode 100644
index 7f1e4572f..000000000
--- a/src/3rdparty/assimp/code/TextureTransform.h
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Definition of a helper step that processes texture transformations */
-#ifndef AI_TEXTURE_TRANSFORM_H_INCLUDED
-#define AI_TEXTURE_TRANSFORM_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "BaseProcess.h"
-
-#include <assimp/material.h>
-#include <list>
-
-struct aiNode;
-struct aiMaterial;
-
-namespace Assimp {
-
-#define AI_TT_UV_IDX_LOCK_TBD 0xffffffff
-#define AI_TT_UV_IDX_LOCK_NONE 0xeeeeeeee
-
-
-#define AI_TT_ROTATION_EPSILON ((float)AI_DEG_TO_RAD(0.5))
-
-// ---------------------------------------------------------------------------
-/** Small helper structure representing a shortcut into the material list
- * to be able to update some values quickly.
-*/
-struct TTUpdateInfo
-{
- TTUpdateInfo() :
- directShortcut (NULL)
- , mat (NULL)
- , semantic (0)
- , index (0)
- {}
-
- //! Direct shortcut, if available
- unsigned int* directShortcut;
-
- //! Material
- aiMaterial *mat;
-
- //! Texture type and index
- unsigned int semantic, index;
-};
-
-
-// ---------------------------------------------------------------------------
-/** Helper class representing texture coordinate transformations
-*/
-struct STransformVecInfo : public aiUVTransform
-{
-
- STransformVecInfo()
- : uvIndex (0)
- , mapU (aiTextureMapMode_Wrap)
- , mapV (aiTextureMapMode_Wrap)
- , lockedPos (AI_TT_UV_IDX_LOCK_NONE)
- {}
-
- //! Source texture coordinate index
- unsigned int uvIndex;
-
- //! Texture mapping mode in the u, v direction
- aiTextureMapMode mapU,mapV;
-
- //! Locked destination UV index
- //! AI_TT_UV_IDX_LOCK_TBD - to be determined
- //! AI_TT_UV_IDX_LOCK_NONE - none (default)
- unsigned int lockedPos;
-
- //! Update info - shortcuts into all materials
- //! that are referencing this transform setup
- std::list<TTUpdateInfo> updateList;
-
-
- // -------------------------------------------------------------------
- /** Compare two transform setups
- */
- inline bool operator== (const STransformVecInfo& other) const
- {
- // We use a small epsilon here
- const static float epsilon = 0.05f;
-
- if (std::fabs( mTranslation.x - other.mTranslation.x ) > epsilon ||
- std::fabs( mTranslation.y - other.mTranslation.y ) > epsilon)
- {
- return false;
- }
-
- if (std::fabs( mScaling.x - other.mScaling.x ) > epsilon ||
- std::fabs( mScaling.y - other.mScaling.y ) > epsilon)
- {
- return false;
- }
-
- if (std::fabs( mRotation - other.mRotation) > epsilon)
- {
- return false;
- }
- return true;
- }
-
- inline bool operator!= (const STransformVecInfo& other) const
- {
- return !(*this == other);
- }
-
-
- // -------------------------------------------------------------------
- /** Returns whether this is an untransformed texture coordinate set
- */
- inline bool IsUntransformed() const
- {
- return (1.0f == mScaling.x && 1.f == mScaling.y &&
- !mTranslation.x && !mTranslation.y &&
- mRotation < AI_TT_ROTATION_EPSILON);
- }
-
- // -------------------------------------------------------------------
- /** Build a 3x3 matrix from the transformations
- */
- inline void GetMatrix(aiMatrix3x3& mOut)
- {
- mOut = aiMatrix3x3();
-
- if (1.0f != mScaling.x || 1.0f != mScaling.y)
- {
- aiMatrix3x3 mScale;
- mScale.a1 = mScaling.x;
- mScale.b2 = mScaling.y;
- mOut = mScale;
- }
- if (mRotation)
- {
- aiMatrix3x3 mRot;
- mRot.a1 = mRot.b2 = std::cos(mRotation);
- mRot.a2 = mRot.b1 = std::sin(mRotation);
- mRot.a2 = -mRot.a2;
- mOut *= mRot;
- }
- if (mTranslation.x || mTranslation.y)
- {
- aiMatrix3x3 mTrans;
- mTrans.a3 = mTranslation.x;
- mTrans.b3 = mTranslation.y;
- mOut *= mTrans;
- }
- }
-};
-
-
-// ---------------------------------------------------------------------------
-/** Helper step to compute final UV coordinate sets if there are scalings
- * or rotations in the original data read from the file.
-*/
-class TextureTransformStep : public BaseProcess
-{
-public:
-
- TextureTransformStep();
- ~TextureTransformStep();
-
-public:
-
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
- // -------------------------------------------------------------------
- void SetupProperties(const Importer* pImp);
-
-
-protected:
-
-
- // -------------------------------------------------------------------
- /** Preprocess a specific UV transformation setup
- *
- * @param info Transformation setup to be preprocessed.
- */
- void PreProcessUVTransform(STransformVecInfo& info);
-
-private:
-
- unsigned int configFlags;
-};
-
-}
-
-#endif //! AI_TEXTURE_TRANSFORM_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/TinyFormatter.h b/src/3rdparty/assimp/code/TinyFormatter.h
deleted file mode 100644
index 1612282fb..000000000
--- a/src/3rdparty/assimp/code/TinyFormatter.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 TinyFormatter.h
- * @brief Utility to format log messages more easily. Introduced
- * to get rid of the boost::format dependency. Much slinker,
- * basically just extends stringstream.
- */
-#ifndef INCLUDED_TINY_FORMATTER_H
-#define INCLUDED_TINY_FORMATTER_H
-
-#include <sstream>
-
-namespace Assimp {
-namespace Formatter {
-
-// ------------------------------------------------------------------------------------------------
-/** stringstream utility. Usage:
- * @code
- * void writelog(const std::string&s);
- * void writelog(const std::wstring&s);
- * ...
- * writelog(format()<< "hi! this is a number: " << 4);
- * writelog(wformat()<< L"hi! this is a number: " << 4);
- *
- * @endcode */
-template < typename T,
- typename CharTraits = std::char_traits<T>,
- typename Allocator = std::allocator<T>
->
-class basic_formatter
-{
-
-public:
-
- typedef class std::basic_string<
- T,CharTraits,Allocator
- > string;
-
- typedef class std::basic_ostringstream<
- T,CharTraits,Allocator
- > stringstream;
-
-public:
-
- basic_formatter() {}
-
- /* Allow basic_formatter<T>'s to be used almost interchangeably
- * with std::(w)string or const (w)char* arguments because the
- * conversion c'tor is called implicitly. */
- template <typename TT>
- basic_formatter(const TT& sin) {
- 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)
- explicit basic_formatter(const basic_formatter& other) {
- underlying << (string)other;
- }
-#endif
-
-
-public:
-
- operator string () const {
- return underlying.str();
- }
-
-
- /* note - this is declared const because binding temporaries does only
- * work for const references, so many function prototypes will
- * include const basic_formatter<T>& s but might still want to
- * modify the formatted string without the need for a full copy.*/
- template <typename TToken>
- const basic_formatter& operator << (const TToken& s) const {
- underlying << s;
- return *this;
- }
-
- template <typename TToken>
- basic_formatter& operator << (const TToken& s) {
- underlying << s;
- return *this;
- }
-
-
- // comma operator overloaded as well, choose your preferred way.
- template <typename TToken>
- const basic_formatter& operator, (const TToken& s) const {
- underlying << s;
- return *this;
- }
-
- template <typename TToken>
- basic_formatter& operator, (const TToken& s) {
- underlying << s;
- return *this;
- }
-
- // Fix for MSVC8
- // See https://sourceforge.net/projects/assimp/forums/forum/817654/topic/4372824
- template <typename TToken>
- basic_formatter& operator, (TToken& s) {
- underlying << s;
- return *this;
- }
-
-
-private:
- mutable stringstream underlying;
-};
-
-
-typedef basic_formatter< char > format;
-typedef basic_formatter< wchar_t > wformat;
-
-} // ! namespace Formatter
-
-} // ! namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/TriangulateProcess.cpp b/src/3rdparty/assimp/code/TriangulateProcess.cpp
deleted file mode 100644
index e2d77a80f..000000000
--- a/src/3rdparty/assimp/code/TriangulateProcess.cpp
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 TriangulateProcess.cpp
- * @brief Implementation of the post processing step to split up
- * all faces with more than three indices into triangles.
- *
- *
- * The triangulation algorithm will handle concave or convex polygons.
- * Self-intersecting or non-planar polygons are not rejected, but
- * they're probably not triangulated correctly.
- *
- * DEBUG SWITCHES - do not enable any of them in release builds:
- *
- * AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- * - generates vertex colors to represent the face winding order.
- * the first vertex of a polygon becomes red, the last blue.
- * AI_BUILD_TRIANGULATE_DEBUG_POLYS
- * - dump all polygons and their triangulation sequences to
- * a file
- */
-#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
-#include "TriangulateProcess.h"
-#include "ProcessHelper.h"
-#include "PolyTools.h"
-#include <memory>
-
-//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
-//#define AI_BUILD_TRIANGULATE_DEBUG_POLYS
-
-#define POLY_GRID_Y 40
-#define POLY_GRID_X 70
-#define POLY_GRID_XPAD 20
-#define POLY_OUTPUT_FILE "assimp_polygons_debug.txt"
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-TriangulateProcess::TriangulateProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-TriangulateProcess::~TriangulateProcess()
-{
- // nothing to do here
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool TriangulateProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_Triangulate) != 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void TriangulateProcess::Execute( aiScene* pScene)
-{
- DefaultLogger::get()->debug("TriangulateProcess begin");
-
- bool bHas = false;
- for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
- {
- if ( TriangulateMesh( pScene->mMeshes[ a ] ) ) {
- bHas = true;
- }
- }
- if ( bHas ) {
- DefaultLogger::get()->info( "TriangulateProcess finished. All polygons have been triangulated." );
- } else {
- DefaultLogger::get()->debug( "TriangulateProcess finished. There was nothing to be done." );
- }
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Triangulates the given mesh.
-bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
-{
- // Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
- if (!pMesh->mPrimitiveTypes) {
- bool bNeed = false;
-
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- const aiFace& face = pMesh->mFaces[a];
-
- if( face.mNumIndices != 3) {
- bNeed = true;
- }
- }
- if (!bNeed)
- return false;
- }
- else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
- return false;
- }
-
- // Find out how many output faces we'll get
- unsigned int numOut = 0, max_out = 0;
- bool get_normals = true;
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- aiFace& face = pMesh->mFaces[a];
- if (face.mNumIndices <= 4) {
- get_normals = false;
- }
- if( face.mNumIndices <= 3) {
- numOut++;
-
- }
- else {
- numOut += face.mNumIndices-2;
- max_out = std::max(max_out,face.mNumIndices);
- }
- }
-
- // Just another check whether aiMesh::mPrimitiveTypes is correct
- ai_assert(numOut != pMesh->mNumFaces);
-
- aiVector3D* nor_out = NULL;
-
- // if we don't have normals yet, but expect them to be a cheap side
- // product of triangulation anyway, allocate storage for them.
- if (!pMesh->mNormals && get_normals) {
- // XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals
- // nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
- }
-
- // the output mesh will contain triangles, but no polys anymore
- pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
-
- aiFace* out = new aiFace[numOut](), *curOut = out;
- std::vector<aiVector3D> temp_verts3d(max_out+2); /* temporary storage for vertices */
- std::vector<aiVector2D> temp_verts(max_out+2);
-
- // Apply vertex colors to represent the face winding?
-#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- if (!pMesh->mColors[0])
- pMesh->mColors[0] = new aiColor4D[pMesh->mNumVertices];
- else
- new(pMesh->mColors[0]) aiColor4D[pMesh->mNumVertices];
-
- aiColor4D* clr = pMesh->mColors[0];
-#endif
-
-#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
- FILE* fout = fopen(POLY_OUTPUT_FILE,"a");
-#endif
-
- const aiVector3D* verts = pMesh->mVertices;
-
- // use std::unique_ptr to avoid slow std::vector<bool> specialiations
- std::unique_ptr<bool[]> done(new bool[max_out]);
- for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
- aiFace& face = pMesh->mFaces[a];
-
- unsigned int* idx = face.mIndices;
- int num = (int)face.mNumIndices, ear = 0, tmp, prev = num-1, next = 0, max = num;
-
- // Apply vertex colors to represent the face winding?
-#ifdef AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
- for (unsigned int i = 0; i < face.mNumIndices; ++i) {
- aiColor4D& c = clr[idx[i]];
- c.r = (i+1) / (float)max;
- c.b = 1.f - c.r;
- }
-#endif
-
- aiFace* const last_face = curOut;
-
- // if it's a simple point,line or triangle: just copy it
- if( face.mNumIndices <= 3)
- {
- aiFace& nface = *curOut++;
- nface.mNumIndices = face.mNumIndices;
- nface.mIndices = face.mIndices;
-
- face.mIndices = NULL;
- continue;
- }
- // 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 = std::acos(left*diag) + std::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] = 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.
- // Usually everything we're getting is convex and we could easily
- // triangulate by tri-fanning. However, LightWave is probably the only
- // modeling suite to make extensive use of highly concave, monster polygons ...
- // so we need to apply the full 'ear cutting' algorithm to get it right.
-
- // RERQUIREMENT: polygon is expected to be simple and *nearly* planar.
- // We project it onto a plane to get a 2d triangle.
-
- // Collect all vertices of of the polygon.
- for (tmp = 0; tmp < max; ++tmp) {
- temp_verts3d[tmp] = verts[idx[tmp]];
- }
-
- // Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
- aiVector3D n;
- NewellNormal<3,3,3>(n,max,&temp_verts3d.front().x,&temp_verts3d.front().y,&temp_verts3d.front().z);
- if (nor_out) {
- for (tmp = 0; tmp < max; ++tmp)
- nor_out[idx[tmp]] = n;
- }
-
- // Select largest normal coordinate to ignore for projection
- const float ax = (n.x>0 ? n.x : -n.x);
- const float ay = (n.y>0 ? n.y : -n.y);
- const float az = (n.z>0 ? n.z : -n.z);
-
- unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */
- float inv = n.z;
- if (ax > ay) {
- if (ax > az) { /* no x coord. projection to yz */
- ac = 1; bc = 2;
- inv = n.x;
- }
- }
- else if (ay > az) { /* no y coord. projection to zy */
- ac = 2; bc = 0;
- inv = n.y;
- }
-
- // Swap projection axes to take the negated projection vector into account
- if (inv < 0.f) {
- std::swap(ac,bc);
- }
-
- for (tmp =0; tmp < max; ++tmp) {
- temp_verts[tmp].x = verts[idx[tmp]][ac];
- temp_verts[tmp].y = verts[idx[tmp]][bc];
- done[tmp] = false;
- }
-
-#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
- // plot the plane onto which we mapped the polygon to a 2D ASCII pic
- aiVector2D bmin,bmax;
- ArrayBounds(&temp_verts[0],max,bmin,bmax);
-
- char grid[POLY_GRID_Y][POLY_GRID_X+POLY_GRID_XPAD];
- std::fill_n((char*)grid,POLY_GRID_Y*(POLY_GRID_X+POLY_GRID_XPAD),' ');
-
- for (int i =0; i < max; ++i) {
- const aiVector2D& v = (temp_verts[i] - bmin) / (bmax-bmin);
- const size_t x = static_cast<size_t>(v.x*(POLY_GRID_X-1)), y = static_cast<size_t>(v.y*(POLY_GRID_Y-1));
- char* loc = grid[y]+x;
- if (grid[y][x] != ' ') {
- for(;*loc != ' '; ++loc);
- *loc++ = '_';
- }
- *(loc+::ai_snprintf(loc, POLY_GRID_XPAD,"%i",i)) = ' ';
- }
-
-
- for(size_t y = 0; y < POLY_GRID_Y; ++y) {
- grid[y][POLY_GRID_X+POLY_GRID_XPAD-1] = '\0';
- fprintf(fout,"%s\n",grid[y]);
- }
-
- fprintf(fout,"\ntriangulation sequence: ");
-#endif
-
- //
- // FIXME: currently this is the slow O(kn) variant with a worst case
- // complexity of O(n^2) (I think). Can be done in O(n).
- while (num > 3) {
-
- // Find the next ear of the polygon
- int num_found = 0;
- for (ear = next;;prev = ear,ear = next) {
-
- // break after we looped two times without a positive match
- for (next=ear+1;done[(next>=max?next=0:next)];++next);
- if (next < ear) {
- if (++num_found == 2) {
- break;
- }
- }
- const aiVector2D* pnt1 = &temp_verts[ear],
- *pnt0 = &temp_verts[prev],
- *pnt2 = &temp_verts[next];
-
- // Must be a convex point. Assuming ccw winding, it must be on the right of the line between p-1 and p+1.
- if (OnLeftSideOfLine2D(*pnt0,*pnt2,*pnt1)) {
- continue;
- }
-
- // and no other point may be contained in this triangle
- for ( tmp = 0; tmp < max; ++tmp) {
-
- // We need to compare the actual values because it's possible that multiple indexes in
- // the polygon are referring to the same position. concave_polygon.obj is a sample
- //
- // FIXME: Use 'epsiloned' comparisons instead? Due to numeric inaccuracies in
- // PointInTriangle() I'm guessing that it's actually possible to construct
- // input data that would cause us to end up with no ears. The problem is,
- // which epsilon? If we chose a too large value, we'd get wrong results
- const aiVector2D& vtmp = temp_verts[tmp];
- if ( vtmp != *pnt1 && vtmp != *pnt2 && vtmp != *pnt0 && PointInTriangle2D(*pnt0,*pnt1,*pnt2,vtmp)) {
- break;
- }
- }
- if (tmp != max) {
- continue;
- }
-
- // this vertex is an ear
- break;
- }
- if (num_found == 2) {
-
- // Due to the 'two ear theorem', every simple polygon with more than three points must
- // have 2 'ears'. Here's definitely something wrong ... but we don't give up yet.
- //
-
- // Instead we're continuing with the standard tri-fanning algorithm which we'd
- // use if we had only convex polygons. That's life.
- DefaultLogger::get()->error("Failed to triangulate polygon (no ear found). Probably not a simple polygon?");
-
-#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
- fprintf(fout,"critical error here, no ear found! ");
-#endif
- num = 0;
- break;
-
- curOut -= (max-num); /* undo all previous work */
- for (tmp = 0; tmp < max-2; ++tmp) {
- aiFace& nface = *curOut++;
-
- nface.mNumIndices = 3;
- if (!nface.mIndices)
- nface.mIndices = new unsigned int[3];
-
- nface.mIndices[0] = 0;
- nface.mIndices[1] = tmp+1;
- nface.mIndices[2] = tmp+2;
-
- }
- num = 0;
- break;
- }
-
- aiFace& nface = *curOut++;
- nface.mNumIndices = 3;
-
- if (!nface.mIndices) {
- nface.mIndices = new unsigned int[3];
- }
-
- // setup indices for the new triangle ...
- nface.mIndices[0] = prev;
- nface.mIndices[1] = ear;
- nface.mIndices[2] = next;
-
- // exclude the ear from most further processing
- done[ear] = true;
- --num;
- }
- if (num > 0) {
- // We have three indices forming the last 'ear' remaining. Collect them.
- aiFace& nface = *curOut++;
- nface.mNumIndices = 3;
- if (!nface.mIndices) {
- nface.mIndices = new unsigned int[3];
- }
-
- for (tmp = 0; done[tmp]; ++tmp);
- nface.mIndices[0] = tmp;
-
- for (++tmp; done[tmp]; ++tmp);
- nface.mIndices[1] = tmp;
-
- for (++tmp; done[tmp]; ++tmp);
- nface.mIndices[2] = tmp;
-
- }
- }
-
-#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
-
- for(aiFace* f = last_face; f != curOut; ++f) {
- unsigned int* i = f->mIndices;
- fprintf(fout," (%i %i %i)",i[0],i[1],i[2]);
- }
-
- fprintf(fout,"\n*********************************************************************\n");
- fflush(fout);
-
-#endif
-
- for(aiFace* f = last_face; f != curOut; ) {
- unsigned int* i = f->mIndices;
-
- // drop dumb 0-area triangles
- if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
- DefaultLogger::get()->debug("Dropping triangle with area 0");
- --curOut;
-
- delete[] f->mIndices;
- f->mIndices = NULL;
-
- for(aiFace* ff = f; ff != curOut; ++ff) {
- ff->mNumIndices = (ff+1)->mNumIndices;
- ff->mIndices = (ff+1)->mIndices;
- (ff+1)->mIndices = NULL;
- }
- continue;
- }
-
- i[0] = idx[i[0]];
- i[1] = idx[i[1]];
- i[2] = idx[i[2]];
- ++f;
- }
-
- delete[] face.mIndices;
- face.mIndices = NULL;
- }
-
-#ifdef AI_BUILD_TRIANGULATE_DEBUG_POLYS
- fclose(fout);
-#endif
-
- // kill the old faces
- delete [] pMesh->mFaces;
-
- // ... and store the new ones
- pMesh->mFaces = out;
- pMesh->mNumFaces = (unsigned int)(curOut-out); /* not necessarily equal to numOut */
- return true;
-}
-
-#endif // !! ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
diff --git a/src/3rdparty/assimp/code/TriangulateProcess.h b/src/3rdparty/assimp/code/TriangulateProcess.h
deleted file mode 100644
index 6775eca7c..000000000
--- a/src/3rdparty/assimp/code/TriangulateProcess.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a post processing step to triangulate all faces
- with more than three vertices.
- */
-#ifndef AI_TRIANGULATEPROCESS_H_INC
-#define AI_TRIANGULATEPROCESS_H_INC
-
-#include "BaseProcess.h"
-
-struct aiMesh;
-
-class TriangulateProcessTest;
-
-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 ASSIMP_API TriangulateProcess : public BaseProcess
-{
-public:
-
- TriangulateProcess();
- ~TriangulateProcess();
-
-public:
- // -------------------------------------------------------------------
- /** Returns whether the processing step is present in the given flag field.
- * @param pFlags The processing flags the importer was called with. A bitwise
- * combination of #aiPostProcessSteps.
- * @return true if the process is present in this flag fields, false if not.
- */
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Executes the post processing step on the given imported data.
- * At the moment a process is not supposed to fail.
- * @param pScene The imported data to work at.
- */
- void Execute( aiScene* pScene);
-
-public:
- // -------------------------------------------------------------------
- /** Triangulates the given mesh.
- * @param pMesh The mesh to triangulate.
- */
- bool TriangulateMesh( aiMesh* pMesh);
-};
-
-} // end of namespace Assimp
-
-#endif // AI_TRIANGULATEPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/UnrealLoader.cpp b/src/3rdparty/assimp/code/UnrealLoader.cpp
deleted file mode 100644
index a79a2a5c5..000000000
--- a/src/3rdparty/assimp/code/UnrealLoader.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 UnrealLoader.cpp
- * @brief Implementation of the UNREAL (*.3D) importer class
- *
- * Sources:
- * http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
- */
-
-
-
-#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
-
-#include "UnrealLoader.h"
-#include "StreamReader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-#include "ConvertToLHProcess.h"
-
-#include <assimp/Importer.hpp>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-using namespace Assimp;
-
-static const aiImporterDesc desc = {
- "Unreal Mesh Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour,
- 0,
- 0,
- 0,
- 0,
- "3d uc"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-UnrealImporter::UnrealImporter()
-: configFrameID (0)
-, configHandleFlags (true)
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-UnrealImporter::~UnrealImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
-{
- return SimpleExtensionCheck(pFile,"3d","uc");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Build a string of all file extensions supported
-const aiImporterDesc* UnrealImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Setup configuration properties for the loader
-void UnrealImporter::SetupProperties(const Importer* pImp)
-{
- // The
- // AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
- // AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME,-1);
- if(static_cast<unsigned int>(-1) == configFrameID) {
- configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
- }
-
- // AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
- configHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS,1));
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void UnrealImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
- // For any of the 3 files being passed get the three correct paths
- // First of all, determine file extension
- std::string::size_type pos = pFile.find_last_of('.');
- std::string extension = GetExtension(pFile);
-
- std::string d_path,a_path,uc_path;
- if (extension == "3d") {
- // jjjj_d.3d
- // jjjj_a.3d
- pos = pFile.find_last_of('_');
- if (std::string::npos == pos) {
- throw DeadlyImportError("UNREAL: Unexpected naming scheme");
- }
- extension = pFile.substr(0,pos);
- }
- else {
- extension = pFile.substr(0,pos);
- }
-
- // build proper paths
- d_path = extension+"_d.3d";
- a_path = extension+"_a.3d";
- uc_path = extension+".uc";
-
- DefaultLogger::get()->debug("UNREAL: data file is " + d_path);
- DefaultLogger::get()->debug("UNREAL: aniv file is " + a_path);
- DefaultLogger::get()->debug("UNREAL: uc file is " + uc_path);
-
- // and open the files ... we can't live without them
- std::unique_ptr<IOStream> p(pIOHandler->Open(d_path));
- if (!p)
- throw DeadlyImportError("UNREAL: Unable to open _d file");
- StreamReaderLE d_reader(pIOHandler->Open(d_path));
-
- const uint16_t numTris = d_reader.GetI2();
- const uint16_t numVert = d_reader.GetI2();
- d_reader.IncPtr(44);
- if (!numTris || numVert < 3)
- throw DeadlyImportError("UNREAL: Invalid number of vertices/triangles");
-
- // maximum texture index
- unsigned int maxTexIdx = 0;
-
- // collect triangles
- std::vector<Unreal::Triangle> triangles(numTris);
- for (auto & tri : triangles) {
- for (unsigned int i = 0; i < 3;++i) {
-
- tri.mVertex[i] = d_reader.GetI2();
- if (tri.mVertex[i] >= numTris) {
- DefaultLogger::get()->warn("UNREAL: vertex index out of range");
- tri.mVertex[i] = 0;
- }
- }
- tri.mType = d_reader.GetI1();
-
- // handle mesh flagss?
- if (configHandleFlags)
- tri.mType = Unreal::MF_NORMAL_OS;
- else {
- // ignore MOD and MASKED for the moment, treat them as two-sided
- if (tri.mType == Unreal::MF_NORMAL_MOD_TS || tri.mType == Unreal::MF_NORMAL_MASKED_TS)
- tri.mType = Unreal::MF_NORMAL_TS;
- }
- d_reader.IncPtr(1);
-
- for (unsigned int i = 0; i < 3;++i)
- for (unsigned int i2 = 0; i2 < 2;++i2)
- tri.mTex[i][i2] = d_reader.GetI1();
-
- tri.mTextureNum = d_reader.GetI1();
- maxTexIdx = std::max(maxTexIdx,(unsigned int)tri.mTextureNum);
- d_reader.IncPtr(1);
- }
-
- p.reset(pIOHandler->Open(a_path));
- if (!p)
- throw DeadlyImportError("UNREAL: Unable to open _a file");
- StreamReaderLE a_reader(pIOHandler->Open(a_path));
-
- // read number of frames
- const uint32_t numFrames = a_reader.GetI2();
- if (configFrameID >= numFrames)
- throw DeadlyImportError("UNREAL: The requested frame does not exist");
-
- uint32_t st = a_reader.GetI2();
- if (st != numVert*4)
- throw DeadlyImportError("UNREAL: Unexpected aniv file length");
-
- // skip to our frame
- a_reader.IncPtr(configFrameID *numVert*4);
-
- // collect vertices
- std::vector<aiVector3D> vertices(numVert);
- for (auto &vertex : vertices) {
- int32_t val = a_reader.GetI4();
- Unreal::DecompressVertex(vertex ,val);
- }
-
- // list of textures.
- std::vector< std::pair<unsigned int, std::string> > textures;
-
- // allocate the output scene
- aiNode* nd = pScene->mRootNode = new aiNode();
- nd->mName.Set("<UnrealRoot>");
-
- // we can live without the uc file if necessary
- std::unique_ptr<IOStream> pb (pIOHandler->Open(uc_path));
- if (pb.get()) {
-
- std::vector<char> _data;
- TextFileToBuffer(pb.get(),_data);
- const char* data = &_data[0];
-
- std::vector< std::pair< std::string,std::string > > tempTextures;
-
- // do a quick search in the UC file for some known, usually texture-related, tags
- for (;*data;++data) {
- if (TokenMatchI(data,"#exec",5)) {
- SkipSpacesAndLineEnd(&data);
-
- // #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
- if (TokenMatchI(data,"TEXTURE",7)) {
- SkipSpacesAndLineEnd(&data);
-
- if (TokenMatchI(data,"IMPORT",6)) {
- tempTextures.push_back(std::pair< std::string,std::string >());
- std::pair< std::string,std::string >& me = tempTextures.back();
- for (;!IsLineEnd(*data);++data) {
- if (!::ASSIMP_strincmp(data,"NAME=",5)) {
- const char *d = data+=5;
- for (;!IsSpaceOrNewLine(*data);++data);
- me.first = std::string(d,(size_t)(data-d));
- }
- else if (!::ASSIMP_strincmp(data,"FILE=",5)) {
- const char *d = data+=5;
- for (;!IsSpaceOrNewLine(*data);++data);
- me.second = std::string(d,(size_t)(data-d));
- }
- }
- if (!me.first.length() || !me.second.length())
- tempTextures.pop_back();
- }
- }
- // #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
- // #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
- else if (TokenMatchI(data,"MESHMAP",7)) {
- SkipSpacesAndLineEnd(&data);
-
- if (TokenMatchI(data,"SETTEXTURE",10)) {
-
- textures.push_back(std::pair<unsigned int, std::string>());
- std::pair<unsigned int, std::string>& me = textures.back();
-
- for (;!IsLineEnd(*data);++data) {
- if (!::ASSIMP_strincmp(data,"NUM=",4)) {
- data += 4;
- me.first = strtoul10(data,&data);
- }
- else if (!::ASSIMP_strincmp(data,"TEXTURE=",8)) {
- data += 8;
- const char *d = data;
- for (;!IsSpaceOrNewLine(*data);++data);
- me.second = std::string(d,(size_t)(data-d));
-
- // try to find matching path names, doesn't care if we don't find them
- for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
- it != tempTextures.end(); ++it) {
- if ((*it).first == me.second) {
- me.second = (*it).second;
- break;
- }
- }
- }
- }
- }
- else if (TokenMatchI(data,"SCALE",5)) {
-
- for (;!IsLineEnd(*data);++data) {
- if (data[0] == 'X' && data[1] == '=') {
- data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.a1);
- }
- else if (data[0] == 'Y' && data[1] == '=') {
- data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.b2);
- }
- else if (data[0] == 'Z' && data[1] == '=') {
- data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.c3);
- }
- }
- }
- }
- }
- }
- }
- else {
- DefaultLogger::get()->error("Unable to open .uc file");
- }
-
- std::vector<Unreal::TempMat> materials;
- materials.reserve(textures.size()*2+5);
-
- // find out how many output meshes and materials we'll have and build material indices
- for (Unreal::Triangle &tri : triangles) {
- Unreal::TempMat mat(tri);
- std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
- if (nt == materials.end()) {
- // add material
- tri.matIndex = static_cast<unsigned int>(materials.size());
- mat.numFaces = 1;
- materials.push_back(mat);
-
- ++pScene->mNumMeshes;
- }
- else {
- tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
- ++nt->numFaces;
- }
- }
-
- if (!pScene->mNumMeshes) {
- throw DeadlyImportError("UNREAL: Unable to find valid mesh data");
- }
-
- // allocate meshes and bind them to the node graph
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
-
- nd->mNumMeshes = pScene->mNumMeshes;
- nd->mMeshes = new unsigned int[nd->mNumMeshes];
- for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
- aiMesh* m = pScene->mMeshes[i] = new aiMesh();
- m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
-
- const unsigned int num = materials[i].numFaces;
- m->mFaces = new aiFace [num];
- m->mVertices = new aiVector3D [num*3];
- m->mTextureCoords[0] = new aiVector3D [num*3];
-
- nd->mMeshes[i] = i;
-
- // create materials, too
- aiMaterial* mat = new aiMaterial();
- pScene->mMaterials[i] = mat;
-
- // all white by default - texture rulez
- aiColor3D color(1.f,1.f,1.f);
-
- aiString s;
- ::ai_snprintf( s.data, MAXLEN, "mat%u_tx%u_",i,materials[i].tex );
-
- // set the two-sided flag
- if (materials[i].type == Unreal::MF_NORMAL_TS) {
- const int twosided = 1;
- mat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
- ::strcat(s.data,"ts_");
- }
- else ::strcat(s.data,"os_");
-
- // make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
- if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
- const float opac = 0.9f;
- mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
- ::strcat(s.data,"tran_");
- }
- else ::strcat(s.data,"opaq_");
-
- // a special name for the weapon attachment point
- if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
- s.length = ::ai_snprintf( s.data, MAXLEN, "$WeaponTag$" );
- color = aiColor3D(0.f,0.f,0.f);
- }
-
- // set color and name
- mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
- s.length = ::strlen(s.data);
- mat->AddProperty(&s,AI_MATKEY_NAME);
-
- // set texture, if any
- const unsigned int tex = materials[i].tex;
- for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it) {
- if ((*it).first == tex) {
- s.Set((*it).second);
- mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
- break;
- }
- }
- }
-
- // fill them.
- for (const Unreal::Triangle &tri : triangles) {
- Unreal::TempMat mat(tri);
- std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
-
- aiMesh* mesh = pScene->mMeshes[nt-materials.begin()];
- aiFace& f = mesh->mFaces[mesh->mNumFaces++];
- f.mIndices = new unsigned int[f.mNumIndices = 3];
-
- for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
- f.mIndices[i] = mesh->mNumVertices;
-
- mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
- mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
- }
- }
-
- // convert to RH
- MakeLeftHandedProcess hero;
- hero.Execute(pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-}
-
-#endif // !! ASSIMP_BUILD_NO_3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/UnrealLoader.h b/src/3rdparty/assimp/code/UnrealLoader.h
deleted file mode 100644
index a2ceb3d54..000000000
--- a/src/3rdparty/assimp/code/UnrealLoader.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 UnrealLoader.h
- * @brief Declaration of the .3d (UNREAL) importer class.
- */
-#ifndef INCLUDED_AI_3D_LOADER_H
-#define INCLUDED_AI_3D_LOADER_H
-
-#include "BaseImporter.h"
-#include <stdint.h>
-
-namespace Assimp {
-namespace Unreal {
-
- /*
- 0 = Normal one-sided
- 1 = Normal two-sided
- 2 = Translucent two-sided
- 3 = Masked two-sided
- 4 = Modulation blended two-sided
- 8 = Placeholder triangle for weapon positioning (invisible)
- */
-enum MeshFlags {
- MF_NORMAL_OS = 0,
- MF_NORMAL_TS = 1,
- MF_NORMAL_TRANS_TS = 2,
- MF_NORMAL_MASKED_TS = 3,
- MF_NORMAL_MOD_TS = 4,
- MF_WEAPON_PLACEHOLDER = 8
-};
-
- // a single triangle
-struct Triangle {
- uint16_t mVertex[3]; // Vertex indices
- char mType; // James' Mesh Type
- char mColor; // Color for flat and Gourand Shaded
- unsigned char mTex[3][2]; // Texture UV coordinates
- unsigned char mTextureNum; // Source texture offset
- char mFlags; // Unreal Mesh Flags (unused)
-
- unsigned int matIndex;
-};
-
-// temporary representation for a material
-struct TempMat {
- TempMat()
- : type()
- , tex()
- , numFaces (0)
- {}
-
- explicit TempMat(const Triangle& in)
- : type ((Unreal::MeshFlags)in.mType)
- , tex (in.mTextureNum)
- , numFaces (0)
- {}
-
- // type of mesh
- Unreal::MeshFlags type;
-
- // index of texture
- unsigned int tex;
-
- // number of faces using us
- unsigned int numFaces;
-
- // for std::find
- bool operator == (const TempMat& o ) {
- return (tex == o.tex && type == o.type);
- }
-};
-
-struct Vertex
-{
- int32_t X : 11;
- int32_t Y : 11;
- int32_t Z : 10;
-};
-
- // UNREAL vertex compression
-inline void CompressVertex(const aiVector3D& v, uint32_t& out)
-{
- union {
- Vertex n;
- int32_t t;
- };
- n.X = (int32_t)v.x;
- n.Y = (int32_t)v.y;
- n.Z = (int32_t)v.z;
- out = t;
-}
-
- // UNREAL vertex decompression
-inline void DecompressVertex(aiVector3D& v, int32_t in)
-{
- union {
- Vertex n;
- int32_t i;
- };
- i = in;
-
- v.x = (float)n.X;
- v.y = (float)n.Y;
- v.z = (float)n.Z;
-}
-
-} // end namespace Unreal
-
-// ---------------------------------------------------------------------------
-/** @brief Importer class to load UNREAL files (*.3d)
-*/
-class UnrealImporter : public BaseImporter
-{
-public:
- UnrealImporter();
- ~UnrealImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** @brief Returns whether we can handle the format of the given file
- *
- * See BaseImporter::CanRead() for details.
- **/
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** @brief Called by Importer::GetExtensionList()
- *
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
-
- // -------------------------------------------------------------------
- /** @brief Setup properties for the importer
- *
- * See BaseImporter::SetupProperties() for details
- */
- void SetupProperties(const Importer* pImp);
-
-
- // -------------------------------------------------------------------
- /** @brief Imports the given file into the given scene structure.
- *
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
- //! frame to be loaded
- uint32_t configFrameID;
-
- //! process surface flags
- bool configHandleFlags;
-
-}; // !class UnrealImporter
-
-} // end of namespace Assimp
-#endif // AI_UNREALIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/ValidateDataStructure.cpp b/src/3rdparty/assimp/code/ValidateDataStructure.cpp
deleted file mode 100644
index c036eac18..000000000
--- a/src/3rdparty/assimp/code/ValidateDataStructure.cpp
+++ /dev/null
@@ -1,969 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ValidateDataStructure.cpp
- * @brief Implementation of the post processing step to validate
- * the data structure returned by Assimp.
- */
-
-
-
-// internal headers
-#include "ValidateDataStructure.h"
-#include "BaseImporter.h"
-#include "fast_atof.h"
-#include "ProcessHelper.h"
-#include <memory>
-
-// CRT headers
-#include <stdarg.h>
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-ValidateDSProcess::ValidateDSProcess() :
- mScene()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ValidateDSProcess::~ValidateDSProcess()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the processing step is present in the given flag field.
-bool ValidateDSProcess::IsActive( unsigned int pFlags) const
-{
- return (pFlags & aiProcess_ValidateDataStructure) != 0;
-}
-// ------------------------------------------------------------------------------------------------
-AI_WONT_RETURN void ValidateDSProcess::ReportError(const char* msg,...)
-{
- ai_assert(NULL != msg);
-
- va_list args;
- va_start(args,msg);
-
- char szBuffer[3000];
- const int iLen = vsprintf(szBuffer,msg,args);
- ai_assert(iLen > 0);
-
- va_end(args);
-
- throw DeadlyImportError("Validation failed: " + std::string(szBuffer,iLen));
-}
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::ReportWarning(const char* msg,...)
-{
- ai_assert(NULL != msg);
-
- va_list args;
- va_start(args,msg);
-
- char szBuffer[3000];
- const int iLen = vsprintf(szBuffer,msg,args);
- ai_assert(iLen > 0);
-
- va_end(args);
- DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
-}
-
-// ------------------------------------------------------------------------------------------------
-inline int HasNameMatch(const aiString& in, aiNode* node)
-{
- int result = (node->mName == in ? 1 : 0 );
- for (unsigned int i = 0; i < node->mNumChildren;++i) {
- result += HasNameMatch(in,node->mChildren[i]);
- }
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidation(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
- // validate all entries
- if (size)
- {
- if (!parray)
- {
- ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
- firstName, secondName, size);
- }
- for (unsigned int i = 0; i < size;++i)
- {
- if (!parray[i])
- {
- ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
- firstName,i,secondName,size);
- }
- Validate(parray[i]);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
- const char* firstName, const char* secondName)
-{
- // validate all entries
- if (size)
- {
- if (!parray) {
- ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
- firstName, secondName, size);
- }
- for (unsigned int i = 0; i < size;++i)
- {
- if (!parray[i])
- {
- ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
- firstName,i,secondName,size);
- }
- Validate(parray[i]);
-
- // check whether there are duplicate names
- for (unsigned int a = i+1; a < size;++a)
- {
- if (parray[i]->mName == parray[a]->mName)
- {
- this->ReportError("aiScene::%s[%i] has the same name as "
- "aiScene::%s[%i]",firstName, i,secondName, a);
- }
- }
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename T>
-inline void ValidateDSProcess::DoValidationWithNameCheck(T** array,
- unsigned int size, const char* firstName,
- const char* secondName)
-{
- // validate all entries
- DoValidationEx(array,size,firstName,secondName);
-
- for (unsigned int i = 0; i < size;++i)
- {
- int res = HasNameMatch(array[i]->mName,mScene->mRootNode);
- if (!res) {
- ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)",
- firstName,i,array[i]->mName.data);
- }
- else if (1 != res) {
- ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name",
- firstName,i,array[i]->mName.data);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Executes the post processing step on the given imported data.
-void ValidateDSProcess::Execute( aiScene* pScene)
-{
- this->mScene = pScene;
- DefaultLogger::get()->debug("ValidateDataStructureProcess begin");
-
- // validate the node graph of the scene
- Validate(pScene->mRootNode);
-
- // validate all meshes
- if (pScene->mNumMeshes) {
- DoValidation(pScene->mMeshes,pScene->mNumMeshes,"mMeshes","mNumMeshes");
- }
- else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
- ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
- }
- else if (pScene->mMeshes) {
- ReportError("aiScene::mMeshes is non-null although there are no meshes");
- }
-
- // validate all animations
- if (pScene->mNumAnimations) {
- DoValidation(pScene->mAnimations,pScene->mNumAnimations,
- "mAnimations","mNumAnimations");
- }
- else if (pScene->mAnimations) {
- ReportError("aiScene::mAnimations is non-null although there are no animations");
- }
-
- // validate all cameras
- if (pScene->mNumCameras) {
- DoValidationWithNameCheck(pScene->mCameras,pScene->mNumCameras,
- "mCameras","mNumCameras");
- }
- else if (pScene->mCameras) {
- ReportError("aiScene::mCameras is non-null although there are no cameras");
- }
-
- // validate all lights
- if (pScene->mNumLights) {
- DoValidationWithNameCheck(pScene->mLights,pScene->mNumLights,
- "mLights","mNumLights");
- }
- else if (pScene->mLights) {
- ReportError("aiScene::mLights is non-null although there are no lights");
- }
-
- // validate all textures
- if (pScene->mNumTextures) {
- DoValidation(pScene->mTextures,pScene->mNumTextures,
- "mTextures","mNumTextures");
- }
- else if (pScene->mTextures) {
- ReportError("aiScene::mTextures is non-null although there are no textures");
- }
-
- // validate all materials
- if (pScene->mNumMaterials) {
- DoValidation(pScene->mMaterials,pScene->mNumMaterials,"mMaterials","mNumMaterials");
- }
-#if 0
- // NOTE: ScenePreprocessor generates a default material if none is there
- else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
- ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
- }
-#endif
- else if (pScene->mMaterials) {
- ReportError("aiScene::mMaterials is non-null although there are no materials");
- }
-
-// if (!has)ReportError("The aiScene data structure is empty");
- DefaultLogger::get()->debug("ValidateDataStructureProcess end");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiLight* pLight)
-{
- if (pLight->mType == aiLightSource_UNDEFINED)
- ReportWarning("aiLight::mType is aiLightSource_UNDEFINED");
-
- if (!pLight->mAttenuationConstant &&
- !pLight->mAttenuationLinear &&
- !pLight->mAttenuationQuadratic) {
- ReportWarning("aiLight::mAttenuationXXX - all are zero");
- }
-
- if (pLight->mAngleInnerCone > pLight->mAngleOuterCone)
- ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone");
-
- if (pLight->mColorDiffuse.IsBlack() && pLight->mColorAmbient.IsBlack()
- && pLight->mColorSpecular.IsBlack())
- {
- ReportWarning("aiLight::mColorXXX - all are black and won't have any influence");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiCamera* pCamera)
-{
- if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
- ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
-
- // FIX: there are many 3ds files with invalid FOVs. No reason to
- // reject them at all ... a warning is appropriate.
- if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
- ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh)
-{
- // validate the material index of the mesh
- if (mScene->mNumMaterials && pMesh->mMaterialIndex >= mScene->mNumMaterials)
- {
- ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
- pMesh->mMaterialIndex,mScene->mNumMaterials-1);
- }
-
- Validate(&pMesh->mName);
-
- for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
- {
- aiFace& face = pMesh->mFaces[i];
-
- if (pMesh->mPrimitiveTypes)
- {
- switch (face.mNumIndices)
- {
- case 0:
- ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
- case 1:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
- {
- ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
- "does not report the POINT flag",i);
- }
- break;
- case 2:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
- {
- ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
- "does not report the LINE flag",i);
- }
- break;
- case 3:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
- {
- ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
- "does not report the TRIANGLE flag",i);
- }
- break;
- default:
- if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
- {
- this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
- "does not report the POLYGON flag",i);
- }
- break;
- };
- }
-
- if (!face.mIndices)
- ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
- }
-
- // positions must always be there ...
- if (!pMesh->mNumVertices || (!pMesh->mVertices && !mScene->mFlags)) {
- ReportError("The mesh contains no vertices");
- }
-
- if (pMesh->mNumVertices > AI_MAX_VERTICES) {
- ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
- }
- if (pMesh->mNumFaces > AI_MAX_FACES) {
- ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
- }
-
- // if tangents are there there must also be bitangent vectors ...
- if ((pMesh->mTangents != NULL) != (pMesh->mBitangents != NULL)) {
- ReportError("If there are tangents, bitangent vectors must be present as well");
- }
-
- // faces, too
- if (!pMesh->mNumFaces || (!pMesh->mFaces && !mScene->mFlags)) {
- ReportError("Mesh contains no faces");
- }
-
- // now check whether the face indexing layout is correct:
- // unique vertices, pseudo-indexed.
- std::vector<bool> abRefList;
- abRefList.resize(pMesh->mNumVertices,false);
- for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
- {
- aiFace& face = pMesh->mFaces[i];
- if (face.mNumIndices > AI_MAX_FACE_INDICES) {
- ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
- }
-
- for (unsigned int a = 0; a < face.mNumIndices;++a)
- {
- if (face.mIndices[a] >= pMesh->mNumVertices) {
- ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
- }
- // the MSB flag is temporarily used by the extra verbose
- // mode to tell us that the JoinVerticesProcess might have
- // been executed already.
- /*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
- abRefList[face.mIndices[a]])
- {
- ReportError("aiMesh::mVertices[%i] is referenced twice - second "
- "time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
- }*/
- abRefList[face.mIndices[a]] = true;
- }
- }
-
- // check whether there are vertices that aren't referenced by a face
- bool b = false;
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i) {
- if (!abRefList[i])b = true;
- }
- abRefList.clear();
- if (b)ReportWarning("There are unreferenced vertices");
-
- // texture channel 2 may not be set if channel 1 is zero ...
- {
- unsigned int i = 0;
- for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- {
- if (!pMesh->HasTextureCoords(i))break;
- }
- for (;i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
- if (pMesh->HasTextureCoords(i))
- {
- ReportError("Texture coordinate channel %i exists "
- "although the previous channel was NULL.",i);
- }
- }
- // the same for the vertex colors
- {
- unsigned int i = 0;
- for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- {
- if (!pMesh->HasVertexColors(i))break;
- }
- for (;i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
- if (pMesh->HasVertexColors(i))
- {
- ReportError("Vertex color channel %i is exists "
- "although the previous channel was NULL.",i);
- }
- }
-
-
- // now validate all bones
- if (pMesh->mNumBones)
- {
- if (!pMesh->mBones)
- {
- ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
- pMesh->mNumBones);
- }
- std::unique_ptr<float[]> afSum(nullptr);
- if (pMesh->mNumVertices)
- {
- afSum.reset(new float[pMesh->mNumVertices]);
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
- afSum[i] = 0.0f;
- }
-
- // check whether there are duplicate bone names
- for (unsigned int i = 0; i < pMesh->mNumBones;++i)
- {
- const aiBone* bone = pMesh->mBones[i];
- if (bone->mNumWeights > AI_MAX_BONE_WEIGHTS) {
- ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
- }
-
- if (!pMesh->mBones[i])
- {
- ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
- i,pMesh->mNumBones);
- }
- Validate(pMesh,pMesh->mBones[i],afSum.get());
-
- for (unsigned int a = i+1; a < pMesh->mNumBones;++a)
- {
- if (pMesh->mBones[i]->mName == pMesh->mBones[a]->mName)
- {
- ReportError("aiMesh::mBones[%i] has the same name as "
- "aiMesh::mBones[%i]",i,a);
- }
- }
- }
- // check whether all bone weights for a vertex sum to 1.0 ...
- for (unsigned int i = 0; i < pMesh->mNumVertices;++i)
- {
- if (afSum[i] && (afSum[i] <= 0.94 || afSum[i] >= 1.05)) {
- ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
- }
- }
- }
- else if (pMesh->mBones)
- {
- ReportError("aiMesh::mBones is non-null although there are no bones");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMesh* pMesh,
- const aiBone* pBone,float* afSum)
-{
- this->Validate(&pBone->mName);
-
- if (!pBone->mNumWeights) {
- ReportError("aiBone::mNumWeights is zero");
- }
-
- // check whether all vertices affected by this bone are valid
- for (unsigned int i = 0; i < pBone->mNumWeights;++i)
- {
- if (pBone->mWeights[i].mVertexId >= pMesh->mNumVertices) {
- ReportError("aiBone::mWeights[%i].mVertexId is out of range",i);
- }
- else if (!pBone->mWeights[i].mWeight || pBone->mWeights[i].mWeight > 1.0f) {
- ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i);
- }
- afSum[pBone->mWeights[i].mVertexId] += pBone->mWeights[i].mWeight;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
-{
- Validate(&pAnimation->mName);
-
- // validate all materials
- if (pAnimation->mNumChannels)
- {
- if (!pAnimation->mChannels) {
- ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
- pAnimation->mNumChannels);
- }
- for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
- {
- if (!pAnimation->mChannels[i])
- {
- ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)",
- i, pAnimation->mNumChannels);
- }
- Validate(pAnimation, pAnimation->mChannels[i]);
- }
- }
- else ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
-
- // Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
- // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
- aiTextureType type)
-{
- const char* szType = TextureTypeToString(type);
-
- // ****************************************************************************
- // Search all keys of the material ...
- // textures must be specified with ascending indices
- // (e.g. diffuse #2 may not be specified if diffuse #1 is not there ...)
- // ****************************************************************************
-
- int iNumIndices = 0;
- int iIndex = -1;
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type) {
- iIndex = std::max(iIndex, (int) prop->mIndex);
- ++iNumIndices;
-
- if (aiPTI_String != prop->mType)
- ReportError("Material property %s is expected to be a string",prop->mKey.data);
- }
- }
- if (iIndex +1 != iNumIndices) {
- ReportError("%s #%i is set, but there are only %i %s textures",
- szType,iIndex,iNumIndices,szType);
- }
- if (!iNumIndices)return;
- std::vector<aiTextureMapping> mappings(iNumIndices);
-
- // Now check whether all UV indices are valid ...
- bool bNoSpecified = true;
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (prop->mSemantic != type)continue;
-
- if ((int)prop->mIndex >= iNumIndices)
- {
- ReportError("Found texture property with index %i, although there "
- "are only %i textures of type %s",
- prop->mIndex, iNumIndices, szType);
- }
-
- if (!::strcmp(prop->mKey.data,"$tex.mapping")) {
- if (aiPTI_Integer != prop->mType || prop->mDataLength < sizeof(aiTextureMapping))
- {
- ReportError("Material property %s%i is expected to be an integer (size is %i)",
- prop->mKey.data,prop->mIndex,prop->mDataLength);
- }
- mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
- }
- else if (!::strcmp(prop->mKey.data,"$tex.uvtrafo")) {
- if (aiPTI_Float != prop->mType || prop->mDataLength < sizeof(aiUVTransform))
- {
- ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
- prop->mKey.data,prop->mIndex, prop->mDataLength);
- }
- mappings[prop->mIndex] = *((aiTextureMapping*)prop->mData);
- }
- else if (!::strcmp(prop->mKey.data,"$tex.uvwsrc")) {
- if (aiPTI_Integer != prop->mType || sizeof(int) > prop->mDataLength)
- {
- ReportError("Material property %s%i is expected to be an integer (size is %i)",
- prop->mKey.data,prop->mIndex,prop->mDataLength);
- }
- bNoSpecified = false;
-
- // Ignore UV indices for texture channels that are not there ...
-
- // Get the value
- iIndex = *((unsigned int*)prop->mData);
-
- // Check whether there is a mesh using this material
- // which has not enough UV channels ...
- for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
- {
- aiMesh* mesh = this->mScene->mMeshes[a];
- if(mesh->mMaterialIndex == (unsigned int)i)
- {
- int iChannels = 0;
- while (mesh->HasTextureCoords(iChannels))++iChannels;
- if (iIndex >= iChannels)
- {
- ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
- iIndex,prop->mKey.data,a,iChannels);
- }
- }
- }
- }
- }
- if (bNoSpecified)
- {
- // Assume that all textures are using the first UV channel
- for (unsigned int a = 0; a < mScene->mNumMeshes;++a)
- {
- aiMesh* mesh = mScene->mMeshes[a];
- if(mesh->mMaterialIndex == (unsigned int)iIndex && mappings[0] == aiTextureMapping_UV)
- {
- if (!mesh->mTextureCoords[0])
- {
- // This is a special case ... it could be that the
- // original mesh format intended the use of a special
- // mapping here.
- ReportWarning("UV-mapped texture, but there are no UV coords");
- }
- }
- }
- }
-}
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiMaterial* pMaterial)
-{
- // check whether there are material keys that are obviously not legal
- for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
- {
- const aiMaterialProperty* prop = pMaterial->mProperties[i];
- if (!prop) {
- ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
- i,pMaterial->mNumProperties);
- }
- if (!prop->mDataLength || !prop->mData) {
- ReportError("aiMaterial::mProperties[%i].mDataLength or "
- "aiMaterial::mProperties[%i].mData is 0",i,i);
- }
- // check all predefined types
- if (aiPTI_String == prop->mType) {
- // FIX: strings are now stored in a less expensive way, but we can't use the
- // validation routine for 'normal' aiStrings
- if (prop->mDataLength < 5 || prop->mDataLength < 4 + (*reinterpret_cast<uint32_t*>(prop->mData)) + 1) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain a string (%i, needed: %i)",
- i,prop->mDataLength,sizeof(aiString));
- }
- if(prop->mData[prop->mDataLength-1]) {
- ReportError("Missing null-terminator in string material property");
- }
- // Validate((const aiString*)prop->mData);
- }
- else if (aiPTI_Float == prop->mType) {
- if (prop->mDataLength < sizeof(float)) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain a float (%i, needed: %i)",
- i,prop->mDataLength,sizeof(float));
- }
- }
- else if (aiPTI_Integer == prop->mType) {
- if (prop->mDataLength < sizeof(int)) {
- ReportError("aiMaterial::mProperties[%i].mDataLength is "
- "too small to contain an integer (%i, needed: %i)",
- i,prop->mDataLength,sizeof(int));
- }
- }
- // TODO: check whether there is a key with an unknown name ...
- }
-
- // make some more specific tests
- ai_real fTemp;
- int iShading;
- if (AI_SUCCESS == aiGetMaterialInteger( pMaterial,AI_MATKEY_SHADING_MODEL,&iShading)) {
- switch ((aiShadingMode)iShading)
- {
- case aiShadingMode_Blinn:
- case aiShadingMode_CookTorrance:
- case aiShadingMode_Phong:
-
- if (AI_SUCCESS != aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS,&fTemp)) {
- ReportWarning("A specular shading model is specified but there is no "
- "AI_MATKEY_SHININESS key");
- }
- if (AI_SUCCESS == aiGetMaterialFloat(pMaterial,AI_MATKEY_SHININESS_STRENGTH,&fTemp) && !fTemp) {
- ReportWarning("A specular shading model is specified but the value of the "
- "AI_MATKEY_SHININESS_STRENGTH key is 0.0");
- }
- break;
- default: ;
- };
- }
-
- if (AI_SUCCESS == aiGetMaterialFloat( pMaterial,AI_MATKEY_OPACITY,&fTemp) && (!fTemp || fTemp > 1.01)) {
- ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
- }
-
- // Check whether there are invalid texture keys
- // TODO: that's a relict of the past, where texture type and index were baked
- // into the material string ... we could do that in one single pass.
- SearchForInvalidTextures(pMaterial,aiTextureType_DIFFUSE);
- SearchForInvalidTextures(pMaterial,aiTextureType_SPECULAR);
- SearchForInvalidTextures(pMaterial,aiTextureType_AMBIENT);
- SearchForInvalidTextures(pMaterial,aiTextureType_EMISSIVE);
- SearchForInvalidTextures(pMaterial,aiTextureType_OPACITY);
- SearchForInvalidTextures(pMaterial,aiTextureType_SHININESS);
- SearchForInvalidTextures(pMaterial,aiTextureType_HEIGHT);
- SearchForInvalidTextures(pMaterial,aiTextureType_NORMALS);
- SearchForInvalidTextures(pMaterial,aiTextureType_DISPLACEMENT);
- SearchForInvalidTextures(pMaterial,aiTextureType_LIGHTMAP);
- SearchForInvalidTextures(pMaterial,aiTextureType_REFLECTION);
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiTexture* pTexture)
-{
- // the data section may NEVER be NULL
- if (!pTexture->pcData) {
- ReportError("aiTexture::pcData is NULL");
- }
- if (pTexture->mHeight)
- {
- if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero "
- "(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight);
- }
- else
- {
- if (!pTexture->mWidth) {
- ReportError("aiTexture::mWidth is zero (compressed texture)");
- }
- if ('\0' != pTexture->achFormatHint[3]) {
- ReportWarning("aiTexture::achFormatHint must be zero-terminated");
- }
- else if ('.' == pTexture->achFormatHint[0]) {
- ReportWarning("aiTexture::achFormatHint should contain a file extension "
- "without a leading dot (format hint: %s).",pTexture->achFormatHint);
- }
- }
-
- const char* sz = pTexture->achFormatHint;
- if ((sz[0] >= 'A' && sz[0] <= 'Z') ||
- (sz[1] >= 'A' && sz[1] <= 'Z') ||
- (sz[2] >= 'A' && sz[2] <= 'Z') ||
- (sz[3] >= 'A' && sz[3] <= 'Z')) {
- ReportError("aiTexture::achFormatHint contains non-lowercase letters");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
- const aiNodeAnim* pNodeAnim)
-{
- Validate(&pNodeAnim->mNodeName);
-
- if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys)
- ReportError("Empty node animation channel");
-
- // otherwise check whether one of the keys exceeds the total duration of the animation
- if (pNodeAnim->mNumPositionKeys)
- {
- if (!pNodeAnim->mPositionKeys)
- {
- this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
- pNodeAnim->mNumPositionKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumPositionKeys;++i)
- {
- // ScenePreprocessor will compute the duration if still the default value
- // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
- // seems to be due the compilers register usage/width.
- if (pAnimation->mDuration > 0. && pNodeAnim->mPositionKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mPositionKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mPositionKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mPositionKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mPositionKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mPositionKeys[i].mTime;
- }
- }
- // rotation keys
- if (pNodeAnim->mNumRotationKeys)
- {
- if (!pNodeAnim->mRotationKeys)
- {
- this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
- pNodeAnim->mNumRotationKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumRotationKeys;++i)
- {
- if (pAnimation->mDuration > 0. && pNodeAnim->mRotationKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mRotationKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mRotationKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mRotationKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mRotationKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mRotationKeys[i].mTime;
- }
- }
- // scaling keys
- if (pNodeAnim->mNumScalingKeys)
- {
- if (!pNodeAnim->mScalingKeys) {
- ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)",
- pNodeAnim->mNumScalingKeys);
- }
- double dLast = -10e10;
- for (unsigned int i = 0; i < pNodeAnim->mNumScalingKeys;++i)
- {
- if (pAnimation->mDuration > 0. && pNodeAnim->mScalingKeys[i].mTime > pAnimation->mDuration+0.001)
- {
- ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger "
- "than aiAnimation::mDuration (which is %.5f)",i,
- (float)pNodeAnim->mScalingKeys[i].mTime,
- (float)pAnimation->mDuration);
- }
- if (i && pNodeAnim->mScalingKeys[i].mTime <= dLast)
- {
- ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller "
- "than aiAnimation::mScalingKeys[%i] (which is %.5f)",i,
- (float)pNodeAnim->mScalingKeys[i].mTime,
- i-1, (float)dLast);
- }
- dLast = pNodeAnim->mScalingKeys[i].mTime;
- }
- }
-
- if (!pNodeAnim->mNumScalingKeys && !pNodeAnim->mNumRotationKeys &&
- !pNodeAnim->mNumPositionKeys)
- {
- ReportError("A node animation channel must have at least one subtrack");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiNode* pNode)
-{
- if (!pNode)ReportError("A node of the scenegraph is NULL");
- if (pNode != mScene->mRootNode && !pNode->mParent)
- this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
-
- this->Validate(&pNode->mName);
-
- // validate all meshes
- if (pNode->mNumMeshes)
- {
- if (!pNode->mMeshes)
- {
- ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
- pNode->mNumMeshes);
- }
- std::vector<bool> abHadMesh;
- abHadMesh.resize(mScene->mNumMeshes,false);
- for (unsigned int i = 0; i < pNode->mNumMeshes;++i)
- {
- if (pNode->mMeshes[i] >= mScene->mNumMeshes)
- {
- ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
- pNode->mMeshes[i],mScene->mNumMeshes-1);
- }
- if (abHadMesh[pNode->mMeshes[i]])
- {
- ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
- i,pNode->mMeshes[i]);
- }
- abHadMesh[pNode->mMeshes[i]] = true;
- }
- }
- if (pNode->mNumChildren)
- {
- if (!pNode->mChildren) {
- ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)",
- pNode->mNumChildren);
- }
- for (unsigned int i = 0; i < pNode->mNumChildren;++i) {
- Validate(pNode->mChildren[i]);
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void ValidateDSProcess::Validate( const aiString* pString)
-{
- if (pString->length > MAXLEN)
- {
- this->ReportError("aiString::length is too large (%i, maximum is %i)",
- pString->length,MAXLEN);
- }
- const char* sz = pString->data;
- while (true)
- {
- if ('\0' == *sz)
- {
- if (pString->length != (unsigned int)(sz-pString->data))
- ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
- break;
- }
- else if (sz >= &pString->data[MAXLEN])
- ReportError("aiString::data is invalid. There is no terminal character");
- ++sz;
- }
-}
diff --git a/src/3rdparty/assimp/code/ValidateDataStructure.h b/src/3rdparty/assimp/code/ValidateDataStructure.h
deleted file mode 100644
index 084a2b083..000000000
--- a/src/3rdparty/assimp/code/ValidateDataStructure.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a (dummy) post processing step to validate the loader's
- * output data structure (for debugging)
- */
-#ifndef AI_VALIDATEPROCESS_H_INC
-#define AI_VALIDATEPROCESS_H_INC
-
-#include <assimp/types.h>
-#include <assimp/material.h>
-#include "BaseProcess.h"
-
-struct aiBone;
-struct aiMesh;
-struct aiAnimation;
-struct aiNodeAnim;
-struct aiTexture;
-struct aiMaterial;
-struct aiNode;
-struct aiString;
-struct aiCamera;
-struct aiLight;
-
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------
-/** Validates the whole ASSIMP scene data structure for correctness.
- * ImportErrorException is thrown of the scene is corrupt.*/
-// --------------------------------------------------------------------------------------
-class ValidateDSProcess : public BaseProcess
-{
-public:
-
- ValidateDSProcess();
- ~ValidateDSProcess();
-
-public:
- // -------------------------------------------------------------------
- bool IsActive( unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- void Execute( aiScene* pScene);
-
-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_SUFFIX;
-
-
- // -------------------------------------------------------------------
- /** Report a validation warning. This won't throw an exception,
- * control will return to the caller.
- * @param msg Format string for sprintf().*/
- void ReportWarning(const char* msg,...);
-
-
- // -------------------------------------------------------------------
- /** Validates a mesh
- * @param pMesh Input mesh*/
- void Validate( const aiMesh* pMesh);
-
- // -------------------------------------------------------------------
- /** Validates a bone
- * @param pMesh Input mesh
- * @param pBone Input bone*/
- void Validate( const aiMesh* pMesh,const aiBone* pBone,float* afSum);
-
- // -------------------------------------------------------------------
- /** Validates an animation
- * @param pAnimation Input animation*/
- void Validate( const aiAnimation* pAnimation);
-
- // -------------------------------------------------------------------
- /** Validates a material
- * @param pMaterial Input material*/
- void Validate( const aiMaterial* pMaterial);
-
- // -------------------------------------------------------------------
- /** Search the material data structure for invalid or corrupt
- * texture keys.
- * @param pMaterial Input material
- * @param type Type of the texture*/
- void SearchForInvalidTextures(const aiMaterial* pMaterial,
- aiTextureType type);
-
- // -------------------------------------------------------------------
- /** Validates a texture
- * @param pTexture Input texture*/
- void Validate( const aiTexture* pTexture);
-
- // -------------------------------------------------------------------
- /** Validates a light source
- * @param pLight Input light
- */
- void Validate( const aiLight* pLight);
-
- // -------------------------------------------------------------------
- /** Validates a camera
- * @param pCamera Input camera*/
- void Validate( const aiCamera* pCamera);
-
- // -------------------------------------------------------------------
- /** Validates a bone animation channel
- * @param pAnimation Animation channel.
- * @param pBoneAnim Input bone animation */
- void Validate( const aiAnimation* pAnimation,
- const aiNodeAnim* pBoneAnim);
-
- // -------------------------------------------------------------------
- /** Validates a node and all of its subnodes
- * @param Node Input node*/
- void Validate( const aiNode* pNode);
-
- // -------------------------------------------------------------------
- /** Validates a string
- * @param pString Input string*/
- void Validate( const aiString* pString);
-
-private:
-
- // template to validate one of the aiScene::mXXX arrays
- template <typename T>
- inline void DoValidation(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- // extended version: checks whether T::mName occurs twice
- template <typename T>
- inline void DoValidationEx(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- // extension to the first template which does also search
- // the nodegraph for an item with the same name
- template <typename T>
- inline void DoValidationWithNameCheck(T** array, unsigned int size,
- const char* firstName, const char* secondName);
-
- aiScene* mScene;
-};
-
-
-
-
-} // end of namespace Assimp
-
-#endif // AI_VALIDATEPROCESS_H_INC
diff --git a/src/3rdparty/assimp/code/Version.cpp b/src/3rdparty/assimp/code/Version.cpp
deleted file mode 100644
index fe9a2fdaa..000000000
--- a/src/3rdparty/assimp/code/Version.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
----------------------------------------------------------------------------
-*/
-
-// Actually just a dummy, used by the compiler to build the precompiled header.
-
-#include <assimp/version.h>
-#include <assimp/scene.h>
-#include "ScenePrivate.h"
-
-static const unsigned int MajorVersion = 4;
-static const unsigned int MinorVersion = 1;
-
-// --------------------------------------------------------------------------------
-// Legal information string - dont't remove this.
-static const char* LEGAL_INFORMATION =
-
-"Open Asset Import Library (Assimp).\n"
-"A free C/C++ library to import various 3D file formats into applications\n\n"
-
-"(c) 2008-2017, assimp team\n"
-"License under the terms and conditions of the 3-clause BSD license\n"
-"http://assimp.sourceforge.net\n"
-;
-
-// ------------------------------------------------------------------------------------------------
-// Get legal string
-ASSIMP_API const char* aiGetLegalString () {
- return LEGAL_INFORMATION;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get Assimp minor version
-ASSIMP_API unsigned int aiGetVersionMinor () {
- return MinorVersion;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get Assimp major version
-ASSIMP_API unsigned int aiGetVersionMajor () {
- return MajorVersion;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get flags used for compilation
-ASSIMP_API unsigned int aiGetCompileFlags () {
-
- unsigned int flags = 0;
-
-#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
- flags |= ASSIMP_CFLAGS_NOBOOST;
-#endif
-#ifdef ASSIMP_BUILD_SINGLETHREADED
- flags |= ASSIMP_CFLAGS_SINGLETHREADED;
-#endif
-#ifdef ASSIMP_BUILD_DEBUG
- flags |= ASSIMP_CFLAGS_DEBUG;
-#endif
-#ifdef ASSIMP_BUILD_DLL_EXPORT
- flags |= ASSIMP_CFLAGS_SHARED;
-#endif
-#ifdef _STLPORT_VERSION
- flags |= ASSIMP_CFLAGS_STLPORT;
-#endif
-
- return flags;
-}
-
-// include current build revision, which is even updated from time to time -- :-)
-#include "revision.h"
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API unsigned int aiGetVersionRevision() {
- return GitVersion;
-}
-
-// ------------------------------------------------------------------------------------------------
-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()) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-ASSIMP_API aiScene::~aiScene() {
- // delete all sub-objects recursively
- delete mRootNode;
-
- // To make sure we won't crash if the data is invalid it's
- // much better to check whether both mNumXXX and mXXX are
- // valid instead of relying on just one of them.
- if (mNumMeshes && mMeshes)
- for( unsigned int a = 0; a < mNumMeshes; a++)
- delete mMeshes[a];
- delete [] mMeshes;
-
- if (mNumMaterials && mMaterials)
- for( unsigned int a = 0; a < mNumMaterials; a++)
- delete mMaterials[a];
- delete [] mMaterials;
-
- if (mNumAnimations && mAnimations)
- for( unsigned int a = 0; a < mNumAnimations; a++)
- delete mAnimations[a];
- delete [] mAnimations;
-
- if (mNumTextures && mTextures)
- for( unsigned int a = 0; a < mNumTextures; a++)
- delete mTextures[a];
- delete [] mTextures;
-
- if (mNumLights && mLights)
- for( unsigned int a = 0; a < mNumLights; a++)
- delete mLights[a];
- delete [] mLights;
-
- if (mNumCameras && mCameras)
- for( unsigned int a = 0; a < mNumCameras; a++)
- delete mCameras[a];
- delete [] mCameras;
-
- delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
-}
-
diff --git a/src/3rdparty/assimp/code/Vertex.h b/src/3rdparty/assimp/code/Vertex.h
deleted file mode 100644
index 1f1685ae9..000000000
--- a/src/3rdparty/assimp/code/Vertex.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a helper class to represent an interleaved vertex
- along with arithmetic operations to support vertex operations
- such as subdivision, smoothing etc.
-
- While the code is kept as general as possible, arithmetic operations
- that are not currently well-defined (and would cause compile errors
- due to missing operators in the math library), are commented.
- */
-#ifndef AI_VERTEX_H_INC
-#define AI_VERTEX_H_INC
-
-#include <assimp/vector3.h>
-#include <assimp/mesh.h>
-#include <assimp/ai_assert.h>
-#include <functional>
-
-namespace Assimp {
-
- ///////////////////////////////////////////////////////////////////////////
- // std::plus-family operates on operands with identical types - we need to
- // support all the (vectype op float) combinations in vector maths.
- // Providing T(float) would open the way to endless implicit conversions.
- ///////////////////////////////////////////////////////////////////////////
- namespace Intern {
- template <typename T0, typename T1, typename TRES = T0> struct plus {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0+t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct minus {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0-t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct multiplies {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0*t1;
- }
- };
- template <typename T0, typename T1, typename TRES = T0> struct divides {
- TRES operator() (const T0& t0, const T1& t1) const {
- return t0/t1;
- }
- };
- }
-
-// ------------------------------------------------------------------------------------------------
-/** Intermediate description a vertex with all possible components. Defines a full set of
- * operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied
- * to *all* vertex components equally. This is useful for stuff like interpolation
- * or subdivision, but won't work if special handling is required for some vertex components. */
-// ------------------------------------------------------------------------------------------------
-class Vertex
-{
- friend Vertex operator + (const Vertex&,const Vertex&);
- friend Vertex operator - (const Vertex&,const Vertex&);
-
-// friend Vertex operator + (const Vertex&,ai_real);
-// friend Vertex operator - (const Vertex&,ai_real);
- friend Vertex operator * (const Vertex&,ai_real);
- friend Vertex operator / (const Vertex&,ai_real);
-
-// friend Vertex operator + (ai_real, const Vertex&);
-// friend Vertex operator - (ai_real, const Vertex&);
- friend Vertex operator * (ai_real, const Vertex&);
-// friend Vertex operator / (ai_real, const Vertex&);
-
-public:
-
- Vertex() {}
-
- // ----------------------------------------------------------------------------
- /** Extract a particular vertex from a mesh and interleave all components */
- explicit Vertex(const aiMesh* msh, unsigned int idx) {
- ai_assert(idx < msh->mNumVertices);
- position = msh->mVertices[idx];
-
- if (msh->HasNormals()) {
- normal = msh->mNormals[idx];
- }
-
- if (msh->HasTangentsAndBitangents()) {
- tangent = msh->mTangents[idx];
- bitangent = msh->mBitangents[idx];
- }
-
- for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
- texcoords[i] = msh->mTextureCoords[i][idx];
- }
-
- for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
- colors[i] = msh->mColors[i][idx];
- }
- }
-
-public:
-
- Vertex& operator += (const Vertex& v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (const Vertex& v) {
- *this = *this-v;
- return *this;
- }
-
-
-/*
- Vertex& operator += (ai_real v) {
- *this = *this+v;
- return *this;
- }
-
- Vertex& operator -= (ai_real v) {
- *this = *this-v;
- return *this;
- }
-*/
- Vertex& operator *= (ai_real v) {
- *this = *this*v;
- return *this;
- }
-
- Vertex& operator /= (ai_real v) {
- *this = *this/v;
- return *this;
- }
-
-public:
-
- // ----------------------------------------------------------------------------
- /** Convert back to non-interleaved storage */
- void SortBack(aiMesh* out, unsigned int idx) const {
-
- ai_assert(idx<out->mNumVertices);
- out->mVertices[idx] = position;
-
- if (out->HasNormals()) {
- out->mNormals[idx] = normal;
- }
-
- if (out->HasTangentsAndBitangents()) {
- out->mTangents[idx] = tangent;
- out->mBitangents[idx] = bitangent;
- }
-
- for(unsigned int i = 0; out->HasTextureCoords(i); ++i) {
- out->mTextureCoords[i][idx] = texcoords[i];
- }
-
- for(unsigned int i = 0; out->HasVertexColors(i); ++i) {
- out->mColors[i][idx] = colors[i];
- }
- }
-
-private:
-
- // ----------------------------------------------------------------------------
- /** Construct from two operands and a binary operation to combine them */
- template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<aiVector3D>()(v0.position,v1.position);
- res.normal = op<aiVector3D>()(v0.normal,v1.normal);
- res.tangent = op<aiVector3D>()(v0.tangent,v1.tangent);
- res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]);
- }
- return res;
- }
-
- // ----------------------------------------------------------------------------
- /** This time binary arithmetics of v0 with a floating-point number */
- template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<aiVector3D,ai_real,aiVector3D>()(v0.position,f);
- res.normal = op<aiVector3D,ai_real,aiVector3D>()(v0.normal,f);
- res.tangent = op<aiVector3D,ai_real,aiVector3D>()(v0.tangent,f);
- res.bitangent = op<aiVector3D,ai_real,aiVector3D>()(v0.bitangent,f);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<aiVector3D,ai_real,aiVector3D>()(v0.texcoords[i],f);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<aiColor4D,ai_real,aiColor4D>()(v0.colors[i],f);
- }
- return res;
- }
-
- // ----------------------------------------------------------------------------
- /** This time binary arithmetics of v0 with a floating-point number */
- template <template <typename, typename, typename> class op> static Vertex BinaryOp(ai_real f, const Vertex& v0) {
- // this is a heavy task for the compiler to optimize ... *pray*
-
- Vertex res;
- res.position = op<ai_real,aiVector3D,aiVector3D>()(f,v0.position);
- res.normal = op<ai_real,aiVector3D,aiVector3D>()(f,v0.normal);
- res.tangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.tangent);
- res.bitangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.bitangent);
-
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- res.texcoords[i] = op<ai_real,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
- }
- for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
- res.colors[i] = op<ai_real,aiColor4D,aiColor4D>()(f,v0.colors[i]);
- }
- return res;
- }
-
-public:
-
- aiVector3D position;
- aiVector3D normal;
- aiVector3D tangent, bitangent;
-
- aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
-};
-
-
-
-// ------------------------------------------------------------------------------------------------
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
- return Vertex::BinaryOp<std::plus>(v0,v1);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
- return Vertex::BinaryOp<std::minus>(v0,v1);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::plus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::minus>(v0,f);
-}
-
-*/
-
-AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::multiplies>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
- return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
-}
-
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::plus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::minus>(f,v0);
-}
-*/
-
-AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::multiplies>(f,v0);
-}
-
-/*
-AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
- return Vertex::BinaryOp<Intern::divides>(f,v0);
-}
-*/
-
-}
-#endif
diff --git a/src/3rdparty/assimp/code/VertexTriangleAdjacency.cpp b/src/3rdparty/assimp/code/VertexTriangleAdjacency.cpp
deleted file mode 100644
index 09c0a51a7..000000000
--- a/src/3rdparty/assimp/code/VertexTriangleAdjacency.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the VertexTriangleAdjacency helper class
- */
-
-// internal headers
-#include "VertexTriangleAdjacency.h"
-#include <assimp/mesh.h>
-
-
-using namespace Assimp;
-
-// ------------------------------------------------------------------------------------------------
-VertexTriangleAdjacency::VertexTriangleAdjacency(aiFace *pcFaces,
- unsigned int iNumFaces,
- unsigned int iNumVertices /*= 0*/,
- bool bComputeNumTriangles /*= false*/)
-{
- // compute the number of referenced vertices if it wasn't specified by the caller
- const aiFace* const pcFaceEnd = pcFaces + iNumFaces;
- if (!iNumVertices) {
-
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace) {
- ai_assert(3 == pcFace->mNumIndices);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[0]);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[1]);
- iNumVertices = std::max(iNumVertices,pcFace->mIndices[2]);
- }
- }
-
- this->iNumVertices = iNumVertices;
-
- unsigned int* pi;
-
- // allocate storage
- if (bComputeNumTriangles) {
- pi = mLiveTriangles = new unsigned int[iNumVertices+1];
- memset(mLiveTriangles,0,sizeof(unsigned int)*(iNumVertices+1));
- mOffsetTable = new unsigned int[iNumVertices+2]+1;
- }
- else {
- pi = mOffsetTable = new unsigned int[iNumVertices+2]+1;
- memset(mOffsetTable,0,sizeof(unsigned int)*(iNumVertices+1));
- mLiveTriangles = NULL; // important, otherwise the d'tor would crash
- }
-
- // get a pointer to the end of the buffer
- unsigned int* piEnd = pi+iNumVertices;
- *piEnd++ = 0u;
-
- // first pass: compute the number of faces referencing each vertex
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace)
- {
- pi[pcFace->mIndices[0]]++;
- pi[pcFace->mIndices[1]]++;
- pi[pcFace->mIndices[2]]++;
- }
-
- // second pass: compute the final offset table
- unsigned int iSum = 0;
- unsigned int* piCurOut = this->mOffsetTable;
- for (unsigned int* piCur = pi; piCur != piEnd;++piCur,++piCurOut) {
-
- unsigned int iLastSum = iSum;
- iSum += *piCur;
- *piCurOut = iLastSum;
- }
- pi = this->mOffsetTable;
-
- // third pass: compute the final table
- this->mAdjacencyTable = new unsigned int[iSum];
- iSum = 0;
- for (aiFace* pcFace = pcFaces; pcFace != pcFaceEnd; ++pcFace,++iSum) {
-
- unsigned int idx = pcFace->mIndices[0];
- mAdjacencyTable[pi[idx]++] = iSum;
-
- idx = pcFace->mIndices[1];
- mAdjacencyTable[pi[idx]++] = iSum;
-
- idx = pcFace->mIndices[2];
- mAdjacencyTable[pi[idx]++] = iSum;
- }
- // fourth pass: undo the offset computations made during the third pass
- // We could do this in a separate buffer, but this would be TIMES slower.
- --mOffsetTable;
- *mOffsetTable = 0u;
-}
-// ------------------------------------------------------------------------------------------------
-VertexTriangleAdjacency::~VertexTriangleAdjacency()
-{
- // delete allocated storage
- delete[] mOffsetTable;
- delete[] mAdjacencyTable;
- delete[] mLiveTriangles;
-}
diff --git a/src/3rdparty/assimp/code/VertexTriangleAdjacency.h b/src/3rdparty/assimp/code/VertexTriangleAdjacency.h
deleted file mode 100644
index ed7b83a6b..000000000
--- a/src/3rdparty/assimp/code/VertexTriangleAdjacency.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines a helper class to compute a vertex-triangle adjacency map */
-#ifndef AI_VTADJACENCY_H_INC
-#define AI_VTADJACENCY_H_INC
-
-#include "BaseProcess.h"
-#include <assimp/types.h>
-#include <assimp/ai_assert.h>
-
-struct aiMesh;
-struct aiFace;
-
-namespace Assimp {
-
-// --------------------------------------------------------------------------------------------
-/** @brief The VertexTriangleAdjacency class computes a vertex-triangle
- * adjacency map from a given index buffer.
- *
- * @note Although it is called #VertexTriangleAdjacency, the current version does also
- * support arbitrary polygons. */
-// --------------------------------------------------------------------------------------------
-class ASSIMP_API VertexTriangleAdjacency
-{
-public:
-
- // ----------------------------------------------------------------------------
- /** @brief Construction from an existing index buffer
- * @param pcFaces Index buffer
- * @param iNumFaces Number of faces in the buffer
- * @param iNumVertices Number of referenced vertices. This value
- * is computed automatically if 0 is specified.
- * @param bComputeNumTriangles If you want the class to compute
- * a list containing the number of referenced triangles per vertex
- * per vertex - pass true. */
- VertexTriangleAdjacency(aiFace* pcFaces,unsigned int iNumFaces,
- unsigned int iNumVertices = 0,
- bool bComputeNumTriangles = true);
-
-
- // ----------------------------------------------------------------------------
- /** @brief Destructor */
- ~VertexTriangleAdjacency();
-
-
-public:
-
- // ----------------------------------------------------------------------------
- /** @brief Get all triangles adjacent to a vertex
- * @param iVertIndex Index of the vertex
- * @return A pointer to the adjacency list. */
- unsigned int* GetAdjacentTriangles(unsigned int iVertIndex) const
- {
- ai_assert(iVertIndex < iNumVertices);
- return &mAdjacencyTable[ mOffsetTable[iVertIndex]];
- }
-
-
- // ----------------------------------------------------------------------------
- /** @brief Get the number of triangles that are referenced by
- * a vertex. This function returns a reference that can be modified
- * @param iVertIndex Index of the vertex
- * @return Number of referenced triangles */
- unsigned int& GetNumTrianglesPtr(unsigned int iVertIndex)
- {
- ai_assert(iVertIndex < iNumVertices && NULL != mLiveTriangles);
- return mLiveTriangles[iVertIndex];
- }
-
-
-public:
-
- //! Offset table
- unsigned int* mOffsetTable;
-
- //! Adjacency table
- unsigned int* mAdjacencyTable;
-
- //! Table containing the number of referenced triangles per vertex
- unsigned int* mLiveTriangles;
-
- //! Debug: Number of referenced vertices
- unsigned int iNumVertices;
-
-};
-}
-
-#endif // !! AI_VTADJACENCY_H_INC
diff --git a/src/3rdparty/assimp/code/Win32DebugLogStream.h b/src/3rdparty/assimp/code/Win32DebugLogStream.h
deleted file mode 100644
index 0833712f9..000000000
--- a/src/3rdparty/assimp/code/Win32DebugLogStream.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Win32DebugLogStream.h
-* @brief Implementation of Win32DebugLogStream
-*/
-#ifndef AI_WIN32DEBUGLOGSTREAM_H_INC
-#define AI_WIN32DEBUGLOGSTREAM_H_INC
-
-#ifdef _WIN32
-
-#include <assimp/LogStream.hpp>
-#include "windows.h"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @class Win32DebugLogStream
- * @brief Logs into the debug stream from win32.
- */
-class Win32DebugLogStream : public LogStream {
-public:
- /** @brief Default constructor */
- Win32DebugLogStream();
-
- /** @brief Destructor */
- ~Win32DebugLogStream();
-
- /** @brief Writer */
- void write(const char* messgae);
-};
-
-// ---------------------------------------------------------------------------
-inline
-Win32DebugLogStream::Win32DebugLogStream(){
- // empty
-}
-
-// ---------------------------------------------------------------------------
-inline
-Win32DebugLogStream::~Win32DebugLogStream(){
- // empty
-}
-
-// ---------------------------------------------------------------------------
-inline
-void Win32DebugLogStream::write(const char* message) {
- ::OutputDebugStringA( message);
-}
-
-// ---------------------------------------------------------------------------
-} // Namespace Assimp
-
-#endif // ! _WIN32
-#endif // guard
diff --git a/src/3rdparty/assimp/code/X3DExporter.cpp b/src/3rdparty/assimp/code/X3DExporter.cpp
deleted file mode 100644
index b560855fb..000000000
--- a/src/3rdparty/assimp/code/X3DExporter.cpp
+++ /dev/null
@@ -1,735 +0,0 @@
-/// \file X3DExporter.cpp
-/// \brief X3D-format files exporter for Assimp. Implementation.
-/// \date 2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
-
-#include "X3DExporter.hpp"
-
-// Header files, Assimp.
-#include "Exceptional.h"
-#include "StringUtils.h"
-#include <assimp/Exporter.hpp>
-#include <assimp/IOSystem.hpp>
-
-using namespace std;
-
-namespace Assimp
-{
-
-void ExportSceneX3D(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
-{
- X3DExporter exporter(pFile, pIOSystem, pScene, pProperties);
-}
-
-}// namespace Assimp
-
-namespace Assimp
-{
-
-void X3DExporter::IndentationStringSet(const size_t pNewLevel)
-{
- if(pNewLevel > mIndentationString.size())
- {
- if(pNewLevel > mIndentationString.capacity()) mIndentationString.reserve(pNewLevel + 1);
-
- for(size_t i = 0, i_e = pNewLevel - mIndentationString.size(); i < i_e; i++) mIndentationString.push_back('\t');
- }
- else if(pNewLevel < mIndentationString.size())
- {
- mIndentationString.resize(pNewLevel);
- }
-}
-
-void X3DExporter::XML_Write(const string& pData)
-{
- if(pData.size() == 0) return;
- if(mOutFile->Write((void*)pData.data(), pData.length(), 1) != 1) throw DeadlyExportError("Failed to write scene data!");
-}
-
-aiMatrix4x4 X3DExporter::Matrix_GlobalToCurrent(const aiNode& pNode) const
-{
-aiNode* cur_node;
-std::list<aiMatrix4x4> matr;
-aiMatrix4x4 out_matr;
-
- // starting walk from current element to root
- matr.push_back(pNode.mTransformation);
- cur_node = pNode.mParent;
- if(cur_node != nullptr)
- {
- do
- {
- matr.push_back(cur_node->mTransformation);
- cur_node = cur_node->mParent;
- } while(cur_node != nullptr);
- }
-
- // multiplicate all matrices in reverse order
- for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
-
- return out_matr;
-}
-
-void X3DExporter::AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
-{
- pTargetString = to_string(pValue);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, string& pTargetString)
-{
- pTargetString.clear();
- pTargetString.reserve(pArray_Size * 6);// (Number + space) * 3.
- for(size_t idx = 0; idx < pArray_Size; idx++)
- pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " " + to_string(pArray[idx].z) + " ");
-
- // remove last space symbol.
- pTargetString.resize(pTargetString.length() - 1);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
-{
- pTargetString.clear();
- pTargetString.reserve(pArray_Size * 4);// (Number + space) * 2.
- for(size_t idx = 0; idx < pArray_Size; idx++)
- pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " ");
-
- // remove last space symbol.
- pTargetString.resize(pTargetString.length() - 1);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, string& pTargetString)
-{
- pTargetString.clear();
- pTargetString.reserve(pArray_Size * 4);// (Number + space) * 2.
- for(size_t idx = 0; idx < pArray_Size; idx++)
- pTargetString.append(to_string(pArray[idx].x) + " " + to_string(pArray[idx].y) + " ");
-
- // remove last space symbol.
- pTargetString.resize(pTargetString.length() - 1);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, string& pTargetString)
-{
- pTargetString.clear();
- pTargetString.reserve(pArray_Size * 8);// (Number + space) * 4.
- for(size_t idx = 0; idx < pArray_Size; idx++)
- pTargetString.append(to_string(pArray[idx].r) + " " + to_string(pArray[idx].g) + " " + to_string(pArray[idx].b) + " " +
- to_string(pArray[idx].a) + " ");
-
- // remove last space symbol.
- pTargetString.resize(pTargetString.length() - 1);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
-{
- pTargetString.clear();
- pTargetString.reserve(pArray_Size * 6);// (Number + space) * 3.
- for(size_t idx = 0; idx < pArray_Size; idx++)
- pTargetString.append(to_string(pArray[idx].r) + " " + to_string(pArray[idx].g) + " " + to_string(pArray[idx].b) + " ");
-
- // remove last space symbol.
- pTargetString.resize(pTargetString.length() - 1);
- AttrHelper_CommaToPoint(pTargetString);
-}
-
-void X3DExporter::AttrHelper_Color3ToAttrList(std::list<SAttribute>& pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
-{
-string tstr;
-
- if(pValue == pDefaultValue) return;
-
- AttrHelper_Col3DArrToString(&pValue, 1, tstr);
- pList.push_back({pName, tstr});
-}
-
-void X3DExporter::AttrHelper_FloatToAttrList(std::list<SAttribute>& pList, const string& pName, const float pValue, const float pDefaultValue)
-{
-string tstr;
-
- if(pValue == pDefaultValue) return;
-
- AttrHelper_FloatToString(pValue, tstr);
- pList.push_back({pName, tstr});
-}
-
-void X3DExporter::NodeHelper_OpenNode(const string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const list<SAttribute>& pAttrList)
-{
- // Write indentation.
- IndentationStringSet(pTabLevel);
- XML_Write(mIndentationString);
- // Begin of the element
- XML_Write("<" + pNodeName);
- // Write attributes
- for(const SAttribute& attr: pAttrList) { XML_Write(" " + attr.Name + "='" + attr.Value + "'"); }
-
- // End of the element
- if(pEmptyElement)
- {
- XML_Write("/>\n");
- }
- else
- {
- XML_Write(">\n");
- }
-}
-
-void X3DExporter::NodeHelper_OpenNode(const string& pNodeName, const size_t pTabLevel, const bool pEmptyElement)
-{
-const list<SAttribute> attr_list;
-
- NodeHelper_OpenNode(pNodeName, pTabLevel, pEmptyElement, attr_list);
-}
-
-void X3DExporter::NodeHelper_CloseNode(const string& pNodeName, const size_t pTabLevel)
-{
- // Write indentation.
- IndentationStringSet(pTabLevel);
- XML_Write(mIndentationString);
- // Write element
- XML_Write("</" + pNodeName + ">\n");
-}
-
-void X3DExporter::Export_Node(const aiNode *pNode, const size_t pTabLevel)
-{
-bool transform = false;
-list<SAttribute> attr_list;
-
- // In Assimp lights is stored in next way: light source store in mScene->mLights and in node tree must present aiNode with name same as
- // light source has. Considering it we must compare every aiNode name with light sources names. Why not to look where ligths is present
- // and save them to fili? Because corresponding aiNode can be already written to file and we can only add information to file not to edit.
- if(CheckAndExport_Light(*pNode, pTabLevel)) return;
-
- // Check if need DEF.
- if(pNode->mName.length) attr_list.push_back({"DEF", pNode->mName.C_Str()});
-
- // Check if need <Transformation> node against <Group>.
- if(!pNode->mTransformation.IsIdentity())
- {
- auto Vector2String = [this](const aiVector3D pVector) -> string
- {
- string tstr = to_string(pVector.x) + " " + to_string(pVector.y) + " " + to_string(pVector.z);
-
- AttrHelper_CommaToPoint(tstr);
-
- return tstr;
- };
-
- auto Rotation2String = [this](const aiVector3D pAxis, const ai_real pAngle) -> string
- {
- string tstr = to_string(pAxis.x) + " " + to_string(pAxis.y) + " " + to_string(pAxis.z) + " " + to_string(pAngle);
-
- AttrHelper_CommaToPoint(tstr);
-
- return tstr;
- };
-
- aiVector3D scale, translate, rotate_axis;
- ai_real rotate_angle;
-
- transform = true;
- pNode->mTransformation.Decompose(scale, rotate_axis, rotate_angle, translate);
- // Check if values different from default
- if((rotate_angle != 0) && (rotate_axis.Length() > 0))
- attr_list.push_back({"rotation", Rotation2String(rotate_axis, rotate_angle)});
-
- if(!scale.Equal({1.0,1.0,1.0})) {
- attr_list.push_back({"scale", Vector2String(scale)});
- }
- if(translate.Length() > 0) {
- attr_list.push_back({"translation", Vector2String(translate)});
- }
- }
-
- // Begin node if need.
- if(transform)
- NodeHelper_OpenNode("Transform", pTabLevel, false, attr_list);
- else
- NodeHelper_OpenNode("Group", pTabLevel);
-
- // Export metadata
- if(pNode->mMetaData != nullptr)
- {
- for(size_t idx_prop = 0; idx_prop < pNode->mMetaData->mNumProperties; idx_prop++)
- {
- const aiString* key;
- const aiMetadataEntry* entry;
-
- if(pNode->mMetaData->Get(idx_prop, key, entry))
- {
- switch(entry->mType)
- {
- case AI_BOOL:
- Export_MetadataBoolean(*key, *static_cast<bool*>(entry->mData), pTabLevel + 1);
- break;
- case AI_DOUBLE:
- Export_MetadataDouble(*key, *static_cast<double*>(entry->mData), pTabLevel + 1);
- break;
- case AI_FLOAT:
- Export_MetadataFloat(*key, *static_cast<float*>(entry->mData), pTabLevel + 1);
- break;
- case AI_INT32:
- Export_MetadataInteger(*key, *static_cast<int32_t*>(entry->mData), pTabLevel + 1);
- break;
- case AI_AISTRING:
- Export_MetadataString(*key, *static_cast<aiString*>(entry->mData), pTabLevel + 1);
- break;
- default:
- LogError("Unsupported metadata type: " + to_string(entry->mType));
- break;
- }// switch(entry->mType)
- }
- }
- }// if(pNode->mMetaData != nullptr)
-
- // Export meshes.
- for(size_t idx_mesh = 0; idx_mesh < pNode->mNumMeshes; idx_mesh++) Export_Mesh(pNode->mMeshes[idx_mesh], pTabLevel + 1);
- // Export children.
- for(size_t idx_node = 0; idx_node < pNode->mNumChildren; idx_node++) Export_Node(pNode->mChildren[idx_node], pTabLevel + 1);
-
- // End node if need.
- if(transform)
- NodeHelper_CloseNode("Transform", pTabLevel);
- else
- NodeHelper_CloseNode("Group", pTabLevel);
-}
-
-void X3DExporter::Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
-{
-const char* NodeName_IFS = "IndexedFaceSet";
-const char* NodeName_Shape = "Shape";
-
-list<SAttribute> attr_list;
-aiMesh& mesh = *mScene->mMeshes[pIdxMesh];// create alias for conveniance.
-
- // Check if mesh already defined early.
- if(mDEF_Map_Mesh.find(pIdxMesh) != mDEF_Map_Mesh.end())
- {
- // Mesh already defined, just refer to it
- attr_list.push_back({"USE", mDEF_Map_Mesh.at(pIdxMesh)});
- NodeHelper_OpenNode(NodeName_Shape, pTabLevel, true, attr_list);
-
- return;
- }
-
- string mesh_name(mesh.mName.C_Str() + string("_IDX_") + to_string(pIdxMesh));// Create mesh name
-
- // Define mesh name.
- attr_list.push_back({"DEF", mesh_name});
- mDEF_Map_Mesh[pIdxMesh] = mesh_name;
-
- //
- // "Shape" node.
- //
- NodeHelper_OpenNode(NodeName_Shape, pTabLevel, false, attr_list);
- attr_list.clear();
-
- //
- // "Appearance" node.
- //
- Export_Material(mesh.mMaterialIndex, pTabLevel + 1);
-
- //
- // "IndexedFaceSet" node.
- //
- // Fill attributes which differ from default. In Assimp for colors, vertices and normals used one indices set. So, only "coordIndex" must be set.
- string coordIndex;
-
- // fill coordinates index.
- coordIndex.reserve(mesh.mNumVertices * 4);// Index + space + Face delimiter
- for(size_t idx_face = 0; idx_face < mesh.mNumFaces; idx_face++)
- {
- const aiFace& face_cur = mesh.mFaces[idx_face];
-
- for(size_t idx_vert = 0; idx_vert < face_cur.mNumIndices; idx_vert++)
- {
- coordIndex.append(to_string(face_cur.mIndices[idx_vert]) + " ");
- }
-
- coordIndex.append("-1 ");// face delimiter.
- }
-
- // remove last space symbol.
- coordIndex.resize(coordIndex.length() - 1);
- attr_list.push_back({"coordIndex", coordIndex});
- // create node
- NodeHelper_OpenNode(NodeName_IFS, pTabLevel + 1, false, attr_list);
- attr_list.clear();
- // Child nodes for "IndexedFaceSet" needed when used colors, textures or normals.
- string attr_value;
-
- // Export <Coordinate>
- AttrHelper_Vec3DArrToString(mesh.mVertices, mesh.mNumVertices, attr_value);
- attr_list.push_back({"point", attr_value});
- NodeHelper_OpenNode("Coordinate", pTabLevel + 2, true, attr_list);
- attr_list.clear();
-
- // Export <ColorRGBA>
- if(mesh.HasVertexColors(0))
- {
- AttrHelper_Col4DArrToString(mesh.mColors[0], mesh.mNumVertices, attr_value);
- attr_list.push_back({"color", attr_value});
- NodeHelper_OpenNode("ColorRGBA", pTabLevel + 2, true, attr_list);
- attr_list.clear();
- }
-
- // Export <TextureCoordinate>
- if(mesh.HasTextureCoords(0))
- {
- AttrHelper_Vec3DAsVec2fArrToString(mesh.mTextureCoords[0], mesh.mNumVertices, attr_value);
- attr_list.push_back({"point", attr_value});
- NodeHelper_OpenNode("TextureCoordinate", pTabLevel + 2, true, attr_list);
- attr_list.clear();
- }
-
- // Export <Normal>
- if(mesh.HasNormals())
- {
- AttrHelper_Vec3DArrToString(mesh.mNormals, mesh.mNumVertices, attr_value);
- attr_list.push_back({"vector", attr_value});
- NodeHelper_OpenNode("Normal", pTabLevel + 2, true, attr_list);
- attr_list.clear();
- }
-
- //
- // Close opened nodes.
- //
- NodeHelper_CloseNode(NodeName_IFS, pTabLevel + 1);
- NodeHelper_CloseNode(NodeName_Shape, pTabLevel);
-}
-
-void X3DExporter::Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
-{
-const char* NodeName_A = "Appearance";
-
-list<SAttribute> attr_list;
-aiMaterial& material = *mScene->mMaterials[pIdxMaterial];// create alias for conveniance.
-
- // Check if material already defined early.
- if(mDEF_Map_Material.find(pIdxMaterial) != mDEF_Map_Material.end())
- {
- // Material already defined, just refer to it
- attr_list.push_back({"USE", mDEF_Map_Material.at(pIdxMaterial)});
- NodeHelper_OpenNode(NodeName_A, pTabLevel, true, attr_list);
-
- return;
- }
-
- string material_name(string("_IDX_") + to_string(pIdxMaterial));// Create material name
- aiString ai_mat_name;
-
- if(material.Get(AI_MATKEY_NAME, ai_mat_name) == AI_SUCCESS) material_name.insert(0, ai_mat_name.C_Str());
-
- // Define material name.
- attr_list.push_back({"DEF", material_name});
- mDEF_Map_Material[pIdxMaterial] = material_name;
-
- //
- // "Appearance" node.
- //
- NodeHelper_OpenNode(NodeName_A, pTabLevel, false, attr_list);
- attr_list.clear();
-
- //
- // "Material" node.
- //
- {
- auto Color4ToAttrList = [&](const string& pAttrName, const aiColor4D& pAttrValue, const aiColor3D& pAttrDefaultValue)
- {
- string tstr;
-
- if(aiColor3D(pAttrValue.r, pAttrValue.g, pAttrValue.b) != pAttrDefaultValue)
- {
- AttrHelper_Col4DArrToString(&pAttrValue, 1, tstr);
- attr_list.push_back({pAttrName, tstr});
- }
- };
-
- float tvalf;
- aiColor3D color3;
- aiColor4D color4;
-
- // ambientIntensity="0.2" SFFloat [inputOutput]
- if(material.Get(AI_MATKEY_COLOR_AMBIENT, color3) == AI_SUCCESS)
- AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", (color3.r + color3.g + color3.b) / 3.0f, 0.2f);
- else if(material.Get(AI_MATKEY_COLOR_AMBIENT, color4) == AI_SUCCESS)
- AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", (color4.r + color4.g + color4.b) / 3.0f, 0.2f);
-
- // diffuseColor="0.8 0.8 0.8" SFColor [inputOutput]
- if(material.Get(AI_MATKEY_COLOR_DIFFUSE, color3) == AI_SUCCESS)
- AttrHelper_Color3ToAttrList(attr_list, "diffuseColor", color3, aiColor3D(0.8f, 0.8f, 0.8f));
- else if(material.Get(AI_MATKEY_COLOR_DIFFUSE, color4) == AI_SUCCESS)
- Color4ToAttrList("diffuseColor", color4, aiColor3D(0.8f, 0.8f, 0.8f));
-
- // emissiveColor="0 0 0" SFColor [inputOutput]
- if(material.Get(AI_MATKEY_COLOR_EMISSIVE, color3) == AI_SUCCESS)
- AttrHelper_Color3ToAttrList(attr_list, "emissiveColor", color3, aiColor3D(0, 0, 0));
- else if(material.Get(AI_MATKEY_COLOR_EMISSIVE, color4) == AI_SUCCESS)
- Color4ToAttrList("emissiveColor", color4, aiColor3D(0, 0, 0));
-
- // shininess="0.2" SFFloat [inputOutput]
- if(material.Get(AI_MATKEY_SHININESS, tvalf) == AI_SUCCESS) AttrHelper_FloatToAttrList(attr_list, "shininess", tvalf, 0.2f);
-
- // specularColor="0 0 0" SFColor [inputOutput]
- if(material.Get(AI_MATKEY_COLOR_SPECULAR, color3) == AI_SUCCESS)
- AttrHelper_Color3ToAttrList(attr_list, "specularColor", color3, aiColor3D(0, 0, 0));
- else if(material.Get(AI_MATKEY_COLOR_SPECULAR, color4) == AI_SUCCESS)
- Color4ToAttrList("specularColor", color4, aiColor3D(0, 0, 0));
-
- // transparency="0" SFFloat [inputOutput]
- if(material.Get(AI_MATKEY_OPACITY, tvalf) == AI_SUCCESS)
- {
- if(tvalf > 1) tvalf = 1;
-
- tvalf = 1.0f - tvalf;
- AttrHelper_FloatToAttrList(attr_list, "transparency", tvalf, 0);
- }
-
- NodeHelper_OpenNode("Material", pTabLevel + 1, true, attr_list);
- attr_list.clear();
- }// "Material" node. END.
-
- //
- // "ImageTexture" node.
- //
- {
- auto RepeatToAttrList = [&](const string& pAttrName, const bool pAttrValue)
- {
- if(!pAttrValue) attr_list.push_back({pAttrName, "false"});
- };
-
- bool tvalb;
- aiString tstring;
-
- // url="" MFString
- if(material.Get(AI_MATKEY_TEXTURE_DIFFUSE(0), tstring) == AI_SUCCESS)
- {
- if(strncmp(tstring.C_Str(), AI_EMBEDDED_TEXNAME_PREFIX, strlen(AI_EMBEDDED_TEXNAME_PREFIX)) == 0)
- LogError("Embedded texture is not supported");
- else
- attr_list.push_back({"url", string("\"") + tstring.C_Str() + "\""});
- }
-
- // repeatS="true" SFBool
- if(material.Get(AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0), tvalb) == AI_SUCCESS) RepeatToAttrList("repeatS", tvalb);
-
- // repeatT="true" SFBool
- if(material.Get(AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0), tvalb) == AI_SUCCESS) RepeatToAttrList("repeatT", tvalb);
-
- NodeHelper_OpenNode("ImageTexture", pTabLevel + 1, true, attr_list);
- attr_list.clear();
- }// "ImageTexture" node. END.
-
- //
- // "TextureTransform" node.
- //
- {
- auto Vec2ToAttrList = [&](const string& pAttrName, const aiVector2D& pAttrValue, const aiVector2D& pAttrDefaultValue)
- {
- string tstr;
-
- if(pAttrValue != pAttrDefaultValue)
- {
- AttrHelper_Vec2DArrToString(&pAttrValue, 1, tstr);
- attr_list.push_back({pAttrName, tstr});
- }
- };
-
- aiUVTransform transform;
-
- if(material.Get(AI_MATKEY_UVTRANSFORM_DIFFUSE(0), transform) == AI_SUCCESS)
- {
- Vec2ToAttrList("translation", transform.mTranslation, aiVector2D(0, 0));
- AttrHelper_FloatToAttrList(attr_list, "rotation", transform.mRotation, 0);
- Vec2ToAttrList("scale", transform.mScaling, aiVector2D(1, 1));
-
- NodeHelper_OpenNode("TextureTransform", pTabLevel + 1, true, attr_list);
- attr_list.clear();
- }
- }// "TextureTransform" node. END.
-
- //
- // Close opened nodes.
- //
- NodeHelper_CloseNode(NodeName_A, pTabLevel);
-
-}
-
-void X3DExporter::Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
- attr_list.push_back({"name", pKey.C_Str()});
- attr_list.push_back({"value", pValue ? "true" : "false"});
- NodeHelper_OpenNode("MetadataBoolean", pTabLevel, true, attr_list);
-}
-
-void X3DExporter::Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
- attr_list.push_back({"name", pKey.C_Str()});
- attr_list.push_back({"value", to_string(pValue)});
- NodeHelper_OpenNode("MetadataDouble", pTabLevel, true, attr_list);
-}
-
-void X3DExporter::Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
- attr_list.push_back({"name", pKey.C_Str()});
- attr_list.push_back({"value", to_string(pValue)});
- NodeHelper_OpenNode("MetadataFloat", pTabLevel, true, attr_list);
-}
-
-void X3DExporter::Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
- attr_list.push_back({"name", pKey.C_Str()});
- attr_list.push_back({"value", to_string(pValue)});
- NodeHelper_OpenNode("MetadataInteger", pTabLevel, true, attr_list);
-}
-
-void X3DExporter::Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
- attr_list.push_back({"name", pKey.C_Str()});
- attr_list.push_back({"value", pValue.C_Str()});
- NodeHelper_OpenNode("MetadataString", pTabLevel, true, attr_list);
-}
-
-bool X3DExporter::CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
-{
-list<SAttribute> attr_list;
-
-auto Vec3ToAttrList = [&](const string& pAttrName, const aiVector3D& pAttrValue, const aiVector3D& pAttrDefaultValue)
-{
- string tstr;
-
- if(pAttrValue != pAttrDefaultValue)
- {
- AttrHelper_Vec3DArrToString(&pAttrValue, 1, tstr);
- attr_list.push_back({pAttrName, tstr});
- }
-};
-
-size_t idx_light;
-bool found = false;
-
- // Name of the light source can not be empty.
- if(pNode.mName.length == 0) return false;
-
- // search for light with name like node has.
- for(idx_light = 0; mScene->mNumLights; idx_light++)
- {
- if(pNode.mName == mScene->mLights[idx_light]->mName)
- {
- found = true;
- break;
- }
- }
-
- if(!found) return false;
-
- // Light source is found.
- const aiLight& light = *mScene->mLights[idx_light];// Alias for conveniance.
-
- aiMatrix4x4 trafo_mat = Matrix_GlobalToCurrent(pNode).Inverse();
-
- attr_list.push_back({"DEF", light.mName.C_Str()});
- attr_list.push_back({"global", "true"});// "false" is not supported.
- // ambientIntensity="0" SFFloat [inputOutput]
- AttrHelper_FloatToAttrList(attr_list, "ambientIntensity", aiVector3D(light.mColorAmbient.r, light.mColorAmbient.g, light.mColorAmbient.b).Length(), 0);
- // color="1 1 1" SFColor [inputOutput]
- AttrHelper_Color3ToAttrList(attr_list, "color", light.mColorDiffuse, aiColor3D(1, 1, 1));
-
- switch(light.mType)
- {
- case aiLightSource_DIRECTIONAL:
- {
- aiVector3D direction = trafo_mat * light.mDirection;
-
- Vec3ToAttrList("direction", direction, aiVector3D(0, 0, -1));
- NodeHelper_OpenNode("DirectionalLight", pTabLevel, true, attr_list);
- }
-
- break;
- case aiLightSource_POINT:
- {
- aiVector3D attenuation(light.mAttenuationConstant, light.mAttenuationLinear, light.mAttenuationQuadratic);
- aiVector3D location = trafo_mat * light.mPosition;
-
- Vec3ToAttrList("attenuation", attenuation, aiVector3D(1, 0, 0));
- Vec3ToAttrList("location", location, aiVector3D(0, 0, 0));
- NodeHelper_OpenNode("PointLight", pTabLevel, true, attr_list);
- }
-
- break;
- case aiLightSource_SPOT:
- {
- aiVector3D attenuation(light.mAttenuationConstant, light.mAttenuationLinear, light.mAttenuationQuadratic);
- aiVector3D location = trafo_mat * light.mPosition;
- aiVector3D direction = trafo_mat * light.mDirection;
-
- Vec3ToAttrList("attenuation", attenuation, aiVector3D(1, 0, 0));
- Vec3ToAttrList("location", location, aiVector3D(0, 0, 0));
- Vec3ToAttrList("direction", direction, aiVector3D(0, 0, -1));
- AttrHelper_FloatToAttrList(attr_list, "beamWidth", light.mAngleInnerCone, 0.7854f);
- AttrHelper_FloatToAttrList(attr_list, "cutOffAngle", light.mAngleOuterCone, 1.570796f);
- NodeHelper_OpenNode("SpotLight", pTabLevel, true, attr_list);
- }
-
- break;
- default:
- throw DeadlyExportError("Unknown light type: " + to_string(light.mType));
- }// switch(light.mType)
-
- return true;
-}
-
-X3DExporter::X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
- : mScene(pScene)
-{
-list<SAttribute> attr_list;
-
- mOutFile = pIOSystem->Open(pFileName, "wt");
- if(mOutFile == nullptr) throw DeadlyExportError("Could not open output .x3d file: " + string(pFileName));
-
- // Begin document
- XML_Write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- XML_Write("<!DOCTYPE X3D PUBLIC \"ISO//Web3D//DTD X3D 3.3//EN\" \"http://www.web3d.org/specifications/x3d-3.3.dtd\">\n");
- // Root node
- attr_list.push_back({"profile", "Interchange"});
- attr_list.push_back({"version", "3.3"});
- attr_list.push_back({"xmlns:xsd", "http://www.w3.org/2001/XMLSchema-instance"});
- attr_list.push_back({"xsd:noNamespaceSchemaLocation", "http://www.web3d.org/specifications/x3d-3.3.xsd"});
- NodeHelper_OpenNode("X3D", 0, false, attr_list);
- attr_list.clear();
- // <head>: meta data.
- NodeHelper_OpenNode("head", 1);
- XML_Write(mIndentationString + "<!-- All \"meta\" from this section tou will found in <Scene> node as MetadataString nodes. -->\n");
- NodeHelper_CloseNode("head", 1);
- // Scene node.
- NodeHelper_OpenNode("Scene", 1);
- Export_Node(mScene->mRootNode, 2);
- NodeHelper_CloseNode("Scene", 1);
- // Close Root node.
- NodeHelper_CloseNode("X3D", 0);
- // Cleanup
- pIOSystem->Close(mOutFile);
- mOutFile = nullptr;
-}
-
-}// namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_X3D_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/X3DExporter.hpp b/src/3rdparty/assimp/code/X3DExporter.hpp
deleted file mode 100644
index 45f302d8d..000000000
--- a/src/3rdparty/assimp/code/X3DExporter.hpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/// \file X3DExporter.hpp
-/// \brief X3D-format files exporter for Assimp.
-/// \date 2016
-/// \author smal.root@gmail.com
-// Thanks to acorn89 for support.
-
-#ifndef INCLUDED_AI_X3D_EXPORTER_H
-#define INCLUDED_AI_X3D_EXPORTER_H
-
-// Header files, Assimp.
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-
-// Header files, stdlib.
-#include <list>
-#include <string>
-
-namespace Assimp
-{
-
-/// \class X3DExporter
-/// Class which export aiScene to X3D file.
-///
-/// Limitations.
-///
-/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
-/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
-/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
-///
-/// Supported nodes:
-/// Core component:
-/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
-/// Geometry3D component:
-/// "IndexedFaceSet"
-/// Grouping component:
-/// "Group", "Transform"
-/// Lighting component:
-/// "DirectionalLight", "PointLight", "SpotLight"
-/// Rendering component:
-/// "ColorRGBA", "Coordinate", "Normal"
-/// Shape component:
-/// "Shape", "Appearance", "Material"
-/// Texturing component:
-/// "ImageTexture", "TextureCoordinate", "TextureTransform"
-///
-class X3DExporter
-{
- /***********************************************/
- /******************** Types ********************/
- /***********************************************/
-
- struct SAttribute
- {
- const std::string Name;
- const std::string Value;
- };
-
- /***********************************************/
- /****************** Constants ******************/
- /***********************************************/
-
- const aiScene* const mScene;
-
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
- IOStream* mOutFile;
- std::map<size_t, std::string> mDEF_Map_Mesh;
- std::map<size_t, std::string> mDEF_Map_Material;
-
-private:
-
- std::string mIndentationString;
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
- /// \fn void IndentationStringSet(const size_t pNewLevel)
- /// Set value of the indentation string.
- /// \param [in] pNewLevel - new level of the indentation.
- void IndentationStringSet(const size_t pNewLevel);
-
- /// \fn void XML_Write(const std::string& pData)
- /// Write data to XML-file.
- /// \param [in] pData - reference to string which must be written.
- void XML_Write(const std::string& pData);
-
- /// \fn aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const
- /// Calculate transformation matrix for transformation from global coordinate system to pointed aiNode.
- /// \param [in] pNode - reference to local node.
- /// \return calculated matrix.
- aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
-
- /// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
- /// Convert commas in string to points. That's needed because "std::to_string" result depends on locale (regional settings).
- /// \param [in, out] pStringWithComma - reference to string, which must be modified.
- void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }
-
- /// \fn void AttrHelper_FloatToString(const float pValue, std::string& pTargetString)
- /// Converts float to string.
- /// \param [in] pValue - value for converting.
- /// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
- void AttrHelper_FloatToString(const float pValue, std::string& pTargetString);
-
- /// \fn void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// Converts array of vectors to string.
- /// \param [in] pArray - pointer to array of vectors.
- /// \param [in] pArray_Size - count of elements in array.
- /// \param [out] pTargetString - reference to string where result will be placed. Will be cleared before using.
- void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
-
- /// \fn void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- void AttrHelper_Vec2DArrToString(const aiVector2D* pArray, const size_t pArray_Size, std::string& pTargetString);
-
- /// \fn void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// Only x, y is used from aiVector3D.
- void AttrHelper_Vec3DAsVec2fArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString);
-
- /// \fn void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// \overload void AttrHelper_Vec3DArrToString(const aiVector3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// Converts array of colors to string.
- void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString);
-
- /// \fn void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// \overload void AttrHelper_Col4DArrToString(const aiColor4D* pArray, const size_t pArray_Size, std::string& pTargetString)
- /// Converts array of colors to string.
- void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString);
-
- /// \fn void AttrHelper_FloatToAttrList(std::list<SAttribute> pList, const std::string& pName, const float pValue, const float pDefaultValue)
- /// \overload void AttrHelper_Col3DArrToString(const aiColor3D* pArray, const size_t pArray_Size, std::string& pTargetString)
- void AttrHelper_FloatToAttrList(std::list<SAttribute> &pList, const std::string& pName, const float pValue, const float pDefaultValue);
-
- /// \fn void AttrHelper_Color3ToAttrList(std::list<SAttribute> pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue)
- /// Add attribute to list if value not equal to default.
- /// \param [in] pList - target list of the attributes.
- /// \param [in] pName - name of new attribute.
- /// \param [in] pValue - value of the new attribute.
- /// \param [in] pDefaultValue - default value for checking: if pValue is equal to pDefaultValue then attribute will not be added.
- void AttrHelper_Color3ToAttrList(std::list<SAttribute> &pList, const std::string& pName, const aiColor3D& pValue, const aiColor3D& pDefaultValue);
-
- /// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
- /// Begin new XML-node element.
- /// \param [in] pNodeName - name of the element.
- /// \param [in] pTabLevel - indentation level.
- /// \param [in] pEmtyElement - if true then empty element will be created.
- /// \param [in] pAttrList - list of the attributes for element.
- void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList);
-
- /// \fn void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false)
- /// \overload void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement, const std::list<SAttribute>& pAttrList)
- void NodeHelper_OpenNode(const std::string& pNodeName, const size_t pTabLevel, const bool pEmptyElement = false);
-
- /// \fn void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel)
- /// End XML-node element.
- /// \param [in] pNodeName - name of the element.
- /// \param [in] pTabLevel - indentation level.
- void NodeHelper_CloseNode(const std::string& pNodeName, const size_t pTabLevel);
-
- /// \fn void Export_Node(const aiNode* pNode, const size_t pTabLevel)
- /// Export data from scene to XML-file: aiNode.
- /// \param [in] pNode - source aiNode.
- /// \param [in] pTabLevel - indentation level.
- void Export_Node(const aiNode* pNode, const size_t pTabLevel);
-
- /// \fn void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel)
- /// Export data from scene to XML-file: aiMesh.
- /// \param [in] pMesh - index of the source aiMesh.
- /// \param [in] pTabLevel - indentation level.
- void Export_Mesh(const size_t pIdxMesh, const size_t pTabLevel);
-
- /// \fn void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel)
- /// Export data from scene to XML-file: aiMaterial.
- /// \param [in] pIdxMaterial - index of the source aiMaterial.
- /// \param [in] pTabLevel - indentation level.
- void Export_Material(const size_t pIdxMaterial, const size_t pTabLevel);
-
- /// \fn void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
- /// Export data from scene to XML-file: aiMetadata.
- /// \param [in] pKey - source data: value of the metadata key.
- /// \param [in] pValue - source data: value of the metadata value.
- /// \param [in] pTabLevel - indentation level.
- void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel);
-
- /// \fn void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel)
- /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
- void Export_MetadataDouble(const aiString& pKey, const double pValue, const size_t pTabLevel);
-
- /// \fn void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel)
- /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
- void Export_MetadataFloat(const aiString& pKey, const float pValue, const size_t pTabLevel);
-
- /// \fn void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel)
- /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
- void Export_MetadataInteger(const aiString& pKey, const int32_t pValue, const size_t pTabLevel);
-
- /// \fn void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel)
- /// \overload void Export_MetadataBoolean(const aiString& pKey, const bool pValue, const size_t pTabLevel)
- void Export_MetadataString(const aiString& pKey, const aiString& pValue, const size_t pTabLevel);
-
- /// \fn bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel)
- /// Check if node point to light source. If yes then export light source.
- /// \param [in] pNode - reference to node for checking.
- /// \param [in] pTabLevel - indentation level.
- /// \return true - if node assigned with light and it was exported, else - return false.
- bool CheckAndExport_Light(const aiNode& pNode, const size_t pTabLevel);
-
- /***********************************************/
- /************** Functions: LOG set *************/
- /***********************************************/
-
- /// \fn void LogError(const std::string& pMessage)
- /// Short variant for calling \ref DefaultLogger::get()->error()
- void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
-
-public:
-
- /// \fn X3DExporter()
- /// Default constructor.
- X3DExporter(const char* pFileName, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties);
-
- /// \fn ~X3DExporter()
- /// Default destructor.
- ~X3DExporter() {}
-
-};// class X3DExporter
-
-}// namespace Assimp
-
-#endif // INCLUDED_AI_X3D_EXPORTER_H
diff --git a/src/3rdparty/assimp/code/X3DImporter.cpp b/src/3rdparty/assimp/code/X3DImporter.cpp
deleted file mode 100644
index aaf99b309..000000000
--- a/src/3rdparty/assimp/code/X3DImporter.cpp
+++ /dev/null
@@ -1,1728 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter.cpp
-/// \brief X3D-format files importer for Assimp: main algorithm implementation.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-#include "StringUtils.h"
-
-// Header files, Assimp.
-#include <assimp/DefaultIOSystem.h>
-#include "fast_atof.h"
-#include "FIReader.hpp"
-
-// Header files, stdlib.
-#include <memory>
-#include <string>
-#include <iterator>
-
-namespace Assimp {
-
-/// \var aiImporterDesc X3DImporter::Description
-/// Constant which holds the importer description
-const aiImporterDesc X3DImporter::Description = {
- "Extensible 3D(X3D) Importer",
- "smalcom",
- "",
- "See documentation in source code. Chapter: Limitations.",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
- 0,
- 0,
- 0,
- 0,
- "x3d x3db"
-};
-
-//const std::regex X3DImporter::pattern_nws(R"([^, \t\r\n]+)");
-//const std::regex X3DImporter::pattern_true(R"(^\s*(?:true|1)\s*$)", std::regex::icase);
-
-struct WordIterator: public std::iterator<std::input_iterator_tag, const char*> {
- static const char *whitespace;
- const char *start_, *end_;
- WordIterator(const char *start, const char *end): start_(start), end_(end) {
- start_ = start + strspn(start, whitespace);
- if (start_ >= end_) {
- start_ = 0;
- }
- }
- WordIterator(): start_(0), end_(0) {}
- WordIterator(const WordIterator &other): start_(other.start_), end_(other.end_) {}
- WordIterator &operator=(const WordIterator &other) {
- start_ = other.start_;
- end_ = other.end_;
- return *this;
- }
- bool operator==(const WordIterator &other) const { return start_ == other.start_; }
- bool operator!=(const WordIterator &other) const { return start_ != other.start_; }
- WordIterator &operator++() {
- start_ += strcspn(start_, whitespace);
- start_ += strspn(start_, whitespace);
- if (start_ >= end_) {
- start_ = 0;
- }
- return *this;
- }
- WordIterator operator++(int) {
- WordIterator result(*this);
- ++(*this);
- return result;
- }
- const char *operator*() const { return start_; }
-};
-
-const char *WordIterator::whitespace = ", \t\r\n";
-
-X3DImporter::X3DImporter()
-: NodeElement_Cur( nullptr )
-, mReader( nullptr ) {
- // empty
-}
-
-X3DImporter::~X3DImporter() {
- // Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
- Clear();
-}
-
-void X3DImporter::Clear() {
- NodeElement_Cur = nullptr;
- // Delete all elements
- if(NodeElement_List.size()) {
- for ( std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++ ) {
- delete *it;
- }
- NodeElement_List.clear();
- }
-}
-
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: find set ************************************************************/
-/*********************************************************************************************************************************************/
-
-bool X3DImporter::FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
-{
- for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++)
- {
- if(((*it)->Type == pType) && ((*it)->ID == pID))
- {
- if(pElement != nullptr) *pElement = *it;
-
- return true;
- }
- }// for(std::list<CX3DImporter_NodeElement*>::iterator it = NodeElement_List.begin(); it != NodeElement_List.end(); it++)
-
- return false;
-}
-
-bool X3DImporter::FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID,
- const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
-{
- bool found = false;// flag: true - if requested element is found.
-
- // Check if pStartNode - this is the element, we are looking for.
- if((pStartNode->Type == pType) && (pStartNode->ID == pID))
- {
- found = true;
- if ( pElement != nullptr )
- {
- *pElement = pStartNode;
- }
-
- goto fne_fn_end;
- }// if((pStartNode->Type() == pType) && (pStartNode->ID() == pID))
-
- // Check childs of pStartNode.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = pStartNode->Child.begin(); ch_it != pStartNode->Child.end(); ch_it++)
- {
- found = FindNodeElement_FromNode(*ch_it, pID, pType, pElement);
- if ( found )
- {
- break;
- }
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = it->Child.begin(); ch_it != it->Child.end(); ch_it++)
-
-fne_fn_end:
-
- return found;
-}
-
-bool X3DImporter::FindNodeElement(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement)
-{
- CX3DImporter_NodeElement* tnd = NodeElement_Cur;// temporary pointer to node.
- bool static_search = false;// flag: true if searching in static node.
-
- // At first check if we have deal with static node. Go up through parent nodes and check flag.
- while(tnd != nullptr)
- {
- if(tnd->Type == CX3DImporter_NodeElement::ENET_Group)
- {
- if(((CX3DImporter_NodeElement_Group*)tnd)->Static)
- {
- static_search = true;// Flag found, stop walking up. Node with static flag will holded in tnd variable.
- break;
- }
- }
-
- tnd = tnd->Parent;// go up in graph.
- }// while(tnd != nullptr)
-
- // at now call appropriate search function.
- if ( static_search )
- {
- return FindNodeElement_FromNode( tnd, pID, pType, pElement );
- }
- else
- {
- return FindNodeElement_FromRoot( pID, pType, pElement );
- }
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: throw set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void X3DImporter::Throw_ArgOutOfRange(const std::string& pArgument)
-{
- throw DeadlyImportError("Argument value is out of range for: \"" + pArgument + "\".");
-}
-
-void X3DImporter::Throw_CloseNotFound(const std::string& pNode)
-{
- throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
-}
-
-void X3DImporter::Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue)
-{
- throw DeadlyImportError("In <" + std::string(mReader->getNodeName()) + "> failed to convert attribute value \"" + pAttrValue +
- "\" from string to array of floats.");
-}
-
-void X3DImporter::Throw_DEF_And_USE()
-{
- throw DeadlyImportError("\"DEF\" and \"USE\" can not be defined both in <" + std::string(mReader->getNodeName()) + ">.");
-}
-
-void X3DImporter::Throw_IncorrectAttr(const std::string& pAttrName)
-{
- throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
-}
-
-void X3DImporter::Throw_IncorrectAttrValue(const std::string& pAttrName)
-{
- throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
-}
-
-void X3DImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription)
-{
- throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription);
-}
-
-void X3DImporter::Throw_TagCountIncorrect(const std::string& pNode)
-{
- throw DeadlyImportError("Count of open and close tags for node <" + pNode + "> are not equivalent. Seems file is corrupt.");
-}
-
-void X3DImporter::Throw_USE_NotFound(const std::string& pAttrValue)
-{
- throw DeadlyImportError("Not found node with name \"" + pAttrValue + "\" in <" + std::string(mReader->getNodeName()) + ">.");
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************* Functions: XML set ************************************************************/
-/*********************************************************************************************************************************************/
-
-void X3DImporter::XML_CheckNode_MustBeEmpty()
-{
- if(!mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must be empty.");
-}
-
-void X3DImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
-{
- static const size_t Uns_Skip_Len = 192;
- const char* Uns_Skip[ Uns_Skip_Len ] = {
- // CAD geometry component
- "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet",
- // Core
- "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo",
- // Distributed interactive simulation (DIS) component
- "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu",
- // Cube map environmental texturing component
- "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture",
- // Environmental effects component
- "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground",
- // Environmental sensor component
- "ProximitySensor", "TransformSensor", "VisibilitySensor",
- // Followers component
- "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser", "PositionChaser2D",
- "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D",
- // Geospatial component
- "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor",
- "GeoTouchSensor", "GeoTransform", "GeoViewpoint",
- // Humanoid Animation (H-Anim) component
- "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite",
- // Interpolation component
- "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator",
- "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D",
- "SplineScalarInterpolator", "SquadOrientationInterpolator",
- // Key device sensor component
- "KeySensor", "StringSensor",
- // Layering component
- "Layer", "LayerSet", "Viewport",
- // Layout component
- "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup",
- // Navigation component
- "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup",
- // Networking component
- "EXPORT", "IMPORT", "Anchor", "LoadSensor",
- // NURBS component
- "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
- "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
- "NurbsTrimmedSurface",
- // Particle systems component
- "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter", "SurfaceEmitter",
- "VolumeEmitter", "WindPhysicsModel",
- // Picking component
- "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor",
- // Pointing device sensor component
- "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor",
- // Rendering component
- "ClipPlane",
- // Rigid body physics
- "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint",
- "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint",
- // Scripting component
- "Script",
- // Programmable shaders component
- "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart",
- "ShaderProgram",
- // Shape component
- "FillProperties", "LineProperties", "TwoSidedMaterial",
- // Sound component
- "AudioClip", "Sound",
- // Text component
- "FontStyle", "Text",
- // Texturing3D Component
- "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D", "TextureTransform3D",
- // Texturing component
- "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator", "TextureProperties",
- // Time component
- "TimeSensor",
- // Event Utilities component
- "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger",
- // Volume rendering component
- "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle", "IsoSurfaceVolumeData",
- "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle", "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle",
- "VolumeData"
- };
-
- const std::string nn( mReader->getNodeName() );
- bool found = false;
- bool close_found = false;
-
- for(size_t i = 0; i < Uns_Skip_Len; i++)
- {
- if(nn == Uns_Skip[i])
- {
- found = true;
- if(mReader->isEmptyElement())
- {
- close_found = true;
-
- goto casu_cres;
- }
-
- while(mReader->read())
- {
- if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName()))
- {
- close_found = true;
-
- goto casu_cres;
- }
- }
- }
- }
-
-casu_cres:
-
- if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
-
- if(close_found)
- LogInfo("Skipping node \"" + nn + "\" in " + pParentNodeName + ".");
- else
- Throw_CloseNotFound(nn);
-}
-
-bool X3DImporter::XML_SearchNode(const std::string& pNodeName)
-{
- while(mReader->read())
- {
- if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true;
- }
-
- return false;
-}
-
-bool X3DImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
-{
- auto boolValue = std::dynamic_pointer_cast<const FIBoolValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (boolValue) {
- if (boolValue->value.size() == 1) {
- return boolValue->value.front();
- }
- throw DeadlyImportError("Invalid bool value");
- }
- else {
- std::string val(mReader->getAttributeValue(pAttrIdx));
-
- if(val == "false")
- return false;
- else if(val == "true")
- return true;
- else
- throw DeadlyImportError("Bool attribute value can contain \"false\" or \"true\" not the \"" + val + "\"");
- }
-}
-
-float X3DImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
-{
- auto floatValue = std::dynamic_pointer_cast<const FIFloatValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (floatValue) {
- if (floatValue->value.size() == 1) {
- return floatValue->value.front();
- }
- throw DeadlyImportError("Invalid float value");
- }
- else {
- std::string val;
- float tvalf;
-
- ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
- fast_atoreal_move(val.c_str(), tvalf, false);
-
- return tvalf;
- }
-}
-
-int32_t X3DImporter::XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx)
-{
- auto intValue = std::dynamic_pointer_cast<const FIIntValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (intValue) {
- if (intValue->value.size() == 1) {
- return intValue->value.front();
- }
- throw DeadlyImportError("Invalid int value");
- }
- else {
- return strtol10(mReader->getAttributeValue(pAttrIdx));
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue)
-{
- std::vector<float> tlist;
- std::vector<float>::iterator it;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
- if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
-
- it = tlist.begin();
- pValue.r = *it++;
- pValue.g = *it++;
- pValue.b = *it;
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue)
-{
- std::vector<float> tlist;
- std::vector<float>::iterator it;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
- if(tlist.size() != 2) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
-
- it = tlist.begin();
- pValue.x = *it++;
- pValue.y = *it;
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue)
-{
- std::vector<float> tlist;
- std::vector<float>::iterator it;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);
- if(tlist.size() != 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
-
- it = tlist.begin();
- pValue.x = *it++;
- pValue.y = *it++;
- pValue.z = *it;
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue)
-{
- auto boolValue = std::dynamic_pointer_cast<const FIBoolValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (boolValue) {
- pValue = boolValue->value;
- }
- else {
- const char *val = mReader->getAttributeValue(pAttrIdx);
- pValue.clear();
-
- //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
- //const std::cregex_iterator wordItEnd;
- //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::regex_match(match.str(), pattern_true); });
-
- WordIterator wordItBegin(val, val + strlen(val));
- WordIterator wordItEnd;
- std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return (::tolower(match[0]) == 't') || (match[0] == '1'); });
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector<int32_t>& pValue)
-{
- auto intValue = std::dynamic_pointer_cast<const FIIntValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (intValue) {
- pValue = intValue->value;
- }
- else {
- const char *val = mReader->getAttributeValue(pAttrIdx);
- pValue.clear();
-
- //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
- //const std::cregex_iterator wordItEnd;
- //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stoi(match.str()); });
-
- WordIterator wordItBegin(val, val + strlen(val));
- WordIterator wordItEnd;
- std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atoi(match); });
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector<float>& pValue)
-{
- auto floatValue = std::dynamic_pointer_cast<const FIFloatValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (floatValue) {
- pValue = floatValue->value;
- }
- else {
- const char *val = mReader->getAttributeValue(pAttrIdx);
- pValue.clear();
-
- //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
- //const std::cregex_iterator wordItEnd;
- //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stof(match.str()); });
-
- WordIterator wordItBegin(val, val + strlen(val));
- WordIterator wordItEnd;
- std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return static_cast<float>(atof(match)); });
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector<double>& pValue)
-{
- auto doubleValue = std::dynamic_pointer_cast<const FIDoubleValue>(mReader->getAttributeEncodedValue(pAttrIdx));
- if (doubleValue) {
- pValue = doubleValue->value;
- }
- else {
- const char *val = mReader->getAttributeValue(pAttrIdx);
- pValue.clear();
-
- //std::cregex_iterator wordItBegin(val, val + strlen(val), pattern_nws);
- //const std::cregex_iterator wordItEnd;
- //std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const std::cmatch &match) { return std::stod(match.str()); });
-
- WordIterator wordItBegin(val, val + strlen(val));
- WordIterator wordItEnd;
- std::transform(wordItBegin, wordItEnd, std::back_inserter(pValue), [](const char *match) { return atof(match); });
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list<aiColor3D>& pValue)
-{
- std::vector<float> tlist;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
- if(tlist.size() % 3) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
-
- // copy data to array
- for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
- {
- aiColor3D tcol;
-
- tcol.r = *it++;
- tcol.g = *it++;
- tcol.b = *it++;
- pValue.push_back(tcol);
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector<aiColor3D>& pValue)
-{
- std::list<aiColor3D> tlist;
-
- XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list
- // and copy to array
- if(tlist.size() > 0)
- {
- pValue.reserve(tlist.size());
- for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); it++) pValue.push_back(*it);
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue)
-{
- std::vector<float> tlist;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
- if(tlist.size() % 4) Throw_ConvertFail_Str2ArrF(mReader->getAttributeValue(pAttrIdx));
-
- // copy data to array
- for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
- {
- aiColor4D tcol;
-
- tcol.r = *it++;
- tcol.g = *it++;
- tcol.b = *it++;
- tcol.a = *it++;
- pValue.push_back(tcol);
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector<aiColor4D>& pValue)
-{
- std::list<aiColor4D> tlist;
-
- XML_ReadNode_GetAttrVal_AsListCol4f(pAttrIdx, tlist);// read as list
- // and copy to array
- if(tlist.size() > 0)
- {
- pValue.reserve(tlist.size());
- for ( std::list<aiColor4D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
- {
- pValue.push_back( *it );
- }
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue)
-{
- std::vector<float> tlist;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
- if ( tlist.size() % 2 )
- {
- Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) );
- }
-
- // copy data to array
- for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
- {
- aiVector2D tvec;
-
- tvec.x = *it++;
- tvec.y = *it++;
- pValue.push_back(tvec);
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector<aiVector2D>& pValue)
-{
- std::list<aiVector2D> tlist;
-
- XML_ReadNode_GetAttrVal_AsListVec2f(pAttrIdx, tlist);// read as list
- // and copy to array
- if(tlist.size() > 0)
- {
- pValue.reserve(tlist.size());
- for ( std::list<aiVector2D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
- {
- pValue.push_back( *it );
- }
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue)
-{
- std::vector<float> tlist;
-
- XML_ReadNode_GetAttrVal_AsArrF(pAttrIdx, tlist);// read as list
- if ( tlist.size() % 3 )
- {
- Throw_ConvertFail_Str2ArrF( mReader->getAttributeValue( pAttrIdx ) );
- }
-
- // copy data to array
- for(std::vector<float>::iterator it = tlist.begin(); it != tlist.end();)
- {
- aiVector3D tvec;
-
- tvec.x = *it++;
- tvec.y = *it++;
- tvec.z = *it++;
- pValue.push_back(tvec);
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector<aiVector3D>& pValue)
-{
- std::list<aiVector3D> tlist;
-
- XML_ReadNode_GetAttrVal_AsListVec3f(pAttrIdx, tlist);// read as list
- // and copy to array
- if(tlist.size() > 0)
- {
- pValue.reserve(tlist.size());
- for ( std::list<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++ )
- {
- pValue.push_back( *it );
- }
- }
-}
-
-void X3DImporter::XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list<std::string>& pValue)
-{
- // make copy of attribute value - strings list.
- const size_t tok_str_len = strlen(mReader->getAttributeValue(pAttrIdx));
- if ( 0 == tok_str_len )
- {
- Throw_IncorrectAttrValue( mReader->getAttributeName( pAttrIdx ) );
- }
-
- // get pointer to begin of value.
- char *tok_str = const_cast<char*>(mReader->getAttributeValue(pAttrIdx));
- char *tok_str_end = tok_str + tok_str_len;
- // string list has following format: attr_name='"s1" "s2" "sn"'.
- do
- {
- char* tbeg;
- char* tend;
- size_t tlen;
- std::string tstr;
-
- // find begin of string(element of string list): "sn".
- tbeg = strstr(tok_str, "\"");
- if(tbeg == nullptr) Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx));
-
- tbeg++;// forward pointer from '\"' symbol to next after it.
- tok_str = tbeg;
- // find end of string(element of string list): "sn".
- tend = strstr(tok_str, "\"");
- if(tend == nullptr) Throw_IncorrectAttrValue(mReader->getAttributeName(pAttrIdx));
-
- tok_str = tend + 1;
- // create storage for new string
- tlen = tend - tbeg;
- tstr.resize(tlen);// reserve enough space and copy data
- memcpy((void*)tstr.data(), tbeg, tlen);// not strcpy because end of copied string from tok_str has no terminator.
- // and store string in output list.
- pValue.push_back(tstr);
- } while(tok_str < tok_str_end);
-}
-
-/*********************************************************************************************************************************************/
-/****************************************************** Functions: geometry helper set ******************************************************/
-/*********************************************************************************************************************************************/
-
-aiVector3D X3DImporter::GeometryHelper_Make_Point2D(const float pAngle, const float pRadius)
-{
- return aiVector3D(pRadius * std::cos(pAngle), pRadius * std::sin(pAngle), 0);
-}
-
-void X3DImporter::GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments,
- std::list<aiVector3D>& pVertices)
-{
- // check argument values ranges.
- if ( ( pStartAngle < -AI_MATH_TWO_PI_F ) || ( pStartAngle > AI_MATH_TWO_PI_F ) )
- {
- Throw_ArgOutOfRange( "GeometryHelper_Make_Arc2D.pStartAngle" );
- }
- if ( ( pEndAngle < -AI_MATH_TWO_PI_F ) || ( pEndAngle > AI_MATH_TWO_PI_F ) )
- {
- Throw_ArgOutOfRange( "GeometryHelper_Make_Arc2D.pEndAngle" );
- }
- if ( pRadius <= 0 )
- {
- Throw_ArgOutOfRange( "GeometryHelper_Make_Arc2D.pRadius" );
- }
-
- // calculate arc angle and check type of arc
- float angle_full = std::fabs(pEndAngle - pStartAngle);
- if ( ( angle_full > AI_MATH_TWO_PI_F ) || ( angle_full == 0.0f ) )
- {
- angle_full = AI_MATH_TWO_PI_F;
- }
-
- // calculate angle for one step - angle to next point of line.
- float angle_step = angle_full / (float)pNumSegments;
- // make points
- for(size_t pi = 0; pi <= pNumSegments; pi++)
- {
- float tangle = pStartAngle + pi * angle_step;
- pVertices.push_back(GeometryHelper_Make_Point2D(tangle, pRadius));
- }// for(size_t pi = 0; pi <= pNumSegments; pi++)
-
- // if we making full circle then add last vertex equal to first vertex
- if(angle_full == AI_MATH_TWO_PI_F) pVertices.push_back(*pVertices.begin());
-}
-
-void X3DImporter::GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>& pPoint, std::list<aiVector3D>& pLine)
-{
- std::list<aiVector3D>::const_iterator pit = pPoint.begin();
- std::list<aiVector3D>::const_iterator pit_last = pPoint.end();
-
- pit_last--;
-
- if ( pPoint.size() < 2 )
- {
- Throw_ArgOutOfRange( "GeometryHelper_Extend_PointToLine.pPoint.size() can not be less than 2." );
- }
-
- // add first point of first line.
- pLine.push_back(*pit++);
- // add internal points
- while(pit != pit_last)
- {
- pLine.push_back(*pit);// second point of previous line
- pLine.push_back(*pit);// first point of next line
- pit++;
- }
- // add last point of last line
- pLine.push_back(*pit);
-}
-
-void X3DImporter::GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int32_t>& pPolylineCoordIdx, std::list<int32_t>& pLineCoordIdx)
-{
- std::list<int32_t>::const_iterator plit = pPolylineCoordIdx.begin();
-
- while(plit != pPolylineCoordIdx.end())
- {
- // add first point of polyline
- pLineCoordIdx.push_back(*plit++);
- while((*plit != (-1)) && (plit != pPolylineCoordIdx.end()))
- {
- std::list<int32_t>::const_iterator plit_next;
-
- plit_next = plit, plit_next++;
- pLineCoordIdx.push_back(*plit);// second point of previous line.
- pLineCoordIdx.push_back(-1);// delimiter
- if((*plit_next == (-1)) || (plit_next == pPolylineCoordIdx.end())) break;// current polyline is finished
-
- pLineCoordIdx.push_back(*plit);// first point of next line.
- plit = plit_next;
- }// while((*plit != (-1)) && (plit != pPolylineCoordIdx.end()))
- }// while(plit != pPolylineCoordIdx.end())
-}
-
-#define MESH_RectParallelepiped_CREATE_VERT \
-aiVector3D vert_set[8]; \
-float x1, x2, y1, y2, z1, z2, hs; \
- \
- hs = pSize.x / 2, x1 = -hs, x2 = hs; \
- hs = pSize.y / 2, y1 = -hs, y2 = hs; \
- hs = pSize.z / 2, z1 = -hs, z2 = hs; \
- vert_set[0].Set(x2, y1, z2); \
- vert_set[1].Set(x2, y2, z2); \
- vert_set[2].Set(x2, y2, z1); \
- vert_set[3].Set(x2, y1, z1); \
- vert_set[4].Set(x1, y1, z2); \
- vert_set[5].Set(x1, y2, z2); \
- vert_set[6].Set(x1, y2, z1); \
- vert_set[7].Set(x1, y1, z1)
-
-void X3DImporter::GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list<aiVector3D>& pVertices)
-{
- MESH_RectParallelepiped_CREATE_VERT;
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 3, 2, 1, 0);// front
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 6, 7, 4, 5);// back
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 7, 3, 0, 4);// left
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 2, 6, 5, 1);// right
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 0, 1, 5, 4);// top
- MACRO_FACE_ADD_QUAD_FA(true, pVertices, vert_set, 7, 6, 2, 3);// bottom
-}
-
-#undef MESH_RectParallelepiped_CREATE_VERT
-
-void X3DImporter::GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const
-{
- std::vector<int32_t> f_data(pCoordIdx);
- std::vector<unsigned int> inds;
- unsigned int prim_type = 0;
-
- if ( f_data.back() != ( -1 ) )
- {
- f_data.push_back( -1 );
- }
-
- // reserve average size.
- pFaces.reserve(f_data.size() / 3);
- inds.reserve(4);
- //PrintVectorSet("build. ci", pCoordIdx);
- for(std::vector<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
- {
- // when face is got count how many indices in it.
- if(*it == (-1))
- {
- aiFace tface;
- size_t ts;
-
- ts = inds.size();
- switch(ts)
- {
- case 0: goto mg_m_err;
- case 1: prim_type |= aiPrimitiveType_POINT; break;
- case 2: prim_type |= aiPrimitiveType_LINE; break;
- case 3: prim_type |= aiPrimitiveType_TRIANGLE; break;
- default: prim_type |= aiPrimitiveType_POLYGON; break;
- }
-
- tface.mNumIndices = static_cast<unsigned int>(ts);
- tface.mIndices = new unsigned int[ts];
- memcpy(tface.mIndices, inds.data(), ts * sizeof(unsigned int));
- pFaces.push_back(tface);
- inds.clear();
- }// if(*it == (-1))
- else
- {
- inds.push_back(*it);
- }// if(*it == (-1)) else
- }// for(std::list<int32_t>::iterator it = f_data.begin(); it != f_data.end(); it++)
-//PrintVectorSet("build. faces", pCoordIdx);
-
- pPrimitiveTypes = prim_type;
-
- return;
-
-mg_m_err:
-
- for(size_t i = 0, i_e = pFaces.size(); i < i_e; i++) delete [] pFaces.at(i).mIndices;
-
- pFaces.clear();
-}
-
-void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const
-{
-std::list<aiColor4D> tcol;
-
- // create RGBA array from RGB.
- for(std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++) tcol.push_back(aiColor4D((*it).r, (*it).g, (*it).b, 1));
-
- // call existing function for adding RGBA colors
- MeshGeometry_AddColor(pMesh, tcol, pColorPerVertex);
-}
-
-void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const
-{
- std::list<aiColor4D>::const_iterator col_it = pColors.begin();
-
- if(pColorPerVertex)
- {
- if(pColors.size() < pMesh.mNumVertices)
- {
- throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
- to_string(pMesh.mNumVertices) + ").");
- }
-
- // copy colors to mesh
- pMesh.mColors[0] = new aiColor4D[pMesh.mNumVertices];
- for(size_t i = 0; i < pMesh.mNumVertices; i++) pMesh.mColors[0][i] = *col_it++;
- }// if(pColorPerVertex)
- else
- {
- if(pColors.size() < pMesh.mNumFaces)
- {
- throw DeadlyImportError("MeshGeometry_AddColor1. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
- to_string(pMesh.mNumFaces) + ").");
- }
-
- // copy colors to mesh
- pMesh.mColors[0] = new aiColor4D[pMesh.mNumVertices];
- for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
- {
- // apply color to all vertices of face
- for ( size_t vi = 0, vi_e = pMesh.mFaces[ fi ].mNumIndices; vi < vi_e; vi++ )
- {
- pMesh.mColors[ 0 ][ pMesh.mFaces[ fi ].mIndices[ vi ] ] = *col_it;
- }
-
- col_it++;
- }
- }// if(pColorPerVertex) else
-}
-
-void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
- const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const
-{
- std::list<aiColor4D> tcol;
-
- // create RGBA array from RGB.
- for ( std::list<aiColor3D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
- {
- tcol.push_back( aiColor4D( ( *it ).r, ( *it ).g, ( *it ).b, 1 ) );
- }
-
- // call existing function for adding RGBA colors
- MeshGeometry_AddColor(pMesh, pCoordIdx, pColorIdx, tcol, pColorPerVertex);
-}
-
-void X3DImporter::MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
- const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const
-{
- std::vector<aiColor4D> col_tgt_arr;
- std::list<aiColor4D> col_tgt_list;
- std::vector<aiColor4D> col_arr_copy;
-
- if ( pCoordIdx.size() == 0 )
- {
- throw DeadlyImportError( "MeshGeometry_AddColor2. pCoordIdx can not be empty." );
- }
-
- // copy list to array because we are need indexed access to colors.
- col_arr_copy.reserve(pColors.size());
- for ( std::list<aiColor4D>::const_iterator it = pColors.begin(); it != pColors.end(); it++ )
- {
- col_arr_copy.push_back( *it );
- }
-
- if(pColorPerVertex)
- {
- if(pColorIdx.size() > 0)
- {
- // check indices array count.
- if(pColorIdx.size() < pCoordIdx.size())
- {
- throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
- ") can not be less than Coords inidces count(" + to_string(pCoordIdx.size()) + ").");
- }
- // create list with colors for every vertex.
- col_tgt_arr.resize(pMesh.mNumVertices);
- for(std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin(), coordidx_it = pCoordIdx.begin(); colidx_it != pColorIdx.end(); colidx_it++, coordidx_it++)
- {
- if ( *colidx_it == ( -1 ) )
- {
- continue;// skip faces delimiter
- }
- if ( ( unsigned int ) ( *coordidx_it ) > pMesh.mNumVertices )
- {
- throw DeadlyImportError( "MeshGeometry_AddColor2. Coordinate idx is out of range." );
- }
- if ( ( unsigned int ) *colidx_it > pMesh.mNumVertices )
- {
- throw DeadlyImportError( "MeshGeometry_AddColor2. Color idx is out of range." );
- }
-
- col_tgt_arr[*coordidx_it] = col_arr_copy[*colidx_it];
- }
- }// if(pColorIdx.size() > 0)
- else
- {
- // when color indices list is absent use CoordIdx.
- // check indices array count.
- if(pColors.size() < pMesh.mNumVertices)
- {
- throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Vertices count(" +
- to_string(pMesh.mNumVertices) + ").");
- }
- // create list with colors for every vertex.
- col_tgt_arr.resize(pMesh.mNumVertices);
- for ( size_t i = 0; i < pMesh.mNumVertices; i++ )
- {
- col_tgt_arr[ i ] = col_arr_copy[ i ];
- }
- }// if(pColorIdx.size() > 0) else
- }// if(pColorPerVertex)
- else
- {
- if(pColorIdx.size() > 0)
- {
- // check indices array count.
- if(pColorIdx.size() < pMesh.mNumFaces)
- {
- throw DeadlyImportError("MeshGeometry_AddColor2. Colors indices count(" + to_string(pColorIdx.size()) +
- ") can not be less than Faces count(" + to_string(pMesh.mNumFaces) + ").");
- }
- // create list with colors for every vertex using faces indices.
- col_tgt_arr.resize(pMesh.mNumFaces);
-
- std::vector<int32_t>::const_iterator colidx_it = pColorIdx.begin();
- for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
- {
- if((unsigned int)*colidx_it > pMesh.mNumFaces) throw DeadlyImportError("MeshGeometry_AddColor2. Face idx is out of range.");
-
- col_tgt_arr[fi] = col_arr_copy[*colidx_it++];
- }
- }// if(pColorIdx.size() > 0)
- else
- {
- // when color indices list is absent use CoordIdx.
- // check indices array count.
- if(pColors.size() < pMesh.mNumFaces)
- {
- throw DeadlyImportError("MeshGeometry_AddColor2. Colors count(" + to_string(pColors.size()) + ") can not be less than Faces count(" +
- to_string(pMesh.mNumFaces) + ").");
- }
- // create list with colors for every vertex using faces indices.
- col_tgt_arr.resize(pMesh.mNumFaces);
- for(size_t fi = 0; fi < pMesh.mNumFaces; fi++) col_tgt_arr[fi] = col_arr_copy[fi];
-
- }// if(pColorIdx.size() > 0) else
- }// if(pColorPerVertex) else
-
- // copy array to list for calling function that add colors.
- for(std::vector<aiColor4D>::const_iterator it = col_tgt_arr.begin(); it != col_tgt_arr.end(); it++) col_tgt_list.push_back(*it);
- // add prepared colors list to mesh.
- MeshGeometry_AddColor(pMesh, col_tgt_list, pColorPerVertex);
-}
-
-void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pNormalIdx,
- const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const
-{
- std::vector<size_t> tind;
- std::vector<aiVector3D> norm_arr_copy;
-
- // copy list to array because we are need indexed access to normals.
- norm_arr_copy.reserve(pNormals.size());
- for ( std::list<aiVector3D>::const_iterator it = pNormals.begin(); it != pNormals.end(); it++ )
- {
- norm_arr_copy.push_back( *it );
- }
-
- if(pNormalPerVertex)
- {
- if(pNormalIdx.size() > 0)
- {
- // check indices array count.
- if(pNormalIdx.size() != pCoordIdx.size()) throw DeadlyImportError("Normals and Coords inidces count must be equal.");
-
- tind.reserve(pNormalIdx.size());
- for(std::vector<int32_t>::const_iterator it = pNormalIdx.begin(); it != pNormalIdx.end(); it++)
- {
- if(*it != (-1)) tind.push_back(*it);
- }
-
- // copy normals to mesh
- pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
- for(size_t i = 0; (i < pMesh.mNumVertices) && (i < tind.size()); i++)
- {
- if(tind[i] >= norm_arr_copy.size())
- throw DeadlyImportError("MeshGeometry_AddNormal. Normal index(" + to_string(tind[i]) +
- ") is out of range. Normals count: " + to_string(norm_arr_copy.size()) + ".");
-
- pMesh.mNormals[i] = norm_arr_copy[tind[i]];
- }
- }
- else
- {
- if(pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal.");
-
- // copy normals to mesh
- pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
- std::list<aiVector3D>::const_iterator norm_it = pNormals.begin();
- for(size_t i = 0; i < pMesh.mNumVertices; i++) pMesh.mNormals[i] = *norm_it++;
- }
- }// if(pNormalPerVertex)
- else
- {
- if(pNormalIdx.size() > 0)
- {
- if(pMesh.mNumFaces != pNormalIdx.size()) throw DeadlyImportError("Normals faces count must be equal to mesh faces count.");
-
- std::vector<int32_t>::const_iterator normidx_it = pNormalIdx.begin();
-
- tind.reserve(pNormalIdx.size());
- for(size_t i = 0, i_e = pNormalIdx.size(); i < i_e; i++) tind.push_back(*normidx_it++);
-
- }
- else
- {
- tind.reserve(pMesh.mNumFaces);
- for(size_t i = 0; i < pMesh.mNumFaces; i++) tind.push_back(i);
-
- }
-
- // copy normals to mesh
- pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
- for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
- {
- aiVector3D tnorm;
-
- tnorm = norm_arr_copy[tind[fi]];
- for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = tnorm;
- }
- }// if(pNormalPerVertex) else
-}
-
-void X3DImporter::MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const
-{
- std::list<aiVector3D>::const_iterator norm_it = pNormals.begin();
-
- if(pNormalPerVertex)
- {
- if(pNormals.size() != pMesh.mNumVertices) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and vertices count must be equal.");
-
- // copy normals to mesh
- pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
- for(size_t i = 0; i < pMesh.mNumVertices; i++) pMesh.mNormals[i] = *norm_it++;
- }// if(pNormalPerVertex)
- else
- {
- if(pNormals.size() != pMesh.mNumFaces) throw DeadlyImportError("MeshGeometry_AddNormal. Normals and faces count must be equal.");
-
- // copy normals to mesh
- pMesh.mNormals = new aiVector3D[pMesh.mNumVertices];
- for(size_t fi = 0; fi < pMesh.mNumFaces; fi++)
- {
- // apply color to all vertices of face
- for(size_t vi = 0, vi_e = pMesh.mFaces[fi].mNumIndices; vi < vi_e; vi++) pMesh.mNormals[pMesh.mFaces[fi].mIndices[vi]] = *norm_it;
-
- norm_it++;
- }
- }// if(pNormalPerVertex) else
-}
-
-void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pTexCoordIdx,
- const std::list<aiVector2D>& pTexCoords) const
-{
- std::vector<aiVector3D> texcoord_arr_copy;
- std::vector<aiFace> faces;
- unsigned int prim_type;
-
- // copy list to array because we are need indexed access to normals.
- texcoord_arr_copy.reserve(pTexCoords.size());
- for(std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++)
- {
- texcoord_arr_copy.push_back(aiVector3D((*it).x, (*it).y, 0));
- }
-
- if(pTexCoordIdx.size() > 0)
- {
- GeometryHelper_CoordIdxStr2FacesArr(pTexCoordIdx, faces, prim_type);
- if ( faces.empty() )
- {
- throw DeadlyImportError( "Failed to add texture coordinates to mesh, faces list is empty." );
- }
- if ( faces.size() != pMesh.mNumFaces )
- {
- throw DeadlyImportError( "Texture coordinates faces count must be equal to mesh faces count." );
- }
- }
- else
- {
- GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type);
- }
-
- pMesh.mTextureCoords[0] = new aiVector3D[pMesh.mNumVertices];
- pMesh.mNumUVComponents[0] = 2;
- for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++)
- {
- if(pMesh.mFaces[fi].mNumIndices != faces.at(fi).mNumIndices)
- throw DeadlyImportError("Number of indices in texture face and mesh face must be equal. Invalid face index: " + to_string(fi) + ".");
-
- for(size_t ii = 0; ii < pMesh.mFaces[fi].mNumIndices; ii++)
- {
- size_t vert_idx = pMesh.mFaces[fi].mIndices[ii];
- size_t tc_idx = faces.at(fi).mIndices[ii];
-
- pMesh.mTextureCoords[0][vert_idx] = texcoord_arr_copy.at(tc_idx);
- }
- }// for(size_t fi = 0, fi_e = faces.size(); fi < fi_e; fi++)
-}
-
-void X3DImporter::MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVector2D>& pTexCoords) const
-{
- std::vector<aiVector3D> tc_arr_copy;
-
- if ( pTexCoords.size() != pMesh.mNumVertices )
- {
- throw DeadlyImportError( "MeshGeometry_AddTexCoord. Texture coordinates and vertices count must be equal." );
- }
-
- // copy list to array because we are need convert aiVector2D to aiVector3D and also get indexed access as a bonus.
- tc_arr_copy.reserve(pTexCoords.size());
- for ( std::list<aiVector2D>::const_iterator it = pTexCoords.begin(); it != pTexCoords.end(); it++ )
- {
- tc_arr_copy.push_back( aiVector3D( ( *it ).x, ( *it ).y, 0 ) );
- }
-
- // copy texture coordinates to mesh
- pMesh.mTextureCoords[0] = new aiVector3D[pMesh.mNumVertices];
- pMesh.mNumUVComponents[0] = 2;
- for ( size_t i = 0; i < pMesh.mNumVertices; i++ )
- {
- pMesh.mTextureCoords[ 0 ][ i ] = tc_arr_copy[ i ];
- }
-}
-
-aiMesh* X3DImporter::GeometryHelper_MakeMesh(const std::vector<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const
-{
- std::vector<aiFace> faces;
- unsigned int prim_type = 0;
-
- // create faces array from input string with vertices indices.
- GeometryHelper_CoordIdxStr2FacesArr(pCoordIdx, faces, prim_type);
- if ( !faces.size() )
- {
- throw DeadlyImportError( "Failed to create mesh, faces list is empty." );
- }
-
- //
- // Create new mesh and copy geometry data.
- //
- aiMesh *tmesh = new aiMesh;
- size_t ts = faces.size();
- // faces
- tmesh->mFaces = new aiFace[ts];
- tmesh->mNumFaces = static_cast<unsigned int>(ts);
- for(size_t i = 0; i < ts; i++) tmesh->mFaces[i] = faces.at(i);
-
- // vertices
- std::list<aiVector3D>::const_iterator vit = pVertices.begin();
-
- ts = pVertices.size();
- tmesh->mVertices = new aiVector3D[ts];
- tmesh->mNumVertices = static_cast<unsigned int>(ts);
- for ( size_t i = 0; i < ts; i++ )
- {
- tmesh->mVertices[ i ] = *vit++;
- }
-
- // set primitives type and return result.
- tmesh->mPrimitiveTypes = prim_type;
-
- return tmesh;
-}
-
-/*********************************************************************************************************************************************/
-/************************************************************ Functions: parse set ***********************************************************/
-/*********************************************************************************************************************************************/
-
-void X3DImporter::ParseHelper_Group_Begin(const bool pStatic)
-{
- CX3DImporter_NodeElement_Group* new_group = new CX3DImporter_NodeElement_Group(NodeElement_Cur, pStatic);// create new node with current node as parent.
-
- // if we are adding not the root element then add new element to current element child list.
- if ( NodeElement_Cur != nullptr )
- {
- NodeElement_Cur->Child.push_back( new_group );
- }
-
- NodeElement_List.push_back(new_group);// it's a new element - add it to list.
- NodeElement_Cur = new_group;// switch current element to new one.
-}
-
-void X3DImporter::ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode)
-{
- NodeElement_Cur->Child.push_back(pNode);// add new element to current element child list.
- NodeElement_Cur = pNode;// switch current element to new one.
-}
-
-void X3DImporter::ParseHelper_Node_Exit()
-{
- // check if we can walk up.
- if ( NodeElement_Cur != nullptr )
- {
- NodeElement_Cur = NodeElement_Cur->Parent;
- }
-}
-
-void X3DImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
-{
- pOutString.clear();
- const size_t instr_len = strlen(pInStr);
- if ( 0 == instr_len )
- {
- return;
- }
-
- pOutString.reserve(instr_len * 3 / 2);
- // check and correct floats in format ".x". Must be "x.y".
- if ( pInStr[ 0 ] == '.' )
- {
- pOutString.push_back( '0' );
- }
-
- pOutString.push_back(pInStr[0]);
- for(size_t ci = 1; ci < instr_len; ci++)
- {
- if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t')))
- {
- pOutString.push_back('0');
- pOutString.push_back('.');
- }
- else
- {
- pOutString.push_back(pInStr[ci]);
- }
- }
-}
-
-extern FIVocabulary X3D_vocabulary_3_2;
-extern FIVocabulary X3D_vocabulary_3_3;
-
-void X3DImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
-{
- std::unique_ptr<FIReader> OldReader = std::move(mReader);// store current XMLreader.
- std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
-
- // Check whether we can read from the file
- if ( file.get() == nullptr )
- {
- throw DeadlyImportError( "Failed to open X3D file " + pFile + "." );
- }
- mReader = FIReader::create(file.get());
- if ( !mReader )
- {
- throw DeadlyImportError( "Failed to create XML reader for file" + pFile + "." );
- }
- mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.2", &X3D_vocabulary_3_2);
- mReader->registerVocabulary("urn:web3d:x3d:fi-vocabulary-3.3", &X3D_vocabulary_3_3);
- // start reading
- ParseNode_Root();
-
- // restore old XMLreader
- mReader = std::move(OldReader);
-}
-
-void X3DImporter::ParseNode_Root()
-{
- // search for root tag <X3D>
- if ( !XML_SearchNode( "X3D" ) )
- {
- throw DeadlyImportError( "Root node \"X3D\" not found." );
- }
-
- ParseHelper_Group_Begin();// create root node element.
- // parse other contents
- while(mReader->read())
- {
- if ( mReader->getNodeType() != irr::io::EXN_ELEMENT )
- {
- continue;
- }
-
- if(XML_CheckNode_NameEqual("head"))
- ParseNode_Head();
- else if(XML_CheckNode_NameEqual("Scene"))
- ParseNode_Scene();
- else
- XML_CheckNode_SkipUnsupported("Root");
- }
-
- // exit from root node element.
- ParseHelper_Node_Exit();
-}
-
-void X3DImporter::ParseNode_Head()
-{
- bool close_found = false;// flag: true if close tag of node are found.
-
- while(mReader->read())
- {
- if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if(XML_CheckNode_NameEqual("meta"))
- {
- XML_CheckNode_MustBeEmpty();
-
- // adding metadata from <head> as MetaString from <Scene>
- bool added( false );
- CX3DImporter_NodeElement_MetaString* ms = new CX3DImporter_NodeElement_MetaString(NodeElement_Cur);
-
- ms->Name = mReader->getAttributeValueSafe("name");
- // name must not be empty
- if(!ms->Name.empty())
- {
- ms->Value.push_back(mReader->getAttributeValueSafe("content"));
- NodeElement_List.push_back(ms);
- if ( NodeElement_Cur != nullptr )
- {
- NodeElement_Cur->Child.push_back( ms );
- added = true;
- }
- }
- // if an error has occurred, release instance
- if ( !added ) {
- delete ms;
- }
- }// if(XML_CheckNode_NameEqual("meta"))
- }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
- else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if(XML_CheckNode_NameEqual("head"))
- {
- close_found = true;
- break;
- }
- }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else
- }// while(mReader->read())
-
- if ( !close_found )
- {
- Throw_CloseNotFound( "head" );
- }
-}
-
-void X3DImporter::ParseNode_Scene()
-{
- auto GroupCounter_Increase = [](size_t& pCounter, const char* pGroupName) -> void
- {
- pCounter++;
- if(pCounter == 0) throw DeadlyImportError("Group counter overflow. Too much groups with type: " + std::string(pGroupName) + ".");
-};
-
-auto GroupCounter_Decrease = [&](size_t& pCounter, const char* pGroupName) -> void
-{
- if(pCounter == 0) Throw_TagCountIncorrect(pGroupName);
-
- pCounter--;
-};
-
-static const char* GroupName_Group = "Group";
-static const char* GroupName_StaticGroup = "StaticGroup";
-static const char* GroupName_Transform = "Transform";
-static const char* GroupName_Switch = "Switch";
-
-bool close_found = false;
-size_t counter_group = 0;
-size_t counter_transform = 0;
-size_t counter_switch = 0;
-
- // while create static node? Because objects name used deeper in "USE" attribute can be equal to some meta in <head> node.
- ParseHelper_Group_Begin(true);
- while(mReader->read())
- {
- if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
- {
- if(XML_CheckNode_NameEqual("Shape"))
- {
- ParseNode_Shape_Shape();
- }
- else if(XML_CheckNode_NameEqual(GroupName_Group))
- {
- GroupCounter_Increase(counter_group, GroupName_Group);
- ParseNode_Grouping_Group();
- // if node is empty then decrease group counter at this place.
- if(mReader->isEmptyElement()) GroupCounter_Decrease(counter_group, GroupName_Group);
- }
- else if(XML_CheckNode_NameEqual(GroupName_StaticGroup))
- {
- GroupCounter_Increase(counter_group, GroupName_StaticGroup);
- ParseNode_Grouping_StaticGroup();
- // if node is empty then decrease group counter at this place.
- if(mReader->isEmptyElement()) GroupCounter_Decrease(counter_group, GroupName_StaticGroup);
- }
- else if(XML_CheckNode_NameEqual(GroupName_Transform))
- {
- GroupCounter_Increase(counter_transform, GroupName_Transform);
- ParseNode_Grouping_Transform();
- // if node is empty then decrease group counter at this place.
- if(mReader->isEmptyElement()) GroupCounter_Decrease(counter_transform, GroupName_Transform);
- }
- else if(XML_CheckNode_NameEqual(GroupName_Switch))
- {
- GroupCounter_Increase(counter_switch, GroupName_Switch);
- ParseNode_Grouping_Switch();
- // if node is empty then decrease group counter at this place.
- if(mReader->isEmptyElement()) GroupCounter_Decrease(counter_switch, GroupName_Switch);
- }
- else if(XML_CheckNode_NameEqual("DirectionalLight"))
- {
- ParseNode_Lighting_DirectionalLight();
- }
- else if(XML_CheckNode_NameEqual("PointLight"))
- {
- ParseNode_Lighting_PointLight();
- }
- else if(XML_CheckNode_NameEqual("SpotLight"))
- {
- ParseNode_Lighting_SpotLight();
- }
- else if(XML_CheckNode_NameEqual("Inline"))
- {
- ParseNode_Networking_Inline();
- }
- else if(!ParseHelper_CheckRead_X3DMetadataObject())
- {
- XML_CheckNode_SkipUnsupported("Scene");
- }
- }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT)
- else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
- {
- if(XML_CheckNode_NameEqual("Scene"))
- {
- close_found = true;
-
- break;
- }
- else if(XML_CheckNode_NameEqual(GroupName_Group))
- {
- GroupCounter_Decrease(counter_group, GroupName_Group);
- ParseNode_Grouping_GroupEnd();
- }
- else if(XML_CheckNode_NameEqual(GroupName_StaticGroup))
- {
- GroupCounter_Decrease(counter_group, GroupName_StaticGroup);
- ParseNode_Grouping_StaticGroupEnd();
- }
- else if(XML_CheckNode_NameEqual(GroupName_Transform))
- {
- GroupCounter_Decrease(counter_transform, GroupName_Transform);
- ParseNode_Grouping_TransformEnd();
- }
- else if(XML_CheckNode_NameEqual(GroupName_Switch))
- {
- GroupCounter_Decrease(counter_switch, GroupName_Switch);
- ParseNode_Grouping_SwitchEnd();
- }
- }// if(mReader->getNodeType() == irr::io::EXN_ELEMENT) else
- }// while(mReader->read())
-
- ParseHelper_Node_Exit();
-
- if(counter_group) Throw_TagCountIncorrect("Group");
- if(counter_transform) Throw_TagCountIncorrect("Transform");
- if(counter_switch) Throw_TagCountIncorrect("Switch");
- if(!close_found) Throw_CloseNotFound("Scene");
-
-}
-
-/*********************************************************************************************************************************************/
-/******************************************************** Functions: BaseImporter set ********************************************************/
-/*********************************************************************************************************************************************/
-
-bool X3DImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const
-{
- const std::string extension = GetExtension(pFile);
-
- if((extension == "x3d") || (extension == "x3db")) return true;
-
- if(!extension.length() || pCheckSig)
- {
- const char* tokens[] = { "DOCTYPE X3D PUBLIC", "http://www.web3d.org/specifications/x3d" };
-
- return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 2);
- }
-
- return false;
-}
-
-void X3DImporter::GetExtensionList(std::set<std::string>& pExtensionList)
-{
- pExtensionList.insert("x3d");
- pExtensionList.insert("x3db");
-}
-
-const aiImporterDesc* X3DImporter::GetInfo () const
-{
- return &Description;
-}
-
-void X3DImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- mpIOHandler = pIOHandler;
-
- Clear();// delete old graph.
- std::string::size_type slashPos = pFile.find_last_of("\\/");
- pIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : pFile.substr(0, slashPos + 1));
- ParseFile(pFile, pIOHandler);
- pIOHandler->PopDirectory();
- //
- // Assimp use static arrays of objects for fast speed of rendering. That's good, but need some additional operations/
- // We know that geometry objects(meshes) are stored in <Shape>, also in <Shape>-><Appearance> materials(in Assimp logical view)
- // are stored. So at first we need to count how meshes and materials are stored in scene graph.
- //
- // at first creating root node for aiScene.
- pScene->mRootNode = new aiNode;
- pScene->mRootNode->mParent = nullptr;
- pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
- //search for root node element
- NodeElement_Cur = NodeElement_List.front();
- while(NodeElement_Cur->Parent != nullptr) NodeElement_Cur = NodeElement_Cur->Parent;
-
- {// fill aiScene with objects.
- std::list<aiMesh*> mesh_list;
- std::list<aiMaterial*> mat_list;
- std::list<aiLight*> light_list;
-
- // create nodes tree
- Postprocess_BuildNode(*NodeElement_Cur, *pScene->mRootNode, mesh_list, mat_list, light_list);
- // copy needed data to scene
- if(mesh_list.size() > 0)
- {
- std::list<aiMesh*>::const_iterator it = mesh_list.begin();
-
- pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
- for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *it++;
- }
-
- if(mat_list.size() > 0)
- {
- std::list<aiMaterial*>::const_iterator it = mat_list.begin();
-
- pScene->mNumMaterials = static_cast<unsigned int>(mat_list.size());
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
- for(size_t i = 0; i < pScene->mNumMaterials; i++) pScene->mMaterials[i] = *it++;
- }
-
- if(light_list.size() > 0)
- {
- std::list<aiLight*>::const_iterator it = light_list.begin();
-
- pScene->mNumLights = static_cast<unsigned int>(light_list.size());
- pScene->mLights = new aiLight*[pScene->mNumLights];
- for(size_t i = 0; i < pScene->mNumLights; i++) pScene->mLights[i] = *it++;
- }
- }// END: fill aiScene with objects.
-
- ///TODO: IME optimize tree
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter.hpp b/src/3rdparty/assimp/code/X3DImporter.hpp
deleted file mode 100644
index 468db5f3e..000000000
--- a/src/3rdparty/assimp/code/X3DImporter.hpp
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter.hpp
-/// \brief X3D-format files importer for Assimp.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-// Thanks to acorn89 for support.
-
-#ifndef INCLUDED_AI_X3D_IMPORTER_H
-#define INCLUDED_AI_X3D_IMPORTER_H
-
-#include "X3DImporter_Node.hpp"
-
-// Header files, Assimp.
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-#include <assimp/ProgressHandler.hpp>
-#include <assimp/types.h>
-#include "BaseImporter.h"
-#include "irrXMLWrapper.h"
-#include "FIReader.hpp"
-//#include <regex>
-
-namespace Assimp {
-
-/// \class X3DImporter
-/// Class that holding scene graph which include: groups, geometry, metadata etc.
-///
-/// Limitations.
-///
-/// Pay attention that X3D is format for interactive graphic and simulations for web browsers.
-/// So not all features can be imported using Assimp.
-///
-/// Unsupported nodes:
-/// CAD geometry component:
-/// "CADAssembly", "CADFace", "CADLayer", "CADPart", "IndexedQuadSet", "QuadSet"
-/// Core component:
-/// "ROUTE", "ExternProtoDeclare", "ProtoDeclare", "ProtoInstance", "ProtoInterface", "WorldInfo"
-/// Distributed interactive simulation (DIS) component:
-/// "DISEntityManager", "DISEntityTypeMapping", "EspduTransform", "ReceiverPdu", "SignalPdu", "TransmitterPdu"
-/// Cube map environmental texturing component:
-/// "ComposedCubeMapTexture", "GeneratedCubeMapTexture", "ImageCubeMapTexture"
-/// Environmental effects component:
-/// "Background", "Fog", "FogCoordinate", "LocalFog", "TextureBackground"
-/// Environmental sensor component:
-/// "ProximitySensor", "TransformSensor", "VisibilitySensor"
-/// Followers component:
-/// "ColorChaser", "ColorDamper", "CoordinateChaser", "CoordinateDamper", "OrientationChaser", "OrientationDamper", "PositionChaser",
-/// "PositionChaser2D", "PositionDamper", "PositionDamper2D", "ScalarChaser", "ScalarDamper", "TexCoordChaser2D", "TexCoordDamper2D"
-/// Geospatial component:
-/// "GeoCoordinate", "GeoElevationGrid", "GeoLocation", "GeoLOD", "GeoMetadata", "GeoOrigin", "GeoPositionInterpolator", "GeoProximitySensor",
-/// "GeoTouchSensor", "GeoTransform", "GeoViewpoint"
-/// Humanoid Animation (H-Anim) component:
-/// "HAnimDisplacer", "HAnimHumanoid", "HAnimJoint", "HAnimSegment", "HAnimSite"
-/// Interpolation component:
-/// "ColorInterpolator", "CoordinateInterpolator", "CoordinateInterpolator2D", "EaseInEaseOut", "NormalInterpolator", "OrientationInterpolator",
-/// "PositionInterpolator", "PositionInterpolator2D", "ScalarInterpolator", "SplinePositionInterpolator", "SplinePositionInterpolator2D",
-/// "SplineScalarInterpolator", "SquadOrientationInterpolator",
-/// Key device sensor component:
-/// "KeySensor", "StringSensor"
-/// Layering component:
-/// "Layer", "LayerSet", "Viewport"
-/// Layout component:
-/// "Layout", "LayoutGroup", "LayoutLayer", "ScreenFontStyle", "ScreenGroup"
-/// Navigation component:
-/// "Billboard", "Collision", "LOD", "NavigationInfo", "OrthoViewpoint", "Viewpoint", "ViewpointGroup"
-/// Networking component:
-/// "EXPORT", "IMPORT", "Anchor", "LoadSensor"
-/// NURBS component:
-/// "Contour2D", "ContourPolyline2D", "CoordinateDouble", "NurbsCurve", "NurbsCurve2D", "NurbsOrientationInterpolator", "NurbsPatchSurface",
-/// "NurbsPositionInterpolator", "NurbsSet", "NurbsSurfaceInterpolator", "NurbsSweptSurface", "NurbsSwungSurface", "NurbsTextureCoordinate",
-/// "NurbsTrimmedSurface"
-/// Particle systems component:
-/// "BoundedPhysicsModel", "ConeEmitter", "ExplosionEmitter", "ForcePhysicsModel", "ParticleSystem", "PointEmitter", "PolylineEmitter",
-/// "SurfaceEmitter", "VolumeEmitter", "WindPhysicsModel"
-/// Picking component:
-/// "LinePickSensor", "PickableGroup", "PointPickSensor", "PrimitivePickSensor", "VolumePickSensor"
-/// Pointing device sensor component:
-/// "CylinderSensor", "PlaneSensor", "SphereSensor", "TouchSensor"
-/// Rendering component:
-/// "ClipPlane"
-/// Rigid body physics:
-/// "BallJoint", "CollidableOffset", "CollidableShape", "CollisionCollection", "CollisionSensor", "CollisionSpace", "Contact", "DoubleAxisHingeJoint",
-/// "MotorJoint", "RigidBody", "RigidBodyCollection", "SingleAxisHingeJoint", "SliderJoint", "UniversalJoint"
-/// Scripting component:
-/// "Script"
-/// Programmable shaders component:
-/// "ComposedShader", "FloatVertexAttribute", "Matrix3VertexAttribute", "Matrix4VertexAttribute", "PackagedShader", "ProgramShader", "ShaderPart",
-/// "ShaderProgram",
-/// Shape component:
-/// "FillProperties", "LineProperties", "TwoSidedMaterial"
-/// Sound component:
-/// "AudioClip", "Sound"
-/// Text component:
-/// "FontStyle", "Text"
-/// Texturing3D Component:
-/// "ComposedTexture3D", "ImageTexture3D", "PixelTexture3D", "TextureCoordinate3D", "TextureCoordinate4D", "TextureTransformMatrix3D",
-/// "TextureTransform3D"
-/// Texturing component:
-/// "MovieTexture", "MultiTexture", "MultiTextureCoordinate", "MultiTextureTransform", "PixelTexture", "TextureCoordinateGenerator",
-/// "TextureProperties",
-/// Time component:
-/// "TimeSensor"
-/// Event Utilities component:
-/// "BooleanFilter", "BooleanSequencer", "BooleanToggle", "BooleanTrigger", "IntegerSequencer", "IntegerTrigger", "TimeTrigger",
-/// Volume rendering component:
-/// "BlendedVolumeStyle", "BoundaryEnhancementVolumeStyle", "CartoonVolumeStyle", "ComposedVolumeStyle", "EdgeEnhancementVolumeStyle",
-/// "IsoSurfaceVolumeData", "OpacityMapVolumeStyle", "ProjectionVolumeStyle", "SegmentedVolumeData", "ShadedVolumeStyle",
-/// "SilhouetteEnhancementVolumeStyle", "ToneMappedVolumeStyle", "VolumeData"
-///
-/// Supported nodes:
-/// Core component:
-/// "MetadataBoolean", "MetadataDouble", "MetadataFloat", "MetadataInteger", "MetadataSet", "MetadataString"
-/// Geometry2D component:
-/// "Arc2D", "ArcClose2D", "Circle2D", "Disk2D", "Polyline2D", "Polypoint2D", "Rectangle2D", "TriangleSet2D"
-/// Geometry3D component:
-/// "Box", "Cone", "Cylinder", "ElevationGrid", "Extrusion", "IndexedFaceSet", "Sphere"
-/// Grouping component:
-/// "Group", "StaticGroup", "Switch", "Transform"
-/// Lighting component:
-/// "DirectionalLight", "PointLight", "SpotLight"
-/// Networking component:
-/// "Inline"
-/// Rendering component:
-/// "Color", "ColorRGBA", "Coordinate", "IndexedLineSet", "IndexedTriangleFanSet", "IndexedTriangleSet", "IndexedTriangleStripSet", "LineSet",
-/// "PointSet", "TriangleFanSet", "TriangleSet", "TriangleStripSet", "Normal"
-/// Shape component:
-/// "Shape", "Appearance", "Material"
-/// Texturing component:
-/// "ImageTexture", "TextureCoordinate", "TextureTransform"
-///
-/// Limitations of attribute "USE".
-/// If "USE" is set then node must be empty, like that:
-/// <Node USE='name'/>
-/// not the
-/// <Node USE='name'><!-- something --> </Node>
-///
-/// Ignored attributes: "creaseAngle", "convex", "solid".
-///
-/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
-/// It's better that Assimp main code has powerful texture coordinates generator. Then is not needed to
-/// duplicate this code in every importer.
-///
-/// Lighting limitations.
-/// If light source placed in some group with "DEF" set. And after that some node is use it group with "USE" attribute then
-/// you will get error about duplicate light sources. That's happening because Assimp require names for lights but do not like
-/// duplicates of it )).
-///
-/// Color for faces.
-/// That's happening when attribute "colorPerVertex" is set to "false". But Assimp do not hold how many colors has mesh and require
-/// equal length for mVertices and mColors. You will see the colors but vertices will use call which last used in "colorIdx".
-///
-/// That's all for now. Enjoy
-///
-class X3DImporter : public BaseImporter
-{
-public:
- std::list<CX3DImporter_NodeElement*> NodeElement_List;///< All elements of scene graph.
-
-public:
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
- /// Default constructor.
- X3DImporter();
-
- /// Default destructor.
- ~X3DImporter();
-
- /***********************************************/
- /******** Functions: parse set, public *********/
- /***********************************************/
-
- /// Parse X3D file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
- /// Also exception can be thrown if trouble will found.
- /// \param [in] pFile - name of file to be parsed.
- /// \param [in] pIOHandler - pointer to IO helper object.
- void ParseFile( const std::string& pFile, IOSystem* pIOHandler );
-
- /***********************************************/
- /********* Functions: BaseImporter set *********/
- /***********************************************/
-
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig ) const;
- void GetExtensionList( std::set<std::string>& pExtensionList );
- void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
- const aiImporterDesc* GetInfo()const;
-
-
-private:
- /// Disabled copy constructor.
- X3DImporter(const X3DImporter& pScene);
-
- /// Disabled assign operator.
- X3DImporter& operator=(const X3DImporter& pScene);
-
- /// Clear all temporary data.
- void Clear();
-
- /***********************************************/
- /************* Functions: find set *************/
- /***********************************************/
-
- /// Find requested node element. Search will be made in all existing nodes.
- /// \param [in] pID - ID of requested element.
- /// \param [in] pType - type of requested element.
- /// \param [out] pElement - pointer to pointer to item found.
- /// \return true - if the element is found, else - false.
- bool FindNodeElement_FromRoot(const std::string& pID, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
-
- /// Find requested node element. Search will be made from pointed node down to childs.
- /// \param [in] pStartNode - pointer to start node.
- /// \param [in] pID - ID of requested element.
- /// \param [in] pType - type of requested element.
- /// \param [out] pElement - pointer to pointer to item found.
- /// \return true - if the element is found, else - false.
- bool FindNodeElement_FromNode(CX3DImporter_NodeElement* pStartNode, const std::string& pID, const CX3DImporter_NodeElement::EType pType,
- CX3DImporter_NodeElement** pElement);
-
- /// Find requested node element. For "Node"'s accounting flag "Static".
- /// \param [in] pName - name of requested element.
- /// \param [in] pType - type of requested element.
- /// \param [out] pElement - pointer to pointer to item found.
- /// \return true - if the element is found, else - false.
- bool FindNodeElement(const std::string& pName, const CX3DImporter_NodeElement::EType pType, CX3DImporter_NodeElement** pElement);
-
- /***********************************************/
- /********* Functions: postprocess set **********/
- /***********************************************/
-
- /// \return transformation matrix from global coordinate system to local.
- aiMatrix4x4 PostprocessHelper_Matrix_GlobalToCurrent() const;
-
- /// Check if child elements of node element is metadata and add it to temporary list.
- /// \param [in] pNodeElement - node element where metadata is searching.
- /// \param [out] pList - temporary list for collected metadata.
- void PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const;
-
- /// Check if type of node element is metadata. E.g. <MetadataSet>, <MetadataString>.
- /// \param [in] pType - checked type.
- /// \return true - if the type corresponds to the metadata.
- bool PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const;
-
- /// Check if type of node element is geometry object and can be used to build mesh. E.g. <Box>, <Arc2D>.
- /// \param [in] pType - checked type.
- /// \return true - if the type corresponds to the mesh.
- bool PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const;
-
- /// Read CX3DImporter_NodeElement_Light, create aiLight and add it to list of the lights.
- /// \param [in] pNodeElement - reference to lisght element(<DirectionalLight>, <PointLight>, <SpotLight>).
- /// \param [out] pSceneLightList - reference to list of the lights.
- void Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list<aiLight*>& pSceneLightList) const;
-
- /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
- /// all needed data from scene graph.
- /// \param [in] pNodeElement - reference to material element(<Appearance>).
- /// \param [out] pMaterial - pointer to pointer to created material. *pMaterial must be nullptr.
- void Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const;
-
- /// Create filled structure with type \ref aiMaterial from \ref CX3DImporter_NodeElement. This function itseld extract
- /// all needed data from scene graph.
- /// \param [in] pNodeElement - reference to geometry object.
- /// \param [out] pMesh - pointer to pointer to created mesh. *pMesh must be nullptr.
- void Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const;
-
- /// Create aiNode from CX3DImporter_NodeElement. Also function check children and make recursive call.
- /// \param [out] pNode - pointer to pointer to created node. *pNode must be nullptr.
- /// \param [in] pNodeElement - CX3DImporter_NodeElement which read.
- /// \param [out] pSceneNode - aiNode for filling.
- /// \param [out] pSceneMeshList - list with aiMesh which belong to scene.
- /// \param [out] pSceneMaterialList - list with aiMaterial which belong to scene.
- /// \param [out] pSceneLightList - list with aiLight which belong to scene.
- void Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList,
- std::list<aiMaterial*>& pSceneMaterialList, std::list<aiLight*>& pSceneLightList) const;
-
- /// To create mesh and material kept in <Schape>.
- /// \param pShapeNodeElement - reference to node element which kept <Shape> data.
- /// \param pNodeMeshInd - reference to list with mesh indices. When pShapeNodeElement will read new mesh index will be added to this list.
- /// \param pSceneMeshList - reference to list with meshes. When pShapeNodeElement will read new mesh will be added to this list.
- /// \param pSceneMaterialList - reference to list with materials. When pShapeNodeElement will read new material will be added to this list.
- void Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list<unsigned int>& pNodeMeshInd,
- std::list<aiMesh*>& pSceneMeshList, std::list<aiMaterial*>& pSceneMaterialList) const;
-
- /// Check if child elements of node element is metadata and add it to scene node.
- /// \param [in] pNodeElement - node element where metadata is searching.
- /// \param [out] pSceneNode - scene node in which metadata will be added.
- void Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const;
-
- /***********************************************/
- /************* Functions: throw set ************/
- /***********************************************/
-
- /// Call that function when argument is out of range and exception must be raised.
- /// \throw DeadlyImportError.
- /// \param [in] pArgument - argument name.
- void Throw_ArgOutOfRange(const std::string& pArgument);
-
- /// Call that function when close tag of node not found and exception must be raised.
- /// E.g.:
- /// <Scene>
- /// <Shape>
- /// </Scene> <!--- shape not closed --->
- /// \throw DeadlyImportError.
- /// \param [in] pNode - node name in which exception happened.
- void Throw_CloseNotFound(const std::string& pNode);
-
- /// Call that function when string value can not be converted to floating point value and exception must be raised.
- /// \param [in] pAttrValue - attribute value.
- /// \throw DeadlyImportError.
- void Throw_ConvertFail_Str2ArrF(const std::string& pAttrValue);
-
- /// Call that function when in node defined attributes "DEF" and "USE" and exception must be raised.
- /// E.g.: <Box DEF="BigBox" USE="MegaBox">
- /// \throw DeadlyImportError.
- void Throw_DEF_And_USE();
-
- /// Call that function when attribute name is incorrect and exception must be raised.
- /// \param [in] pAttrName - attribute name.
- /// \throw DeadlyImportError.
- void Throw_IncorrectAttr(const std::string& pAttrName);
-
- /// Call that function when attribute value is incorrect and exception must be raised.
- /// \param [in] pAttrName - attribute name.
- /// \throw DeadlyImportError.
- void Throw_IncorrectAttrValue(const std::string& pAttrName);
-
- /// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
- /// E.g.:
- /// <Shape>
- /// <Box/> <!--- first geometry node --->
- /// <Sphere/> <!--- second geometry node. raise exception --->
- /// </Shape>
- /// \throw DeadlyImportError.
- /// \param [in] pNodeType - type of node which defined one more time.
- /// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
- void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
-
- /// Call that function when count of opening and closing tags which create group(e.g. <Group>) are not equal and exception must be raised.
- /// E.g.:
- /// <Scene>
- /// <Transform> <!--- first grouping node begin --->
- /// <Group> <!--- second grouping node begin --->
- /// </Transform> <!--- first grouping node end --->
- /// </Scene> <!--- one grouping node still not closed --->
- /// \throw DeadlyImportError.
- /// \param [in] pNode - node name in which exception happened.
- void Throw_TagCountIncorrect(const std::string& pNode);
-
- /// Call that function when defined in "USE" element are not found in graph and exception must be raised.
- /// \param [in] pAttrValue - "USE" attribute value.
- /// \throw DeadlyImportError.
- void Throw_USE_NotFound(const std::string& pAttrValue);
-
- /***********************************************/
- /************** Functions: LOG set *************/
- /***********************************************/
-
- /// Short variant for calling \ref DefaultLogger::get()->info()
- void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
-
- /***********************************************/
- /************** Functions: XML set *************/
- /***********************************************/
-
- /// Check if current node is empty: <node />. If not then exception will throwed.
- void XML_CheckNode_MustBeEmpty();
-
- /// Check if current node name is equal to pNodeName.
- /// \param [in] pNodeName - name for checking.
- /// return true if current node name is equal to pNodeName, else - false.
- bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
-
- /// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
- /// \param [in] pParentNodeName - parent node name. Used for reporting.
- void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
-
- /// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
- /// \param [in] pNodeName - requested node name.
- /// return true - if node is found, else - false.
- bool XML_SearchNode(const std::string& pNodeName);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \return read data.
- int32_t XML_ReadNode_GetAttrVal_AsI32(const int pAttrIdx);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsCol3f(const int pAttrIdx, aiColor3D& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsVec2f(const int pAttrIdx, aiVector2D& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsVec3f(const int pAttrIdx, aiVector3D& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsArrB(const int pAttrIdx, std::vector<bool>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsArrI32(const int pAttrIdx, std::vector<int32_t>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsArrF(const int pAttrIdx, std::vector<float>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsArrD(const int pAttrIdx, std::vector<double>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::list<aiColor3D>& pValue);
-
- /// \overload void XML_ReadNode_GetAttrVal_AsListCol3f(const int pAttrIdx, std::vector<aiColor3D>& pValue)
- void XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::vector<aiColor3D>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue);
-
- /// \overload void XML_ReadNode_GetAttrVal_AsListCol4f(const int pAttrIdx, std::list<aiColor4D>& pValue)
- void XML_ReadNode_GetAttrVal_AsArrCol4f(const int pAttrIdx, std::vector<aiColor4D>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue);
-
- /// \overload void XML_ReadNode_GetAttrVal_AsListVec2f(const int pAttrIdx, std::list<aiVector2D>& pValue)
- void XML_ReadNode_GetAttrVal_AsArrVec2f(const int pAttrIdx, std::vector<aiVector2D>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue);
-
- /// \overload void XML_ReadNode_GetAttrVal_AsListVec3f(const int pAttrIdx, std::list<aiVector3D>& pValue)
- void XML_ReadNode_GetAttrVal_AsArrVec3f(const int pAttrIdx, std::vector<aiVector3D>& pValue);
-
- /// Read attribute value.
- /// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
- /// \param [out] pValue - read data.
- void XML_ReadNode_GetAttrVal_AsListS(const int pAttrIdx, std::list<std::string>& pValue);
-
- /***********************************************/
- /******* Functions: geometry helper set *******/
- /***********************************************/
-
- /// Make point on surface oXY.
- /// \param [in] pAngle - angle in radians between radius-vector of point and oX axis. Angle extends from the oX axis counterclockwise to the radius-vector.
- /// \param [in] pRadius - length of radius-vector.
- /// \return made point coordinates.
- aiVector3D GeometryHelper_Make_Point2D(const float pAngle, const float pRadius);
-
- /// Make 2D figure - linear circular arc with center in (0, 0). The z-coordinate is 0. The arc extends from the pStartAngle counterclockwise
- /// to the pEndAngle. If pStartAngle and pEndAngle have the same value, a circle is specified. If the absolute difference between pStartAngle
- /// and pEndAngle is greater than or equal to 2pi, a circle is specified.
- /// \param [in] pStartAngle - angle in radians of start of the arc.
- /// \param [in] pEndAngle - angle in radians of end of the arc.
- /// \param [in] pRadius - radius of the arc.
- /// \param [out] pNumSegments - number of segments in arc. In other words - tesselation factor.
- /// \param [out] pVertices - generated vertices.
- void GeometryHelper_Make_Arc2D(const float pStartAngle, const float pEndAngle, const float pRadius, size_t pNumSegments, std::list<aiVector3D>& pVertices);
-
- /// Create line set from point set.
- /// \param [in] pPoint - input points list.
- /// \param [out] pLine - made lines list.
- void GeometryHelper_Extend_PointToLine(const std::list<aiVector3D>& pPoint, std::list<aiVector3D>& pLine);
-
- /// Create CoordIdx of line set from CoordIdx of polyline set.
- /// \param [in] pPolylineCoordIdx - vertices indices divided by delimiter "-1". Must contain faces with two or more indices.
- /// \param [out] pLineCoordIdx - made CoordIdx of line set.
- void GeometryHelper_Extend_PolylineIdxToLineIdx(const std::list<int32_t>& pPolylineCoordIdx, std::list<int32_t>& pLineCoordIdx);
-
- /// Make 3D body - rectangular parallelepiped with center in (0, 0). QL mean quadlist (\sa pVertices).
- /// \param [in] pSize - scale factor for body for every axis. E.g. (1, 2, 1) mean: X-size and Z-size - 1, Y-size - 2.
- /// \param [out] pVertices - generated vertices. The list of vertices is grouped in quads.
- void GeometryHelper_MakeQL_RectParallelepiped(const aiVector3D& pSize, std::list<aiVector3D>& pVertices);
-
- /// Create faces array from vertices indices array.
- /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
- /// \param [in] pFaces - created faces array.
- /// \param [in] pPrimitiveTypes - type of primitives in faces.
- void GeometryHelper_CoordIdxStr2FacesArr(const std::vector<int32_t>& pCoordIdx, std::vector<aiFace>& pFaces, unsigned int& pPrimitiveTypes) const;
-
- /// Add colors to mesh.
- /// a. If colorPerVertex is FALSE, colours are applied to each face, as follows:
- /// If the colorIndex field is not empty, one colour is used for each face of the mesh. There shall be at least as many indices in the
- /// colorIndex field as there are faces in the mesh. The colorIndex field shall not contain any negative entries.
- /// If the colorIndex field is empty, the colours in the X3DColorNode node are applied to each face of the mesh in order.
- /// There shall be at least as many colours in the X3DColorNode node as there are faces.
- /// b. If colorPerVertex is TRUE, colours are applied to each vertex, as follows:
- /// If the colorIndex field is not empty, colours are applied to each vertex of the mesh in exactly the same manner that the coordIndex
- /// field is used to choose coordinates for each vertex from the <Coordinate> node. The colorIndex field shall contain end-of-face markers (-1)
- /// in exactly the same places as the coordIndex field.
- /// If the colorIndex field is empty, the coordIndex field is used to choose colours from the X3DColorNode node.
- /// \param [in] pMesh - mesh for adding data.
- /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
- /// \param [in] pColorIdx - color indices for every vertex divided by delimiter "-1" if \ref pColorPerVertex is true. if \ref pColorPerVertex is false
- /// then pColorIdx contain color indices for every faces and must not contain delimiter "-1".
- /// \param [in] pColors - defined colors.
- /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
- void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
- const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
-
- /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<int32_t>& pCoordIdx, const std::list<int32_t>& pColorIdx, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
- void MeshGeometry_AddColor(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pColorIdx,
- const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
-
- /// Add colors to mesh.
- /// \param [in] pMesh - mesh for adding data.
- /// \param [in] pColors - defined colors.
- /// \param [in] pColorPerVertex - if \ref pColorPerVertex is true then color in \ref pColors defined for every vertex, if false - for every face.
- void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const;
-
- /// \overload void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor4D>& pColors, const bool pColorPerVertex) const
- void MeshGeometry_AddColor(aiMesh& pMesh, const std::list<aiColor3D>& pColors, const bool pColorPerVertex) const;
-
- /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
- void MeshGeometry_AddNormal(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pNormalIdx,
- const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
-
- /// Add normals to mesh. Function work similar to \ref MeshGeometry_AddColor;
- void MeshGeometry_AddNormal(aiMesh& pMesh, const std::list<aiVector3D>& pNormals, const bool pNormalPerVertex) const;
-
- /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
- void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::vector<int32_t>& pCoordIdx, const std::vector<int32_t>& pTexCoordIdx,
- const std::list<aiVector2D>& pTexCoords) const;
-
- /// Add texture coordinates to mesh. Function work similar to \ref MeshGeometry_AddColor;
- void MeshGeometry_AddTexCoord(aiMesh& pMesh, const std::list<aiVector2D>& pTexCoords) const;
-
- /// Create mesh.
- /// \param [in] pCoordIdx - vertices indices divided by delimiter "-1".
- /// \param [in] pVertices - vertices of mesh.
- /// \return created mesh.
- aiMesh* GeometryHelper_MakeMesh(const std::vector<int32_t>& pCoordIdx, const std::list<aiVector3D>& pVertices) const;
-
- /***********************************************/
- /******** Functions: parse set private *********/
- /***********************************************/
-
- /// Create node element with type "Node" in scene graph. That operation is needed when you enter to X3D group node
- /// like <Group>, <Transform> etc. When exiting from X3D group node(e.g. </Group>) \ref ParseHelper_Node_Exit must
- /// be called.
- /// \param [in] pStatic - flag: if true then static node is created(e.g. <StaticGroup>).
- void ParseHelper_Group_Begin(const bool pStatic = false);
-
- /// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
- /// \param [in] pNode - new current node.
- void ParseHelper_Node_Enter(CX3DImporter_NodeElement* pNode);
-
- /// This function must be called when exiting from X3D group node(e.g. </Group>). \ref ParseHelper_Group_Begin.
- void ParseHelper_Node_Exit();
-
- /// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
- /// must be converted to right form - "0.xxx".
- /// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
- /// \param [out[ pOutString - output string with right form of values.
- void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
-
- /// Check if current node has nodes of type X3DMetadataObject. Why we must do it? Because X3DMetadataObject can be in any non-empty X3DNode.
- /// Meaning that X3DMetadataObject can be in any non-empty node in <Scene>.
- /// \return true - if metadata node are found and parsed, false - metadata not found.
- bool ParseHelper_CheckRead_X3DMetadataObject();
-
- /// Check if current node has nodes of type X3DGeometricPropertyNode. X3DGeometricPropertyNode
- /// X3DGeometricPropertyNode inheritors:
- /// <FogCoordinate>, <HAnimDisplacer>, <Color>, <ColorRGBA>, <Coordinate>, <CoordinateDouble>, <GeoCoordinate>, <Normal>,
- /// <MultiTextureCoordinate>, <TextureCoordinate>, <TextureCoordinate3D>, <TextureCoordinate4D>, <TextureCoordinateGenerator>,
- /// <FloatVertexAttribute>, <Matrix3VertexAttribute>, <Matrix4VertexAttribute>.
- /// \return true - if nodes are found and parsed, false - nodes not found.
- bool ParseHelper_CheckRead_X3DGeometricPropertyNode();
-
- /// Parse <X3D> node of the file.
- void ParseNode_Root();
-
- /// Parse <head> node of the file.
- void ParseNode_Head();
-
- /// Parse <Scene> node of the file.
- void ParseNode_Scene();
-
- /// Parse child nodes of <Metadata*> node.
- /// \param [in] pNodeName - parsed node name. Must be set because that function is general and name needed for checking the end
- /// and error reporing.
- /// \param [in] pParentElement - parent metadata element.
- void ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& pNodeName);
-
- /// Parse <MetadataBoolean> node of the file.
- void ParseNode_MetadataBoolean();
-
- /// Parse <MetadataDouble> node of the file.
- void ParseNode_MetadataDouble();
-
- /// Parse <MetadataFloat> node of the file.
- void ParseNode_MetadataFloat();
-
- /// Parse <MetadataInteger> node of the file.
- void ParseNode_MetadataInteger();
-
- /// Parse <MetadataSet> node of the file.
- void ParseNode_MetadataSet();
-
- /// \fn void ParseNode_MetadataString()
- /// Parse <MetadataString> node of the file.
- void ParseNode_MetadataString();
-
- /// Parse <Arc2D> node of the file.
- void ParseNode_Geometry2D_Arc2D();
-
- /// Parse <ArcClose2D> node of the file.
- void ParseNode_Geometry2D_ArcClose2D();
-
- /// Parse <Circle2D> node of the file.
- void ParseNode_Geometry2D_Circle2D();
-
- /// Parse <Disk2D> node of the file.
- void ParseNode_Geometry2D_Disk2D();
-
- /// Parse <Polyline2D> node of the file.
- void ParseNode_Geometry2D_Polyline2D();
-
- /// Parse <Polypoint2D> node of the file.
- void ParseNode_Geometry2D_Polypoint2D();
-
- /// Parse <Rectangle2D> node of the file.
- void ParseNode_Geometry2D_Rectangle2D();
-
- /// Parse <TriangleSet2D> node of the file.
- void ParseNode_Geometry2D_TriangleSet2D();
-
- /// Parse <Box> node of the file.
- void ParseNode_Geometry3D_Box();
-
- /// Parse <Cone> node of the file.
- void ParseNode_Geometry3D_Cone();
-
- /// Parse <Cylinder> node of the file.
- void ParseNode_Geometry3D_Cylinder();
-
- /// Parse <ElevationGrid> node of the file.
- void ParseNode_Geometry3D_ElevationGrid();
-
- /// Parse <Extrusion> node of the file.
- void ParseNode_Geometry3D_Extrusion();
-
- /// Parse <IndexedFaceSet> node of the file.
- void ParseNode_Geometry3D_IndexedFaceSet();
-
- /// Parse <Sphere> node of the file.
- void ParseNode_Geometry3D_Sphere();
-
- /// Parse <Group> node of the file. And create new node in scene graph.
- void ParseNode_Grouping_Group();
-
- /// Doing actions at an exit from <Group>. Walk up in scene graph.
- void ParseNode_Grouping_GroupEnd();
-
- /// Parse <StaticGroup> node of the file. And create new node in scene graph.
- void ParseNode_Grouping_StaticGroup();
-
- /// Doing actions at an exit from <StaticGroup>. Walk up in scene graph.
- void ParseNode_Grouping_StaticGroupEnd();
-
- /// Parse <Switch> node of the file. And create new node in scene graph.
- void ParseNode_Grouping_Switch();
-
- /// Doing actions at an exit from <Switch>. Walk up in scene graph.
- void ParseNode_Grouping_SwitchEnd();
-
- /// Parse <Transform> node of the file. And create new node in scene graph.
- void ParseNode_Grouping_Transform();
-
- /// Doing actions at an exit from <Transform>. Walk up in scene graph.
- void ParseNode_Grouping_TransformEnd();
-
- /// Parse <Color> node of the file.
- void ParseNode_Rendering_Color();
-
- /// Parse <ColorRGBA> node of the file.
- void ParseNode_Rendering_ColorRGBA();
-
- /// Parse <Coordinate> node of the file.
- void ParseNode_Rendering_Coordinate();
-
- /// Parse <Normal> node of the file.
- void ParseNode_Rendering_Normal();
-
- /// Parse <IndexedLineSet> node of the file.
- void ParseNode_Rendering_IndexedLineSet();
-
- /// Parse <IndexedTriangleFanSet> node of the file.
- void ParseNode_Rendering_IndexedTriangleFanSet();
-
- /// Parse <IndexedTriangleSet> node of the file.
- void ParseNode_Rendering_IndexedTriangleSet();
-
- /// Parse <IndexedTriangleStripSet> node of the file.
- void ParseNode_Rendering_IndexedTriangleStripSet();
-
- /// Parse <LineSet> node of the file.
- void ParseNode_Rendering_LineSet();
-
- /// Parse <PointSet> node of the file.
- void ParseNode_Rendering_PointSet();
-
- /// Parse <TriangleFanSet> node of the file.
- void ParseNode_Rendering_TriangleFanSet();
-
- /// Parse <TriangleSet> node of the file.
- void ParseNode_Rendering_TriangleSet();
-
- /// Parse <TriangleStripSet> node of the file.
- void ParseNode_Rendering_TriangleStripSet();
-
- /// Parse <ImageTexture> node of the file.
- void ParseNode_Texturing_ImageTexture();
-
- /// Parse <TextureCoordinate> node of the file.
- void ParseNode_Texturing_TextureCoordinate();
-
- /// Parse <TextureTransform> node of the file.
- void ParseNode_Texturing_TextureTransform();
-
- /// Parse <Shape> node of the file.
- void ParseNode_Shape_Shape();
-
- /// Parse <Appearance> node of the file.
- void ParseNode_Shape_Appearance();
-
- /// Parse <Material> node of the file.
- void ParseNode_Shape_Material();
-
- /// Parse <Inline> node of the file.
- void ParseNode_Networking_Inline();
-
- /// Parse <DirectionalLight> node of the file.
- void ParseNode_Lighting_DirectionalLight();
-
- /// Parse <PointLight> node of the file.
- void ParseNode_Lighting_PointLight();
-
- /// Parse <SpotLight> node of the file.
- void ParseNode_Lighting_SpotLight();
-
-private:
- /***********************************************/
- /******************** Types ********************/
- /***********************************************/
-
- /***********************************************/
- /****************** Constants ******************/
- /***********************************************/
- static const aiImporterDesc Description;
- //static const std::regex pattern_nws;
- //static const std::regex pattern_true;
-
-
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
- CX3DImporter_NodeElement* NodeElement_Cur;///< Current element.
- std::unique_ptr<FIReader> mReader;///< Pointer to XML-reader object
- IOSystem *mpIOHandler;
-};// class X3DImporter
-
-}// namespace Assimp
-
-#endif // INCLUDED_AI_X3D_IMPORTER_H
diff --git a/src/3rdparty/assimp/code/X3DImporter_Geometry2D.cpp b/src/3rdparty/assimp/code/X3DImporter_Geometry2D.cpp
deleted file mode 100644
index 895ba8798..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Geometry2D.cpp
+++ /dev/null
@@ -1,521 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Geometry2D.cpp
-/// \brief Parsing data from nodes of "Geometry2D" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Node.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <Arc2D
-// DEF="" ID
-// USE="" IDREF
-// endAngle="1.570796" SFFloat [initializeOnly]
-// radius="1" SFFloat [initializeOnly]
-// startAngle="0" SFFloat [initializeOnly]
-// />
-// The Arc2D node specifies a linear circular arc whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping
-// towards the positive y-axis. The radius field specifies the radius of the circle of which the arc is a portion. The arc extends from the startAngle
-// counterclockwise to the endAngle. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different
-// angle base unit has been specified). If startAngle and endAngle have the same value, a circle is specified.
-void X3DImporter::ParseNode_Geometry2D_Arc2D()
-{
- std::string def, use;
- float endAngle = AI_MATH_HALF_PI_F;
- float radius = 1;
- float startAngle = 0;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Arc2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Arc2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // create point list of geometry object and convert it to line set.
- std::list<aiVector3D> tlist;
-
- GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Arc2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <ArcClose2D
-// DEF="" ID
-// USE="" IDREF
-// closureType="PIE" SFString [initializeOnly], {"PIE", "CHORD"}
-// endAngle="1.570796" SFFloat [initializeOnly]
-// radius="1" SFFloat [initializeOnly]
-// solid="false" SFBool [initializeOnly]
-// startAngle="0" SFFloat [initializeOnly]
-// />
-// The ArcClose node specifies a portion of a circle whose center is at (0,0) and whose angles are measured starting at the positive x-axis and sweeping
-// towards the positive y-axis. The end points of the arc specified are connected as defined by the closureType field. The radius field specifies the radius
-// of the circle of which the arc is a portion. The arc extends from the startAngle counterclockwise to the endAngle. The value of radius shall be greater
-// than zero. The values of startAngle and endAngle shall be in the range [-2pi, 2pi] radians (or the equivalent if a different default angle base unit has
-// been specified). If startAngle and endAngle have the same value, a circle is specified and closureType is ignored. If the absolute difference between
-// startAngle and endAngle is greater than or equal to 2pi, a complete circle is produced with no chord or radial line(s) drawn from the center.
-// A closureType of "PIE" connects the end point to the start point by defining two straight line segments first from the end point to the center and then
-// the center to the start point. A closureType of "CHORD" connects the end point to the start point by defining a straight line segment from the end point
-// to the start point. Textures are applied individually to each face of the ArcClose2D. On the front (+Z) and back (-Z) faces of the ArcClose2D, when
-// viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D.
-void X3DImporter::ParseNode_Geometry2D_ArcClose2D()
-{
- std::string def, use;
- std::string closureType("PIE");
- float endAngle = AI_MATH_HALF_PI_F;
- float radius = 1;
- bool solid = false;
- float startAngle = 0;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("closureType", closureType, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("endAngle", endAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("startAngle", startAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_ArcClose2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_ArcClose2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- // create point list of geometry object.
- GeometryHelper_Make_Arc2D(startAngle, endAngle, radius, 10, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);///TODO: IME - AI_CONFIG for NumSeg
- // add chord or two radiuses only if not a circle was defined
- if(!((std::fabs(endAngle - startAngle) >= AI_MATH_TWO_PI_F) || (endAngle == startAngle)))
- {
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
-
- if((closureType == "PIE") || (closureType == "\"PIE\""))
- vlist.push_back(aiVector3D(0, 0, 0));// center point - first radial line
- else if((closureType != "CHORD") && (closureType != "\"CHORD\""))
- Throw_IncorrectAttrValue("closureType");
-
- vlist.push_back(*vlist.begin());// arc first point - chord from first to last point of arc(if CHORD) or second radial line(if PIE).
- }
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.size();
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "ArcClose2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Circle2D
-// DEF="" ID
-// USE="" IDREF
-// radius="1" SFFloat [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry2D_Circle2D()
-{
- std::string def, use;
- float radius = 1;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Circle2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Circle2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // create point list of geometry object and convert it to line set.
- std::list<aiVector3D> tlist;
-
- GeometryHelper_Make_Arc2D(0, 0, radius, 10, tlist);///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Circle2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Disk2D
-// DEF="" ID
-// USE="" IDREF
-// innerRadius="0" SFFloat [initializeOnly]
-// outerRadius="1" SFFloat [initializeOnly]
-// solid="false" SFBool [initializeOnly]
-// />
-// The Disk2D node specifies a circular disk which is centred at (0, 0) in the local coordinate system. The outerRadius field specifies the radius of the
-// outer dimension of the Disk2D. The innerRadius field specifies the inner dimension of the Disk2D. The value of outerRadius shall be greater than zero.
-// The value of innerRadius shall be greater than or equal to zero and less than or equal to outerRadius. If innerRadius is zero, the Disk2D is completely
-// filled. Otherwise, the area within the innerRadius forms a hole in the Disk2D. If innerRadius is equal to outerRadius, a solid circular line shall
-// be drawn using the current line properties. Textures are applied individually to each face of the Disk2D. On the front (+Z) and back (-Z) faces of
-// the Disk2D, when viewed from the +Z-axis, the texture is mapped onto each face with the same orientation as if the image were displayed normally in 2D.
-void X3DImporter::ParseNode_Geometry2D_Disk2D()
-{
- std::string def, use;
- float innerRadius = 0;
- float outerRadius = 1;
- bool solid = false;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("innerRadius", innerRadius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("outerRadius", outerRadius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Disk2D, ne);
- }
- else
- {
- std::list<aiVector3D> tlist_o, tlist_i;
-
- if(innerRadius > outerRadius) Throw_IncorrectAttrValue("innerRadius");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Disk2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // create point list of geometry object.
- ///TODO: IME - AI_CONFIG for NumSeg
- GeometryHelper_Make_Arc2D(0, 0, outerRadius, 10, tlist_o);// outer circle
- if(innerRadius == 0.0f)
- {// make filled disk
- // in tlist_o we already have points of circle. just copy it and sign as polygon.
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices = tlist_o;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = tlist_o.size();
- }
- else if(innerRadius == outerRadius)
- {// make circle
- // in tlist_o we already have points of circle. convert it to line set.
- GeometryHelper_Extend_PointToLine(tlist_o, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- }
- else
- {// make disk
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
-
- GeometryHelper_Make_Arc2D(0, 0, innerRadius, 10, tlist_i);// inner circle
- //
- // create quad list from two point lists
- //
- if(tlist_i.size() < 2) throw DeadlyImportError("Disk2D. Not enough points for creating quad list.");// tlist_i and tlist_o has equal size.
-
- // add all quads except last
- for(std::list<aiVector3D>::iterator it_i = tlist_i.begin(), it_o = tlist_o.begin(); it_i != tlist_i.end();)
- {
- // do not forget - CCW direction
- vlist.push_back(*it_i++);// 1st point
- vlist.push_back(*it_o++);// 2nd point
- vlist.push_back(*it_o);// 3rd point
- vlist.push_back(*it_i);// 4th point
- }
-
- // add last quad
- vlist.push_back(*tlist_i.end());// 1st point
- vlist.push_back(*tlist_o.end());// 2nd point
- vlist.push_back(*tlist_o.begin());// 3rd point
- vlist.push_back(*tlist_o.begin());// 4th point
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 4;
- }
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Disk2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Polyline2D
-// DEF="" ID
-// USE="" IDREF
-// lineSegments="" MFVec2F [intializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry2D_Polyline2D()
-{
- std::string def, use;
- std::list<aiVector2D> lineSegments;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("lineSegments", lineSegments, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polyline2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Polyline2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- //
- // convert read point list of geometry object to line set.
- //
- std::list<aiVector3D> tlist;
-
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = lineSegments.begin(); it2 != lineSegments.end(); it2++) tlist.push_back(aiVector3D(it2->x, it2->y, 0));
-
- // convert point set to line set
- GeometryHelper_Extend_PointToLine(tlist, ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices);
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 2;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Polyline2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Polypoint2D
-// DEF="" ID
-// USE="" IDREF
-// point="" MFVec2F [inputOutput]
-// />
-void X3DImporter::ParseNode_Geometry2D_Polypoint2D()
-{
- std::string def, use;
- std::list<aiVector2D> point;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Polypoint2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Polypoint2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = point.begin(); it2 != point.end(); it2++)
- {
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
- }
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 1;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Polypoint2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Rectangle2D
-// DEF="" ID
-// USE="" IDREF
-// size="2 2" SFVec2f [initializeOnly]
-// solid="false" SFBool [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry2D_Rectangle2D()
-{
- std::string def, use;
- aiVector2D size(2, 2);
- bool solid = false;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("size", size, XML_ReadNode_GetAttrVal_AsVec2f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Rectangle2D, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_Rectangle2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- float x1 = -size.x / 2.0f;
- float x2 = size.x / 2.0f;
- float y1 = -size.y / 2.0f;
- float y2 = size.y / 2.0f;
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices;// just short alias.
-
- vlist.push_back(aiVector3D(x2, y1, 0));// 1st point
- vlist.push_back(aiVector3D(x2, y2, 0));// 2nd point
- vlist.push_back(aiVector3D(x1, y2, 0));// 3rd point
- vlist.push_back(aiVector3D(x1, y1, 0));// 4th point
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 4;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Rectangle2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TriangleSet2D
-// DEF="" ID
-// USE="" IDREF
-// solid="false" SFBool [initializeOnly]
-// vertices="" MFVec2F [inputOutput]
-// />
-void X3DImporter::ParseNode_Geometry2D_TriangleSet2D()
-{
- std::string def, use;
- bool solid = false;
- std::list<aiVector2D> vertices;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("vertices", vertices, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet2D, ne);
- }
- else
- {
- if(vertices.size() % 3) throw DeadlyImportError("TriangleSet2D. Not enough points for defining triangle.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry2D(CX3DImporter_NodeElement::ENET_TriangleSet2D, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // convert vec2 to vec3
- for(std::list<aiVector2D>::iterator it2 = vertices.begin(); it2 != vertices.end(); it2++)
- {
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Vertices.push_back(aiVector3D(it2->x, it2->y, 0));
- }
-
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry2D*)ne)->NumIndices = 3;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "TriangleSet2D");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Geometry3D.cpp b/src/3rdparty/assimp/code/X3DImporter_Geometry3D.cpp
deleted file mode 100644
index b2e9a28f8..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Geometry3D.cpp
+++ /dev/null
@@ -1,998 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Geometry3D.cpp
-/// \brief Parsing data from nodes of "Geometry3D" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-// Header files, Assimp.
-#include "StandardShapes.h"
-
-namespace Assimp
-{
-
-// <Box
-// DEF="" ID
-// USE="" IDREF
-// size="2 2 2" SFVec3f [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// />
-// The Box node specifies a rectangular parallelepiped box centred at (0, 0, 0) in the local coordinate system and aligned with the local coordinate axes.
-// By default, the box measures 2 units in each dimension, from -1 to +1. The size field specifies the extents of the box along the X-, Y-, and Z-axes
-// respectively and each component value shall be greater than zero.
-void X3DImporter::ParseNode_Geometry3D_Box()
-{
- std::string def, use;
- bool solid = true;
- aiVector3D size(2, 2, 2);
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("size", size, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Box, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry3D(CX3DImporter_NodeElement::ENET_Box, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- GeometryHelper_MakeQL_RectParallelepiped(size, ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices);// get quad list
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 4;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Box");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Cone
-// DEF="" ID
-// USE="" IDREF
-// bottom="true" SFBool [initializeOnly]
-// bottomRadius="1" SFloat [initializeOnly]
-// height="2" SFloat [initializeOnly]
-// side="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry3D_Cone()
-{
- std::string use, def;
- bool bottom = true;
- float bottomRadius = 1;
- float height = 2;
- bool side = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("side", side, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("bottom", bottom, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("bottomRadius", bottomRadius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Cone, ne);
- }
- else
- {
- const unsigned int tess = 30;///TODO: IME tesselation factor through ai_property
-
- std::vector<aiVector3D> tvec;// temp array for vertices.
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry3D(CX3DImporter_NodeElement::ENET_Cone, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // make cone or parts according to flags.
- if(side)
- {
- StandardShapes::MakeCone(height, 0, bottomRadius, tess, tvec, !bottom);
- }
- else if(bottom)
- {
- StandardShapes::MakeCircle(bottomRadius, tess, tvec);
- height = -(height / 2);
- for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) it->y = height;// y - because circle made in oXZ.
- }
-
- // copy data from temp array
- for(std::vector<aiVector3D>::iterator it = tvec.begin(); it != tvec.end(); it++) ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it);
-
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Cone");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Cylinder
-// DEF="" ID
-// USE="" IDREF
-// bottom="true" SFBool [initializeOnly]
-// height="2" SFloat [initializeOnly]
-// radius="1" SFloat [initializeOnly]
-// side="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// top="true" SFBool [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry3D_Cylinder()
-{
- std::string use, def;
- bool bottom = true;
- float height = 2;
- float radius = 1;
- bool side = true;
- bool solid = true;
- bool top = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("bottom", bottom, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("top", top, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("side", side, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Cylinder, ne);
- }
- else
- {
- const unsigned int tess = 30;///TODO: IME tesselation factor through ai_property
-
- std::vector<aiVector3D> tside;// temp array for vertices of side.
- std::vector<aiVector3D> tcir;// temp array for vertices of circle.
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry3D(CX3DImporter_NodeElement::ENET_Cylinder, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // make cilynder or parts according to flags.
- if(side) StandardShapes::MakeCone(height, radius, radius, tess, tside, true);
-
- height /= 2;// height defined for whole cylinder, when creating top and bottom circle we are using just half of height.
- if(top || bottom) StandardShapes::MakeCircle(radius, tess, tcir);
- // copy data from temp arrays
- std::list<aiVector3D>& vlist = ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices;// just short alias.
-
- for(std::vector<aiVector3D>::iterator it = tside.begin(); it != tside.end(); it++) vlist.push_back(*it);
-
- if(top)
- {
- for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
- {
- (*it).y = height;// y - because circle made in oXZ.
- vlist.push_back(*it);
- }
- }// if(top)
-
- if(bottom)
- {
- for(std::vector<aiVector3D>::iterator it = tcir.begin(); it != tcir.end(); it++)
- {
- (*it).y = -height;// y - because circle made in oXZ.
- vlist.push_back(*it);
- }
- }// if(top)
-
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Cylinder");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <ElevationGrid
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// creaseAngle="0" SFloat [initializeOnly]
-// height="" MFloat [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// xDimension="0" SFInt32 [initializeOnly]
-// xSpacing="1.0" SFloat [initializeOnly]
-// zDimension="0" SFInt32 [initializeOnly]
-// zSpacing="1.0" SFloat [initializeOnly]
-// >
-// <!-- ColorNormalTexCoordContentModel -->
-// ColorNormalTexCoordContentModel can contain Color (or ColorRGBA), Normal and TextureCoordinate, in any order. No more than one instance of any single
-// node type is allowed. A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </ElevationGrid>
-// The ElevationGrid node specifies a uniform rectangular grid of varying height in the Y=0 plane of the local coordinate system. The geometry is described
-// by a scalar array of height values that specify the height of a surface above each point of the grid. The xDimension and zDimension fields indicate
-// the number of elements of the grid height array in the X and Z directions. Both xDimension and zDimension shall be greater than or equal to zero.
-// If either the xDimension or the zDimension is less than two, the ElevationGrid contains no quadrilaterals.
-void X3DImporter::ParseNode_Geometry3D_ElevationGrid()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- float creaseAngle = 0;
- std::vector<float> height;
- bool normalPerVertex = true;
- bool solid = true;
- int32_t xDimension = 0;
- float xSpacing = 1;
- int32_t zDimension = 0;
- float zSpacing = 1;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("height", height, XML_ReadNode_GetAttrVal_AsArrF);
- MACRO_ATTRREAD_CHECK_RET("xDimension", xDimension, XML_ReadNode_GetAttrVal_AsI32);
- MACRO_ATTRREAD_CHECK_RET("xSpacing", xSpacing, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("zDimension", zDimension, XML_ReadNode_GetAttrVal_AsI32);
- MACRO_ATTRREAD_CHECK_RET("zSpacing", zSpacing, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_ElevationGrid, ne);
- }
- else
- {
- if((xSpacing == 0.0f) || (zSpacing == 0.0f)) throw DeadlyImportError("Spacing in <ElevationGrid> must be grater than zero.");
- if((xDimension <= 0) || (zDimension <= 0)) throw DeadlyImportError("Dimension in <ElevationGrid> must be grater than zero.");
- if((size_t)(xDimension * zDimension) != height.size()) Throw_IncorrectAttrValue("Heights count must be equal to \"xDimension * zDimension\"");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_ElevationGrid(CX3DImporter_NodeElement::ENET_ElevationGrid, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_ElevationGrid& grid_alias = *((CX3DImporter_NodeElement_ElevationGrid*)ne);// create alias for conveience
-
- {// create grid vertices list
- std::vector<float>::const_iterator he_it = height.begin();
-
- for(int32_t zi = 0; zi < zDimension; zi++)// rows
- {
- for(int32_t xi = 0; xi < xDimension; xi++)// columns
- {
- aiVector3D tvec(xSpacing * xi, *he_it, zSpacing * zi);
-
- grid_alias.Vertices.push_back(tvec);
- he_it++;
- }
- }
- }// END: create grid vertices list
- //
- // create faces list. In "coordIdx" format
- //
- // check if we have quads
- if((xDimension < 2) || (zDimension < 2))// only one element in dimension is set, create line set.
- {
- ((CX3DImporter_NodeElement_ElevationGrid*)ne)->NumIndices = 2;// will be holded as line set.
- for(size_t i = 0, i_e = (grid_alias.Vertices.size() - 1); i < i_e; i++)
- {
- grid_alias.CoordIdx.push_back(static_cast<int32_t>(i));
- grid_alias.CoordIdx.push_back(static_cast<int32_t>(i + 1));
- grid_alias.CoordIdx.push_back(-1);
- }
- }
- else// two or more elements in every dimension is set. create quad set.
- {
- ((CX3DImporter_NodeElement_ElevationGrid*)ne)->NumIndices = 4;
- for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)// rows
- {
- for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)// columns
- {
- // points direction in face.
- if(ccw)
- {
- // CCW:
- // 3 2
- // 0 1
- grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + fxi);
- grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1));
- grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1));
- grid_alias.CoordIdx.push_back(fzi * xDimension + fxi);
- }
- else
- {
- // CW:
- // 0 1
- // 3 2
- grid_alias.CoordIdx.push_back(fzi * xDimension + fxi);
- grid_alias.CoordIdx.push_back(fzi * xDimension + (fxi + 1));
- grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + (fxi + 1));
- grid_alias.CoordIdx.push_back((fzi + 1) * xDimension + fxi);
- }// if(ccw) else
-
- grid_alias.CoordIdx.push_back(-1);
- }// for(int32_t fxi = 0, fxi_e = (xDimension - 1); fxi < fxi_e; fxi++)
- }// for(int32_t fzi = 0, fzi_e = (zDimension - 1); fzi < fzi_e; fzi++)
- }// if((xDimension < 2) || (zDimension < 2)) else
-
- grid_alias.ColorPerVertex = colorPerVertex;
- grid_alias.NormalPerVertex = normalPerVertex;
- grid_alias.CreaseAngle = creaseAngle;
- grid_alias.Solid = solid;
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("ElevationGrid");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("ElevationGrid");
-
- MACRO_NODECHECK_LOOPEND("ElevationGrid");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }// if(!mReader->isEmptyElement()) else
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-template<typename TVector>
-static void GeometryHelper_Extrusion_CurveIsClosed(std::vector<TVector>& pCurve, const bool pDropTail, const bool pRemoveLastPoint, bool& pCurveIsClosed)
-{
- size_t cur_sz = pCurve.size();
-
- pCurveIsClosed = false;
- // for curve with less than four points checking is have no sense,
- if(cur_sz < 4) return;
-
- for(size_t s = 3, s_e = cur_sz; s < s_e; s++)
- {
- // search for first point of duplicated part.
- if(pCurve[0] == pCurve[s])
- {
- bool found = true;
-
- // check if tail(indexed by b2) is duplicate of head(indexed by b1).
- for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++)
- {
- if(pCurve[b1] != pCurve[b2])
- {// points not match: clear flag and break loop.
- found = false;
-
- break;
- }
- }// for(size_t b1 = 1, b2 = (s + 1); b2 < cur_sz; b1++, b2++)
-
- // if duplicate tail is found then drop or not it depending on flags.
- if(found)
- {
- pCurveIsClosed = true;
- if(pDropTail)
- {
- if(!pRemoveLastPoint) s++;// prepare value for iterator's arithmetics.
-
- pCurve.erase(pCurve.begin() + s, pCurve.end());// remove tail
- }
-
- break;
- }// if(found)
- }// if(pCurve[0] == pCurve[s])
- }// for(size_t s = 3, s_e = (cur_sz - 1); s < s_e; s++)
-}
-
-static aiVector3D GeometryHelper_Extrusion_GetNextY(const size_t pSpine_PointIdx, const std::vector<aiVector3D>& pSpine, const bool pSpine_Closed)
-{
- const size_t spine_idx_last = pSpine.size() - 1;
- aiVector3D tvec;
-
- if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))// at first special cases
- {
- if(pSpine_Closed)
- {// If the spine curve is closed: The SCP for the first and last points is the same and is found using (spine[1] - spine[n - 2]) to compute the Y-axis.
- // As we even for closed spine curve last and first point in pSpine are not the same: duplicates(spine[n - 1] which are equivalent to spine[0])
- // in tail are removed.
- // So, last point in pSpine is a spine[n - 2]
- tvec = pSpine[1] - pSpine[spine_idx_last];
- }
- else if(pSpine_PointIdx == 0)
- {// The Y-axis used for the first point is the vector from spine[0] to spine[1]
- tvec = pSpine[1] - pSpine[0];
- }
- else
- {// The Y-axis used for the last point it is the vector from spine[n-2] to spine[n-1]. In our case(see above about droping tail) spine[n - 1] is
- // the spine[0].
- tvec = pSpine[spine_idx_last] - pSpine[spine_idx_last - 1];
- }
- }// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last))
- else
- {// For all points other than the first or last: The Y-axis for spine[i] is found by normalizing the vector defined by (spine[i+1] - spine[i-1]).
- tvec = pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx - 1];
- }// if((pSpine_PointIdx == 0) || (pSpine_PointIdx == spine_idx_last)) else
-
- return tvec.Normalize();
-}
-
-static aiVector3D GeometryHelper_Extrusion_GetNextZ(const size_t pSpine_PointIdx, const std::vector<aiVector3D>& pSpine, const bool pSpine_Closed,
- const aiVector3D pVecZ_Prev)
-{
- const aiVector3D zero_vec(0);
- const size_t spine_idx_last = pSpine.size() - 1;
-
- aiVector3D tvec;
-
- // at first special cases
- if(pSpine.size() < 3)// spine have not enough points for vector calculations.
- {
- tvec.Set(0, 0, 1);
- }
- else if(pSpine_PointIdx == 0)// special case: first point
- {
- if(pSpine_Closed)// for calculating use previous point in curve s[n - 2]. In list it's a last point, because point s[n - 1] was removed as duplicate.
- {
- tvec = (pSpine[1] - pSpine[0]) ^ (pSpine[spine_idx_last] - pSpine[0]);
- }
- else // for not closed curve first and next point(s[0] and s[1]) has the same vector Z.
- {
- bool found = false;
-
- // As said: "If the Z-axis of the first point is undefined (because the spine is not closed and the first two spine segments are collinear)
- // then the Z-axis for the first spine point with a defined Z-axis is used."
- // Walk through spine and find Z.
- for(size_t next_point = 2; (next_point <= spine_idx_last) && !found; next_point++)
- {
- // (pSpine[2] - pSpine[1]) ^ (pSpine[0] - pSpine[1])
- tvec = (pSpine[next_point] - pSpine[next_point - 1]) ^ (pSpine[next_point - 2] - pSpine[next_point - 1]);
- found = !tvec.Equal(zero_vec);
- }
-
- // if entire spine are collinear then use OZ axis.
- if(!found) tvec.Set(0, 0, 1);
- }// if(pSpine_Closed) else
- }// else if(pSpine_PointIdx == 0)
- else if(pSpine_PointIdx == spine_idx_last)// special case: last point
- {
- if(pSpine_Closed)
- {// do not forget that real last point s[n - 1] is removed as duplicated. And in this case we are calculating vector Z for point s[n - 2].
- tvec = (pSpine[0] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]);
- // if taken spine vectors are collinear then use previous vector Z.
- if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
- }
- else
- {// vector Z for last point of not closed curve is previous vector Z.
- tvec = pVecZ_Prev;
- }
- }
- else// regular point
- {
- tvec = (pSpine[pSpine_PointIdx + 1] - pSpine[pSpine_PointIdx]) ^ (pSpine[pSpine_PointIdx - 1] - pSpine[pSpine_PointIdx]);
- // if taken spine vectors are collinear then use previous vector Z.
- if(tvec.Equal(zero_vec)) tvec = pVecZ_Prev;
- }
-
- // After determining the Z-axis, its dot product with the Z-axis of the previous spine point is computed. If this value is negative, the Z-axis
- // is flipped (multiplied by -1).
- if((tvec * pVecZ_Prev) < 0) tvec = -tvec;
-
- return tvec.Normalize();
-}
-
-// <Extrusion
-// DEF="" ID
-// USE="" IDREF
-// beginCap="true" SFBool [initializeOnly]
-// ccw="true" SFBool [initializeOnly]
-// convex="true" SFBool [initializeOnly]
-// creaseAngle="0.0" SFloat [initializeOnly]
-// crossSection="1 1 1 -1 -1 -1 -1 1 1 1" MFVec2f [initializeOnly]
-// endCap="true" SFBool [initializeOnly]
-// orientation="0 0 1 0" MFRotation [initializeOnly]
-// scale="1 1" MFVec2f [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// spine="0 0 0 0 1 0" MFVec3f [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry3D_Extrusion()
-{
- std::string use, def;
- bool beginCap = true;
- bool ccw = true;
- bool convex = true;
- float creaseAngle = 0;
- std::vector<aiVector2D> crossSection;
- bool endCap = true;
- std::vector<float> orientation;
- std::vector<aiVector2D> scale;
- bool solid = true;
- std::vector<aiVector3D> spine;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("beginCap", beginCap, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("convex", convex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("crossSection", crossSection, XML_ReadNode_GetAttrVal_AsArrVec2f);
- MACRO_ATTRREAD_CHECK_RET("endCap", endCap, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("orientation", orientation, XML_ReadNode_GetAttrVal_AsArrF);
- MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsArrVec2f);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("spine", spine, XML_ReadNode_GetAttrVal_AsArrVec3f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Extrusion, ne);
- }
- else
- {
- //
- // check if default values must be assigned
- //
- if(spine.size() == 0)
- {
- spine.resize(2);
- spine[0].Set(0, 0, 0), spine[1].Set(0, 1, 0);
- }
- else if(spine.size() == 1)
- {
- throw DeadlyImportError("ParseNode_Geometry3D_Extrusion. Spine must have at least two points.");
- }
-
- if(crossSection.size() == 0)
- {
- crossSection.resize(5);
- crossSection[0].Set(1, 1), crossSection[1].Set(1, -1), crossSection[2].Set(-1, -1), crossSection[3].Set(-1, 1), crossSection[4].Set(1, 1);
- }
-
- {// orientation
- size_t ori_size = orientation.size() / 4;
-
- if(ori_size < spine.size())
- {
- float add_ori[4];// values that will be added
-
- if(ori_size == 1)// if "orientation" has one element(means one MFRotation with four components) then use it value for all spine points.
- {
- add_ori[0] = orientation[0], add_ori[1] = orientation[1], add_ori[2] = orientation[2], add_ori[3] = orientation[3];
- }
- else// else - use default values
- {
- add_ori[0] = 0, add_ori[1] = 0, add_ori[2] = 1, add_ori[3] = 0;
- }
-
- orientation.reserve(spine.size() * 4);
- for(size_t i = 0, i_e = (spine.size() - ori_size); i < i_e; i++)
- orientation.push_back(add_ori[0]), orientation.push_back(add_ori[1]), orientation.push_back(add_ori[2]), orientation.push_back(add_ori[3]);
- }
-
- if(orientation.size() % 4) throw DeadlyImportError("Attribute \"orientation\" in <Extrusion> must has multiple four quantity of numbers.");
- }// END: orientation
-
- {// scale
- if(scale.size() < spine.size())
- {
- aiVector2D add_sc;
-
- if(scale.size() == 1)// if "scale" has one element then use it value for all spine points.
- add_sc = scale[0];
- else// else - use default values
- add_sc.Set(1, 1);
-
- scale.reserve(spine.size());
- for(size_t i = 0, i_e = (spine.size() - scale.size()); i < i_e; i++) scale.push_back(add_sc);
- }
- }// END: scale
- //
- // create and if needed - define new geometry object.
- //
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_Extrusion, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ext_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);// create alias for conveience
- // assign part of input data
- ext_alias.CCW = ccw;
- ext_alias.Convex = convex;
- ext_alias.CreaseAngle = creaseAngle;
- ext_alias.Solid = solid;
-
- //
- // How we done it at all?
- // 1. At first we will calculate array of basises for every point in spine(look SCP in ISO-dic). Also "orientation" vector
- // are applied vor every basis.
- // 2. After that we can create array of point sets: which are scaled, transferred to basis of relative basis and at final translated to real position
- // using relative spine point.
- // 3. Next step is creating CoordIdx array(do not forget "-1" delimiter). While creating CoordIdx also created faces for begin and end caps, if
- // needed. While createing CootdIdx is taking in account CCW flag.
- // 4. The last step: create Vertices list.
- //
- bool spine_closed;// flag: true if spine curve is closed.
- bool cross_closed;// flag: true if cross curve is closed.
- std::vector<aiMatrix3x3> basis_arr;// array of basises. ROW_a - X, ROW_b - Y, ROW_c - Z.
- std::vector<std::vector<aiVector3D> > pointset_arr;// array of point sets: cross curves.
-
- // detect closed curves
- GeometryHelper_Extrusion_CurveIsClosed(crossSection, true, true, cross_closed);// true - drop tail, true - remove duplicate end.
- GeometryHelper_Extrusion_CurveIsClosed(spine, true, true, spine_closed);// true - drop tail, true - remove duplicate end.
- // If both cap are requested and spine curve is closed then we can make only one cap. Because second cap will be the same surface.
- if(spine_closed)
- {
- beginCap |= endCap;
- endCap = false;
- }
-
- {// 1. Calculate array of basises.
- aiMatrix4x4 rotmat;
- aiVector3D vecX(0), vecY(0), vecZ(0);
-
- basis_arr.resize(spine.size());
- for(size_t i = 0, i_e = spine.size(); i < i_e; i++)
- {
- aiVector3D tvec;
-
- // get axises of basis.
- vecY = GeometryHelper_Extrusion_GetNextY(i, spine, spine_closed);
- vecZ = GeometryHelper_Extrusion_GetNextZ(i, spine, spine_closed, vecZ);
- vecX = (vecY ^ vecZ).Normalize();
- // get rotation matrix and apply "orientation" to basis
- aiMatrix4x4::Rotation(orientation[i * 4 + 3], aiVector3D(orientation[i * 4], orientation[i * 4 + 1], orientation[i * 4 + 2]), rotmat);
- tvec = vecX, tvec *= rotmat, basis_arr[i].a1 = tvec.x, basis_arr[i].a2 = tvec.y, basis_arr[i].a3 = tvec.z;
- tvec = vecY, tvec *= rotmat, basis_arr[i].b1 = tvec.x, basis_arr[i].b2 = tvec.y, basis_arr[i].b3 = tvec.z;
- tvec = vecZ, tvec *= rotmat, basis_arr[i].c1 = tvec.x, basis_arr[i].c2 = tvec.y, basis_arr[i].c3 = tvec.z;
- }// for(size_t i = 0, i_e = spine.size(); i < i_e; i++)
- }// END: 1. Calculate array of basises
-
- {// 2. Create array of point sets.
- aiMatrix4x4 scmat;
- std::vector<aiVector3D> tcross(crossSection.size());
-
- pointset_arr.resize(spine.size());
- for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++)
- {
- aiVector3D tc23vec;
-
- tc23vec.Set(scale[spi].x, 0, scale[spi].y);
- aiMatrix4x4::Scaling(tc23vec, scmat);
- for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++)
- {
- aiVector3D tvecX, tvecY, tvecZ;
-
- tc23vec.Set(crossSection[cri].x, 0, crossSection[cri].y);
- // apply scaling to point
- tcross[cri] = scmat * tc23vec;
- //
- // transfer point to new basis
- // calculate coordinate in new basis
- tvecX.Set(basis_arr[spi].a1, basis_arr[spi].a2, basis_arr[spi].a3), tvecX *= tcross[cri].x;
- tvecY.Set(basis_arr[spi].b1, basis_arr[spi].b2, basis_arr[spi].b3), tvecY *= tcross[cri].y;
- tvecZ.Set(basis_arr[spi].c1, basis_arr[spi].c2, basis_arr[spi].c3), tvecZ *= tcross[cri].z;
- // apply new coordinates and translate it to spine point.
- tcross[cri] = tvecX + tvecY + tvecZ + spine[spi];
- }// for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; i++)
-
- pointset_arr[spi] = tcross;// store transferred point set
- }// for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; i++)
- }// END: 2. Create array of point sets.
-
- {// 3. Create CoordIdx.
- // add caps if needed
- if(beginCap)
- {
- // add cap as polygon. vertices of cap are places at begin, so just add numbers from zero.
- for(size_t i = 0, i_e = crossSection.size(); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
-
- // add delimiter
- ext_alias.CoordIndex.push_back(-1);
- }// if(beginCap)
-
- if(endCap)
- {
- // add cap as polygon. vertices of cap are places at end, as for beginCap use just sequence of numbers but with offset.
- size_t beg = (pointset_arr.size() - 1) * crossSection.size();
-
- for(size_t i = beg, i_e = (beg + crossSection.size()); i < i_e; i++) ext_alias.CoordIndex.push_back(static_cast<int32_t>(i));
-
- // add delimiter
- ext_alias.CoordIndex.push_back(-1);
- }// if(beginCap)
-
- // add quads
- for(size_t spi = 0, spi_e = (spine.size() - 1); spi <= spi_e; spi++)
- {
- const size_t cr_sz = crossSection.size();
- const size_t cr_last = crossSection.size() - 1;
-
- size_t right_col;// hold index basis for points of quad placed in right column;
-
- if(spi != spi_e)
- right_col = spi + 1;
- else if(spine_closed)// if spine curve is closed then one more quad is needed: between first and last points of curve.
- right_col = 0;
- else
- break;// if spine curve is not closed then break the loop, because spi is out of range for that type of spine.
-
- for(size_t cri = 0; cri < cr_sz; cri++)
- {
- if(cri != cr_last)
- {
- MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex,
- static_cast<int32_t>(spi * cr_sz + cri),
- static_cast<int32_t>(right_col * cr_sz + cri),
- static_cast<int32_t>(right_col * cr_sz + cri + 1),
- static_cast<int32_t>(spi * cr_sz + cri + 1));
- // add delimiter
- ext_alias.CoordIndex.push_back(-1);
- }
- else if(cross_closed)// if cross curve is closed then one more quad is needed: between first and last points of curve.
- {
- MACRO_FACE_ADD_QUAD(ccw, ext_alias.CoordIndex,
- static_cast<int32_t>(spi * cr_sz + cri),
- static_cast<int32_t>(right_col * cr_sz + cri),
- static_cast<int32_t>(right_col * cr_sz + 0),
- static_cast<int32_t>(spi * cr_sz + 0));
- // add delimiter
- ext_alias.CoordIndex.push_back(-1);
- }
- }// for(size_t cri = 0; cri < cr_sz; cri++)
- }// for(size_t spi = 0, spi_e = (spine.size() - 2); spi < spi_e; spi++)
- }// END: 3. Create CoordIdx.
-
- {// 4. Create vertices list.
- // just copy all vertices
- for(size_t spi = 0, spi_e = spine.size(); spi < spi_e; spi++)
- {
- for(size_t cri = 0, cri_e = crossSection.size(); cri < cri_e; cri++)
- {
- ext_alias.Vertices.push_back(pointset_arr[spi][cri]);
- }
- }
- }// END: 4. Create vertices list.
-//PrintVectorSet("Ext. CoordIdx", ext_alias.CoordIndex);
-//PrintVectorSet("Ext. Vertices", ext_alias.Vertices);
- // check for child nodes
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Extrusion");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <IndexedFaceSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorIndex="" MFInt32 [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// convex="true" SFBool [initializeOnly]
-// coordIndex="" MFInt32 [initializeOnly]
-// creaseAngle="0" SFFloat [initializeOnly]
-// normalIndex="" MFInt32 [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// texCoordIndex="" MFInt32 [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </IndexedFaceSet>
-void X3DImporter::ParseNode_Geometry3D_IndexedFaceSet()
-{
- std::string use, def;
- bool ccw = true;
- std::vector<int32_t> colorIndex;
- bool colorPerVertex = true;
- bool convex = true;
- std::vector<int32_t> coordIndex;
- float creaseAngle = 0;
- std::vector<int32_t> normalIndex;
- bool normalPerVertex = true;
- bool solid = true;
- std::vector<int32_t> texCoordIndex;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("convex", convex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("creaseAngle", creaseAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("normalIndex", normalIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("texCoordIndex", texCoordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedFaceSet, ne);
- }
- else
- {
- // check data
- if(coordIndex.size() == 0) throw DeadlyImportError("IndexedFaceSet must contain not empty \"coordIndex\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedFaceSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorIndex = colorIndex;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.Convex = convex;
- ne_alias.CoordIndex = coordIndex;
- ne_alias.CreaseAngle = creaseAngle;
- ne_alias.NormalIndex = normalIndex;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
- ne_alias.TexCoordIndex = texCoordIndex;
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("IndexedFaceSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedFaceSet");
-
- MACRO_NODECHECK_LOOPEND("IndexedFaceSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Sphere
-// DEF="" ID
-// USE="" IDREF
-// radius="1" SFloat [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// />
-void X3DImporter::ParseNode_Geometry3D_Sphere()
-{
- std::string use, def;
- ai_real radius = 1;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Sphere, ne);
- }
- else
- {
- const unsigned int tess = 3;///TODO: IME tesselation factor through ai_property
-
- std::vector<aiVector3D> tlist;
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Geometry3D(CX3DImporter_NodeElement::ENET_Sphere, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- StandardShapes::MakeSphere(tess, tlist);
- // copy data from temp array and apply scale
- for(std::vector<aiVector3D>::iterator it = tlist.begin(); it != tlist.end(); it++)
- {
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->Vertices.push_back(*it * radius);
- }
-
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->Solid = solid;
- ((CX3DImporter_NodeElement_Geometry3D*)ne)->NumIndices = 3;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Sphere");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Group.cpp b/src/3rdparty/assimp/code/X3DImporter_Group.cpp
deleted file mode 100644
index e7df97b4b..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Group.cpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Group.cpp
-/// \brief Parsing data from nodes of "Grouping" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <Group
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// >
-// <!-- ChildContentModel -->
-// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes,
-// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the
-// precise palette of legal nodes that are available depends on assigned profile and components.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </Group>
-// A Group node contains children nodes without introducing a new transformation. It is equivalent to a Transform node containing an identity transform.
-void X3DImporter::ParseNode_Grouping_Group()
-{
- std::string def, use;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- CX3DImporter_NodeElement* ne;
-
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne);
- }
- else
- {
- ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children.
- // at this place new group mode created and made current, so we can name it.
- if(!def.empty()) NodeElement_Cur->ID = def;
- // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function.
-
- // for empty element exit from node in that place
- if(mReader->isEmptyElement()) ParseHelper_Node_Exit();
- }// if(!use.empty()) else
-}
-
-void X3DImporter::ParseNode_Grouping_GroupEnd()
-{
- ParseHelper_Node_Exit();// go up in scene graph
-}
-
-// <StaticGroup
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// >
-// <!-- ChildContentModel -->
-// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes,
-// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the
-// precise palette of legal nodes that are available depends on assigned profile and components.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </StaticGroup>
-// The StaticGroup node contains children nodes which cannot be modified. StaticGroup children are guaranteed to not change, send events, receive events or
-// contain any USE references outside the StaticGroup.
-void X3DImporter::ParseNode_Grouping_StaticGroup()
-{
- std::string def, use;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- CX3DImporter_NodeElement* ne;
-
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne);
- }
- else
- {
- ParseHelper_Group_Begin(true);// create new grouping element and go deeper if node has children.
- // at this place new group mode created and made current, so we can name it.
- if(!def.empty()) NodeElement_Cur->ID = def;
- // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function.
-
- // for empty element exit from node in that place
- if(mReader->isEmptyElement()) ParseHelper_Node_Exit();
- }// if(!use.empty()) else
-}
-
-void X3DImporter::ParseNode_Grouping_StaticGroupEnd()
-{
- ParseHelper_Node_Exit();// go up in scene graph
-}
-
-// <Switch
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// whichChoice="-1" SFInt32 [inputOutput]
-// >
-// <!-- ChildContentModel -->
-// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes,
-// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the
-// precise palette of legal nodes that are available depends on assigned profile and components.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </Switch>
-// The Switch grouping node traverses zero or one of the nodes specified in the children field. The whichChoice field specifies the index of the child
-// to traverse, with the first child having index 0. If whichChoice is less than zero or greater than the number of nodes in the children field, nothing
-// is chosen.
-void X3DImporter::ParseNode_Grouping_Switch()
-{
- std::string def, use;
- int32_t whichChoice = -1;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("whichChoice", whichChoice, XML_ReadNode_GetAttrVal_AsI32);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- CX3DImporter_NodeElement* ne;
-
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne);
- }
- else
- {
- ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children.
- // at this place new group mode created and made current, so we can name it.
- if(!def.empty()) NodeElement_Cur->ID = def;
-
- // also set values specific to this type of group
- ((CX3DImporter_NodeElement_Group*)NodeElement_Cur)->UseChoice = true;
- ((CX3DImporter_NodeElement_Group*)NodeElement_Cur)->Choice = whichChoice;
- // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function.
-
- // for empty element exit from node in that place
- if(mReader->isEmptyElement()) ParseHelper_Node_Exit();
- }// if(!use.empty()) else
-}
-
-void X3DImporter::ParseNode_Grouping_SwitchEnd()
-{
- // just exit from node. Defined choice will be accepted at postprocessing stage.
- ParseHelper_Node_Exit();// go up in scene graph
-}
-
-// <Transform
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// center="0 0 0" SFVec3f [inputOutput]
-// rotation="0 0 1 0" SFRotation [inputOutput]
-// scale="1 1 1" SFVec3f [inputOutput]
-// scaleOrientation="0 0 1 0" SFRotation [inputOutput]
-// translation="0 0 0" SFVec3f [inputOutput]
-// >
-// <!-- ChildContentModel -->
-// ChildContentModel is the child-node content model corresponding to X3DChildNode, combining all profiles. ChildContentModel can contain most nodes,
-// other Grouping nodes, Prototype declarations and ProtoInstances in any order and any combination. When the assigned profile is less than Full, the
-// precise palette of legal nodes that are available depends on assigned profile and components.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </Transform>
-// The Transform node is a grouping node that defines a coordinate system for its children that is relative to the coordinate systems of its ancestors.
-// Given a 3-dimensional point P and Transform node, P is transformed into point P' in its parent's coordinate system by a series of intermediate
-// transformations. In matrix transformation notation, where C (center), SR (scaleOrientation), T (translation), R (rotation), and S (scale) are the
-// equivalent transformation matrices,
-// P' = T * C * R * SR * S * -SR * -C * P
-void X3DImporter::ParseNode_Grouping_Transform()
-{
- aiVector3D center(0, 0, 0);
- float rotation[4] = {0, 0, 1, 0};
- aiVector3D scale(1, 1, 1);// A value of zero indicates that any child geometry shall not be displayed
- float scale_orientation[4] = {0, 0, 1, 0};
- aiVector3D translation(0, 0, 0);
- aiMatrix4x4 matr, tmatr;
- std::string use, def;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("center", center, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_REF("translation", translation, XML_ReadNode_GetAttrVal_AsVec3f);
- if(an == "rotation")
- {
- std::vector<float> tvec;
-
- XML_ReadNode_GetAttrVal_AsArrF(idx, tvec);
- if(tvec.size() != 4) throw DeadlyImportError("<Transform>: rotation vector must have 4 elements.");
-
- memcpy(rotation, tvec.data(), sizeof(rotation));
-
- continue;
- }
-
- if(an == "scaleOrientation")
- {
- std::vector<float> tvec;
- XML_ReadNode_GetAttrVal_AsArrF(idx, tvec);
- if ( tvec.size() != 4 )
- {
- throw DeadlyImportError( "<Transform>: scaleOrientation vector must have 4 elements." );
- }
-
- ::memcpy(scale_orientation, tvec.data(), sizeof(scale_orientation) );
-
- continue;
- }
-
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne);
- }
- else
- {
- ParseHelper_Group_Begin();// create new grouping element and go deeper if node has children.
- // at this place new group mode created and made current, so we can name it.
- if ( !def.empty() )
- {
- NodeElement_Cur->ID = def;
- }
-
- //
- // also set values specific to this type of group
- //
- // calculate transformation matrix
- aiMatrix4x4::Translation(translation, matr);// T
- aiMatrix4x4::Translation(center, tmatr);// C
- matr *= tmatr;
- aiMatrix4x4::Rotation(rotation[3], aiVector3D(rotation[0], rotation[1], rotation[2]), tmatr);// R
- matr *= tmatr;
- aiMatrix4x4::Rotation(scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr);// SR
- matr *= tmatr;
- aiMatrix4x4::Scaling(scale, tmatr);// S
- matr *= tmatr;
- aiMatrix4x4::Rotation(-scale_orientation[3], aiVector3D(scale_orientation[0], scale_orientation[1], scale_orientation[2]), tmatr);// -SR
- matr *= tmatr;
- aiMatrix4x4::Translation(-center, tmatr);// -C
- matr *= tmatr;
- // and assign it
- ((CX3DImporter_NodeElement_Group*)NodeElement_Cur)->Transformation = matr;
- // in grouping set of nodes check X3DMetadataObject is not needed, because it is done in <Scene> parser function.
-
- // for empty element exit from node in that place
- if ( mReader->isEmptyElement() )
- {
- ParseHelper_Node_Exit();
- }
- }// if(!use.empty()) else
-}
-
-void X3DImporter::ParseNode_Grouping_TransformEnd()
-{
- ParseHelper_Node_Exit();// go up in scene graph
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Light.cpp b/src/3rdparty/assimp/code/X3DImporter_Light.cpp
deleted file mode 100644
index ff450f7a9..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Light.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Light.cpp
-/// \brief Parsing data from nodes of "Lighting" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-#include "StringUtils.h"
-
-namespace Assimp {
-
-// <DirectionalLight
-// DEF="" ID
-// USE="" IDREF
-// ambientIntensity="0" SFFloat [inputOutput]
-// color="1 1 1" SFColor [inputOutput]
-// direction="0 0 -1" SFVec3f [inputOutput]
-// global="false" SFBool [inputOutput]
-// intensity="1" SFFloat [inputOutput]
-// on="true" SFBool [inputOutput]
-// />
-void X3DImporter::ParseNode_Lighting_DirectionalLight()
-{
- std::string def, use;
- float ambientIntensity = 0;
- aiColor3D color(1, 1, 1);
- aiVector3D direction(0, 0, -1);
- bool global = false;
- float intensity = 1;
- bool on = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_CHECK_REF("direction", direction, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_DirectionalLight, ne);
- }
- else
- {
- if(on)
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Light(CX3DImporter_NodeElement::ENET_DirectionalLight, NodeElement_Cur);
- if(!def.empty())
- ne->ID = def;
- else
- ne->ID = "DirectionalLight_" + to_string((size_t)ne);// make random name
-
- ((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity;
- ((CX3DImporter_NodeElement_Light*)ne)->Color = color;
- ((CX3DImporter_NodeElement_Light*)ne)->Direction = direction;
- ((CX3DImporter_NodeElement_Light*)ne)->Global = global;
- ((CX3DImporter_NodeElement_Light*)ne)->Intensity = intensity;
- // Assimp want a node with name similar to a light. "Why? I don't no." )
- ParseHelper_Group_Begin(false);
-
- NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
- ParseHelper_Node_Exit();
- // check for child nodes
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "DirectionalLight");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(on)
- }// if(!use.empty()) else
-}
-
-// <PointLight
-// DEF="" ID
-// USE="" IDREF
-// ambientIntensity="0" SFFloat [inputOutput]
-// attenuation="1 0 0" SFVec3f [inputOutput]
-// color="1 1 1" SFColor [inputOutput]
-// global="true" SFBool [inputOutput]
-// intensity="1" SFFloat [inputOutput]
-// location="0 0 0" SFVec3f [inputOutput]
-// on="true" SFBool [inputOutput]
-// radius="100" SFFloat [inputOutput]
-// />
-void X3DImporter::ParseNode_Lighting_PointLight()
-{
- std::string def, use;
- float ambientIntensity = 0;
- aiVector3D attenuation( 1, 0, 0 );
- aiColor3D color( 1, 1, 1 );
- bool global = true;
- float intensity = 1;
- aiVector3D location( 0, 0, 0 );
- bool on = true;
- float radius = 100;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("attenuation", attenuation, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("location", location, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_PointLight, ne);
- }
- else
- {
- if(on)
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Light(CX3DImporter_NodeElement::ENET_PointLight, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity;
- ((CX3DImporter_NodeElement_Light*)ne)->Attenuation = attenuation;
- ((CX3DImporter_NodeElement_Light*)ne)->Color = color;
- ((CX3DImporter_NodeElement_Light*)ne)->Global = global;
- ((CX3DImporter_NodeElement_Light*)ne)->Intensity = intensity;
- ((CX3DImporter_NodeElement_Light*)ne)->Location = location;
- ((CX3DImporter_NodeElement_Light*)ne)->Radius = radius;
- // Assimp want a node with name similar to a light. "Why? I don't no." )
- ParseHelper_Group_Begin(false);
- // make random name
- if(ne->ID.empty()) ne->ID = "PointLight_" + to_string((size_t)ne);
-
- NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
- ParseHelper_Node_Exit();
- // check for child nodes
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "PointLight");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(on)
- }// if(!use.empty()) else
-}
-
-// <SpotLight
-// DEF="" ID
-// USE="" IDREF
-// ambientIntensity="0" SFFloat [inputOutput]
-// attenuation="1 0 0" SFVec3f [inputOutput]
-// beamWidth="0.7854" SFFloat [inputOutput]
-// color="1 1 1" SFColor [inputOutput]
-// cutOffAngle="1.570796" SFFloat [inputOutput]
-// direction="0 0 -1" SFVec3f [inputOutput]
-// global="true" SFBool [inputOutput]
-// intensity="1" SFFloat [inputOutput]
-// location="0 0 0" SFVec3f [inputOutput]
-// on="true" SFBool [inputOutput]
-// radius="100" SFFloat [inputOutput]
-// />
-void X3DImporter::ParseNode_Lighting_SpotLight()
-{
- std::string def, use;
- float ambientIntensity = 0;
- aiVector3D attenuation( 1, 0, 0 );
- float beamWidth = 0.7854f;
- aiColor3D color( 1, 1, 1 );
- float cutOffAngle = 1.570796f;
- aiVector3D direction( 0, 0, -1 );
- bool global = true;
- float intensity = 1;
- aiVector3D location( 0, 0, 0 );
- bool on = true;
- float radius = 100;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("attenuation", attenuation, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("beamWidth", beamWidth, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_CHECK_RET("cutOffAngle", cutOffAngle, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("direction", direction, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("global", global, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("intensity", intensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("location", location, XML_ReadNode_GetAttrVal_AsVec3f);
- MACRO_ATTRREAD_CHECK_RET("on", on, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("radius", radius, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_SpotLight, ne);
- }
- else
- {
- if(on)
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Light(CX3DImporter_NodeElement::ENET_SpotLight, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- if(beamWidth > cutOffAngle) beamWidth = cutOffAngle;
-
- ((CX3DImporter_NodeElement_Light*)ne)->AmbientIntensity = ambientIntensity;
- ((CX3DImporter_NodeElement_Light*)ne)->Attenuation = attenuation;
- ((CX3DImporter_NodeElement_Light*)ne)->BeamWidth = beamWidth;
- ((CX3DImporter_NodeElement_Light*)ne)->Color = color;
- ((CX3DImporter_NodeElement_Light*)ne)->CutOffAngle = cutOffAngle;
- ((CX3DImporter_NodeElement_Light*)ne)->Direction = direction;
- ((CX3DImporter_NodeElement_Light*)ne)->Global = global;
- ((CX3DImporter_NodeElement_Light*)ne)->Intensity = intensity;
- ((CX3DImporter_NodeElement_Light*)ne)->Location = location;
- ((CX3DImporter_NodeElement_Light*)ne)->Radius = radius;
-
- // Assimp want a node with name similar to a light. "Why? I don't no." )
- ParseHelper_Group_Begin(false);
- // make random name
- if(ne->ID.empty()) ne->ID = "SpotLight_" + to_string((size_t)ne);
-
- NodeElement_Cur->ID = ne->ID;// assign name to node and return to light element.
- ParseHelper_Node_Exit();
- // check for child nodes
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "SpotLight");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(on)
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Macro.hpp b/src/3rdparty/assimp/code/X3DImporter_Macro.hpp
deleted file mode 100644
index 6281efcd5..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Macro.hpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Macro.hpp
-/// \brief Useful macrodefines.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef X3DIMPORTER_MACRO_HPP_INCLUDED
-#define X3DIMPORTER_MACRO_HPP_INCLUDED
-
-/// \def MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pNE)
-/// Used for regular checking while attribute "USE" is defined.
-/// \param [in] pDEF - string holding "DEF" value.
-/// \param [in] pUSE - string holding "USE" value.
-/// \param [in] pType - type of element to find.
-/// \param [out] pNE - pointer to found node element.
-#define MACRO_USE_CHECKANDAPPLY(pDEF, pUSE, pType, pNE) \
- do { \
- XML_CheckNode_MustBeEmpty(); \
- if(!pDEF.empty()) Throw_DEF_And_USE(); \
- if(!FindNodeElement(pUSE, CX3DImporter_NodeElement::pType, &pNE)) Throw_USE_NotFound(pUSE); \
- \
- NodeElement_Cur->Child.push_back(pNE);/* add found object as child to current element */ \
- } while(false)
-
-/// \def MACRO_ATTRREAD_LOOPBEG
-/// Begin of loop that read attributes values.
-#define MACRO_ATTRREAD_LOOPBEG \
- for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
- { \
- std::string an(mReader->getAttributeName(idx));
-
-/// \def MACRO_ATTRREAD_LOOPEND
-/// End of loop that read attributes values.
-#define MACRO_ATTRREAD_LOOPEND \
- Throw_IncorrectAttr(an); \
- }
-
-/// \def MACRO_ATTRREAD_CHECK_REF
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
-/// "continue" will called.
-/// \param [in] pAttrName - attribute name.
-/// \param [out] pVarName - output variable name.
-/// \param [in] pFunction - function which read attribute value and write it to pVarName.
-#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
- if(an == pAttrName) \
- { \
- pFunction(idx, pVarName); \
- continue; \
- }
-
-/// \def MACRO_ATTRREAD_CHECK_RET
-/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
-/// If result was read then "continue" will called.
-/// \param [in] pAttrName - attribute name.
-/// \param [out] pVarName - output variable name.
-/// \param [in] pFunction - function which read attribute value and write it to pVarName.
-#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
- if(an == pAttrName) \
- { \
- pVarName = pFunction(idx); \
- continue; \
- }
-
-/// \def MACRO_ATTRREAD_CHECKUSEDEF_RET
-/// Compact variant for checking "USE" and "DEF". Also skip bbox attributes: "bboxCenter", "bboxSize".
-/// If result was read then "continue" will called.
-/// \param [out] pDEF_Var - output variable name for "DEF" value.
-/// \param [out] pUSE_Var - output variable name for "USE" value.
-#define MACRO_ATTRREAD_CHECKUSEDEF_RET(pDEF_Var, pUSE_Var) \
- MACRO_ATTRREAD_CHECK_RET("DEF", pDEF_Var, mReader->getAttributeValue); \
- MACRO_ATTRREAD_CHECK_RET("USE", pUSE_Var, mReader->getAttributeValue); \
- if(an == "bboxCenter") continue; \
- if(an == "bboxSize") continue; \
- if(an == "containerField") continue; \
- do {} while(false)
-
-/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
-/// Begin of loop of parsing child nodes. Do not add ';' at end.
-/// \param [in] pNodeName - current node name.
-#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
- do { \
- bool close_found = false; \
- \
- while(mReader->read()) \
- { \
- if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
- {
-
-/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
-/// End of loop of parsing child nodes.
-/// \param [in] pNodeName - current node name.
-#define MACRO_NODECHECK_LOOPEND(pNodeName) \
- }/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
- else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
- { \
- if(XML_CheckNode_NameEqual(pNodeName)) \
- { \
- close_found = true; \
- \
- break; \
- } \
- }/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
- }/* while(mReader->read()) */ \
- \
- if(!close_found) Throw_CloseNotFound(pNodeName); \
- \
- } while(false)
-
-#define MACRO_NODECHECK_METADATA(pNodeName) \
- MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
- /* and childs must be metadata nodes */ \
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported(pNodeName); \
- MACRO_NODECHECK_LOOPEND(pNodeName)
-
-/// \def MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4)
-/// Add points as quad. Means that pP1..pP4 set in CCW order.
-#define MACRO_FACE_ADD_QUAD_FA(pCCW, pOut, pIn, pP1, pP2, pP3, pP4) \
- do { \
- if(pCCW) \
- { \
- pOut.push_back(pIn[pP1]); \
- pOut.push_back(pIn[pP2]); \
- pOut.push_back(pIn[pP3]); \
- pOut.push_back(pIn[pP4]); \
- } \
- else \
- { \
- pOut.push_back(pIn[pP4]); \
- pOut.push_back(pIn[pP3]); \
- pOut.push_back(pIn[pP2]); \
- pOut.push_back(pIn[pP1]); \
- } \
- } while(false)
-
-/// \def MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4)
-/// Add points as quad. Means that pP1..pP4 set in CCW order.
-#define MACRO_FACE_ADD_QUAD(pCCW, pOut, pP1, pP2, pP3, pP4) \
- do { \
- if(pCCW) \
- { \
- pOut.push_back(pP1); \
- pOut.push_back(pP2); \
- pOut.push_back(pP3); \
- pOut.push_back(pP4); \
- } \
- else \
- { \
- pOut.push_back(pP4); \
- pOut.push_back(pP3); \
- pOut.push_back(pP2); \
- pOut.push_back(pP1); \
- } \
- } while(false)
-
-#endif // X3DIMPORTER_MACRO_HPP_INCLUDED
diff --git a/src/3rdparty/assimp/code/X3DImporter_Metadata.cpp b/src/3rdparty/assimp/code/X3DImporter_Metadata.cpp
deleted file mode 100644
index 0fa1b27b3..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Metadata.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Metadata.cpp
-/// \brief Parsing data from nodes of "Metadata" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-/// \def MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaName)
-/// Find element by "USE" or create new one.
-/// \param [in] pDEF_Var - variable name with "DEF" value.
-/// \param [in] pUSE_Var - variable name with "USE" value.
-/// \param [in] pReference - variable name with "reference" value.
-/// \param [in] pValue - variable name with "value" value.
-/// \param [in, out] pNE - pointer to node element.
-/// \param [in] pMetaClass - Class of node.
-/// \param [in] pMetaName - Name of node.
-/// \param [in] pType - type of element to find.
-#define MACRO_METADATA_FINDCREATE(pDEF_Var, pUSE_Var, pReference, pValue, pNE, pMetaClass, pMetaName, pType) \
- /* if "USE" defined then find already defined element. */ \
- if(!pUSE_Var.empty()) \
- { \
- MACRO_USE_CHECKANDAPPLY(pDEF_Var, pUSE_Var, pType, pNE); \
- } \
- else \
- { \
- pNE = new pMetaClass(NodeElement_Cur); \
- if(!pDEF_Var.empty()) pNE->ID = pDEF_Var; \
- \
- ((pMetaClass*)pNE)->Reference = pReference; \
- ((pMetaClass*)pNE)->Value = pValue; \
- /* also metadata node can contain childs */ \
- if(!mReader->isEmptyElement()) \
- ParseNode_Metadata(pNE, pMetaName);/* in that case node element will be added to child elements list of current node. */ \
- else \
- NodeElement_Cur->Child.push_back(pNE);/* else - add element to child list manualy */ \
- \
- NodeElement_List.push_back(pNE);/* add new element to elements list. */ \
- }/* if(!pUSE_Var.empty()) else */ \
- \
- do {} while(false)
-
-bool X3DImporter::ParseHelper_CheckRead_X3DMetadataObject()
-{
- if(XML_CheckNode_NameEqual("MetadataBoolean"))
- ParseNode_MetadataBoolean();
- else if(XML_CheckNode_NameEqual("MetadataDouble"))
- ParseNode_MetadataDouble();
- else if(XML_CheckNode_NameEqual("MetadataFloat"))
- ParseNode_MetadataFloat();
- else if(XML_CheckNode_NameEqual("MetadataInteger"))
- ParseNode_MetadataInteger();
- else if(XML_CheckNode_NameEqual("MetadataSet"))
- ParseNode_MetadataSet();
- else if(XML_CheckNode_NameEqual("MetadataString"))
- ParseNode_MetadataString();
- else
- return false;
-
- return true;
-}
-
-void X3DImporter::ParseNode_Metadata(CX3DImporter_NodeElement* pParentElement, const std::string& /*pNodeName*/)
-{
- ParseHelper_Node_Enter(pParentElement);
- MACRO_NODECHECK_METADATA(mReader->getNodeName());
- ParseHelper_Node_Exit();
-}
-
-// <MetadataBoolean
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// value="" MFBool [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataBoolean()
-{
- std::string def, use;
- std::string name, reference;
- std::vector<bool> value;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrB);
- MACRO_ATTRREAD_LOOPEND;
-
- MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaBoolean, "MetadataBoolean", ENET_MetaBoolean);
-}
-
-// <MetadataDouble
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// value="" MFDouble [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataDouble()
-{
- std::string def, use;
- std::string name, reference;
- std::vector<double> value;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrD);
- MACRO_ATTRREAD_LOOPEND;
-
- MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaDouble, "MetadataDouble", ENET_MetaDouble);
-}
-
-// <MetadataFloat
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// value="" MFFloat [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataFloat()
-{
- std::string def, use;
- std::string name, reference;
- std::vector<float> value;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrF);
- MACRO_ATTRREAD_LOOPEND;
-
- MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaFloat, "MetadataFloat", ENET_MetaFloat);
-}
-
-// <MetadataInteger
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// value="" MFInteger [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataInteger()
-{
- std::string def, use;
- std::string name, reference;
- std::vector<int32_t> value;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_LOOPEND;
-
- MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaInteger, "MetadataInteger", ENET_MetaInteger);
-}
-
-// <MetadataSet
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataSet()
-{
- std::string def, use;
- std::string name, reference;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_MetaSet, ne);
- }
- else
- {
- ne = new CX3DImporter_NodeElement_MetaSet(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_MetaSet*)ne)->Reference = reference;
- // also metadata node can contain childs
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "MetadataSet");
- else
- NodeElement_Cur->Child.push_back(ne);// made object as child to current element
-
- NodeElement_List.push_back(ne);// add new element to elements list.
- }// if(!use.empty()) else
-}
-
-// <MetadataString
-// DEF="" ID
-// USE="" IDREF
-// name="" SFString [inputOutput]
-// reference="" SFString [inputOutput]
-// value="" MFString [inputOutput]
-// />
-void X3DImporter::ParseNode_MetadataString()
-{
- std::string def, use;
- std::string name, reference;
- std::list<std::string> value;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("name", name, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_RET("reference", reference, mReader->getAttributeValue);
- MACRO_ATTRREAD_CHECK_REF("value", value, XML_ReadNode_GetAttrVal_AsListS);
- MACRO_ATTRREAD_LOOPEND;
-
- MACRO_METADATA_FINDCREATE(def, use, reference, value, ne, CX3DImporter_NodeElement_MetaString, "MetadataString", ENET_MetaString);
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Networking.cpp b/src/3rdparty/assimp/code/X3DImporter_Networking.cpp
deleted file mode 100644
index 269c58ba3..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Networking.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Networking.cpp
-/// \brief Parsing data from nodes of "Networking" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-// Header files, Assimp.
-#include <assimp/DefaultIOSystem.h>
-
-//#include <regex>
-
-namespace Assimp
-{
-
-//static std::regex pattern_parentDir(R"((^|/)[^/]+/../)");
-static std::string parentDir("/../");
-
-// <Inline
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// load="true" SFBool [inputOutput]
-// url="" MFString [inputOutput]
-// />
-void X3DImporter::ParseNode_Networking_Inline()
-{
- std::string def, use;
- bool load = true;
- std::list<std::string> url;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("load", load, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("url", url, XML_ReadNode_GetAttrVal_AsListS);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- CX3DImporter_NodeElement* ne;
-
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Group, ne);
- }
- else
- {
- ParseHelper_Group_Begin(true);// create new grouping element and go deeper if node has children.
- // at this place new group mode created and made current, so we can name it.
- if(!def.empty()) NodeElement_Cur->ID = def;
-
- if(load && (url.size() > 0))
- {
- std::string full_path = mpIOHandler->CurrentDirectory() + url.front();
-
- //full_path = std::regex_replace(full_path, pattern_parentDir, "$1");
- for (std::string::size_type pos = full_path.find(parentDir); pos != std::string::npos; pos = full_path.find(parentDir, pos)) {
- if (pos > 0) {
- std::string::size_type pos2 = full_path.rfind('/', pos - 1);
- if (pos2 != std::string::npos) {
- full_path.erase(pos2, pos - pos2 + 3);
- pos = pos2;
- }
- else {
- full_path.erase(0, pos + 4);
- pos = 0;
- }
- }
- else {
- pos += 3;
- }
- }
- // Attribute "url" can contain list of strings. But we need only one - first.
- std::string::size_type slashPos = full_path.find_last_of("\\/");
- mpIOHandler->PushDirectory(slashPos == std::string::npos ? std::string() : full_path.substr(0, slashPos + 1));
- ParseFile(full_path, mpIOHandler);
- mpIOHandler->PopDirectory();
- }
-
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement()) ParseNode_Metadata(NodeElement_Cur, "Inline");
-
- // exit from node in that place
- ParseHelper_Node_Exit();
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Node.hpp b/src/3rdparty/assimp/code/X3DImporter_Node.hpp
deleted file mode 100644
index 6ed96c2f9..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Node.hpp
+++ /dev/null
@@ -1,779 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Node.hpp
-/// \brief Elements of scene graph.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef INCLUDED_AI_X3D_IMPORTER_NODE_H
-#define INCLUDED_AI_X3D_IMPORTER_NODE_H
-
-// Header files, Assimp.
-#include <assimp/scene.h>
-#include <assimp/types.h>
-
-// Header files, stdlib.
-#include <list>
-#include <vector>
-#include <string>
-
-/// \class CX3DImporter_NodeElement
-/// Base class for elements of nodes.
-class CX3DImporter_NodeElement
-{
- /***********************************************/
- /******************** Types ********************/
- /***********************************************/
-
-public:
-
- /// \enum EType
- /// Define what data type contain node element.
- enum EType
- {
- ENET_Group, ///< Element has type "Group".
- ENET_MetaBoolean, ///< Element has type "Metadata boolean".
- ENET_MetaDouble, ///< Element has type "Metadata double".
- ENET_MetaFloat, ///< Element has type "Metadata float".
- ENET_MetaInteger, ///< Element has type "Metadata integer".
- ENET_MetaSet, ///< Element has type "Metadata set".
- ENET_MetaString, ///< Element has type "Metadata string".
- ENET_Arc2D, ///< Element has type "Arc2D".
- ENET_ArcClose2D, ///< Element has type "ArcClose2D".
- ENET_Circle2D, ///< Element has type "Circle2D".
- ENET_Disk2D, ///< Element has type "Disk2D".
- ENET_Polyline2D, ///< Element has type "Polyline2D".
- ENET_Polypoint2D, ///< Element has type "Polypoint2D".
- ENET_Rectangle2D, ///< Element has type "Rectangle2D".
- ENET_TriangleSet2D, ///< Element has type "TriangleSet2D".
- ENET_Box, ///< Element has type "Box".
- ENET_Cone, ///< Element has type "Cone".
- ENET_Cylinder, ///< Element has type "Cylinder".
- ENET_Sphere, ///< Element has type "Sphere".
- ENET_ElevationGrid, ///< Element has type "ElevationGrid".
- ENET_Extrusion, ///< Element has type "Extrusion".
- ENET_Coordinate, ///< Element has type "Coordinate".
- ENET_Normal, ///< Element has type "Normal".
- ENET_TextureCoordinate, ///< Element has type "TextureCoordinate".
- ENET_IndexedFaceSet, ///< Element has type "IndexedFaceSet".
- ENET_IndexedLineSet, ///< Element has type "IndexedLineSet".
- ENET_IndexedTriangleSet, ///< Element has type "IndexedTriangleSet".
- ENET_IndexedTriangleFanSet, ///< Element has type "IndexedTriangleFanSet".
- ENET_IndexedTriangleStripSet,///< Element has type "IndexedTriangleStripSet".
- ENET_LineSet, ///< Element has type "LineSet".
- ENET_PointSet, ///< Element has type "PointSet".
- ENET_TriangleSet, ///< Element has type "TriangleSet".
- ENET_TriangleFanSet, ///< Element has type "TriangleFanSet".
- ENET_TriangleStripSet, ///< Element has type "TriangleStripSet".
- ENET_Color, ///< Element has type "Color".
- ENET_ColorRGBA, ///< Element has type "ColorRGBA".
- ENET_Shape, ///< Element has type "Shape".
- ENET_Appearance, ///< Element has type "Appearance".
- ENET_Material, ///< Element has type "Material".
- ENET_ImageTexture, ///< Element has type "ImageTexture".
- ENET_TextureTransform, ///< Element has type "TextureTransform".
- ENET_DirectionalLight, ///< Element has type "DirectionalLight".
- ENET_PointLight, ///< Element has type "PointLight".
- ENET_SpotLight, ///< Element has type "SpotLight".
-
- ENET_Invalid ///< Element has invalid type and possible contain invalid data.
- };
-
- /***********************************************/
- /****************** Constants ******************/
- /***********************************************/
-
-public:
-
- const EType Type;
-
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- std::string ID;///< ID of the element. Can be empty. In X3D synonym for "ID" attribute.
- CX3DImporter_NodeElement* Parent;///< Parent element. If nullptr then this node is root.
- std::list<CX3DImporter_NodeElement*> Child;///< Child elements.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
- /// @brief The destructor, virtual.
- virtual ~CX3DImporter_NodeElement() {
- // empty
- }
-
-private:
- /// Disabled copy constructor.
- CX3DImporter_NodeElement(const CX3DImporter_NodeElement& pNodeElement);
-
- /// Disabled assign operator.
- CX3DImporter_NodeElement& operator=(const CX3DImporter_NodeElement& pNodeElement);
-
- /// Disabled default constructor.
- CX3DImporter_NodeElement();
-
-protected:
- /// In constructor inheritor must set element type.
- /// \param [in] pType - element type.
- /// \param [in] pParent - parent element.
- CX3DImporter_NodeElement(const EType pType, CX3DImporter_NodeElement* pParent)
- : Type(pType), Parent(pParent)
- {}
-};// class IX3DImporter_NodeElement
-
-/// \class CX3DImporter_NodeElement_Group
-/// Class that define grouping node. Define transformation matrix for children.
-/// Also can select which child will be kept and others are removed.
-class CX3DImporter_NodeElement_Group : public CX3DImporter_NodeElement
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- aiMatrix4x4 Transformation;///< Transformation matrix.
-
- /// \var bool Static
- /// As you know node elements can use already defined node elements when attribute "USE" is defined.
- /// Standard search when looking for an element in the whole scene graph, existing at this moment.
- /// If a node is marked as static, the children(or lower) can not search for elements in the nodes upper then static.
- bool Static;
-
- bool UseChoice;///< Flag: if true then use number from \ref Choice to choose what the child will be kept.
- int32_t Choice;///< Number of the child which will be kept.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_Group(const CX3DImporter_NodeElement_Group& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Group(const CX3DImporter_NodeElement_Group& pNode);
-
- /// \fn CX3DImporter_NodeElement_Group& operator=(const CX3DImporter_NodeElement_Group& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Group& operator=(const CX3DImporter_NodeElement_Group& pNode);
-
- /// \fn CX3DImporter_NodeElement_Group()
- /// Disabled default constructor.
- CX3DImporter_NodeElement_Group();
-
-public:
-
- /// \fn CX3DImporter_NodeElement_Group(CX3DImporter_NodeElement_Group* pParent, const bool pStatic = false)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pStatic - static node flag.
- CX3DImporter_NodeElement_Group(CX3DImporter_NodeElement* pParent, const bool pStatic = false)
- : CX3DImporter_NodeElement(ENET_Group, pParent), Static(pStatic), UseChoice(false)
- {}
-
-};// class CX3DImporter_NodeElement_Group
-
-/// \class CX3DImporter_NodeElement_Meta
-/// This struct describe metavalue.
-class CX3DImporter_NodeElement_Meta : public CX3DImporter_NodeElement
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- std::string Name;///< Name of metadata object.
- /// \var std::string Reference
- /// If provided, it identifies the metadata standard or other specification that defines the name field. If the reference field is not provided or is
- /// empty, the meaning of the name field is considered implicit to the characters in the string.
- std::string Reference;
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_Meta(const CX3DImporter_NodeElement_Meta& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Meta(const CX3DImporter_NodeElement_Meta& pNode);
-
- /// \fn CX3DImporter_NodeElement_Meta& operator=(const CX3DImporter_NodeElement_Meta& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Meta& operator=(const CX3DImporter_NodeElement_Meta& pNode);
-
- /// \fn CX3DImporter_NodeElement_Meta()
- /// Disabled default constructor.
- CX3DImporter_NodeElement_Meta();
-
-public:
-
- /// \fn CX3DImporter_NodeElement_Meta(const EType pType, CX3DImporter_NodeElement* pParent)
- /// In constructor inheritor must set element type.
- /// \param [in] pType - element type.
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Meta(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(pType, pParent)
- {}
-
-};// class CX3DImporter_NodeElement_Meta
-
-/// \struct CX3DImporter_NodeElement_MetaBoolean
-/// This struct describe metavalue of type boolean.
-struct CX3DImporter_NodeElement_MetaBoolean : public CX3DImporter_NodeElement_Meta
-{
- std::vector<bool> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaBoolean(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaBoolean(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaBoolean, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaBoolean
-
-/// \struct CX3DImporter_NodeElement_MetaDouble
-/// This struct describe metavalue of type double.
-struct CX3DImporter_NodeElement_MetaDouble : public CX3DImporter_NodeElement_Meta
-{
- std::vector<double> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaDouble(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaDouble(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaDouble, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaDouble
-
-/// \struct CX3DImporter_NodeElement_MetaFloat
-/// This struct describe metavalue of type float.
-struct CX3DImporter_NodeElement_MetaFloat : public CX3DImporter_NodeElement_Meta
-{
- std::vector<float> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaFloat(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaFloat(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaFloat, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaFloat
-
-/// \struct CX3DImporter_NodeElement_MetaInteger
-/// This struct describe metavalue of type integer.
-struct CX3DImporter_NodeElement_MetaInteger : public CX3DImporter_NodeElement_Meta
-{
- std::vector<int32_t> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaInteger(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaInteger(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaInteger, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaInteger
-
-/// \struct CX3DImporter_NodeElement_MetaSet
-/// This struct describe container for metaobjects.
-struct CX3DImporter_NodeElement_MetaSet : public CX3DImporter_NodeElement_Meta
-{
- std::list<CX3DImporter_NodeElement_Meta> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaSet(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaSet(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaSet, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaSet
-
-/// \struct CX3DImporter_NodeElement_MetaString
-/// This struct describe metavalue of type string.
-struct CX3DImporter_NodeElement_MetaString : public CX3DImporter_NodeElement_Meta
-{
- std::list<std::string> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_MetaString(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_MetaString(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Meta(ENET_MetaString, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_MetaString
-
-/// \struct CX3DImporter_NodeElement_Color
-/// This struct hold <Color> value.
-struct CX3DImporter_NodeElement_Color : public CX3DImporter_NodeElement
-{
- std::list<aiColor3D> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_Color(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Color(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Color, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Color
-
-/// \struct CX3DImporter_NodeElement_ColorRGBA
-/// This struct hold <ColorRGBA> value.
-struct CX3DImporter_NodeElement_ColorRGBA : public CX3DImporter_NodeElement
-{
- std::list<aiColor4D> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_ColorRGBA(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_ColorRGBA(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_ColorRGBA, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_ColorRGBA
-
-/// \struct CX3DImporter_NodeElement_Coordinate
-/// This struct hold <Coordinate> value.
-struct CX3DImporter_NodeElement_Coordinate : public CX3DImporter_NodeElement
-{
- std::list<aiVector3D> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_Coordinate(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Coordinate(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Coordinate, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Coordinate
-
-/// \struct CX3DImporter_NodeElement_Normal
-/// This struct hold <Normal> value.
-struct CX3DImporter_NodeElement_Normal : public CX3DImporter_NodeElement
-{
- std::list<aiVector3D> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_Normal(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Normal(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Normal, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Normal
-
-/// \struct CX3DImporter_NodeElement_TextureCoordinate
-/// This struct hold <TextureCoordinate> value.
-struct CX3DImporter_NodeElement_TextureCoordinate : public CX3DImporter_NodeElement
-{
- std::list<aiVector2D> Value;///< Stored value.
-
- /// \fn CX3DImporter_NodeElement_TextureCoordinate(CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_TextureCoordinate(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_TextureCoordinate, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_TextureCoordinate
-
-/// \class CX3DImporter_NodeElement_Geometry2D
-/// Two-dimensional figure.
-class CX3DImporter_NodeElement_Geometry2D : public CX3DImporter_NodeElement
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- std::list<aiVector3D> Vertices;///< Vertices list.
- size_t NumIndices;///< Number of indices in one face.
- bool Solid;///< Flag: if true then render must use back-face culling, else render must draw both sides of object.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_Geometry2D(const CX3DImporter_NodeElement_Geometry2D& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Geometry2D(const CX3DImporter_NodeElement_Geometry2D& pNode);
-
- /// \fn CX3DImporter_NodeElement_Geometry2D& operator=(const CX3DImporter_NodeElement_Geometry2D& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Geometry2D& operator=(const CX3DImporter_NodeElement_Geometry2D& pNode);
-
-public:
-
- /// \fn CX3DImporter_NodeElement_Geometry2D(const EType pType, CX3DImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_Geometry2D(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(pType, pParent), Solid(true)
- {}
-
-};// class CX3DImporter_NodeElement_Geometry2D
-
-/// \class CX3DImporter_NodeElement_Geometry3D
-/// Three-dimensional body.
-class CX3DImporter_NodeElement_Geometry3D : public CX3DImporter_NodeElement {
-public:
- std::list<aiVector3D> Vertices; ///< Vertices list.
- size_t NumIndices;///< Number of indices in one face.
- bool Solid; ///< Flag: if true then render must use back-face culling, else render must draw both sides of object.
-
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_Geometry3D(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(pType, pParent)
- , Vertices()
- , NumIndices( 0 )
- , Solid(true) {
- // empty
- }
-
-private:
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Geometry3D(const CX3DImporter_NodeElement_Geometry3D& pNode);
-
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Geometry3D& operator=(const CX3DImporter_NodeElement_Geometry3D& pNode);
-};// class CX3DImporter_NodeElement_Geometry3D
-
-/// \class CX3DImporter_NodeElement_ElevationGrid
-/// Uniform rectangular grid of varying height.
-class CX3DImporter_NodeElement_ElevationGrid : public CX3DImporter_NodeElement_Geometry3D
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line).
- bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line).
- /// \var CreaseAngle
- /// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are
- /// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced.
- float CreaseAngle;
- std::vector<int32_t> CoordIdx;///< Coordinates list by faces. In X3D format: "-1" - delimiter for faces.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_ElevationGrid(const CX3DImporter_NodeElement_ElevationGrid& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_ElevationGrid(const CX3DImporter_NodeElement_ElevationGrid& pNode);
-
- /// \fn CX3DImporter_NodeElement_ElevationGrid& operator=(const CX3DImporter_NodeElement_ElevationGrid& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_ElevationGrid& operator=(const CX3DImporter_NodeElement_ElevationGrid& pNode);
-
-public:
-
- /// \fn CX3DImporter_NodeElement_ElevationGrid(const EType pType, CX3DImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_ElevationGrid(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Geometry3D(pType, pParent)
- {}
-
-};// class CX3DImporter_NodeElement_IndexedSet
-
-/// \class CX3DImporter_NodeElement_IndexedSet
-/// Shape with indexed vertices.
-class CX3DImporter_NodeElement_IndexedSet : public CX3DImporter_NodeElement_Geometry3D
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- /// \var CCW
- /// The ccw field defines the ordering of the vertex coordinates of the geometry with respect to user-given or automatically generated normal vectors
- /// used in the lighting model equations. If ccw is TRUE, the normals shall follow the right hand rule; the orientation of each normal with respect to
- /// the vertices (taken in order) shall be such that the vertices appear to be oriented in a counterclockwise order when the vertices are viewed (in the
- /// local coordinate system of the Shape) from the opposite direction as the normal. If ccw is FALSE, the normals shall be oriented in the opposite
- /// direction. If normals are not generated but are supplied using a Normal node, and the orientation of the normals does not match the setting of the
- /// ccw field, results are undefined.
- bool CCW;
- std::vector<int32_t> ColorIndex;///< Field to specify the polygonal faces by indexing into the <Color> or <ColorRGBA>.
- bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line).
- /// \var Convex
- /// The convex field indicates whether all polygons in the shape are convex (TRUE). A polygon is convex if it is planar, does not intersect itself,
- /// and all of the interior angles at its vertices are less than 180 degrees. Non planar and self intersecting polygons may produce undefined results
- /// even if the convex field is FALSE.
- bool Convex;
- std::vector<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
- /// \var CreaseAngle
- /// If the angle between the geometric normals of two adjacent faces is less than the crease angle, normals shall be calculated so that the faces are
- /// shaded smoothly across the edge; otherwise, normals shall be calculated so that a lighting discontinuity across the edge is produced.
- float CreaseAngle;
- std::vector<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
- bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line).
- std::vector<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_IndexedSet(const CX3DImporter_NodeElement_IndexedSet& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_IndexedSet(const CX3DImporter_NodeElement_IndexedSet& pNode);
-
- /// \fn CX3DImporter_NodeElement_IndexedSet& operator=(const CX3DImporter_NodeElement_IndexedSet& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_IndexedSet& operator=(const CX3DImporter_NodeElement_IndexedSet& pNode);
-
-public:
-
- /// \fn CX3DImporter_NodeElement_IndexedSet(const EType pType, CX3DImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_IndexedSet(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Geometry3D(pType, pParent)
- {}
-
-};// class CX3DImporter_NodeElement_IndexedSet
-
-/// \class CX3DImporter_NodeElement_Set
-/// Shape with set of vertices.
-class CX3DImporter_NodeElement_Set : public CX3DImporter_NodeElement_Geometry3D
-{
- /***********************************************/
- /****************** Variables ******************/
- /***********************************************/
-
-public:
-
- /// \var CCW
- /// The ccw field defines the ordering of the vertex coordinates of the geometry with respect to user-given or automatically generated normal vectors
- /// used in the lighting model equations. If ccw is TRUE, the normals shall follow the right hand rule; the orientation of each normal with respect to
- /// the vertices (taken in order) shall be such that the vertices appear to be oriented in a counterclockwise order when the vertices are viewed (in the
- /// local coordinate system of the Shape) from the opposite direction as the normal. If ccw is FALSE, the normals shall be oriented in the opposite
- /// direction. If normals are not generated but are supplied using a Normal node, and the orientation of the normals does not match the setting of the
- /// ccw field, results are undefined.
- bool CCW;
- bool ColorPerVertex;///< If true then colors are defined for every vertex, else for every face(line).
- bool NormalPerVertex;///< If true then normals are defined for every vertex, else for every face(line).
- std::vector<int32_t> CoordIndex;///< Field to specify the polygonal faces by indexing into the <Coordinate>.
- std::vector<int32_t> NormalIndex;///< Field to specify the polygonal faces by indexing into the <Normal>.
- std::vector<int32_t> TexCoordIndex;///< Field to specify the polygonal faces by indexing into the <TextureCoordinate>.
- std::vector<int32_t> VertexCount;///< Field describes how many vertices are to be used in each polyline(polygon) from the <Coordinate> field.
-
- /***********************************************/
- /****************** Functions ******************/
- /***********************************************/
-
-private:
-
- /// \fn CX3DImporter_NodeElement_Set(const CX3DImporter_NodeElement_Set& pNode)
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Set(const CX3DImporter_NodeElement_Set& pNode);
-
- /// \fn CX3DImporter_NodeElement_Set& operator=(const CX3DImporter_NodeElement_Set& pNode)
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Set& operator=(const CX3DImporter_NodeElement_Set& pNode);
-
-public:
-
- /// \fn CX3DImporter_NodeElement_Set(const EType pType, CX3DImporter_NodeElement* pParent)
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_Set(const EType pType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement_Geometry3D(pType, pParent)
- {}
-
-};// class CX3DImporter_NodeElement_Set
-
-/// \struct CX3DImporter_NodeElement_Shape
-/// This struct hold <Shape> value.
-struct CX3DImporter_NodeElement_Shape : public CX3DImporter_NodeElement
-{
- /// \fn CX3DImporter_NodeElement_Shape(CX3DImporter_NodeElement_Shape* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Shape(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Shape, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Shape
-
-/// \struct CX3DImporter_NodeElement_Appearance
-/// This struct hold <Appearance> value.
-struct CX3DImporter_NodeElement_Appearance : public CX3DImporter_NodeElement
-{
- /// \fn CX3DImporter_NodeElement_Appearance(CX3DImporter_NodeElement_Appearance* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_Appearance(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Appearance, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Appearance
-
-/// \class CX3DImporter_NodeElement_Material
-/// Material.
-class CX3DImporter_NodeElement_Material : public CX3DImporter_NodeElement {
-public:
- float AmbientIntensity;///< Specifies how much ambient light from light sources this surface shall reflect.
- aiColor3D DiffuseColor; ///< Reflects all X3D light sources depending on the angle of the surface with respect to the light source.
- aiColor3D EmissiveColor; ///< Models "glowing" objects. This can be useful for displaying pre-lit models.
- float Shininess; ///< Lower shininess values produce soft glows, while higher values result in sharper, smaller highlights.
- aiColor3D SpecularColor; ///< The specularColor and shininess fields determine the specular highlights.
- float Transparency; ///< Specifies how "clear" an object is, with 1.0 being completely transparent, and 0.0 completely opaque.
-
- /// Constructor.
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pType - type of geometry object.
- CX3DImporter_NodeElement_Material(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_Material, pParent)
- , AmbientIntensity( 0.0f )
- , DiffuseColor()
- , EmissiveColor()
- , Shininess( 0.0f )
- , SpecularColor()
- , Transparency( 1.0f ) {
- // empty
- }
-
-private:
- /// Disabled copy constructor.
- CX3DImporter_NodeElement_Material(const CX3DImporter_NodeElement_Material& pNode);
-
- /// Disabled assign operator.
- CX3DImporter_NodeElement_Material& operator=(const CX3DImporter_NodeElement_Material& pNode);
-};// class CX3DImporter_NodeElement_Material
-
-/// \struct CX3DImporter_NodeElement_ImageTexture
-/// This struct hold <ImageTexture> value.
-struct CX3DImporter_NodeElement_ImageTexture : public CX3DImporter_NodeElement
-{
- /// \var RepeatS
- /// RepeatS and RepeatT, that specify how the texture wraps in the S and T directions. If repeatS is TRUE (the default), the texture map is repeated
- /// outside the [0.0, 1.0] texture coordinate range in the S direction so that it fills the shape. If repeatS is FALSE, the texture coordinates are
- /// clamped in the S direction to lie within the [0.0, 1.0] range. The repeatT field is analogous to the repeatS field.
- bool RepeatS;
- bool RepeatT;///< See \ref RepeatS.
- std::string URL;///< URL of the texture.
- /// \fn CX3DImporter_NodeElement_ImageTexture(CX3DImporter_NodeElement_ImageTexture* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_ImageTexture(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_ImageTexture, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_ImageTexture
-
-/// \struct CX3DImporter_NodeElement_TextureTransform
-/// This struct hold <TextureTransform> value.
-struct CX3DImporter_NodeElement_TextureTransform : public CX3DImporter_NodeElement
-{
- aiVector2D Center;///< Specifies a translation offset in texture coordinate space about which the rotation and scale fields are applied.
- float Rotation;///< Specifies a rotation in angle base units of the texture coordinates about the center point after the scale has been applied.
- aiVector2D Scale;///< Specifies a scaling factor in S and T of the texture coordinates about the center point.
- aiVector2D Translation;///< Specifies a translation of the texture coordinates.
-
- /// \fn CX3DImporter_NodeElement_TextureTransform(CX3DImporter_NodeElement_TextureTransform* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- CX3DImporter_NodeElement_TextureTransform(CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(ENET_TextureTransform, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_TextureTransform
-
-/// \struct CX3DImporter_NodeElement_Light
-/// This struct hold <TextureTransform> value.
-struct CX3DImporter_NodeElement_Light : public CX3DImporter_NodeElement
-{
- float AmbientIntensity;///< Specifies the intensity of the ambient emission from the light.
- aiColor3D Color;///< specifies the spectral colour properties of both the direct and ambient light emission as an RGB value.
- aiVector3D Direction;///< Specifies the direction vector of the illumination emanating from the light source in the local coordinate system.
- /// \var Global
- /// Field that determines whether the light is global or scoped. Global lights illuminate all objects that fall within their volume of lighting influence.
- /// Scoped lights only illuminate objects that are in the same transformation hierarchy as the light.
- bool Global;
- float Intensity;///< Specifies the brightness of the direct emission from the light.
- /// \var Attenuation
- /// PointLight node's illumination falls off with distance as specified by three attenuation coefficients. The attenuation factor
- /// is: "1 / max(attenuation[0] + attenuation[1] * r + attenuation[2] * r2, 1)", where r is the distance from the light to the surface being illuminated.
- aiVector3D Attenuation;
- aiVector3D Location;///< Specifies a translation offset of the centre point of the light source from the light's local coordinate system origin.
- float Radius;///< Specifies the radial extent of the solid angle and the maximum distance from location that may be illuminated by the light source.
- float BeamWidth;///< Specifies an inner solid angle in which the light source emits light at uniform full intensity.
- float CutOffAngle;///< The light source's emission intensity drops off from the inner solid angle (beamWidth) to the outer solid angle (cutOffAngle).
-
- /// \fn CX3DImporter_NodeElement_Light(EType pLightType, CX3DImporter_NodeElement* pParent)
- /// Constructor
- /// \param [in] pParent - pointer to parent node.
- /// \param [in] pLightType - type of the light source.
- CX3DImporter_NodeElement_Light(EType pLightType, CX3DImporter_NodeElement* pParent)
- : CX3DImporter_NodeElement(pLightType, pParent)
- {}
-
-};// struct CX3DImporter_NodeElement_Light
-
-#endif // INCLUDED_AI_X3D_IMPORTER_NODE_H
diff --git a/src/3rdparty/assimp/code/X3DImporter_Postprocess.cpp b/src/3rdparty/assimp/code/X3DImporter_Postprocess.cpp
deleted file mode 100644
index 390ef8995..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Postprocess.cpp
+++ /dev/null
@@ -1,826 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Postprocess.cpp
-/// \brief Convert built scenegraph and objects to Assimp scenegraph.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-
-// Header files, Assimp.
-#include <assimp/ai_assert.h>
-#include "StandardShapes.h"
-#include "StringUtils.h"
-
-// Header files, stdlib.
-#include <algorithm>
-#include <iterator>
-#include <string>
-
-namespace Assimp
-{
-
-aiMatrix4x4 X3DImporter::PostprocessHelper_Matrix_GlobalToCurrent() const
-{
- CX3DImporter_NodeElement* cur_node;
- std::list<aiMatrix4x4> matr;
- aiMatrix4x4 out_matr;
-
- // starting walk from current element to root
- cur_node = NodeElement_Cur;
- if(cur_node != nullptr)
- {
- do
- {
- // if cur_node is group then store group transformation matrix in list.
- if(cur_node->Type == CX3DImporter_NodeElement::ENET_Group) matr.push_back(((CX3DImporter_NodeElement_Group*)cur_node)->Transformation);
-
- cur_node = cur_node->Parent;
- } while(cur_node != nullptr);
- }
-
- // multiplicate all matrices in reverse order
- for(std::list<aiMatrix4x4>::reverse_iterator rit = matr.rbegin(); rit != matr.rend(); rit++) out_matr = out_matr * (*rit);
-
- return out_matr;
-}
-
-void X3DImporter::PostprocessHelper_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, std::list<CX3DImporter_NodeElement*>& pList) const
-{
- // walk through childs and find for metadata.
- for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
- {
- if(((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble) ||
- ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat) || ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger) ||
- ((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaString))
- {
- pList.push_back(*el_it);
- }
- else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_MetaSet)
- {
- PostprocessHelper_CollectMetadata(**el_it, pList);
- }
- }// for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
-}
-
-bool X3DImporter::PostprocessHelper_ElementIsMetadata(const CX3DImporter_NodeElement::EType pType) const
-{
- if((pType == CX3DImporter_NodeElement::ENET_MetaBoolean) || (pType == CX3DImporter_NodeElement::ENET_MetaDouble) ||
- (pType == CX3DImporter_NodeElement::ENET_MetaFloat) || (pType == CX3DImporter_NodeElement::ENET_MetaInteger) ||
- (pType == CX3DImporter_NodeElement::ENET_MetaString) || (pType == CX3DImporter_NodeElement::ENET_MetaSet))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool X3DImporter::PostprocessHelper_ElementIsMesh(const CX3DImporter_NodeElement::EType pType) const
-{
- if((pType == CX3DImporter_NodeElement::ENET_Arc2D) || (pType == CX3DImporter_NodeElement::ENET_ArcClose2D) ||
- (pType == CX3DImporter_NodeElement::ENET_Box) || (pType == CX3DImporter_NodeElement::ENET_Circle2D) ||
- (pType == CX3DImporter_NodeElement::ENET_Cone) || (pType == CX3DImporter_NodeElement::ENET_Cylinder) ||
- (pType == CX3DImporter_NodeElement::ENET_Disk2D) || (pType == CX3DImporter_NodeElement::ENET_ElevationGrid) ||
- (pType == CX3DImporter_NodeElement::ENET_Extrusion) || (pType == CX3DImporter_NodeElement::ENET_IndexedFaceSet) ||
- (pType == CX3DImporter_NodeElement::ENET_IndexedLineSet) || (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) ||
- (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleSet) || (pType == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet) ||
- (pType == CX3DImporter_NodeElement::ENET_PointSet) || (pType == CX3DImporter_NodeElement::ENET_LineSet) ||
- (pType == CX3DImporter_NodeElement::ENET_Polyline2D) || (pType == CX3DImporter_NodeElement::ENET_Polypoint2D) ||
- (pType == CX3DImporter_NodeElement::ENET_Rectangle2D) || (pType == CX3DImporter_NodeElement::ENET_Sphere) ||
- (pType == CX3DImporter_NodeElement::ENET_TriangleFanSet) || (pType == CX3DImporter_NodeElement::ENET_TriangleSet) ||
- (pType == CX3DImporter_NodeElement::ENET_TriangleSet2D) || (pType == CX3DImporter_NodeElement::ENET_TriangleStripSet))
- {
- return true;
- }
- else
- {
- return false;
- }
-}
-
-void X3DImporter::Postprocess_BuildLight(const CX3DImporter_NodeElement& pNodeElement, std::list<aiLight*>& pSceneLightList) const
-{
- const CX3DImporter_NodeElement_Light& ne = *( ( CX3DImporter_NodeElement_Light* ) &pNodeElement );
- aiMatrix4x4 transform_matr = PostprocessHelper_Matrix_GlobalToCurrent();
- aiLight* new_light = new aiLight;
-
- new_light->mName = ne.ID;
- new_light->mColorAmbient = ne.Color * ne.AmbientIntensity;
- new_light->mColorDiffuse = ne.Color * ne.Intensity;
- new_light->mColorSpecular = ne.Color * ne.Intensity;
- switch(pNodeElement.Type)
- {
- case CX3DImporter_NodeElement::ENET_DirectionalLight:
- new_light->mType = aiLightSource_DIRECTIONAL;
- new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr;
-
- break;
- case CX3DImporter_NodeElement::ENET_PointLight:
- new_light->mType = aiLightSource_POINT;
- new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr;
- new_light->mAttenuationConstant = ne.Attenuation.x;
- new_light->mAttenuationLinear = ne.Attenuation.y;
- new_light->mAttenuationQuadratic = ne.Attenuation.z;
-
- break;
- case CX3DImporter_NodeElement::ENET_SpotLight:
- new_light->mType = aiLightSource_SPOT;
- new_light->mPosition = ne.Location, new_light->mPosition *= transform_matr;
- new_light->mDirection = ne.Direction, new_light->mDirection *= transform_matr;
- new_light->mAttenuationConstant = ne.Attenuation.x;
- new_light->mAttenuationLinear = ne.Attenuation.y;
- new_light->mAttenuationQuadratic = ne.Attenuation.z;
- new_light->mAngleInnerCone = ne.BeamWidth;
- new_light->mAngleOuterCone = ne.CutOffAngle;
-
- break;
- default:
- throw DeadlyImportError("Postprocess_BuildLight. Unknown type of light: " + to_string(pNodeElement.Type) + ".");
- }
-
- pSceneLightList.push_back(new_light);
-}
-
-void X3DImporter::Postprocess_BuildMaterial(const CX3DImporter_NodeElement& pNodeElement, aiMaterial** pMaterial) const
-{
- // check argument
- if(pMaterial == nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. pMaterial is nullptr.");
- if(*pMaterial != nullptr) throw DeadlyImportError("Postprocess_BuildMaterial. *pMaterial must be nullptr.");
-
- *pMaterial = new aiMaterial;
- aiMaterial& taimat = **pMaterial;// creating alias for convenience.
-
- // at this point pNodeElement point to <Appearance> node. Walk through childs and add all stored data.
- for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
- {
- if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
- {
- aiColor3D tcol3;
- float tvalf;
- CX3DImporter_NodeElement_Material& tnemat = *((CX3DImporter_NodeElement_Material*)*el_it);
-
- tcol3.r = tnemat.AmbientIntensity, tcol3.g = tnemat.AmbientIntensity, tcol3.b = tnemat.AmbientIntensity;
- taimat.AddProperty(&tcol3, 1, AI_MATKEY_COLOR_AMBIENT);
- taimat.AddProperty(&tnemat.DiffuseColor, 1, AI_MATKEY_COLOR_DIFFUSE);
- taimat.AddProperty(&tnemat.EmissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
- taimat.AddProperty(&tnemat.SpecularColor, 1, AI_MATKEY_COLOR_SPECULAR);
- tvalf = 1;
- taimat.AddProperty(&tvalf, 1, AI_MATKEY_SHININESS_STRENGTH);
- taimat.AddProperty(&tnemat.Shininess, 1, AI_MATKEY_SHININESS);
- tvalf = 1.0f - tnemat.Transparency;
- taimat.AddProperty(&tvalf, 1, AI_MATKEY_OPACITY);
- }// if((*el_it)->Type == CX3DImporter_NodeElement::ENET_Material)
- else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_ImageTexture)
- {
- CX3DImporter_NodeElement_ImageTexture& tnetex = *((CX3DImporter_NodeElement_ImageTexture*)*el_it);
- aiString url_str(tnetex.URL.c_str());
- int mode = aiTextureOp_Multiply;
-
- taimat.AddProperty(&url_str, AI_MATKEY_TEXTURE_DIFFUSE(0));
- taimat.AddProperty(&tnetex.RepeatS, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
- taimat.AddProperty(&tnetex.RepeatT, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
- taimat.AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0));
- }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_ImageTexture)
- else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_TextureTransform)
- {
- aiUVTransform trans;
- CX3DImporter_NodeElement_TextureTransform& tnetextr = *((CX3DImporter_NodeElement_TextureTransform*)*el_it);
-
- trans.mTranslation = tnetextr.Translation - tnetextr.Center;
- trans.mScaling = tnetextr.Scale;
- trans.mRotation = tnetextr.Rotation;
- taimat.AddProperty(&trans, 1, AI_MATKEY_UVTRANSFORM_DIFFUSE(0));
- }// else if((*el_it)->Type == CX3DImporter_NodeElement::ENET_TextureTransform)
- }// for(std::list<CX3DImporter_NodeElement*>::const_iterator el_it = pNodeElement.Child.begin(); el_it != pNodeElement.Child.end(); el_it++)
-}
-
-void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeElement, aiMesh** pMesh) const
-{
- // check argument
- if(pMesh == nullptr) throw DeadlyImportError("Postprocess_BuildMesh. pMesh is nullptr.");
- if(*pMesh != nullptr) throw DeadlyImportError("Postprocess_BuildMesh. *pMesh must be nullptr.");
-
- /************************************************************************************************************************************/
- /************************************************************ Geometry2D ************************************************************/
- /************************************************************************************************************************************/
- if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_Arc2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_ArcClose2D) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Circle2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Disk2D) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Polyline2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Polypoint2D) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Rectangle2D) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet2D))
- {
- CX3DImporter_NodeElement_Geometry2D& tnemesh = *((CX3DImporter_NodeElement_Geometry2D*)&pNodeElement);// create alias for convenience
- std::vector<aiVector3D> tarr;
-
- tarr.reserve(tnemesh.Vertices.size());
- for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
- *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
-
- return;// mesh is build, nothing to do anymore.
- }
- /************************************************************************************************************************************/
- /************************************************************ Geometry3D ************************************************************/
- /************************************************************************************************************************************/
- //
- // Predefined figures
- //
- if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_Box) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Cone) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Cylinder) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_Sphere))
- {
- CX3DImporter_NodeElement_Geometry3D& tnemesh = *((CX3DImporter_NodeElement_Geometry3D*)&pNodeElement);// create alias for convenience
- std::vector<aiVector3D> tarr;
-
- tarr.reserve(tnemesh.Vertices.size());
- for(std::list<aiVector3D>::iterator it = tnemesh.Vertices.begin(); it != tnemesh.Vertices.end(); it++) tarr.push_back(*it);
-
- *pMesh = StandardShapes::MakeMesh(tarr, static_cast<unsigned int>(tnemesh.NumIndices));// create mesh from vertices using Assimp help.
-
- return;// mesh is build, nothing to do anymore.
- }
- //
- // Parametric figures
- //
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
- {
- CX3DImporter_NodeElement_ElevationGrid& tnemesh = *((CX3DImporter_NodeElement_ElevationGrid*)&pNodeElement);// create alias for convenience
-
- // at first create mesh from existing vertices.
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices);
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value, tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
- //
- // Indexed primitives sets
- //
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
- {
- CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value,
- tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value,
- tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
- {
- CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value,
- tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
-
- if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleSet) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) ||
- (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
- {
- CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value,
- tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value,
- tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
- IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Extrusion)
- {
- CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
-
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, tnemesh.Vertices);
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Extrusion)
-
- //
- // Primitives sets
- //
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
- {
- CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- std::vector<aiVector3D> vec_copy;
-
- vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
- for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
- it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
- {
- vec_copy.push_back(*it);
- }
-
- *pMesh = StandardShapes::MakeMesh(vec_copy, 1);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, true);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
- {
- CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, true);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
- {
- CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if ( nullptr == *pMesh ) {
- break;
- }
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value,tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value,
- tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
- {
- CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- std::vector<aiVector3D> vec_copy;
-
- vec_copy.reserve(((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.size());
- for(std::list<aiVector3D>::const_iterator it = ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.begin();
- it != ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value.end(); it++)
- {
- vec_copy.push_back(*it);
- }
-
- *pMesh = StandardShapes::MakeMesh(vec_copy, 3);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value,
- tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
-
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
- {
- CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
-
- // at first search for <Coordinate> node and create mesh.
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {
- *pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIndex, ((CX3DImporter_NodeElement_Coordinate*)*ch_it)->Value);
- }
- }
-
- // copy additional information from children
- for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
- {
- ai_assert(*pMesh);
- if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
- MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_ColorRGBA*)*ch_it)->Value, tnemesh.ColorPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
- {} // skip because already read when mesh created.
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Normal)
- MeshGeometry_AddNormal(**pMesh, tnemesh.CoordIndex, tnemesh.NormalIndex, ((CX3DImporter_NodeElement_Normal*)*ch_it)->Value,
- tnemesh.NormalPerVertex);
- else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_TextureCoordinate)
- MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
- else
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
- }// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
-
- return;// mesh is build, nothing to do anymore.
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)
-
- throw DeadlyImportError("Postprocess_BuildMesh. Unknown mesh type: " + to_string(pNodeElement.Type) + ".");
-}
-
-void X3DImporter::Postprocess_BuildNode(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode, std::list<aiMesh*>& pSceneMeshList,
- std::list<aiMaterial*>& pSceneMaterialList, std::list<aiLight*>& pSceneLightList) const
-{
- std::list<CX3DImporter_NodeElement*>::const_iterator chit_begin = pNodeElement.Child.begin();
- std::list<CX3DImporter_NodeElement*>::const_iterator chit_end = pNodeElement.Child.end();
- std::list<aiNode*> SceneNode_Child;
- std::list<unsigned int> SceneNode_Mesh;
-
- // At first read all metadata
- Postprocess_CollectMetadata(pNodeElement, pSceneNode);
- // check if we have deal with grouping node. Which can contain transformation or switch
- if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
- {
- const CX3DImporter_NodeElement_Group& tne_group = *((CX3DImporter_NodeElement_Group*)&pNodeElement);// create alias for convenience
-
- pSceneNode.mTransformation = tne_group.Transformation;
- if(tne_group.UseChoice)
- {
- // If Choice is less than zero or greater than the number of nodes in the children field, nothing is chosen.
- if((tne_group.Choice < 0) || ((size_t)tne_group.Choice >= pNodeElement.Child.size()))
- {
- chit_begin = pNodeElement.Child.end();
- chit_end = pNodeElement.Child.end();
- }
- else
- {
- for(size_t i = 0; i < (size_t)tne_group.Choice; i++) chit_begin++;// forward iterator to chosen node.
-
- chit_end = chit_begin;
- chit_end++;// point end iterator to next element after chosen node.
- }
- }// if(tne_group.UseChoice)
- }// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_Group)
-
- // Reserve memory for fast access and check children.
- for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
- {// in this loop we do not read metadata because it's already read at begin.
- if((*it)->Type == CX3DImporter_NodeElement::ENET_Group)
- {
- // if child is group then create new node and do recursive call.
- aiNode* new_node = new aiNode;
-
- new_node->mName = (*it)->ID;
- new_node->mParent = &pSceneNode;
- SceneNode_Child.push_back(new_node);
- Postprocess_BuildNode(**it, *new_node, pSceneMeshList, pSceneMaterialList, pSceneLightList);
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_Shape)
- {
- // shape can contain only one geometry and one appearance nodes.
- Postprocess_BuildShape(*((CX3DImporter_NodeElement_Shape*)*it), SceneNode_Mesh, pSceneMeshList, pSceneMaterialList);
- }
- else if(((*it)->Type == CX3DImporter_NodeElement::ENET_DirectionalLight) || ((*it)->Type == CX3DImporter_NodeElement::ENET_PointLight) ||
- ((*it)->Type == CX3DImporter_NodeElement::ENET_SpotLight))
- {
- Postprocess_BuildLight(*((CX3DImporter_NodeElement_Light*)*it), pSceneLightList);
- }
- else if(!PostprocessHelper_ElementIsMetadata((*it)->Type))// skip metadata
- {
- throw DeadlyImportError("Postprocess_BuildNode. Unknown type: " + to_string((*it)->Type) + ".");
- }
- }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = chit_begin; it != chit_end; it++)
-
- // copy data about children and meshes to aiNode.
- if(SceneNode_Child.size() > 0)
- {
- std::list<aiNode*>::const_iterator it = SceneNode_Child.begin();
-
- pSceneNode.mNumChildren = static_cast<unsigned int>(SceneNode_Child.size());
- pSceneNode.mChildren = new aiNode*[pSceneNode.mNumChildren];
- for(size_t i = 0; i < pSceneNode.mNumChildren; i++) pSceneNode.mChildren[i] = *it++;
- }
-
- if(SceneNode_Mesh.size() > 0)
- {
- std::list<unsigned int>::const_iterator it = SceneNode_Mesh.begin();
-
- pSceneNode.mNumMeshes = static_cast<unsigned int>(SceneNode_Mesh.size());
- pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes];
- for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *it++;
- }
-
- // that's all. return to previous deals
-}
-
-void X3DImporter::Postprocess_BuildShape(const CX3DImporter_NodeElement_Shape& pShapeNodeElement, std::list<unsigned int>& pNodeMeshInd,
- std::list<aiMesh*>& pSceneMeshList, std::list<aiMaterial*>& pSceneMaterialList) const
-{
- aiMaterial* tmat = nullptr;
- aiMesh* tmesh = nullptr;
- CX3DImporter_NodeElement::EType mesh_type = CX3DImporter_NodeElement::ENET_Invalid;
- unsigned int mat_ind = 0;
-
- for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++)
- {
- if(PostprocessHelper_ElementIsMesh((*it)->Type))
- {
- Postprocess_BuildMesh(**it, &tmesh);
- if(tmesh != nullptr)
- {
- // if mesh successfully built then add data about it to arrays
- pNodeMeshInd.push_back(static_cast<unsigned int>(pSceneMeshList.size()));
- pSceneMeshList.push_back(tmesh);
- // keep mesh type. Need above for texture coordinate generation.
- mesh_type = (*it)->Type;
- }
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_Appearance)
- {
- Postprocess_BuildMaterial(**it, &tmat);
- if(tmat != nullptr)
- {
- // if material successfully built then add data about it to array
- mat_ind = static_cast<unsigned int>(pSceneMaterialList.size());
- pSceneMaterialList.push_back(tmat);
- }
- }
- }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = pShapeNodeElement.Child.begin(); it != pShapeNodeElement.Child.end(); it++)
-
- // associate read material with read mesh.
- if((tmesh != nullptr) && (tmat != nullptr))
- {
- tmesh->mMaterialIndex = mat_ind;
- // Check texture mapping. If material has texture but mesh has no texture coordinate then try to ask Assimp to generate texture coordinates.
- if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0))
- {
- int32_t tm;
- aiVector3D tvec3;
-
- switch(mesh_type)
- {
- case CX3DImporter_NodeElement::ENET_Box:
- tm = aiTextureMapping_BOX;
- break;
- case CX3DImporter_NodeElement::ENET_Cone:
- case CX3DImporter_NodeElement::ENET_Cylinder:
- tm = aiTextureMapping_CYLINDER;
- break;
- case CX3DImporter_NodeElement::ENET_Sphere:
- tm = aiTextureMapping_SPHERE;
- break;
- default:
- tm = aiTextureMapping_PLANE;
- break;
- }// switch(mesh_type)
-
- tmat->AddProperty(&tm, 1, AI_MATKEY_MAPPING_DIFFUSE(0));
- }// if((tmat->GetTextureCount(aiTextureType_DIFFUSE) != 0) && !tmesh->HasTextureCoords(0))
- }// if((tmesh != nullptr) && (tmat != nullptr))
-}
-
-void X3DImporter::Postprocess_CollectMetadata(const CX3DImporter_NodeElement& pNodeElement, aiNode& pSceneNode) const
-{
- std::list<CX3DImporter_NodeElement*> meta_list;
- size_t meta_idx;
-
- PostprocessHelper_CollectMetadata(pNodeElement, meta_list);// find metadata in current node element.
- if ( !meta_list.empty() )
- {
- if ( pSceneNode.mMetaData != nullptr ) {
- throw DeadlyImportError( "Postprocess. MetaData member in node are not nullptr. Something went wrong." );
- }
-
- // copy collected metadata to output node.
- pSceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(meta_list.size()) );
- meta_idx = 0;
- for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++, meta_idx++)
- {
- CX3DImporter_NodeElement_Meta* cur_meta = (CX3DImporter_NodeElement_Meta*)*it;
-
- // due to limitations we can add only first element of value list.
- // Add an element according to its type.
- if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaBoolean)
- {
- if(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.size() > 0)
- pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaBoolean*)cur_meta)->Value.begin()));
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaDouble)
- {
- if(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.size() > 0)
- pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, (float)*(((CX3DImporter_NodeElement_MetaDouble*)cur_meta)->Value.begin()));
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaFloat)
- {
- if(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.size() > 0)
- pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaFloat*)cur_meta)->Value.begin()));
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaInteger)
- {
- if(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.size() > 0)
- pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, *(((CX3DImporter_NodeElement_MetaInteger*)cur_meta)->Value.begin()));
- }
- else if((*it)->Type == CX3DImporter_NodeElement::ENET_MetaString)
- {
- if(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.size() > 0)
- {
- aiString tstr(((CX3DImporter_NodeElement_MetaString*)cur_meta)->Value.begin()->data());
-
- pSceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx), cur_meta->Name, tstr);
- }
- }
- else
- {
- throw DeadlyImportError("Postprocess. Unknown metadata type.");
- }// if((*it)->Type == CX3DImporter_NodeElement::ENET_Meta*) else
- }// for(std::list<CX3DImporter_NodeElement*>::const_iterator it = meta_list.begin(); it != meta_list.end(); it++)
- }// if( !meta_list.empty() )
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Rendering.cpp b/src/3rdparty/assimp/code/X3DImporter_Rendering.cpp
deleted file mode 100644
index 1d4632f32..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Rendering.cpp
+++ /dev/null
@@ -1,1070 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Rendering.cpp
-/// \brief Parsing data from nodes of "Rendering" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <Color
-// DEF="" ID
-// USE="" IDREF
-// color="" MFColor [inputOutput]
-// />
-void X3DImporter::ParseNode_Rendering_Color()
-{
- std::string use, def;
- std::list<aiColor3D> color;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol3f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Color, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Color(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Color*)ne)->Value = color;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Color");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <ColorRGBA
-// DEF="" ID
-// USE="" IDREF
-// color="" MFColorRGBA [inputOutput]
-// />
-void X3DImporter::ParseNode_Rendering_ColorRGBA()
-{
- std::string use, def;
- std::list<aiColor4D> color;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("color", color, XML_ReadNode_GetAttrVal_AsListCol4f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_ColorRGBA, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_ColorRGBA(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_ColorRGBA*)ne)->Value = color;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "ColorRGBA");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Coordinate
-// DEF="" ID
-// USE="" IDREF
-// point="" MFVec3f [inputOutput]
-// />
-void X3DImporter::ParseNode_Rendering_Coordinate()
-{
- std::string use, def;
- std::list<aiVector3D> point;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec3f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Coordinate, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Coordinate(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Coordinate*)ne)->Value = point;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Coordinate");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <IndexedLineSet
-// DEF="" ID
-// USE="" IDREF
-// colorIndex="" MFInt32 [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// coordIndex="" MFInt32 [initializeOnly]
-// >
-// <!-- ColorCoordinateContentModel -->
-// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
-// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </IndexedLineSet>
-void X3DImporter::ParseNode_Rendering_IndexedLineSet()
-{
- std::string use, def;
- std::vector<int32_t> colorIndex;
- bool colorPerVertex = true;
- std::vector<int32_t> coordIndex;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("colorIndex", colorIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("coordIndex", coordIndex, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedLineSet, ne);
- }
- else
- {
- // check data
- if((coordIndex.size() < 2) || ((coordIndex.back() == (-1)) && (coordIndex.size() < 3)))
- throw DeadlyImportError("IndexedLineSet must contain not empty \"coordIndex\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedLineSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
-
- ne_alias.ColorIndex = colorIndex;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.CoordIndex = coordIndex;
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("IndexedLineSet");
- // check for Color and Coordinate nodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedLineSet");
-
- MACRO_NODECHECK_LOOPEND("IndexedLineSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <IndexedTriangleFanSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// index="" MFInt32 [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </IndexedTriangleFanSet>
-void X3DImporter::ParseNode_Rendering_IndexedTriangleFanSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- std::vector<int32_t> index;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleFanSet, ne);
- }
- else
- {
- // check data
- if(index.size() == 0) throw DeadlyImportError("IndexedTriangleFanSet must contain not empty \"index\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
-
- ne_alias.CoordIndex.clear();
- int counter = 0;
- int32_t idx[3];
- for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
- {
- idx[2] = *idx_it;
- if (idx[2] < 0)
- {
- counter = 0;
- }
- else
- {
- if (counter >= 2)
- {
- if(ccw)
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[1]);
- ne_alias.CoordIndex.push_back(idx[2]);
- }
- else
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[2]);
- ne_alias.CoordIndex.push_back(idx[1]);
- }
- ne_alias.CoordIndex.push_back(-1);
- idx[1] = idx[2];
- }
- else
- {
- idx[counter] = idx[2];
- }
- ++counter;
- }
- }// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleFanSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleFanSet");
-
- MACRO_NODECHECK_LOOPEND("IndexedTriangleFanSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <IndexedTriangleSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// index="" MFInt32 [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </IndexedTriangleSet>
-void X3DImporter::ParseNode_Rendering_IndexedTriangleSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- std::vector<int32_t> index;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleSet, ne);
- }
- else
- {
- // check data
- if(index.size() == 0) throw DeadlyImportError("IndexedTriangleSet must contain not empty \"index\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
-
- ne_alias.CoordIndex.clear();
- int counter = 0;
- int32_t idx[3];
- for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
- {
- idx[counter++] = *idx_it;
- if (counter > 2)
- {
- counter = 0;
- if(ccw)
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[1]);
- ne_alias.CoordIndex.push_back(idx[2]);
- }
- else
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[2]);
- ne_alias.CoordIndex.push_back(idx[1]);
- }
- ne_alias.CoordIndex.push_back(-1);
- }
- }// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleSet");
-
- MACRO_NODECHECK_LOOPEND("IndexedTriangleSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <IndexedTriangleStripSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// index="" MFInt32 [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </IndexedTriangleStripSet>
-void X3DImporter::ParseNode_Rendering_IndexedTriangleStripSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- std::vector<int32_t> index;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("index", index, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_IndexedTriangleStripSet, ne);
- }
- else
- {
- // check data
- if(index.size() == 0) throw DeadlyImportError("IndexedTriangleStripSet must contain not empty \"index\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_IndexedSet& ne_alias = *((CX3DImporter_NodeElement_IndexedSet*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
-
- ne_alias.CoordIndex.clear();
- int counter = 0;
- int32_t idx[3];
- for(std::vector<int32_t>::const_iterator idx_it = index.begin(); idx_it != index.end(); idx_it++)
- {
- idx[2] = *idx_it;
- if (idx[2] < 0)
- {
- counter = 0;
- }
- else
- {
- if (counter >= 2)
- {
- if(ccw)
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[1]);
- ne_alias.CoordIndex.push_back(idx[2]);
- }
- else
- {
- ne_alias.CoordIndex.push_back(idx[0]);
- ne_alias.CoordIndex.push_back(idx[2]);
- ne_alias.CoordIndex.push_back(idx[1]);
- }
- ne_alias.CoordIndex.push_back(-1);
- }
- idx[counter & 1] = idx[2];
- ++counter;
- }
- }// for(std::list<int32_t>::const_iterator idx_it = index.begin(); idx_it != ne_alias.index.end(); idx_it++)
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("IndexedTriangleStripSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("IndexedTriangleStripSet");
-
- MACRO_NODECHECK_LOOPEND("IndexedTriangleStripSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <LineSet
-// DEF="" ID
-// USE="" IDREF
-// vertexCount="" MFInt32 [initializeOnly]
-// >
-// <!-- ColorCoordinateContentModel -->
-// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
-// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </LineSet>
-void X3DImporter::ParseNode_Rendering_LineSet()
-{
- std::string use, def;
- std::vector<int32_t> vertexCount;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("vertexCount", vertexCount, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_LineSet, ne);
- }
- else
- {
- // check data
- if(vertexCount.size() == 0) throw DeadlyImportError("LineSet must contain not empty \"vertexCount\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_LineSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
-
- ne_alias.VertexCount = vertexCount;
- // create CoordIdx
- size_t coord_num = 0;
-
- ne_alias.CoordIndex.clear();
- for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
- {
- if(*vc_it < 2) throw DeadlyImportError("LineSet. vertexCount shall be greater than or equal to two.");
-
- for(int32_t i = 0; i < *vc_it; i++) ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num++));// add vertices indices
-
- ne_alias.CoordIndex.push_back(-1);// add face delimiter.
- }
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("LineSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("LineSet");
-
- MACRO_NODECHECK_LOOPEND("LineSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <PointSet
-// DEF="" ID
-// USE="" IDREF
-// >
-// <!-- ColorCoordinateContentModel -->
-// ColorCoordinateContentModel is the child-node content model corresponding to IndexedLineSet, LineSet and PointSet. ColorCoordinateContentModel can
-// contain any-order Coordinate node with Color (or ColorRGBA) node. No more than one instance of any single node type is allowed.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </PointSet>
-void X3DImporter::ParseNode_Rendering_PointSet()
-{
- std::string use, def;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_PointSet, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_PointSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("PointSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("PointSet");
-
- MACRO_NODECHECK_LOOPEND("PointSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TriangleFanSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// fanCount="" MFInt32 [inputOutput]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </TriangleFanSet>
-void X3DImporter::ParseNode_Rendering_TriangleFanSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- std::vector<int32_t> fanCount;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("fanCount", fanCount, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleFanSet, ne);
- }
- else
- {
- // check data
- if(fanCount.size() == 0) throw DeadlyImportError("TriangleFanSet must contain not empty \"fanCount\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_TriangleFanSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.VertexCount = fanCount;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
- // create CoordIdx
- size_t coord_num_first, coord_num_prev;
-
- ne_alias.CoordIndex.clear();
- // assign indices for first triangle
- coord_num_first = 0;
- coord_num_prev = 1;
- for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
- {
- if(*vc_it < 3) throw DeadlyImportError("TriangleFanSet. fanCount shall be greater than or equal to three.");
-
- for(int32_t vc = 2; vc < *vc_it; vc++)
- {
- if(ccw)
- {
- // 2 1
- // 0
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_first));// first vertex is a center and always is [0].
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev++));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev));
- }
- else
- {
- // 1 2
- // 0
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_first));// first vertex is a center and always is [0].
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev + 1));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num_prev++));
- }// if(ccw) else
-
- ne_alias.CoordIndex.push_back(-1);// add face delimiter.
- }// for(int32_t vc = 2; vc < *vc_it; vc++)
-
- coord_num_prev++;// that index will be center of next fan
- coord_num_first = coord_num_prev++;// forward to next point - second point of fan
- }// for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("TriangleFanSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleFanSet");
-
- MACRO_NODECHECK_LOOPEND("TriangleFanSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TriangleSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </TriangleSet>
-void X3DImporter::ParseNode_Rendering_TriangleSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleSet, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_IndexedSet(CX3DImporter_NodeElement::ENET_TriangleSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("TriangleSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleSet");
-
- MACRO_NODECHECK_LOOPEND("TriangleSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TriangleStripSet
-// DEF="" ID
-// USE="" IDREF
-// ccw="true" SFBool [initializeOnly]
-// colorPerVertex="true" SFBool [initializeOnly]
-// normalPerVertex="true" SFBool [initializeOnly]
-// solid="true" SFBool [initializeOnly]
-// stripCount="" MFInt32 [inputOutput]
-// >
-// <!-- ComposedGeometryContentModel -->
-// ComposedGeometryContentModel is the child-node content model corresponding to X3DComposedGeometryNodes. It can contain Color (or ColorRGBA), Coordinate,
-// Normal and TextureCoordinate, in any order. No more than one instance of these nodes is allowed. Multiple VertexAttribute (FloatVertexAttribute,
-// Matrix3VertexAttribute, Matrix4VertexAttribute) nodes can also be contained.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model.
-// </TriangleStripSet>
-void X3DImporter::ParseNode_Rendering_TriangleStripSet()
-{
- std::string use, def;
- bool ccw = true;
- bool colorPerVertex = true;
- std::vector<int32_t> stripCount;
- bool normalPerVertex = true;
- bool solid = true;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ccw", ccw, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("colorPerVertex", colorPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("stripCount", stripCount, XML_ReadNode_GetAttrVal_AsArrI32);
- MACRO_ATTRREAD_CHECK_RET("normalPerVertex", normalPerVertex, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("solid", solid, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TriangleStripSet, ne);
- }
- else
- {
- // check data
- if(stripCount.size() == 0) throw DeadlyImportError("TriangleStripSet must contain not empty \"stripCount\" attribute.");
-
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Set(CX3DImporter_NodeElement::ENET_TriangleStripSet, NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- CX3DImporter_NodeElement_Set& ne_alias = *((CX3DImporter_NodeElement_Set*)ne);
-
- ne_alias.CCW = ccw;
- ne_alias.ColorPerVertex = colorPerVertex;
- ne_alias.VertexCount = stripCount;
- ne_alias.NormalPerVertex = normalPerVertex;
- ne_alias.Solid = solid;
- // create CoordIdx
- size_t coord_num0, coord_num1, coord_num2;// indices of current triangle
- bool odd_tri;// sequence of current triangle
- size_t coord_num_sb;// index of first point of strip
-
- ne_alias.CoordIndex.clear();
- coord_num_sb = 0;
- for(std::vector<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
- {
- if(*vc_it < 3) throw DeadlyImportError("TriangleStripSet. stripCount shall be greater than or equal to three.");
-
- // set initial values for first triangle
- coord_num0 = coord_num_sb;
- coord_num1 = coord_num_sb + 1;
- coord_num2 = coord_num_sb + 2;
- odd_tri = true;
-
- for(int32_t vc = 2; vc < *vc_it; vc++)
- {
- if(ccw)
- {
- // 0 2
- // 1
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num0));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num1));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num2));
- }
- else
- {
- // 0 1
- // 2
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num0));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num2));
- ne_alias.CoordIndex.push_back(static_cast<int32_t>(coord_num1));
- }// if(ccw) else
-
- ne_alias.CoordIndex.push_back(-1);// add face delimiter.
- // prepare values for next triangle
- if(odd_tri)
- {
- coord_num0 = coord_num2;
- coord_num2++;
- }
- else
- {
- coord_num1 = coord_num2;
- coord_num2 = coord_num1 + 1;
- }
-
- odd_tri = !odd_tri;
- coord_num_sb = coord_num2;// that index will be start of next strip
- }// for(int32_t vc = 2; vc < *vc_it; vc++)
- }// for(std::list<int32_t>::const_iterator vc_it = ne_alias.VertexCount.begin(); vc_it != ne_alias.VertexCount.end(); vc_it++)
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("TriangleStripSet");
- // check for X3DComposedGeometryNodes
- if(XML_CheckNode_NameEqual("Color")) { ParseNode_Rendering_Color(); continue; }
- if(XML_CheckNode_NameEqual("ColorRGBA")) { ParseNode_Rendering_ColorRGBA(); continue; }
- if(XML_CheckNode_NameEqual("Coordinate")) { ParseNode_Rendering_Coordinate(); continue; }
- if(XML_CheckNode_NameEqual("Normal")) { ParseNode_Rendering_Normal(); continue; }
- if(XML_CheckNode_NameEqual("TextureCoordinate")) { ParseNode_Texturing_TextureCoordinate(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("TriangleStripSet");
-
- MACRO_NODECHECK_LOOPEND("TriangleStripSet");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Normal
-// DEF="" ID
-// USE="" IDREF
-// vector="" MFVec3f [inputOutput]
-// />
-void X3DImporter::ParseNode_Rendering_Normal()
-{
-std::string use, def;
-std::list<aiVector3D> vector;
-CX3DImporter_NodeElement* ne;
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("vector", vector, XML_ReadNode_GetAttrVal_AsListVec3f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Normal, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Normal(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Normal*)ne)->Value = vector;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Normal");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Shape.cpp b/src/3rdparty/assimp/code/X3DImporter_Shape.cpp
deleted file mode 100644
index 55ce7fa99..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Shape.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Shape.cpp
-/// \brief Parsing data from nodes of "Shape" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <Shape
-// DEF="" ID
-// USE="" IDREF
-// bboxCenter="0 0 0" SFVec3f [initializeOnly]
-// bboxSize="-1 -1 -1" SFVec3f [initializeOnly]
-// >
-// <!-- ShapeChildContentModel -->
-// "ShapeChildContentModel is the child-node content model corresponding to X3DShapeNode. ShapeChildContentModel can contain a single Appearance node and a
-// single geometry node, in any order.
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
-// </Shape>
-// A Shape node is unlit if either of the following is true:
-// The shape's appearance field is NULL (default).
-// The material field in the Appearance node is NULL (default).
-// NOTE Geometry nodes that represent lines or points do not support lighting.
-void X3DImporter::ParseNode_Shape_Shape()
-{
- std::string use, def;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Shape, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Shape(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("Shape");
- // check for appearance node
- if(XML_CheckNode_NameEqual("Appearance")) { ParseNode_Shape_Appearance(); continue; }
- // check for X3DGeometryNodes
- if(XML_CheckNode_NameEqual("Arc2D")) { ParseNode_Geometry2D_Arc2D(); continue; }
- if(XML_CheckNode_NameEqual("ArcClose2D")) { ParseNode_Geometry2D_ArcClose2D(); continue; }
- if(XML_CheckNode_NameEqual("Circle2D")) { ParseNode_Geometry2D_Circle2D(); continue; }
- if(XML_CheckNode_NameEqual("Disk2D")) { ParseNode_Geometry2D_Disk2D(); continue; }
- if(XML_CheckNode_NameEqual("Polyline2D")) { ParseNode_Geometry2D_Polyline2D(); continue; }
- if(XML_CheckNode_NameEqual("Polypoint2D")) { ParseNode_Geometry2D_Polypoint2D(); continue; }
- if(XML_CheckNode_NameEqual("Rectangle2D")) { ParseNode_Geometry2D_Rectangle2D(); continue; }
- if(XML_CheckNode_NameEqual("TriangleSet2D")) { ParseNode_Geometry2D_TriangleSet2D(); continue; }
- if(XML_CheckNode_NameEqual("Box")) { ParseNode_Geometry3D_Box(); continue; }
- if(XML_CheckNode_NameEqual("Cone")) { ParseNode_Geometry3D_Cone(); continue; }
- if(XML_CheckNode_NameEqual("Cylinder")) { ParseNode_Geometry3D_Cylinder(); continue; }
- if(XML_CheckNode_NameEqual("ElevationGrid")) { ParseNode_Geometry3D_ElevationGrid(); continue; }
- if(XML_CheckNode_NameEqual("Extrusion")) { ParseNode_Geometry3D_Extrusion(); continue; }
- if(XML_CheckNode_NameEqual("IndexedFaceSet")) { ParseNode_Geometry3D_IndexedFaceSet(); continue; }
- if(XML_CheckNode_NameEqual("Sphere")) { ParseNode_Geometry3D_Sphere(); continue; }
- if(XML_CheckNode_NameEqual("IndexedLineSet")) { ParseNode_Rendering_IndexedLineSet(); continue; }
- if(XML_CheckNode_NameEqual("LineSet")) { ParseNode_Rendering_LineSet(); continue; }
- if(XML_CheckNode_NameEqual("PointSet")) { ParseNode_Rendering_PointSet(); continue; }
- if(XML_CheckNode_NameEqual("IndexedTriangleFanSet")) { ParseNode_Rendering_IndexedTriangleFanSet(); continue; }
- if(XML_CheckNode_NameEqual("IndexedTriangleSet")) { ParseNode_Rendering_IndexedTriangleSet(); continue; }
- if(XML_CheckNode_NameEqual("IndexedTriangleStripSet")) { ParseNode_Rendering_IndexedTriangleStripSet(); continue; }
- if(XML_CheckNode_NameEqual("TriangleFanSet")) { ParseNode_Rendering_TriangleFanSet(); continue; }
- if(XML_CheckNode_NameEqual("TriangleSet")) { ParseNode_Rendering_TriangleSet(); continue; }
- if(XML_CheckNode_NameEqual("TriangleStripSet")) { ParseNode_Rendering_TriangleStripSet(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Shape");
-
- MACRO_NODECHECK_LOOPEND("Shape");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Appearance
-// DEF="" ID
-// USE="" IDREF
-// >
-// <!-- AppearanceChildContentModel -->
-// "Child-node content model corresponding to X3DAppearanceChildNode. Appearance can contain FillProperties, LineProperties, Material, any Texture node and
-// any TextureTransform node, in any order. No more than one instance of these nodes is allowed. Appearance may also contain multiple shaders (ComposedShader,
-// PackagedShader, ProgramShader).
-// A ProtoInstance node (with the proper node type) can be substituted for any node in this content model."
-// </Appearance>
-void X3DImporter::ParseNode_Shape_Appearance()
-{
- std::string use, def;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Appearance, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Appearance(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- // check for child nodes
- if(!mReader->isEmptyElement())
- {
- ParseHelper_Node_Enter(ne);
- MACRO_NODECHECK_LOOPBEGIN("Appearance");
- if(XML_CheckNode_NameEqual("Material")) { ParseNode_Shape_Material(); continue; }
- if(XML_CheckNode_NameEqual("ImageTexture")) { ParseNode_Texturing_ImageTexture(); continue; }
- if(XML_CheckNode_NameEqual("TextureTransform")) { ParseNode_Texturing_TextureTransform(); continue; }
- // check for X3DMetadataObject
- if(!ParseHelper_CheckRead_X3DMetadataObject()) XML_CheckNode_SkipUnsupported("Appearance");
-
- MACRO_NODECHECK_LOOPEND("Appearance");
- ParseHelper_Node_Exit();
- }// if(!mReader->isEmptyElement())
- else
- {
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
- }
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <Material
-// DEF="" ID
-// USE="" IDREF
-// ambientIntensity="0.2" SFFloat [inputOutput]
-// diffuseColor="0.8 0.8 0.8" SFColor [inputOutput]
-// emissiveColor="0 0 0" SFColor [inputOutput]
-// shininess="0.2" SFFloat [inputOutput]
-// specularColor="0 0 0" SFColor [inputOutput]
-// transparency="0" SFFloat [inputOutput]
-// />
-void X3DImporter::ParseNode_Shape_Material()
-{
- std::string use, def;
- float ambientIntensity = 0.2f;
- float shininess = 0.2f;
- float transparency = 0;
- aiColor3D diffuseColor(0.8f, 0.8f, 0.8f);
- aiColor3D emissiveColor(0, 0, 0);
- aiColor3D specularColor(0, 0, 0);
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("ambientIntensity", ambientIntensity, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("shininess", shininess, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_RET("transparency", transparency, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("diffuseColor", diffuseColor, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_CHECK_REF("emissiveColor", emissiveColor, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_CHECK_REF("specularColor", specularColor, XML_ReadNode_GetAttrVal_AsCol3f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_Material, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_Material(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_Material*)ne)->AmbientIntensity = ambientIntensity;
- ((CX3DImporter_NodeElement_Material*)ne)->Shininess = shininess;
- ((CX3DImporter_NodeElement_Material*)ne)->Transparency = transparency;
- ((CX3DImporter_NodeElement_Material*)ne)->DiffuseColor = diffuseColor;
- ((CX3DImporter_NodeElement_Material*)ne)->EmissiveColor = emissiveColor;
- ((CX3DImporter_NodeElement_Material*)ne)->SpecularColor = specularColor;
- // check for child nodes
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "Material");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DImporter_Texturing.cpp b/src/3rdparty/assimp/code/X3DImporter_Texturing.cpp
deleted file mode 100644
index 40ea47797..000000000
--- a/src/3rdparty/assimp/code/X3DImporter_Texturing.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DImporter_Texturing.cpp
-/// \brief Parsing data from nodes of "Texturing" set of X3D.
-/// \date 2015-2016
-/// \author smal.root@gmail.com
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "X3DImporter.hpp"
-#include "X3DImporter_Macro.hpp"
-
-namespace Assimp
-{
-
-// <ImageTexture
-// DEF="" ID
-// USE="" IDREF
-// repeatS="true" SFBool
-// repeatT="true" SFBool
-// url="" MFString
-// />
-// When the url field contains no values ([]), texturing is disabled.
-void X3DImporter::ParseNode_Texturing_ImageTexture()
-{
- std::string use, def;
- bool repeatS = true;
- bool repeatT = true;
- std::list<std::string> url;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_RET("repeatS", repeatS, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_RET("repeatT", repeatT, XML_ReadNode_GetAttrVal_AsBool);
- MACRO_ATTRREAD_CHECK_REF("url", url, XML_ReadNode_GetAttrVal_AsListS);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_ImageTexture, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_ImageTexture(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatS = repeatS;
- ((CX3DImporter_NodeElement_ImageTexture*)ne)->RepeatT = repeatT;
- // Attribute "url" can contain list of strings. But we need only one - first.
- if(url.size() > 0)
- ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = url.front();
- else
- ((CX3DImporter_NodeElement_ImageTexture*)ne)->URL = "";
-
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "ImageTexture");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TextureCoordinate
-// DEF="" ID
-// USE="" IDREF
-// point="" MFVec3f [inputOutput]
-// />
-void X3DImporter::ParseNode_Texturing_TextureCoordinate()
-{
- std::string use, def;
- std::list<aiVector2D> point;
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("point", point, XML_ReadNode_GetAttrVal_AsListVec2f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TextureCoordinate, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_TextureCoordinate(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_TextureCoordinate*)ne)->Value = point;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "TextureCoordinate");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-// <TextureTransform
-// DEF="" ID
-// USE="" IDREF
-// center="0 0" SFVec2f [inputOutput]
-// rotation="0" SFFloat [inputOutput]
-// scale="1 1" SFVec2f [inputOutput]
-// translation="0 0" SFVec2f [inputOutput]
-// />
-void X3DImporter::ParseNode_Texturing_TextureTransform()
-{
- std::string use, def;
- aiVector2D center(0, 0);
- float rotation = 0;
- aiVector2D scale(1, 1);
- aiVector2D translation(0, 0);
- CX3DImporter_NodeElement* ne( nullptr );
-
- MACRO_ATTRREAD_LOOPBEG;
- MACRO_ATTRREAD_CHECKUSEDEF_RET(def, use);
- MACRO_ATTRREAD_CHECK_REF("center", center, XML_ReadNode_GetAttrVal_AsVec2f);
- MACRO_ATTRREAD_CHECK_RET("rotation", rotation, XML_ReadNode_GetAttrVal_AsFloat);
- MACRO_ATTRREAD_CHECK_REF("scale", scale, XML_ReadNode_GetAttrVal_AsVec2f);
- MACRO_ATTRREAD_CHECK_REF("translation", translation, XML_ReadNode_GetAttrVal_AsVec2f);
- MACRO_ATTRREAD_LOOPEND;
-
- // if "USE" defined then find already defined element.
- if(!use.empty())
- {
- MACRO_USE_CHECKANDAPPLY(def, use, ENET_TextureTransform, ne);
- }
- else
- {
- // create and if needed - define new geometry object.
- ne = new CX3DImporter_NodeElement_TextureTransform(NodeElement_Cur);
- if(!def.empty()) ne->ID = def;
-
- ((CX3DImporter_NodeElement_TextureTransform*)ne)->Center = center;
- ((CX3DImporter_NodeElement_TextureTransform*)ne)->Rotation = rotation;
- ((CX3DImporter_NodeElement_TextureTransform*)ne)->Scale = scale;
- ((CX3DImporter_NodeElement_TextureTransform*)ne)->Translation = translation;
- // check for X3DMetadataObject childs.
- if(!mReader->isEmptyElement())
- ParseNode_Metadata(ne, "TextureTransform");
- else
- NodeElement_Cur->Child.push_back(ne);// add made object as child to current element
-
- NodeElement_List.push_back(ne);// add element to node element list because its a new object in graph
- }// if(!use.empty()) else
-}
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/X3DVocabulary.cpp b/src/3rdparty/assimp/code/X3DVocabulary.cpp
deleted file mode 100644
index 780c4ffc2..000000000
--- a/src/3rdparty/assimp/code/X3DVocabulary.cpp
+++ /dev/null
@@ -1,1675 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 X3DVocabulary.cpp
-/// \brief Vocabulary for Fast Infoset encoded binary X3D files.
-/// \date 2017
-/// \author Patrick Daehne
-
-#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
-
-#include "FIReader.hpp"
-
-namespace Assimp {
-
-static const char *encodingAlgorithmTable_3_2[] = {
- "encoder://web3d.org/QuantizedFloatArrayEncoder",
- "encoder://web3d.org/DeltazlibIntArrayEncoder",
- "encoder://web3d.org/QuantizedzlibFloatArrayEncoder",
- "encoder://web3d.org/zlibFloatArrayEncoder",
- "encoder://web3d.org/QuantizedDoubleArrayEncoder",
- "encoder://web3d.org/zlibDoubleArrayEncoder",
- "encoder://web3d.org/QuantizedzlibDoubleArrayEncoder",
- "encoder://web3d.org/RangeIntArrayEncoder"
-};
-
-static const std::shared_ptr<const FIValue> attributeValueTable_3_2[] = {
- FIStringValue::create("false"),
- FIStringValue::create("true")
-};
-
-static const FIQName elementNameTable_3_2[] = {
- { "Shape", nullptr, nullptr },
- { "Appearance", nullptr, nullptr },
- { "Material", nullptr, nullptr },
- { "IndexedFaceSet", nullptr, nullptr },
- { "ProtoInstance", nullptr, nullptr },
- { "Transform", nullptr, nullptr },
- { "ImageTexture", nullptr, nullptr },
- { "TextureTransform", nullptr, nullptr },
- { "Coordinate", nullptr, nullptr },
- { "Normal", nullptr, nullptr },
- { "Color", nullptr, nullptr },
- { "ColorRGBA", nullptr, nullptr },
- { "TextureCoordinate", nullptr, nullptr },
- { "ROUTE", nullptr, nullptr },
- { "fieldValue", nullptr, nullptr },
- { "Group", nullptr, nullptr },
- { "LOD", nullptr, nullptr },
- { "Switch", nullptr, nullptr },
- { "Script", nullptr, nullptr },
- { "IndexedTriangleFanSet", nullptr, nullptr },
- { "IndexedTriangleSet", nullptr, nullptr },
- { "IndexedTriangleStripSet", nullptr, nullptr },
- { "MultiTexture", nullptr, nullptr },
- { "MultiTextureCoordinate", nullptr, nullptr },
- { "MultiTextureTransform", nullptr, nullptr },
- { "IndexedLineSet", nullptr, nullptr },
- { "PointSet", nullptr, nullptr },
- { "StaticGroup", nullptr, nullptr },
- { "Sphere", nullptr, nullptr },
- { "Box", nullptr, nullptr },
- { "Cone", nullptr, nullptr },
- { "Anchor", nullptr, nullptr },
- { "Arc2D", nullptr, nullptr },
- { "ArcClose2D", nullptr, nullptr },
- { "AudioClip", nullptr, nullptr },
- { "Background", nullptr, nullptr },
- { "Billboard", nullptr, nullptr },
- { "BooleanFilter", nullptr, nullptr },
- { "BooleanSequencer", nullptr, nullptr },
- { "BooleanToggle", nullptr, nullptr },
- { "BooleanTrigger", nullptr, nullptr },
- { "Circle2D", nullptr, nullptr },
- { "Collision", nullptr, nullptr },
- { "ColorInterpolator", nullptr, nullptr },
- { "Contour2D", nullptr, nullptr },
- { "ContourPolyline2D", nullptr, nullptr },
- { "CoordinateDouble", nullptr, nullptr },
- { "CoordinateInterpolator", nullptr, nullptr },
- { "CoordinateInterpolator2D", nullptr, nullptr },
- { "Cylinder", nullptr, nullptr },
- { "CylinderSensor", nullptr, nullptr },
- { "DirectionalLight", nullptr, nullptr },
- { "Disk2D", nullptr, nullptr },
- { "EXPORT", nullptr, nullptr },
- { "ElevationGrid", nullptr, nullptr },
- { "EspduTransform", nullptr, nullptr },
- { "ExternProtoDeclare", nullptr, nullptr },
- { "Extrusion", nullptr, nullptr },
- { "FillProperties", nullptr, nullptr },
- { "Fog", nullptr, nullptr },
- { "FontStyle", nullptr, nullptr },
- { "GeoCoordinate", nullptr, nullptr },
- { "GeoElevationGrid", nullptr, nullptr },
- { "GeoLOD", nullptr, nullptr },
- { "GeoLocation", nullptr, nullptr },
- { "GeoMetadata", nullptr, nullptr },
- { "GeoOrigin", nullptr, nullptr },
- { "GeoPositionInterpolator", nullptr, nullptr },
- { "GeoTouchSensor", nullptr, nullptr },
- { "GeoViewpoint", nullptr, nullptr },
- { "HAnimDisplacer", nullptr, nullptr },
- { "HAnimHumanoid", nullptr, nullptr },
- { "HAnimJoint", nullptr, nullptr },
- { "HAnimSegment", nullptr, nullptr },
- { "HAnimSite", nullptr, nullptr },
- { "IMPORT", nullptr, nullptr },
- { "IS", nullptr, nullptr },
- { "Inline", nullptr, nullptr },
- { "IntegerSequencer", nullptr, nullptr },
- { "IntegerTrigger", nullptr, nullptr },
- { "KeySensor", nullptr, nullptr },
- { "LineProperties", nullptr, nullptr },
- { "LineSet", nullptr, nullptr },
- { "LoadSensor", nullptr, nullptr },
- { "MetadataDouble", nullptr, nullptr },
- { "MetadataFloat", nullptr, nullptr },
- { "MetadataInteger", nullptr, nullptr },
- { "MetadataSet", nullptr, nullptr },
- { "MetadataString", nullptr, nullptr },
- { "MovieTexture", nullptr, nullptr },
- { "NavigationInfo", nullptr, nullptr },
- { "NormalInterpolator", nullptr, nullptr },
- { "NurbsCurve", nullptr, nullptr },
- { "NurbsCurve2D", nullptr, nullptr },
- { "NurbsOrientationInterpolator", nullptr, nullptr },
- { "NurbsPatchSurface", nullptr, nullptr },
- { "NurbsPositionInterpolator", nullptr, nullptr },
- { "NurbsSet", nullptr, nullptr },
- { "NurbsSurfaceInterpolator", nullptr, nullptr },
- { "NurbsSweptSurface", nullptr, nullptr },
- { "NurbsSwungSurface", nullptr, nullptr },
- { "NurbsTextureCoordinate", nullptr, nullptr },
- { "NurbsTrimmedSurface", nullptr, nullptr },
- { "OrientationInterpolator", nullptr, nullptr },
- { "PixelTexture", nullptr, nullptr },
- { "PlaneSensor", nullptr, nullptr },
- { "PointLight", nullptr, nullptr },
- { "Polyline2D", nullptr, nullptr },
- { "Polypoint2D", nullptr, nullptr },
- { "PositionInterpolator", nullptr, nullptr },
- { "PositionInterpolator2D", nullptr, nullptr },
- { "ProtoBody", nullptr, nullptr },
- { "ProtoDeclare", nullptr, nullptr },
- { "ProtoInterface", nullptr, nullptr },
- { "ProximitySensor", nullptr, nullptr },
- { "ReceiverPdu", nullptr, nullptr },
- { "Rectangle2D", nullptr, nullptr },
- { "ScalarInterpolator", nullptr, nullptr },
- { "Scene", nullptr, nullptr },
- { "SignalPdu", nullptr, nullptr },
- { "Sound", nullptr, nullptr },
- { "SphereSensor", nullptr, nullptr },
- { "SpotLight", nullptr, nullptr },
- { "StringSensor", nullptr, nullptr },
- { "Text", nullptr, nullptr },
- { "TextureBackground", nullptr, nullptr },
- { "TextureCoordinateGenerator", nullptr, nullptr },
- { "TimeSensor", nullptr, nullptr },
- { "TimeTrigger", nullptr, nullptr },
- { "TouchSensor", nullptr, nullptr },
- { "TransmitterPdu", nullptr, nullptr },
- { "TriangleFanSet", nullptr, nullptr },
- { "TriangleSet", nullptr, nullptr },
- { "TriangleSet2D", nullptr, nullptr },
- { "TriangleStripSet", nullptr, nullptr },
- { "Viewpoint", nullptr, nullptr },
- { "VisibilitySensor", nullptr, nullptr },
- { "WorldInfo", nullptr, nullptr },
- { "X3D", nullptr, nullptr },
- { "component", nullptr, nullptr },
- { "connect", nullptr, nullptr },
- { "field", nullptr, nullptr },
- { "head", nullptr, nullptr },
- { "humanoidBodyType", nullptr, nullptr },
- { "meta", nullptr, nullptr },
- { "CADAssembly", nullptr, nullptr },
- { "CADFace", nullptr, nullptr },
- { "CADLayer", nullptr, nullptr },
- { "CADPart", nullptr, nullptr },
- { "ComposedCubeMapTexture", nullptr, nullptr },
- { "ComposedShader", nullptr, nullptr },
- { "ComposedTexture3D", nullptr, nullptr },
- { "FloatVertexAttribute", nullptr, nullptr },
- { "FogCoordinate", nullptr, nullptr },
- { "GeneratedCubeMapTexture", nullptr, nullptr },
- { "ImageCubeMapTexture", nullptr, nullptr },
- { "ImageTexture3D", nullptr, nullptr },
- { "IndexedQuadSet", nullptr, nullptr },
- { "LocalFog", nullptr, nullptr },
- { "Matrix3VertexAttribute", nullptr, nullptr },
- { "Matrix4VertexAttribute", nullptr, nullptr },
- { "PackagedShader", nullptr, nullptr },
- { "PixelTexture3D", nullptr, nullptr },
- { "ProgramShader", nullptr, nullptr },
- { "QuadSet", nullptr, nullptr },
- { "ShaderPart", nullptr, nullptr },
- { "ShaderProgram", nullptr, nullptr },
- { "TextureCoordinate3D", nullptr, nullptr },
- { "TextureCoordinate4D", nullptr, nullptr },
- { "TextureTransform3D", nullptr, nullptr },
- { "TextureTransformMatrix3D", nullptr, nullptr },
- { "BallJoint", nullptr, nullptr },
- { "BoundedPhysicsModel", nullptr, nullptr },
- { "ClipPlane", nullptr, nullptr },
- { "CollidableOffset", nullptr, nullptr },
- { "CollidableShape", nullptr, nullptr },
- { "CollisionCollection", nullptr, nullptr },
- { "CollisionSensor", nullptr, nullptr },
- { "CollisionSpace", nullptr, nullptr },
- { "ColorDamper", nullptr, nullptr },
- { "ConeEmitter", nullptr, nullptr },
- { "Contact", nullptr, nullptr },
- { "CoordinateDamper", nullptr, nullptr },
- { "DISEntityManager", nullptr, nullptr },
- { "DISEntityTypeMapping", nullptr, nullptr },
- { "DoubleAxisHingeJoint", nullptr, nullptr },
- { "EaseInEaseOut", nullptr, nullptr },
- { "ExplosionEmitter", nullptr, nullptr },
- { "ForcePhysicsModel", nullptr, nullptr },
- { "GeoProximitySensor", nullptr, nullptr },
- { "GeoTransform", nullptr, nullptr },
- { "Layer", nullptr, nullptr },
- { "LayerSet", nullptr, nullptr },
- { "Layout", nullptr, nullptr },
- { "LayoutGroup", nullptr, nullptr },
- { "LayoutLayer", nullptr, nullptr },
- { "LinePickSensor", nullptr, nullptr },
- { "MotorJoint", nullptr, nullptr },
- { "OrientationChaser", nullptr, nullptr },
- { "OrientationDamper", nullptr, nullptr },
- { "OrthoViewpoint", nullptr, nullptr },
- { "ParticleSystem", nullptr, nullptr },
- { "PickableGroup", nullptr, nullptr },
- { "PointEmitter", nullptr, nullptr },
- { "PointPickSensor", nullptr, nullptr },
- { "PolylineEmitter", nullptr, nullptr },
- { "PositionChaser", nullptr, nullptr },
- { "PositionChaser2D", nullptr, nullptr },
- { "PositionDamper", nullptr, nullptr },
- { "PositionDamper2D", nullptr, nullptr },
- { "PrimitivePickSensor", nullptr, nullptr },
- { "RigidBody", nullptr, nullptr },
- { "RigidBodyCollection", nullptr, nullptr },
- { "ScalarChaser", nullptr, nullptr },
- { "ScreenFontStyle", nullptr, nullptr },
- { "ScreenGroup", nullptr, nullptr },
- { "SingleAxisHingeJoint", nullptr, nullptr },
- { "SliderJoint", nullptr, nullptr },
- { "SplinePositionInterpolator", nullptr, nullptr },
- { "SplinePositionInterpolator2D", nullptr, nullptr },
- { "SplineScalarInterpolator", nullptr, nullptr },
- { "SquadOrientationInterpolator", nullptr, nullptr },
- { "SurfaceEmitter", nullptr, nullptr },
- { "TexCoordDamper", nullptr, nullptr },
- { "TextureProperties", nullptr, nullptr },
- { "TransformSensor", nullptr, nullptr },
- { "TwoSidedMaterial", nullptr, nullptr },
- { "UniversalJoint", nullptr, nullptr },
- { "ViewpointGroup", nullptr, nullptr },
- { "Viewport", nullptr, nullptr },
- { "VolumeEmitter", nullptr, nullptr },
- { "VolumePickSensor", nullptr, nullptr },
- { "WindPhysicsModel", nullptr, nullptr }
-};
-
-static const FIQName attributeNameTable_3_2[] = {
- { "DEF", nullptr, nullptr },
- { "USE", nullptr, nullptr },
- { "containerField", nullptr, nullptr },
- { "fromNode", nullptr, nullptr },
- { "fromField", nullptr, nullptr },
- { "toNode", nullptr, nullptr },
- { "toField", nullptr, nullptr },
- { "name", nullptr, nullptr },
- { "value", nullptr, nullptr },
- { "color", nullptr, nullptr },
- { "colorIndex", nullptr, nullptr },
- { "coordIndex", nullptr, nullptr },
- { "texCoordIndex", nullptr, nullptr },
- { "normalIndex", nullptr, nullptr },
- { "colorPerVertex", nullptr, nullptr },
- { "normalPerVertex", nullptr, nullptr },
- { "rotation", nullptr, nullptr },
- { "scale", nullptr, nullptr },
- { "center", nullptr, nullptr },
- { "scaleOrientation", nullptr, nullptr },
- { "translation", nullptr, nullptr },
- { "url", nullptr, nullptr },
- { "repeatS", nullptr, nullptr },
- { "repeatT", nullptr, nullptr },
- { "point", nullptr, nullptr },
- { "vector", nullptr, nullptr },
- { "range", nullptr, nullptr },
- { "ambientIntensity", nullptr, nullptr },
- { "diffuseColor", nullptr, nullptr },
- { "emissiveColor", nullptr, nullptr },
- { "shininess", nullptr, nullptr },
- { "specularColor", nullptr, nullptr },
- { "transparency", nullptr, nullptr },
- { "whichChoice", nullptr, nullptr },
- { "index", nullptr, nullptr },
- { "mode", nullptr, nullptr },
- { "source", nullptr, nullptr },
- { "function", nullptr, nullptr },
- { "alpha", nullptr, nullptr },
- { "vertexCount", nullptr, nullptr },
- { "radius", nullptr, nullptr },
- { "size", nullptr, nullptr },
- { "height", nullptr, nullptr },
- { "solid", nullptr, nullptr },
- { "ccw", nullptr, nullptr },
- { "key", nullptr, nullptr },
- { "keyValue", nullptr, nullptr },
- { "enabled", nullptr, nullptr },
- { "direction", nullptr, nullptr },
- { "position", nullptr, nullptr },
- { "orientation", nullptr, nullptr },
- { "bboxCenter", nullptr, nullptr },
- { "bboxSize", nullptr, nullptr },
- { "AS", nullptr, nullptr },
- { "InlineDEF", nullptr, nullptr },
- { "accessType", nullptr, nullptr },
- { "actionKeyPress", nullptr, nullptr },
- { "actionKeyRelease", nullptr, nullptr },
- { "address", nullptr, nullptr },
- { "altKey", nullptr, nullptr },
- { "antennaLocation", nullptr, nullptr },
- { "antennaPatternLength", nullptr, nullptr },
- { "antennaPatternType", nullptr, nullptr },
- { "applicationID", nullptr, nullptr },
- { "articulationParameterArray", nullptr, nullptr },
- { "articulationParameterChangeIndicatorArray", nullptr, nullptr },
- { "articulationParameterCount", nullptr, nullptr },
- { "articulationParameterDesignatorArray", nullptr, nullptr },
- { "articulationParameterIdPartAttachedArray", nullptr, nullptr },
- { "articulationParameterTypeArray", nullptr, nullptr },
- { "attenuation", nullptr, nullptr },
- { "autoOffset", nullptr, nullptr },
- { "avatarSize", nullptr, nullptr },
- { "axisOfRotation", nullptr, nullptr },
- { "backUrl", nullptr, nullptr },
- { "beamWidth", nullptr, nullptr },
- { "beginCap", nullptr, nullptr },
- { "bindTime", nullptr, nullptr },
- { "bottom", nullptr, nullptr },
- { "bottomRadius", nullptr, nullptr },
- { "bottomUrl", nullptr, nullptr },
- { "centerOfMass", nullptr, nullptr },
- { "centerOfRotation", nullptr, nullptr },
- { "child1Url", nullptr, nullptr },
- { "child2Url", nullptr, nullptr },
- { "child3Url", nullptr, nullptr },
- { "child4Url", nullptr, nullptr },
- { "class", nullptr, nullptr },
- { "closureType", nullptr, nullptr },
- { "collideTime", nullptr, nullptr },
- { "content", nullptr, nullptr },
- { "controlKey", nullptr, nullptr },
- { "controlPoint", nullptr, nullptr },
- { "convex", nullptr, nullptr },
- { "coordinateSystem", nullptr, nullptr },
- { "copyright", nullptr, nullptr },
- { "creaseAngle", nullptr, nullptr },
- { "crossSection", nullptr, nullptr },
- { "cryptoKeyID", nullptr, nullptr },
- { "cryptoSystem", nullptr, nullptr },
- { "cutOffAngle", nullptr, nullptr },
- { "cycleInterval", nullptr, nullptr },
- { "cycleTime", nullptr, nullptr },
- { "data", nullptr, nullptr },
- { "dataFormat", nullptr, nullptr },
- { "dataLength", nullptr, nullptr },
- { "dataUrl", nullptr, nullptr },
- { "date", nullptr, nullptr },
- { "deadReckoning", nullptr, nullptr },
- { "deletionAllowed", nullptr, nullptr },
- { "description", nullptr, nullptr },
- { "detonateTime", nullptr, nullptr },
- { "dir", nullptr, nullptr },
- { "directOutput", nullptr, nullptr },
- { "diskAngle", nullptr, nullptr },
- { "displacements", nullptr, nullptr },
- { "documentation", nullptr, nullptr },
- { "elapsedTime", nullptr, nullptr },
- { "ellipsoid", nullptr, nullptr },
- { "encodingScheme", nullptr, nullptr },
- { "endAngle", nullptr, nullptr },
- { "endCap", nullptr, nullptr },
- { "enterTime", nullptr, nullptr },
- { "enteredText", nullptr, nullptr },
- { "entityCategory", nullptr, nullptr },
- { "entityCountry", nullptr, nullptr },
- { "entityDomain", nullptr, nullptr },
- { "entityExtra", nullptr, nullptr },
- { "entityID", nullptr, nullptr },
- { "entityKind", nullptr, nullptr },
- { "entitySpecific", nullptr, nullptr },
- { "entitySubCategory", nullptr, nullptr },
- { "exitTime", nullptr, nullptr },
- { "extent", nullptr, nullptr },
- { "family", nullptr, nullptr },
- { "fanCount", nullptr, nullptr },
- { "fieldOfView", nullptr, nullptr },
- { "filled", nullptr, nullptr },
- { "finalText", nullptr, nullptr },
- { "fireMissionIndex", nullptr, nullptr },
- { "fired1", nullptr, nullptr },
- { "fired2", nullptr, nullptr },
- { "firedTime", nullptr, nullptr },
- { "firingRange", nullptr, nullptr },
- { "firingRate", nullptr, nullptr },
- { "fogType", nullptr, nullptr },
- { "forceID", nullptr, nullptr },
- { "frequency", nullptr, nullptr },
- { "frontUrl", nullptr, nullptr },
- { "fuse", nullptr, nullptr },
- { "geoCoords", nullptr, nullptr },
- { "geoGridOrigin", nullptr, nullptr },
- { "geoSystem", nullptr, nullptr },
- { "groundAngle", nullptr, nullptr },
- { "groundColor", nullptr, nullptr },
- { "hatchColor", nullptr, nullptr },
- { "hatchStyle", nullptr, nullptr },
- { "hatched", nullptr, nullptr },
- { "headlight", nullptr, nullptr },
- { "horizontal", nullptr, nullptr },
- { "horizontalDatum", nullptr, nullptr },
- { "http-equiv", nullptr, nullptr },
- { "image", nullptr, nullptr },
- { "importedDEF", nullptr, nullptr },
- { "info", nullptr, nullptr },
- { "innerRadius", nullptr, nullptr },
- { "inputFalse", nullptr, nullptr },
- { "inputNegate", nullptr, nullptr },
- { "inputSource", nullptr, nullptr },
- { "inputTrue", nullptr, nullptr },
- { "integerKey", nullptr, nullptr },
- { "intensity", nullptr, nullptr },
- { "jump", nullptr, nullptr },
- { "justify", nullptr, nullptr },
- { "keyPress", nullptr, nullptr },
- { "keyRelease", nullptr, nullptr },
- { "knot", nullptr, nullptr },
- { "lang", nullptr, nullptr },
- { "language", nullptr, nullptr },
- { "leftToRight", nullptr, nullptr },
- { "leftUrl", nullptr, nullptr },
- { "length", nullptr, nullptr },
- { "lengthOfModulationParameters", nullptr, nullptr },
- { "level", nullptr, nullptr },
- { "limitOrientation", nullptr, nullptr },
- { "lineSegments", nullptr, nullptr },
- { "linearAcceleration", nullptr, nullptr },
- { "linearVelocity", nullptr, nullptr },
- { "linetype", nullptr, nullptr },
- { "linewidthScaleFactor", nullptr, nullptr },
- { "llimit", nullptr, nullptr },
- { "load", nullptr, nullptr },
- { "loadTime", nullptr, nullptr },
- { "localDEF", nullptr, nullptr },
- { "location", nullptr, nullptr },
- { "loop", nullptr, nullptr },
- { "marking", nullptr, nullptr },
- { "mass", nullptr, nullptr },
- { "maxAngle", nullptr, nullptr },
- { "maxBack", nullptr, nullptr },
- { "maxExtent", nullptr, nullptr },
- { "maxFront", nullptr, nullptr },
- { "maxPosition", nullptr, nullptr },
- { "metadataFormat", nullptr, nullptr },
- { "minAngle", nullptr, nullptr },
- { "minBack", nullptr, nullptr },
- { "minFront", nullptr, nullptr },
- { "minPosition", nullptr, nullptr },
- { "modulationTypeDetail", nullptr, nullptr },
- { "modulationTypeMajor", nullptr, nullptr },
- { "modulationTypeSpreadSpectrum", nullptr, nullptr },
- { "modulationTypeSystem", nullptr, nullptr },
- { "momentsOfInertia", nullptr, nullptr },
- { "multicastRelayHost", nullptr, nullptr },
- { "multicastRelayPort", nullptr, nullptr },
- { "munitionApplicationID", nullptr, nullptr },
- { "munitionEndPoint", nullptr, nullptr },
- { "munitionEntityID", nullptr, nullptr },
- { "munitionQuantity", nullptr, nullptr },
- { "munitionSiteID", nullptr, nullptr },
- { "munitionStartPoint", nullptr, nullptr },
- { "mustEvaluate", nullptr, nullptr },
- { "navType", nullptr, nullptr },
- { "networkMode", nullptr, nullptr },
- { "next", nullptr, nullptr },
- { "nodeField", nullptr, nullptr },
- { "offset", nullptr, nullptr },
- { "on", nullptr, nullptr },
- { "order", nullptr, nullptr },
- { "originator", nullptr, nullptr },
- { "outerRadius", nullptr, nullptr },
- { "parameter", nullptr, nullptr },
- { "pauseTime", nullptr, nullptr },
- { "pitch", nullptr, nullptr },
- { "points", nullptr, nullptr },
- { "port", nullptr, nullptr },
- { "power", nullptr, nullptr },
- { "previous", nullptr, nullptr },
- { "priority", nullptr, nullptr },
- { "profile", nullptr, nullptr },
- { "progress", nullptr, nullptr },
- { "protoField", nullptr, nullptr },
- { "radioEntityTypeCategory", nullptr, nullptr },
- { "radioEntityTypeCountry", nullptr, nullptr },
- { "radioEntityTypeDomain", nullptr, nullptr },
- { "radioEntityTypeKind", nullptr, nullptr },
- { "radioEntityTypeNomenclature", nullptr, nullptr },
- { "radioEntityTypeNomenclatureVersion", nullptr, nullptr },
- { "radioID", nullptr, nullptr },
- { "readInterval", nullptr, nullptr },
- { "receivedPower", nullptr, nullptr },
- { "receiverState", nullptr, nullptr },
- { "reference", nullptr, nullptr },
- { "relativeAntennaLocation", nullptr, nullptr },
- { "resolution", nullptr, nullptr },
- { "resumeTime", nullptr, nullptr },
- { "rightUrl", nullptr, nullptr },
- { "rootUrl", nullptr, nullptr },
- { "rotateYUp", nullptr, nullptr },
- { "rtpHeaderExpected", nullptr, nullptr },
- { "sampleRate", nullptr, nullptr },
- { "samples", nullptr, nullptr },
- { "shiftKey", nullptr, nullptr },
- { "side", nullptr, nullptr },
- { "siteID", nullptr, nullptr },
- { "skinCoordIndex", nullptr, nullptr },
- { "skinCoordWeight", nullptr, nullptr },
- { "skyAngle", nullptr, nullptr },
- { "skyColor", nullptr, nullptr },
- { "spacing", nullptr, nullptr },
- { "spatialize", nullptr, nullptr },
- { "speed", nullptr, nullptr },
- { "speedFactor", nullptr, nullptr },
- { "spine", nullptr, nullptr },
- { "startAngle", nullptr, nullptr },
- { "startTime", nullptr, nullptr },
- { "stiffness", nullptr, nullptr },
- { "stopTime", nullptr, nullptr },
- { "string", nullptr, nullptr },
- { "stripCount", nullptr, nullptr },
- { "style", nullptr, nullptr },
- { "summary", nullptr, nullptr },
- { "tdlType", nullptr, nullptr },
- { "tessellation", nullptr, nullptr },
- { "tessellationScale", nullptr, nullptr },
- { "time", nullptr, nullptr },
- { "timeOut", nullptr, nullptr },
- { "timestamp", nullptr, nullptr },
- { "title", nullptr, nullptr },
- { "toggle", nullptr, nullptr },
- { "top", nullptr, nullptr },
- { "topToBottom", nullptr, nullptr },
- { "topUrl", nullptr, nullptr },
- { "touchTime", nullptr, nullptr },
- { "transmitFrequencyBandwidth", nullptr, nullptr },
- { "transmitState", nullptr, nullptr },
- { "transmitterApplicationID", nullptr, nullptr },
- { "transmitterEntityID", nullptr, nullptr },
- { "transmitterRadioID", nullptr, nullptr },
- { "transmitterSiteID", nullptr, nullptr },
- { "transparent", nullptr, nullptr },
- { "triggerTime", nullptr, nullptr },
- { "triggerTrue", nullptr, nullptr },
- { "triggerValue", nullptr, nullptr },
- { "type", nullptr, nullptr },
- { "uDimension", nullptr, nullptr },
- { "uKnot", nullptr, nullptr },
- { "uOrder", nullptr, nullptr },
- { "uTessellation", nullptr, nullptr },
- { "ulimit", nullptr, nullptr },
- { "vDimension", nullptr, nullptr },
- { "vKnot", nullptr, nullptr },
- { "vOrder", nullptr, nullptr },
- { "vTessellation", nullptr, nullptr },
- { "version", nullptr, nullptr },
- { "verticalDatum", nullptr, nullptr },
- { "vertices", nullptr, nullptr },
- { "visibilityLimit", nullptr, nullptr },
- { "visibilityRange", nullptr, nullptr },
- { "warhead", nullptr, nullptr },
- { "weight", nullptr, nullptr },
- { "whichGeometry", nullptr, nullptr },
- { "writeInterval", nullptr, nullptr },
- { "xDimension", nullptr, nullptr },
- { "xSpacing", nullptr, nullptr },
- { "yScale", nullptr, nullptr },
- { "zDimension", nullptr, nullptr },
- { "zSpacing", nullptr, nullptr },
- { "visible", nullptr, nullptr },
- { "repeatR", nullptr, nullptr },
- { "texture", nullptr, nullptr },
- { "back", nullptr, nullptr },
- { "front", nullptr, nullptr },
- { "left", nullptr, nullptr },
- { "right", nullptr, nullptr },
- { "parts", nullptr, nullptr },
- { "isSelected", nullptr, nullptr },
- { "isValid", nullptr, nullptr },
- { "numComponents", nullptr, nullptr },
- { "depth", nullptr, nullptr },
- { "update", nullptr, nullptr },
- { "fogCoord", nullptr, nullptr },
- { "texCoord", nullptr, nullptr },
- { "activate", nullptr, nullptr },
- { "programs", nullptr, nullptr },
- { "matrix", nullptr, nullptr },
- { "anchorPoint", nullptr, nullptr },
- { "body1", nullptr, nullptr },
- { "body2", nullptr, nullptr },
- { "mustOutput", nullptr, nullptr },
- { "body1AnchorPoint", nullptr, nullptr },
- { "body2AnchorPoint", nullptr, nullptr },
- { "plane", nullptr, nullptr },
- { "appliedParameters", nullptr, nullptr },
- { "bounce", nullptr, nullptr },
- { "frictionCoefficients", nullptr, nullptr },
- { "minBounceSpeed", nullptr, nullptr },
- { "slipFactors", nullptr, nullptr },
- { "softnessConstantForceMix", nullptr, nullptr },
- { "softnessErrorCorrection", nullptr, nullptr },
- { "surfaceSpeed", nullptr, nullptr },
- { "isActive", nullptr, nullptr },
- { "useGeometry", nullptr, nullptr },
- { "set_destination", nullptr, nullptr },
- { "set_value", nullptr, nullptr },
- { "tau", nullptr, nullptr },
- { "tolerance", nullptr, nullptr },
- { "value_changed", nullptr, nullptr },
- { "initialDestination", nullptr, nullptr },
- { "initialValue", nullptr, nullptr },
- { "angle", nullptr, nullptr },
- { "variation", nullptr, nullptr },
- { "surfaceArea", nullptr, nullptr },
- { "frictionDirection", nullptr, nullptr },
- { "slipCoefficients", nullptr, nullptr },
- { "category", nullptr, nullptr },
- { "country", nullptr, nullptr },
- { "domain", nullptr, nullptr },
- { "extra", nullptr, nullptr },
- { "kind", nullptr, nullptr },
- { "specific", nullptr, nullptr },
- { "subcategory", nullptr, nullptr },
- { "axis1", nullptr, nullptr },
- { "axis2", nullptr, nullptr },
- { "desiredAngularVelocity1", nullptr, nullptr },
- { "desiredAngularVelocity2", nullptr, nullptr },
- { "maxAngle1", nullptr, nullptr },
- { "maxTorque1", nullptr, nullptr },
- { "maxTorque2", nullptr, nullptr },
- { "minAngle1", nullptr, nullptr },
- { "stopBounce1", nullptr, nullptr },
- { "stopConstantForceMix1", nullptr, nullptr },
- { "stopErrorCorrection1", nullptr, nullptr },
- { "suspensionErrorCorrection", nullptr, nullptr },
- { "suspensionForce", nullptr, nullptr },
- { "body1Axis", nullptr, nullptr },
- { "body2Axis", nullptr, nullptr },
- { "hinge1Angle", nullptr, nullptr },
- { "hinge1AngleRate", nullptr, nullptr },
- { "hinge2Angle", nullptr, nullptr },
- { "hinge2AngleRate", nullptr, nullptr },
- { "set_fraction", nullptr, nullptr },
- { "easeInEaseOut", nullptr, nullptr },
- { "modifiedFraction_changed", nullptr, nullptr },
- { "force", nullptr, nullptr },
- { "geoCenter", nullptr, nullptr },
- { "centerOfRotation_changed", nullptr, nullptr },
- { "geoCoord_changed", nullptr, nullptr },
- { "orientation_changed", nullptr, nullptr },
- { "position_changed", nullptr, nullptr },
- { "isPickable", nullptr, nullptr },
- { "viewport", nullptr, nullptr },
- { "activeLayer", nullptr, nullptr },
- { "align", nullptr, nullptr },
- { "offsetUnits", nullptr, nullptr },
- { "scaleMode", nullptr, nullptr },
- { "sizeUnits", nullptr, nullptr },
- { "layout", nullptr, nullptr },
- { "objectType", nullptr, nullptr },
- { "pickedNormal", nullptr, nullptr },
- { "pickedPoint", nullptr, nullptr },
- { "pickedTextureCoordinate", nullptr, nullptr },
- { "intersectionType", nullptr, nullptr },
- { "sortOrder", nullptr, nullptr },
- { "axis1Angle", nullptr, nullptr },
- { "axis1Torque", nullptr, nullptr },
- { "axis2Angle", nullptr, nullptr },
- { "axis2Torque", nullptr, nullptr },
- { "axis3Angle", nullptr, nullptr },
- { "axis3Torque", nullptr, nullptr },
- { "enabledAxies", nullptr, nullptr },
- { "motor1Axis", nullptr, nullptr },
- { "motor2Axis", nullptr, nullptr },
- { "motor3Axis", nullptr, nullptr },
- { "stop1Bounce", nullptr, nullptr },
- { "stop1ErrorCorrection", nullptr, nullptr },
- { "stop2Bounce", nullptr, nullptr },
- { "stop2ErrorCorrection", nullptr, nullptr },
- { "stop3Bounce", nullptr, nullptr },
- { "stop3ErrorCorrection", nullptr, nullptr },
- { "motor1Angle", nullptr, nullptr },
- { "motor1AngleRate", nullptr, nullptr },
- { "motor2Angle", nullptr, nullptr },
- { "motor2AngleRate", nullptr, nullptr },
- { "motor3Angle", nullptr, nullptr },
- { "motor3AngleRate", nullptr, nullptr },
- { "autoCalc", nullptr, nullptr },
- { "duration", nullptr, nullptr },
- { "retainUserOffsets", nullptr, nullptr },
- { "isBound", nullptr, nullptr },
- { "appearance", nullptr, nullptr },
- { "createParticles", nullptr, nullptr },
- { "lifetimeVariation", nullptr, nullptr },
- { "maxParticles", nullptr, nullptr },
- { "particleLifetime", nullptr, nullptr },
- { "particleSize", nullptr, nullptr },
- { "colorKey", nullptr, nullptr },
- { "geometryType", nullptr, nullptr },
- { "texCoordKey", nullptr, nullptr },
- { "pickable", nullptr, nullptr },
- { "angularDampingFactor", nullptr, nullptr },
- { "angularVelocity", nullptr, nullptr },
- { "autoDamp", nullptr, nullptr },
- { "autoDisable", nullptr, nullptr },
- { "disableAngularSpeed", nullptr, nullptr },
- { "disableLinearSpeed", nullptr, nullptr },
- { "disableTime", nullptr, nullptr },
- { "finiteRotationAxis", nullptr, nullptr },
- { "fixed", nullptr, nullptr },
- { "forces", nullptr, nullptr },
- { "inertia", nullptr, nullptr },
- { "linearDampingFactor", nullptr, nullptr },
- { "torques", nullptr, nullptr },
- { "useFiniteRotation", nullptr, nullptr },
- { "useGlobalForce", nullptr, nullptr },
- { "constantForceMix", nullptr, nullptr },
- { "constantSurfaceThickness", nullptr, nullptr },
- { "errorCorrection", nullptr, nullptr },
- { "iterations", nullptr, nullptr },
- { "maxCorrectionSpeed", nullptr, nullptr },
- { "preferAccuracy", nullptr, nullptr },
- { "pointSize", nullptr, nullptr },
- { "stopBounce", nullptr, nullptr },
- { "stopErrorCorrection", nullptr, nullptr },
- { "angleRate", nullptr, nullptr },
- { "maxSeparation", nullptr, nullptr },
- { "minSeparation", nullptr, nullptr },
- { "separation", nullptr, nullptr },
- { "separationRate", nullptr, nullptr },
- { "closed", nullptr, nullptr },
- { "keyVelocity", nullptr, nullptr },
- { "normalizeVelocity", nullptr, nullptr },
- { "surface", nullptr, nullptr },
- { "anisotropicDegree", nullptr, nullptr },
- { "borderColor", nullptr, nullptr },
- { "borderWidth", nullptr, nullptr },
- { "boundaryModeS", nullptr, nullptr },
- { "boundaryModeT", nullptr, nullptr },
- { "boundaryModeR", nullptr, nullptr },
- { "magnificationFilter", nullptr, nullptr },
- { "minificationFilter", nullptr, nullptr },
- { "textureCompression", nullptr, nullptr },
- { "texturePriority", nullptr, nullptr },
- { "generateMipMaps", nullptr, nullptr },
- { "targetObject", nullptr, nullptr },
- { "backAmbientIntensity", nullptr, nullptr },
- { "backDiffuseColor", nullptr, nullptr },
- { "backEmissiveColor", nullptr, nullptr },
- { "backShininess", nullptr, nullptr },
- { "backSpecularColor", nullptr, nullptr },
- { "separateBackColor", nullptr, nullptr },
- { "displayed", nullptr, nullptr },
- { "clipBoundary", nullptr, nullptr },
- { "internal", nullptr, nullptr },
- { "gustiness", nullptr, nullptr },
- { "turbulence", nullptr, nullptr }
-};
-
-FIVocabulary X3D_vocabulary_3_2 = {
- nullptr, 0,
- encodingAlgorithmTable_3_2, 8,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- attributeValueTable_3_2, 2,
- nullptr, 0,
- nullptr, 0,
- elementNameTable_3_2, 233,
- attributeNameTable_3_2, 516
-};
-
-static const char *encodingAlgorithmTable_3_3[] = {
- "encoder://web3d.org/QuantizedFloatArrayEncoder",
- "encoder://web3d.org/DeltazlibIntArrayEncoder",
- "encoder://web3d.org/QuantizedzlibFloatArrayEncoder",
- "encoder://web3d.org/zlibFloatArrayEncoder",
- "encoder://web3d.org/QuantizedDoubleArrayEncoder",
- "encoder://web3d.org/zlibDoubleArrayEncoder",
- "encoder://web3d.org/QuantizedzlibDoubleArrayEncoder",
- "encoder://web3d.org/RangeIntArrayEncoder"
-};
-
-static const std::shared_ptr<const FIValue> attributeValueTable_3_3[] = {
- FIStringValue::create("false"),
- FIStringValue::create("true")
-};
-
-static const FIQName elementNameTable_3_3[] = {
- { "Shape", nullptr, nullptr },
- { "Appearance", nullptr, nullptr },
- { "Material", nullptr, nullptr },
- { "IndexedFaceSet", nullptr, nullptr },
- { "ProtoInstance", nullptr, nullptr },
- { "Transform", nullptr, nullptr },
- { "ImageTexture", nullptr, nullptr },
- { "TextureTransform", nullptr, nullptr },
- { "Coordinate", nullptr, nullptr },
- { "Normal", nullptr, nullptr },
- { "Color", nullptr, nullptr },
- { "ColorRGBA", nullptr, nullptr },
- { "TextureCoordinate", nullptr, nullptr },
- { "ROUTE", nullptr, nullptr },
- { "fieldValue", nullptr, nullptr },
- { "Group", nullptr, nullptr },
- { "LOD", nullptr, nullptr },
- { "Switch", nullptr, nullptr },
- { "Script", nullptr, nullptr },
- { "IndexedTriangleFanSet", nullptr, nullptr },
- { "IndexedTriangleSet", nullptr, nullptr },
- { "IndexedTriangleStripSet", nullptr, nullptr },
- { "MultiTexture", nullptr, nullptr },
- { "MultiTextureCoordinate", nullptr, nullptr },
- { "MultiTextureTransform", nullptr, nullptr },
- { "IndexedLineSet", nullptr, nullptr },
- { "PointSet", nullptr, nullptr },
- { "StaticGroup", nullptr, nullptr },
- { "Sphere", nullptr, nullptr },
- { "Box", nullptr, nullptr },
- { "Cone", nullptr, nullptr },
- { "Anchor", nullptr, nullptr },
- { "Arc2D", nullptr, nullptr },
- { "ArcClose2D", nullptr, nullptr },
- { "AudioClip", nullptr, nullptr },
- { "Background", nullptr, nullptr },
- { "Billboard", nullptr, nullptr },
- { "BooleanFilter", nullptr, nullptr },
- { "BooleanSequencer", nullptr, nullptr },
- { "BooleanToggle", nullptr, nullptr },
- { "BooleanTrigger", nullptr, nullptr },
- { "Circle2D", nullptr, nullptr },
- { "Collision", nullptr, nullptr },
- { "ColorInterpolator", nullptr, nullptr },
- { "Contour2D", nullptr, nullptr },
- { "ContourPolyline2D", nullptr, nullptr },
- { "CoordinateDouble", nullptr, nullptr },
- { "CoordinateInterpolator", nullptr, nullptr },
- { "CoordinateInterpolator2D", nullptr, nullptr },
- { "Cylinder", nullptr, nullptr },
- { "CylinderSensor", nullptr, nullptr },
- { "DirectionalLight", nullptr, nullptr },
- { "Disk2D", nullptr, nullptr },
- { "EXPORT", nullptr, nullptr },
- { "ElevationGrid", nullptr, nullptr },
- { "EspduTransform", nullptr, nullptr },
- { "ExternProtoDeclare", nullptr, nullptr },
- { "Extrusion", nullptr, nullptr },
- { "FillProperties", nullptr, nullptr },
- { "Fog", nullptr, nullptr },
- { "FontStyle", nullptr, nullptr },
- { "GeoCoordinate", nullptr, nullptr },
- { "GeoElevationGrid", nullptr, nullptr },
- { "GeoLOD", nullptr, nullptr },
- { "GeoLocation", nullptr, nullptr },
- { "GeoMetadata", nullptr, nullptr },
- { "GeoOrigin", nullptr, nullptr },
- { "GeoPositionInterpolator", nullptr, nullptr },
- { "GeoTouchSensor", nullptr, nullptr },
- { "GeoViewpoint", nullptr, nullptr },
- { "HAnimDisplacer", nullptr, nullptr },
- { "HAnimHumanoid", nullptr, nullptr },
- { "HAnimJoint", nullptr, nullptr },
- { "HAnimSegment", nullptr, nullptr },
- { "HAnimSite", nullptr, nullptr },
- { "IMPORT", nullptr, nullptr },
- { "IS", nullptr, nullptr },
- { "Inline", nullptr, nullptr },
- { "IntegerSequencer", nullptr, nullptr },
- { "IntegerTrigger", nullptr, nullptr },
- { "KeySensor", nullptr, nullptr },
- { "LineProperties", nullptr, nullptr },
- { "LineSet", nullptr, nullptr },
- { "LoadSensor", nullptr, nullptr },
- { "MetadataDouble", nullptr, nullptr },
- { "MetadataFloat", nullptr, nullptr },
- { "MetadataInteger", nullptr, nullptr },
- { "MetadataSet", nullptr, nullptr },
- { "MetadataString", nullptr, nullptr },
- { "MovieTexture", nullptr, nullptr },
- { "NavigationInfo", nullptr, nullptr },
- { "NormalInterpolator", nullptr, nullptr },
- { "NurbsCurve", nullptr, nullptr },
- { "NurbsCurve2D", nullptr, nullptr },
- { "NurbsOrientationInterpolator", nullptr, nullptr },
- { "NurbsPatchSurface", nullptr, nullptr },
- { "NurbsPositionInterpolator", nullptr, nullptr },
- { "NurbsSet", nullptr, nullptr },
- { "NurbsSurfaceInterpolator", nullptr, nullptr },
- { "NurbsSweptSurface", nullptr, nullptr },
- { "NurbsSwungSurface", nullptr, nullptr },
- { "NurbsTextureCoordinate", nullptr, nullptr },
- { "NurbsTrimmedSurface", nullptr, nullptr },
- { "OrientationInterpolator", nullptr, nullptr },
- { "PixelTexture", nullptr, nullptr },
- { "PlaneSensor", nullptr, nullptr },
- { "PointLight", nullptr, nullptr },
- { "Polyline2D", nullptr, nullptr },
- { "Polypoint2D", nullptr, nullptr },
- { "PositionInterpolator", nullptr, nullptr },
- { "PositionInterpolator2D", nullptr, nullptr },
- { "ProtoBody", nullptr, nullptr },
- { "ProtoDeclare", nullptr, nullptr },
- { "ProtoInterface", nullptr, nullptr },
- { "ProximitySensor", nullptr, nullptr },
- { "ReceiverPdu", nullptr, nullptr },
- { "Rectangle2D", nullptr, nullptr },
- { "ScalarInterpolator", nullptr, nullptr },
- { "Scene", nullptr, nullptr },
- { "SignalPdu", nullptr, nullptr },
- { "Sound", nullptr, nullptr },
- { "SphereSensor", nullptr, nullptr },
- { "SpotLight", nullptr, nullptr },
- { "StringSensor", nullptr, nullptr },
- { "Text", nullptr, nullptr },
- { "TextureBackground", nullptr, nullptr },
- { "TextureCoordinateGenerator", nullptr, nullptr },
- { "TimeSensor", nullptr, nullptr },
- { "TimeTrigger", nullptr, nullptr },
- { "TouchSensor", nullptr, nullptr },
- { "TransmitterPdu", nullptr, nullptr },
- { "TriangleFanSet", nullptr, nullptr },
- { "TriangleSet", nullptr, nullptr },
- { "TriangleSet2D", nullptr, nullptr },
- { "TriangleStripSet", nullptr, nullptr },
- { "Viewpoint", nullptr, nullptr },
- { "VisibilitySensor", nullptr, nullptr },
- { "WorldInfo", nullptr, nullptr },
- { "X3D", nullptr, nullptr },
- { "component", nullptr, nullptr },
- { "connect", nullptr, nullptr },
- { "field", nullptr, nullptr },
- { "head", nullptr, nullptr },
- { "humanoidBodyType", nullptr, nullptr },
- { "meta", nullptr, nullptr },
- { "CADAssembly", nullptr, nullptr },
- { "CADFace", nullptr, nullptr },
- { "CADLayer", nullptr, nullptr },
- { "CADPart", nullptr, nullptr },
- { "ComposedCubeMapTexture", nullptr, nullptr },
- { "ComposedShader", nullptr, nullptr },
- { "ComposedTexture3D", nullptr, nullptr },
- { "FloatVertexAttribute", nullptr, nullptr },
- { "FogCoordinate", nullptr, nullptr },
- { "GeneratedCubeMapTexture", nullptr, nullptr },
- { "ImageCubeMapTexture", nullptr, nullptr },
- { "ImageTexture3D", nullptr, nullptr },
- { "IndexedQuadSet", nullptr, nullptr },
- { "LocalFog", nullptr, nullptr },
- { "Matrix3VertexAttribute", nullptr, nullptr },
- { "Matrix4VertexAttribute", nullptr, nullptr },
- { "PackagedShader", nullptr, nullptr },
- { "PixelTexture3D", nullptr, nullptr },
- { "ProgramShader", nullptr, nullptr },
- { "QuadSet", nullptr, nullptr },
- { "ShaderPart", nullptr, nullptr },
- { "ShaderProgram", nullptr, nullptr },
- { "TextureCoordinate3D", nullptr, nullptr },
- { "TextureCoordinate4D", nullptr, nullptr },
- { "TextureTransform3D", nullptr, nullptr },
- { "TextureTransformMatrix3D", nullptr, nullptr },
- { "BallJoint", nullptr, nullptr },
- { "BoundedPhysicsModel", nullptr, nullptr },
- { "ClipPlane", nullptr, nullptr },
- { "CollidableOffset", nullptr, nullptr },
- { "CollidableShape", nullptr, nullptr },
- { "CollisionCollection", nullptr, nullptr },
- { "CollisionSensor", nullptr, nullptr },
- { "CollisionSpace", nullptr, nullptr },
- { "ColorDamper", nullptr, nullptr },
- { "ConeEmitter", nullptr, nullptr },
- { "Contact", nullptr, nullptr },
- { "CoordinateDamper", nullptr, nullptr },
- { "DISEntityManager", nullptr, nullptr },
- { "DISEntityTypeMapping", nullptr, nullptr },
- { "DoubleAxisHingeJoint", nullptr, nullptr },
- { "EaseInEaseOut", nullptr, nullptr },
- { "ExplosionEmitter", nullptr, nullptr },
- { "ForcePhysicsModel", nullptr, nullptr },
- { "GeoProximitySensor", nullptr, nullptr },
- { "GeoTransform", nullptr, nullptr },
- { "Layer", nullptr, nullptr },
- { "LayerSet", nullptr, nullptr },
- { "Layout", nullptr, nullptr },
- { "LayoutGroup", nullptr, nullptr },
- { "LayoutLayer", nullptr, nullptr },
- { "LinePickSensor", nullptr, nullptr },
- { "MotorJoint", nullptr, nullptr },
- { "OrientationChaser", nullptr, nullptr },
- { "OrientationDamper", nullptr, nullptr },
- { "OrthoViewpoint", nullptr, nullptr },
- { "ParticleSystem", nullptr, nullptr },
- { "PickableGroup", nullptr, nullptr },
- { "PointEmitter", nullptr, nullptr },
- { "PointPickSensor", nullptr, nullptr },
- { "PolylineEmitter", nullptr, nullptr },
- { "PositionChaser", nullptr, nullptr },
- { "PositionChaser2D", nullptr, nullptr },
- { "PositionDamper", nullptr, nullptr },
- { "PositionDamper2D", nullptr, nullptr },
- { "PrimitivePickSensor", nullptr, nullptr },
- { "RigidBody", nullptr, nullptr },
- { "RigidBodyCollection", nullptr, nullptr },
- { "ScalarChaser", nullptr, nullptr },
- { "ScreenFontStyle", nullptr, nullptr },
- { "ScreenGroup", nullptr, nullptr },
- { "SingleAxisHingeJoint", nullptr, nullptr },
- { "SliderJoint", nullptr, nullptr },
- { "SplinePositionInterpolator", nullptr, nullptr },
- { "SplinePositionInterpolator2D", nullptr, nullptr },
- { "SplineScalarInterpolator", nullptr, nullptr },
- { "SquadOrientationInterpolator", nullptr, nullptr },
- { "SurfaceEmitter", nullptr, nullptr },
- { "TexCoordDamper2D", nullptr, nullptr },
- { "TextureProperties", nullptr, nullptr },
- { "TransformSensor", nullptr, nullptr },
- { "TwoSidedMaterial", nullptr, nullptr },
- { "UniversalJoint", nullptr, nullptr },
- { "ViewpointGroup", nullptr, nullptr },
- { "Viewport", nullptr, nullptr },
- { "VolumeEmitter", nullptr, nullptr },
- { "VolumePickSensor", nullptr, nullptr },
- { "WindPhysicsModel", nullptr, nullptr },
- { "BlendedVolumeStyle", nullptr, nullptr },
- { "BoundaryEnhancementVolumeStyle", nullptr, nullptr },
- { "CartoonVolumeStyle", nullptr, nullptr },
- { "ComposedVolumeStyle", nullptr, nullptr },
- { "EdgeEnhancementVolumeStyle", nullptr, nullptr },
- { "IsoSurfaceVolumeData", nullptr, nullptr },
- { "MetadataBoolean", nullptr, nullptr },
- { "OpacityMapVolumeStyle", nullptr, nullptr },
- { "ProjectionVolumeStyle", nullptr, nullptr },
- { "SegmentedVolumeData", nullptr, nullptr },
- { "ShadedVolumeStyle", nullptr, nullptr },
- { "SilhouetteEnhancementVolumeStyle", nullptr, nullptr },
- { "ToneMappedVolumeStyle", nullptr, nullptr },
- { "VolumeData", nullptr, nullptr },
- { "ColorChaser", nullptr, nullptr },
- { "CoordinateChaser", nullptr, nullptr },
- { "ScalarDamper", nullptr, nullptr },
- { "TexCoordChaser2D", nullptr, nullptr },
- { "unit", nullptr, nullptr }
-};
-
-static const FIQName attributeNameTable_3_3[] = {
- { "DEF", nullptr, nullptr },
- { "USE", nullptr, nullptr },
- { "containerField", nullptr, nullptr },
- { "fromNode", nullptr, nullptr },
- { "fromField", nullptr, nullptr },
- { "toNode", nullptr, nullptr },
- { "toField", nullptr, nullptr },
- { "name", nullptr, nullptr },
- { "value", nullptr, nullptr },
- { "color", nullptr, nullptr },
- { "colorIndex", nullptr, nullptr },
- { "coordIndex", nullptr, nullptr },
- { "texCoordIndex", nullptr, nullptr },
- { "normalIndex", nullptr, nullptr },
- { "colorPerVertex", nullptr, nullptr },
- { "normalPerVertex", nullptr, nullptr },
- { "rotation", nullptr, nullptr },
- { "scale", nullptr, nullptr },
- { "center", nullptr, nullptr },
- { "scaleOrientation", nullptr, nullptr },
- { "translation", nullptr, nullptr },
- { "url", nullptr, nullptr },
- { "repeatS", nullptr, nullptr },
- { "repeatT", nullptr, nullptr },
- { "point", nullptr, nullptr },
- { "vector", nullptr, nullptr },
- { "range", nullptr, nullptr },
- { "ambientIntensity", nullptr, nullptr },
- { "diffuseColor", nullptr, nullptr },
- { "emissiveColor", nullptr, nullptr },
- { "shininess", nullptr, nullptr },
- { "specularColor", nullptr, nullptr },
- { "transparency", nullptr, nullptr },
- { "whichChoice", nullptr, nullptr },
- { "index", nullptr, nullptr },
- { "mode", nullptr, nullptr },
- { "source", nullptr, nullptr },
- { "function", nullptr, nullptr },
- { "alpha", nullptr, nullptr },
- { "vertexCount", nullptr, nullptr },
- { "radius", nullptr, nullptr },
- { "size", nullptr, nullptr },
- { "height", nullptr, nullptr },
- { "solid", nullptr, nullptr },
- { "ccw", nullptr, nullptr },
- { "key", nullptr, nullptr },
- { "keyValue", nullptr, nullptr },
- { "enabled", nullptr, nullptr },
- { "direction", nullptr, nullptr },
- { "position", nullptr, nullptr },
- { "orientation", nullptr, nullptr },
- { "bboxCenter", nullptr, nullptr },
- { "bboxSize", nullptr, nullptr },
- { "AS", nullptr, nullptr },
- { "InlineDEF", nullptr, nullptr },
- { "accessType", nullptr, nullptr },
- { "actionKeyPress", nullptr, nullptr },
- { "actionKeyRelease", nullptr, nullptr },
- { "address", nullptr, nullptr },
- { "altKey", nullptr, nullptr },
- { "antennaLocation", nullptr, nullptr },
- { "antennaPatternLength", nullptr, nullptr },
- { "antennaPatternType", nullptr, nullptr },
- { "applicationID", nullptr, nullptr },
- { "articulationParameterArray", nullptr, nullptr },
- { "articulationParameterChangeIndicatorArray", nullptr, nullptr },
- { "articulationParameterCount", nullptr, nullptr },
- { "articulationParameterDesignatorArray", nullptr, nullptr },
- { "articulationParameterIdPartAttachedArray", nullptr, nullptr },
- { "articulationParameterTypeArray", nullptr, nullptr },
- { "attenuation", nullptr, nullptr },
- { "autoOffset", nullptr, nullptr },
- { "avatarSize", nullptr, nullptr },
- { "axisOfRotation", nullptr, nullptr },
- { "backUrl", nullptr, nullptr },
- { "beamWidth", nullptr, nullptr },
- { "beginCap", nullptr, nullptr },
- { "bindTime", nullptr, nullptr },
- { "bottom", nullptr, nullptr },
- { "bottomRadius", nullptr, nullptr },
- { "bottomUrl", nullptr, nullptr },
- { "centerOfMass", nullptr, nullptr },
- { "centerOfRotation", nullptr, nullptr },
- { "child1Url", nullptr, nullptr },
- { "child2Url", nullptr, nullptr },
- { "child3Url", nullptr, nullptr },
- { "child4Url", nullptr, nullptr },
- { "class", nullptr, nullptr },
- { "closureType", nullptr, nullptr },
- { "collideTime", nullptr, nullptr },
- { "content", nullptr, nullptr },
- { "controlKey", nullptr, nullptr },
- { "controlPoint", nullptr, nullptr },
- { "convex", nullptr, nullptr },
- { "coordinateSystem", nullptr, nullptr },
- { "copyright", nullptr, nullptr },
- { "creaseAngle", nullptr, nullptr },
- { "crossSection", nullptr, nullptr },
- { "cryptoKeyID", nullptr, nullptr },
- { "cryptoSystem", nullptr, nullptr },
- { "cutOffAngle", nullptr, nullptr },
- { "cycleInterval", nullptr, nullptr },
- { "cycleTime", nullptr, nullptr },
- { "data", nullptr, nullptr },
- { "dataFormat", nullptr, nullptr },
- { "dataLength", nullptr, nullptr },
- { "dataUrl", nullptr, nullptr },
- { "date", nullptr, nullptr },
- { "deadReckoning", nullptr, nullptr },
- { "deletionAllowed", nullptr, nullptr },
- { "description", nullptr, nullptr },
- { "detonateTime", nullptr, nullptr },
- { "dir", nullptr, nullptr },
- { "directOutput", nullptr, nullptr },
- { "diskAngle", nullptr, nullptr },
- { "displacements", nullptr, nullptr },
- { "documentation", nullptr, nullptr },
- { "elapsedTime", nullptr, nullptr },
- { "ellipsoid", nullptr, nullptr },
- { "encodingScheme", nullptr, nullptr },
- { "endAngle", nullptr, nullptr },
- { "endCap", nullptr, nullptr },
- { "enterTime", nullptr, nullptr },
- { "enteredText", nullptr, nullptr },
- { "entityCategory", nullptr, nullptr },
- { "entityCountry", nullptr, nullptr },
- { "entityDomain", nullptr, nullptr },
- { "entityExtra", nullptr, nullptr },
- { "entityID", nullptr, nullptr },
- { "entityKind", nullptr, nullptr },
- { "entitySpecific", nullptr, nullptr },
- { "entitySubCategory", nullptr, nullptr },
- { "exitTime", nullptr, nullptr },
- { "extent", nullptr, nullptr },
- { "family", nullptr, nullptr },
- { "fanCount", nullptr, nullptr },
- { "fieldOfView", nullptr, nullptr },
- { "filled", nullptr, nullptr },
- { "finalText", nullptr, nullptr },
- { "fireMissionIndex", nullptr, nullptr },
- { "fired1", nullptr, nullptr },
- { "fired2", nullptr, nullptr },
- { "firedTime", nullptr, nullptr },
- { "firingRange", nullptr, nullptr },
- { "firingRate", nullptr, nullptr },
- { "fogType", nullptr, nullptr },
- { "forceID", nullptr, nullptr },
- { "frequency", nullptr, nullptr },
- { "frontUrl", nullptr, nullptr },
- { "fuse", nullptr, nullptr },
- { "geoCoords", nullptr, nullptr },
- { "geoGridOrigin", nullptr, nullptr },
- { "geoSystem", nullptr, nullptr },
- { "groundAngle", nullptr, nullptr },
- { "groundColor", nullptr, nullptr },
- { "hatchColor", nullptr, nullptr },
- { "hatchStyle", nullptr, nullptr },
- { "hatched", nullptr, nullptr },
- { "headlight", nullptr, nullptr },
- { "horizontal", nullptr, nullptr },
- { "horizontalDatum", nullptr, nullptr },
- { "http-equiv", nullptr, nullptr },
- { "image", nullptr, nullptr },
- { "importedDEF", nullptr, nullptr },
- { "info", nullptr, nullptr },
- { "innerRadius", nullptr, nullptr },
- { "inputFalse", nullptr, nullptr },
- { "inputNegate", nullptr, nullptr },
- { "inputSource", nullptr, nullptr },
- { "inputTrue", nullptr, nullptr },
- { "integerKey", nullptr, nullptr },
- { "intensity", nullptr, nullptr },
- { "jump", nullptr, nullptr },
- { "justify", nullptr, nullptr },
- { "keyPress", nullptr, nullptr },
- { "keyRelease", nullptr, nullptr },
- { "knot", nullptr, nullptr },
- { "lang", nullptr, nullptr },
- { "language", nullptr, nullptr },
- { "leftToRight", nullptr, nullptr },
- { "leftUrl", nullptr, nullptr },
- { "length", nullptr, nullptr },
- { "lengthOfModulationParameters", nullptr, nullptr },
- { "level", nullptr, nullptr },
- { "limitOrientation", nullptr, nullptr },
- { "lineSegments", nullptr, nullptr },
- { "linearAcceleration", nullptr, nullptr },
- { "linearVelocity", nullptr, nullptr },
- { "linetype", nullptr, nullptr },
- { "linewidthScaleFactor", nullptr, nullptr },
- { "llimit", nullptr, nullptr },
- { "load", nullptr, nullptr },
- { "loadTime", nullptr, nullptr },
- { "localDEF", nullptr, nullptr },
- { "location", nullptr, nullptr },
- { "loop", nullptr, nullptr },
- { "marking", nullptr, nullptr },
- { "mass", nullptr, nullptr },
- { "maxAngle", nullptr, nullptr },
- { "maxBack", nullptr, nullptr },
- { "maxExtent", nullptr, nullptr },
- { "maxFront", nullptr, nullptr },
- { "maxPosition", nullptr, nullptr },
- { "metadataFormat", nullptr, nullptr },
- { "minAngle", nullptr, nullptr },
- { "minBack", nullptr, nullptr },
- { "minFront", nullptr, nullptr },
- { "minPosition", nullptr, nullptr },
- { "modulationTypeDetail", nullptr, nullptr },
- { "modulationTypeMajor", nullptr, nullptr },
- { "modulationTypeSpreadSpectrum", nullptr, nullptr },
- { "modulationTypeSystem", nullptr, nullptr },
- { "momentsOfInertia", nullptr, nullptr },
- { "multicastRelayHost", nullptr, nullptr },
- { "multicastRelayPort", nullptr, nullptr },
- { "munitionApplicationID", nullptr, nullptr },
- { "munitionEndPoint", nullptr, nullptr },
- { "munitionEntityID", nullptr, nullptr },
- { "munitionQuantity", nullptr, nullptr },
- { "munitionSiteID", nullptr, nullptr },
- { "munitionStartPoint", nullptr, nullptr },
- { "mustEvaluate", nullptr, nullptr },
- { "navType", nullptr, nullptr },
- { "networkMode", nullptr, nullptr },
- { "next", nullptr, nullptr },
- { "nodeField", nullptr, nullptr },
- { "offset", nullptr, nullptr },
- { "on", nullptr, nullptr },
- { "order", nullptr, nullptr },
- { "originator", nullptr, nullptr },
- { "outerRadius", nullptr, nullptr },
- { "parameter", nullptr, nullptr },
- { "pauseTime", nullptr, nullptr },
- { "pitch", nullptr, nullptr },
- { "points", nullptr, nullptr },
- { "port", nullptr, nullptr },
- { "power", nullptr, nullptr },
- { "previous", nullptr, nullptr },
- { "priority", nullptr, nullptr },
- { "profile", nullptr, nullptr },
- { "progress", nullptr, nullptr },
- { "protoField", nullptr, nullptr },
- { "radioEntityTypeCategory", nullptr, nullptr },
- { "radioEntityTypeCountry", nullptr, nullptr },
- { "radioEntityTypeDomain", nullptr, nullptr },
- { "radioEntityTypeKind", nullptr, nullptr },
- { "radioEntityTypeNomenclature", nullptr, nullptr },
- { "radioEntityTypeNomenclatureVersion", nullptr, nullptr },
- { "radioID", nullptr, nullptr },
- { "readInterval", nullptr, nullptr },
- { "receivedPower", nullptr, nullptr },
- { "receiverState", nullptr, nullptr },
- { "reference", nullptr, nullptr },
- { "relativeAntennaLocation", nullptr, nullptr },
- { "resolution", nullptr, nullptr },
- { "resumeTime", nullptr, nullptr },
- { "rightUrl", nullptr, nullptr },
- { "rootUrl", nullptr, nullptr },
- { "rotateYUp", nullptr, nullptr },
- { "rtpHeaderExpected", nullptr, nullptr },
- { "sampleRate", nullptr, nullptr },
- { "samples", nullptr, nullptr },
- { "shiftKey", nullptr, nullptr },
- { "side", nullptr, nullptr },
- { "siteID", nullptr, nullptr },
- { "skinCoordIndex", nullptr, nullptr },
- { "skinCoordWeight", nullptr, nullptr },
- { "skyAngle", nullptr, nullptr },
- { "skyColor", nullptr, nullptr },
- { "spacing", nullptr, nullptr },
- { "spatialize", nullptr, nullptr },
- { "speed", nullptr, nullptr },
- { "speedFactor", nullptr, nullptr },
- { "spine", nullptr, nullptr },
- { "startAngle", nullptr, nullptr },
- { "startTime", nullptr, nullptr },
- { "stiffness", nullptr, nullptr },
- { "stopTime", nullptr, nullptr },
- { "string", nullptr, nullptr },
- { "stripCount", nullptr, nullptr },
- { "style", nullptr, nullptr },
- { "summary", nullptr, nullptr },
- { "tdlType", nullptr, nullptr },
- { "tessellation", nullptr, nullptr },
- { "tessellationScale", nullptr, nullptr },
- { "time", nullptr, nullptr },
- { "timeOut", nullptr, nullptr },
- { "timestamp", nullptr, nullptr },
- { "title", nullptr, nullptr },
- { "toggle", nullptr, nullptr },
- { "top", nullptr, nullptr },
- { "topToBottom", nullptr, nullptr },
- { "topUrl", nullptr, nullptr },
- { "touchTime", nullptr, nullptr },
- { "transmitFrequencyBandwidth", nullptr, nullptr },
- { "transmitState", nullptr, nullptr },
- { "transmitterApplicationID", nullptr, nullptr },
- { "transmitterEntityID", nullptr, nullptr },
- { "transmitterRadioID", nullptr, nullptr },
- { "transmitterSiteID", nullptr, nullptr },
- { "transparent", nullptr, nullptr },
- { "triggerTime", nullptr, nullptr },
- { "triggerTrue", nullptr, nullptr },
- { "triggerValue", nullptr, nullptr },
- { "type", nullptr, nullptr },
- { "uDimension", nullptr, nullptr },
- { "uKnot", nullptr, nullptr },
- { "uOrder", nullptr, nullptr },
- { "uTessellation", nullptr, nullptr },
- { "ulimit", nullptr, nullptr },
- { "vDimension", nullptr, nullptr },
- { "vKnot", nullptr, nullptr },
- { "vOrder", nullptr, nullptr },
- { "vTessellation", nullptr, nullptr },
- { "version", nullptr, nullptr },
- { "verticalDatum", nullptr, nullptr },
- { "vertices", nullptr, nullptr },
- { "visibilityLimit", nullptr, nullptr },
- { "visibilityRange", nullptr, nullptr },
- { "warhead", nullptr, nullptr },
- { "weight", nullptr, nullptr },
- { "whichGeometry", nullptr, nullptr },
- { "writeInterval", nullptr, nullptr },
- { "xDimension", nullptr, nullptr },
- { "xSpacing", nullptr, nullptr },
- { "yScale", nullptr, nullptr },
- { "zDimension", nullptr, nullptr },
- { "zSpacing", nullptr, nullptr },
- { "visible", nullptr, nullptr },
- { "repeatR", nullptr, nullptr },
- { "texture", nullptr, nullptr },
- { "back", nullptr, nullptr },
- { "front", nullptr, nullptr },
- { "left", nullptr, nullptr },
- { "right", nullptr, nullptr },
- { "parts", nullptr, nullptr },
- { "isSelected", nullptr, nullptr },
- { "isValid", nullptr, nullptr },
- { "numComponents", nullptr, nullptr },
- { "depth", nullptr, nullptr },
- { "update", nullptr, nullptr },
- { "fogCoord", nullptr, nullptr },
- { "texCoord", nullptr, nullptr },
- { "activate", nullptr, nullptr },
- { "programs", nullptr, nullptr },
- { "matrix", nullptr, nullptr },
- { "anchorPoint", nullptr, nullptr },
- { "body1", nullptr, nullptr },
- { "body2", nullptr, nullptr },
- { "forceOutput", nullptr, nullptr },
- { "body1AnchorPoint", nullptr, nullptr },
- { "body2AnchorPoint", nullptr, nullptr },
- { "plane", nullptr, nullptr },
- { "appliedParameters", nullptr, nullptr },
- { "bounce", nullptr, nullptr },
- { "frictionCoefficients", nullptr, nullptr },
- { "minBounceSpeed", nullptr, nullptr },
- { "slipFactors", nullptr, nullptr },
- { "softnessConstantForceMix", nullptr, nullptr },
- { "softnessErrorCorrection", nullptr, nullptr },
- { "surfaceSpeed", nullptr, nullptr },
- { "isActive", nullptr, nullptr },
- { "useGeometry", nullptr, nullptr },
- { "set_destination", nullptr, nullptr },
- { "set_value", nullptr, nullptr },
- { "tau", nullptr, nullptr },
- { "tolerance", nullptr, nullptr },
- { "value_changed", nullptr, nullptr },
- { "initialDestination", nullptr, nullptr },
- { "initialValue", nullptr, nullptr },
- { "angle", nullptr, nullptr },
- { "variation", nullptr, nullptr },
- { "surfaceArea", nullptr, nullptr },
- { "frictionDirection", nullptr, nullptr },
- { "slipCoefficients", nullptr, nullptr },
- { "category", nullptr, nullptr },
- { "country", nullptr, nullptr },
- { "domain", nullptr, nullptr },
- { "extra", nullptr, nullptr },
- { "kind", nullptr, nullptr },
- { "specific", nullptr, nullptr },
- { "subcategory", nullptr, nullptr },
- { "axis1", nullptr, nullptr },
- { "axis2", nullptr, nullptr },
- { "desiredAngularVelocity1", nullptr, nullptr },
- { "desiredAngularVelocity2", nullptr, nullptr },
- { "maxAngle1", nullptr, nullptr },
- { "maxTorque1", nullptr, nullptr },
- { "maxTorque2", nullptr, nullptr },
- { "minAngle1", nullptr, nullptr },
- { "stopBounce1", nullptr, nullptr },
- { "stopConstantForceMix1", nullptr, nullptr },
- { "stopErrorCorrection1", nullptr, nullptr },
- { "suspensionErrorCorrection", nullptr, nullptr },
- { "suspensionForce", nullptr, nullptr },
- { "body1Axis", nullptr, nullptr },
- { "body2Axis", nullptr, nullptr },
- { "hinge1Angle", nullptr, nullptr },
- { "hinge1AngleRate", nullptr, nullptr },
- { "hinge2Angle", nullptr, nullptr },
- { "hinge2AngleRate", nullptr, nullptr },
- { "set_fraction", nullptr, nullptr },
- { "easeInEaseOut", nullptr, nullptr },
- { "modifiedFraction_changed", nullptr, nullptr },
- { "force", nullptr, nullptr },
- { "geoCenter", nullptr, nullptr },
- { "centerOfRotation_changed", nullptr, nullptr },
- { "geoCoord_changed", nullptr, nullptr },
- { "orientation_changed", nullptr, nullptr },
- { "position_changed", nullptr, nullptr },
- { "isPickable", nullptr, nullptr },
- { "viewport", nullptr, nullptr },
- { "activeLayer", nullptr, nullptr },
- { "align", nullptr, nullptr },
- { "offsetUnits", nullptr, nullptr },
- { "scaleMode", nullptr, nullptr },
- { "sizeUnits", nullptr, nullptr },
- { "layout", nullptr, nullptr },
- { "objectType", nullptr, nullptr },
- { "pickedNormal", nullptr, nullptr },
- { "pickedPoint", nullptr, nullptr },
- { "pickedTextureCoordinate", nullptr, nullptr },
- { "intersectionType", nullptr, nullptr },
- { "sortOrder", nullptr, nullptr },
- { "axis1Angle", nullptr, nullptr },
- { "axis1Torque", nullptr, nullptr },
- { "axis2Angle", nullptr, nullptr },
- { "axis2Torque", nullptr, nullptr },
- { "axis3Angle", nullptr, nullptr },
- { "axis3Torque", nullptr, nullptr },
- { "enabledAxies", nullptr, nullptr },
- { "motor1Axis", nullptr, nullptr },
- { "motor2Axis", nullptr, nullptr },
- { "motor3Axis", nullptr, nullptr },
- { "stop1Bounce", nullptr, nullptr },
- { "stop1ErrorCorrection", nullptr, nullptr },
- { "stop2Bounce", nullptr, nullptr },
- { "stop2ErrorCorrection", nullptr, nullptr },
- { "stop3Bounce", nullptr, nullptr },
- { "stop3ErrorCorrection", nullptr, nullptr },
- { "motor1Angle", nullptr, nullptr },
- { "motor1AngleRate", nullptr, nullptr },
- { "motor2Angle", nullptr, nullptr },
- { "motor2AngleRate", nullptr, nullptr },
- { "motor3Angle", nullptr, nullptr },
- { "motor3AngleRate", nullptr, nullptr },
- { "autoCalc", nullptr, nullptr },
- { "duration", nullptr, nullptr },
- { "retainUserOffsets", nullptr, nullptr },
- { "isBound", nullptr, nullptr },
- { "appearance", nullptr, nullptr },
- { "createParticles", nullptr, nullptr },
- { "lifetimeVariation", nullptr, nullptr },
- { "maxParticles", nullptr, nullptr },
- { "particleLifetime", nullptr, nullptr },
- { "particleSize", nullptr, nullptr },
- { "colorKey", nullptr, nullptr },
- { "geometryType", nullptr, nullptr },
- { "texCoordKey", nullptr, nullptr },
- { "pickable", nullptr, nullptr },
- { "angularDampingFactor", nullptr, nullptr },
- { "angularVelocity", nullptr, nullptr },
- { "autoDamp", nullptr, nullptr },
- { "autoDisable", nullptr, nullptr },
- { "disableAngularSpeed", nullptr, nullptr },
- { "disableLinearSpeed", nullptr, nullptr },
- { "disableTime", nullptr, nullptr },
- { "finiteRotationAxis", nullptr, nullptr },
- { "fixed", nullptr, nullptr },
- { "forces", nullptr, nullptr },
- { "inertia", nullptr, nullptr },
- { "linearDampingFactor", nullptr, nullptr },
- { "torques", nullptr, nullptr },
- { "useFiniteRotation", nullptr, nullptr },
- { "useGlobalForce", nullptr, nullptr },
- { "constantForceMix", nullptr, nullptr },
- { "constantSurfaceThickness", nullptr, nullptr },
- { "errorCorrection", nullptr, nullptr },
- { "iterations", nullptr, nullptr },
- { "maxCorrectionSpeed", nullptr, nullptr },
- { "preferAccuracy", nullptr, nullptr },
- { "pointSize", nullptr, nullptr },
- { "stopBounce", nullptr, nullptr },
- { "stopErrorCorrection", nullptr, nullptr },
- { "angleRate", nullptr, nullptr },
- { "maxSeparation", nullptr, nullptr },
- { "minSeparation", nullptr, nullptr },
- { "separation", nullptr, nullptr },
- { "separationRate", nullptr, nullptr },
- { "closed", nullptr, nullptr },
- { "keyVelocity", nullptr, nullptr },
- { "normalizeVelocity", nullptr, nullptr },
- { "surface", nullptr, nullptr },
- { "anisotropicDegree", nullptr, nullptr },
- { "borderColor", nullptr, nullptr },
- { "borderWidth", nullptr, nullptr },
- { "boundaryModeS", nullptr, nullptr },
- { "boundaryModeT", nullptr, nullptr },
- { "boundaryModeR", nullptr, nullptr },
- { "magnificationFilter", nullptr, nullptr },
- { "minificationFilter", nullptr, nullptr },
- { "textureCompression", nullptr, nullptr },
- { "texturePriority", nullptr, nullptr },
- { "generateMipMaps", nullptr, nullptr },
- { "targetObject", nullptr, nullptr },
- { "backAmbientIntensity", nullptr, nullptr },
- { "backDiffuseColor", nullptr, nullptr },
- { "backEmissiveColor", nullptr, nullptr },
- { "backShininess", nullptr, nullptr },
- { "backSpecularColor", nullptr, nullptr },
- { "separateBackColor", nullptr, nullptr },
- { "displayed", nullptr, nullptr },
- { "clipBoundary", nullptr, nullptr },
- { "internal", nullptr, nullptr },
- { "gustiness", nullptr, nullptr },
- { "turbulence", nullptr, nullptr },
- { "unitCategory", nullptr, nullptr },
- { "unitName", nullptr, nullptr },
- { "unitConversionFactor", nullptr, nullptr },
- { "weightConstant1", nullptr, nullptr },
- { "weightConstant2", nullptr, nullptr },
- { "weightFunction1", nullptr, nullptr },
- { "weightFunction2", nullptr, nullptr },
- { "boundaryOpacity", nullptr, nullptr },
- { "opacityFactor", nullptr, nullptr },
- { "retainedOpacity", nullptr, nullptr },
- { "colorSteps", nullptr, nullptr },
- { "orthogonalColor", nullptr, nullptr },
- { "parallelColor", nullptr, nullptr },
- { "ordered", nullptr, nullptr },
- { "edgeColor", nullptr, nullptr },
- { "gradientThreshold", nullptr, nullptr },
- { "contourStepSize", nullptr, nullptr },
- { "dimensions", nullptr, nullptr },
- { "surfaceTolerance", nullptr, nullptr },
- { "surfaceValues", nullptr, nullptr },
- { "intensityThreshold", nullptr, nullptr },
- { "segmentEnabled", nullptr, nullptr },
- { "lighting", nullptr, nullptr },
- { "shadows", nullptr, nullptr },
- { "phaseFunction", nullptr, nullptr },
- { "silhouetteBoundaryOpacity", nullptr, nullptr },
- { "silhouetteRetainedOpacity", nullptr, nullptr },
- { "silhouetteSharpness", nullptr, nullptr },
- { "coolColor", nullptr, nullptr },
- { "warmColor", nullptr, nullptr }
-};
-
-FIVocabulary X3D_vocabulary_3_3 = {
- nullptr, 0,
- encodingAlgorithmTable_3_3, 8,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- nullptr, 0,
- attributeValueTable_3_3, 2,
- nullptr, 0,
- nullptr, 0,
- elementNameTable_3_3, 252,
- attributeNameTable_3_3, 546
-};
-
-}// namespace Assimp
-
-#endif // !ASSIMP_BUILD_NO_X3D_IMPORTER
diff --git a/src/3rdparty/assimp/code/XFileExporter.cpp b/src/3rdparty/assimp/code/XFileExporter.cpp
deleted file mode 100644
index 6407bf738..000000000
--- a/src/3rdparty/assimp/code/XFileExporter.cpp
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-@author: Richard Steffen, 2014
-----------------------------------------------------------------------
-*/
-
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_X_EXPORTER
-
-#include "XFileExporter.h"
-#include "ConvertToLHProcess.h"
-#include "Bitmap.h"
-#include "BaseImporter.h"
-#include "fast_atof.h"
-#include <assimp/SceneCombiner.h>
-#include <assimp/DefaultIOSystem.h>
-#include <ctime>
-#include <set>
-#include <memory>
-#include "Exceptional.h"
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/light.h>
-
-using namespace Assimp;
-
-namespace Assimp
-{
-
-// ------------------------------------------------------------------------------------------------
-// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
-void ExportSceneXFile(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
-{
- std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
- std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
-
- // create/copy Properties
- ExportProperties props(*pProperties);
-
- // set standard properties if not set
- if (!props.HasPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT)) props.SetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT, false);
-
- // invoke the exporter
- XFileExporter iDoTheExportThing( pScene, pIOSystem, path, file, &props);
-
- if (iDoTheExportThing.mOutput.fail()) {
- throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
- }
-
- // we're still here - export successfully completed. Write result to the given IOSYstem
- std::unique_ptr<IOStream> outfile (pIOSystem->Open(pFile,"wt"));
- if(outfile == NULL) {
- throw DeadlyExportError("could not open output .x 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);
-}
-
-} // end of namespace Assimp
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor for a specific scene to export
-XFileExporter::XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties)
- : mProperties(pProperties),
- mIOSystem(pIOSystem),
- mPath(path),
- mFile(file),
- mScene(pScene),
- mSceneOwned(false),
- endstr("\n")
-{
- // make sure that all formatting happens using the standard, C locale and not the user's current locale
- mOutput.imbue( std::locale("C") );
- mOutput.precision(16);
-
- // start writing
- WriteFile();
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor
-XFileExporter::~XFileExporter()
-{
- if(mSceneOwned) {
- delete mScene;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Starts writing the contents
-void XFileExporter::WriteFile()
-{
- // note, that all realnumber values must be comma separated in x files
- mOutput.setf(std::ios::fixed);
- mOutput.precision(16); // precission for double
-
- // entry of writing the file
- WriteHeader();
-
- mOutput << startstr << "Frame DXCC_ROOT {" << endstr;
- PushTag();
-
- aiMatrix4x4 I; // identity
- WriteFrameTransform(I);
-
- WriteNode(mScene->mRootNode);
- PopTag();
-
- mOutput << startstr << "}" << endstr;
-
-}
-
-// ------------------------------------------------------------------------------------------------
-// Writes the asset header
-void XFileExporter::WriteHeader()
-{
- if (mProperties->GetPropertyBool(AI_CONFIG_EXPORT_XFILE_64BIT) == true)
- mOutput << startstr << "xof 0303txt 0064" << endstr;
- else
- mOutput << startstr << "xof 0303txt 0032" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template Frame {" << endstr;
- PushTag();
- mOutput << startstr << "<3d82ab46-62da-11cf-ab39-0020af71e433>" << endstr;
- mOutput << startstr << "[...]" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template Matrix4x4 {" << endstr;
- PushTag();
- mOutput << startstr << "<f6f23f45-7686-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "array FLOAT matrix[16];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template FrameTransformMatrix {" << endstr;
- PushTag();
- mOutput << startstr << "<f6f23f41-7686-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "Matrix4x4 frameMatrix;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template Vector {" << endstr;
- PushTag();
- mOutput << startstr << "<3d82ab5e-62da-11cf-ab39-0020af71e433>" << endstr;
- mOutput << startstr << "FLOAT x;" << endstr;
- mOutput << startstr << "FLOAT y;" << endstr;
- mOutput << startstr << "FLOAT z;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template MeshFace {" << endstr;
- PushTag();
- mOutput << startstr << "<3d82ab5f-62da-11cf-ab39-0020af71e433>" << endstr;
- mOutput << startstr << "DWORD nFaceVertexIndices;" << endstr;
- mOutput << startstr << "array DWORD faceVertexIndices[nFaceVertexIndices];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template Mesh {" << endstr;
- PushTag();
- mOutput << startstr << "<3d82ab44-62da-11cf-ab39-0020af71e433>" << endstr;
- mOutput << startstr << "DWORD nVertices;" << endstr;
- mOutput << startstr << "array Vector vertices[nVertices];" << endstr;
- mOutput << startstr << "DWORD nFaces;" << endstr;
- mOutput << startstr << "array MeshFace faces[nFaces];" << endstr;
- mOutput << startstr << "[...]" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template MeshNormals {" << endstr;
- PushTag();
- mOutput << startstr << "<f6f23f43-7686-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "DWORD nNormals;" << endstr;
- mOutput << startstr << "array Vector normals[nNormals];" << endstr;
- mOutput << startstr << "DWORD nFaceNormals;" << endstr;
- mOutput << startstr << "array MeshFace faceNormals[nFaceNormals];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template Coords2d {" << endstr;
- PushTag();
- mOutput << startstr << "<f6f23f44-7686-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "FLOAT u;" << endstr;
- mOutput << startstr << "FLOAT v;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template MeshTextureCoords {" << endstr;
- PushTag();
- mOutput << startstr << "<f6f23f40-7686-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "DWORD nTextureCoords;" << endstr;
- mOutput << startstr << "array Coords2d textureCoords[nTextureCoords];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template ColorRGBA {" << endstr;
- PushTag();
- mOutput << startstr << "<35ff44e0-6c7c-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "FLOAT red;" << endstr;
- mOutput << startstr << "FLOAT green;" << endstr;
- mOutput << startstr << "FLOAT blue;" << endstr;
- mOutput << startstr << "FLOAT alpha;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template IndexedColor {" << endstr;
- PushTag();
- mOutput << startstr << "<1630b820-7842-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "DWORD index;" << endstr;
- mOutput << startstr << "ColorRGBA indexColor;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template MeshVertexColors {" << endstr;
- PushTag();
- mOutput << startstr << "<1630b821-7842-11cf-8f52-0040333594a3>" << endstr;
- mOutput << startstr << "DWORD nVertexColors;" << endstr;
- mOutput << startstr << "array IndexedColor vertexColors[nVertexColors];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template VertexElement {" << endstr;
- PushTag();
- mOutput << startstr << "<f752461c-1e23-48f6-b9f8-8350850f336f>" << endstr;
- mOutput << startstr << "DWORD Type;" << endstr;
- mOutput << startstr << "DWORD Method;" << endstr;
- mOutput << startstr << "DWORD Usage;" << endstr;
- mOutput << startstr << "DWORD UsageIndex;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
- mOutput << startstr << "template DeclData {" << endstr;
- PushTag();
- mOutput << startstr << "<bf22e553-292c-4781-9fea-62bd554bdd93>" << endstr;
- mOutput << startstr << "DWORD nElements;" << endstr;
- mOutput << startstr << "array VertexElement Elements[nElements];" << endstr;
- mOutput << startstr << "DWORD nDWords;" << endstr;
- mOutput << startstr << "array DWORD data[nDWords];" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- mOutput << endstr;
-}
-
-
-// Writes the material setup
-void XFileExporter::WriteFrameTransform(aiMatrix4x4& m)
-{
- mOutput << startstr << "FrameTransformMatrix {" << endstr << " ";
- PushTag();
- mOutput << startstr << m.a1 << ", " << m.b1 << ", " << m.c1 << ", " << m.d1 << "," << endstr;
- mOutput << startstr << m.a2 << ", " << m.b2 << ", " << m.c2 << ", " << m.d2 << "," << endstr;
- mOutput << startstr << m.a3 << ", " << m.b3 << ", " << m.c3 << ", " << m.d3 << "," << endstr;
- mOutput << startstr << m.a4 << ", " << m.b4 << ", " << m.c4 << ", " << m.d4 << ";;" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr << endstr;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Recursively writes the given node
-void XFileExporter::WriteNode( aiNode* pNode)
-{
- if (pNode->mName.length==0)
- {
- std::stringstream ss;
- ss << "Node_" << pNode;
- pNode->mName.Set(ss.str());
- }
- mOutput << startstr << "Frame " << toXFileString(pNode->mName) << " {" << endstr;
-
- PushTag();
-
- aiMatrix4x4 m = pNode->mTransformation;
-
- WriteFrameTransform(m);
-
- for (size_t i = 0; i < pNode->mNumMeshes; ++i)
- WriteMesh(mScene->mMeshes[pNode->mMeshes[i]]);
-
- // recursive call the Nodes
- for (size_t i = 0; i < pNode->mNumChildren; ++i)
- WriteNode(pNode->mChildren[i]);
-
- PopTag();
-
- mOutput << startstr << "}" << endstr << endstr;
-}
-
-void XFileExporter::WriteMesh(aiMesh* mesh)
-{
- mOutput << startstr << "Mesh " << toXFileString(mesh->mName) << "_mShape" << " {" << endstr;
-
- PushTag();
-
- // write all the vertices
- mOutput << startstr << mesh->mNumVertices << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumVertices; a++)
- {
- aiVector3D &v = mesh->mVertices[a];
- mOutput << startstr << v[0] << ";"<< v[1] << ";" << v[2] << ";";
- if (a < mesh->mNumVertices - 1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
-
- // write all the faces
- mOutput << startstr << mesh->mNumFaces << ";" << endstr;
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- const aiFace& face = mesh->mFaces[a];
- mOutput << startstr << face.mNumIndices << ";";
- // must be counter clockwise triangle
- //for(int b = face.mNumIndices - 1; b >= 0 ; --b)
- for(size_t b = 0; b < face.mNumIndices ; ++b)
- {
- mOutput << face.mIndices[b];
- //if (b > 0)
- if (b<face.mNumIndices-1)
- mOutput << ",";
- else
- mOutput << ";";
- }
-
- if (a < mesh->mNumFaces - 1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
-
- mOutput << endstr;
-
- if (mesh->HasTextureCoords(0))
- {
- const aiMaterial* mat = mScene->mMaterials[mesh->mMaterialIndex];
- aiString relpath;
- mat->Get(_AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0, relpath);
-
- mOutput << startstr << "MeshMaterialList {" << endstr;
- PushTag();
- mOutput << startstr << "1;" << endstr; // number of materials
- mOutput << startstr << mesh->mNumFaces << ";" << endstr; // number of faces
- mOutput << startstr;
- for( size_t a = 0; a < mesh->mNumFaces; ++a )
- {
- mOutput << "0"; // the material index
- if (a < mesh->mNumFaces - 1)
- mOutput << ", ";
- else
- mOutput << ";" << endstr;
- }
- mOutput << startstr << "Material {" << endstr;
- PushTag();
- mOutput << startstr << "1.0; 1.0; 1.0; 1.000000;;" << endstr;
- mOutput << startstr << "1.000000;" << endstr; // power
- mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // specularity
- mOutput << startstr << "0.000000; 0.000000; 0.000000;;" << endstr; // emission
- mOutput << startstr << "TextureFilename { \"";
-
- writePath(relpath);
-
- mOutput << "\"; }" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- PopTag();
- mOutput << startstr << "}" << endstr;
- }
-
- // write normals (every vertex has one)
- if (mesh->HasNormals())
- {
- mOutput << endstr << startstr << "MeshNormals {" << endstr;
- mOutput << startstr << mesh->mNumVertices << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumVertices; a++)
- {
- aiVector3D &v = mesh->mNormals[a];
- // because we have a LHS and also changed wth winding, we need to invert the normals again
- mOutput << startstr << -v[0] << ";"<< -v[1] << ";" << -v[2] << ";";
- if (a < mesh->mNumVertices - 1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
-
- mOutput << startstr << mesh->mNumFaces << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumFaces; a++)
- {
- const aiFace& face = mesh->mFaces[a];
- mOutput << startstr << face.mNumIndices << ";";
-
- //for(int b = face.mNumIndices-1; b >= 0 ; --b)
- for(size_t b = 0; b < face.mNumIndices ; ++b)
- {
- mOutput << face.mIndices[b];
- //if (b > 0)
- if (b<face.mNumIndices-1)
- mOutput << ",";
- else
- mOutput << ";";
- }
-
- if (a < mesh->mNumFaces-1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
- mOutput << startstr << "}" << endstr;
- }
-
- // write texture UVs if available
- if (mesh->HasTextureCoords(0))
- {
- mOutput << endstr << startstr << "MeshTextureCoords {" << endstr;
- mOutput << startstr << mesh->mNumVertices << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumVertices; a++)
- //for (int a = (int)mesh->mNumVertices-1; a >=0 ; a--)
- {
- aiVector3D& uv = mesh->mTextureCoords[0][a]; // uv of first uv layer for the vertex
- mOutput << startstr << uv.x << ";" << uv.y;
- if (a < mesh->mNumVertices-1)
- //if (a >0 )
- mOutput << ";," << endstr;
- else
- mOutput << ";;" << endstr;
- }
- mOutput << startstr << "}" << endstr;
- }
-
- // write color channel if available
- if (mesh->HasVertexColors(0))
- {
- mOutput << endstr << startstr << "MeshVertexColors {" << endstr;
- mOutput << startstr << mesh->mNumVertices << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumVertices; a++)
- {
- aiColor4D& mColors = mesh->mColors[0][a]; // color of first vertex color set for the vertex
- mOutput << startstr << a << ";" << mColors.r << ";" << mColors.g << ";" << mColors.b << ";" << mColors.a << ";;";
- if (a < mesh->mNumVertices-1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
- mOutput << startstr << "}" << endstr;
- }
- /*
- else
- {
- mOutput << endstr << startstr << "MeshVertexColors {" << endstr;
- mOutput << startstr << mesh->mNumVertices << ";" << endstr;
- for (size_t a = 0; a < mesh->mNumVertices; a++)
- {
- aiColor4D* mColors = mesh->mColors[a];
- mOutput << startstr << a << ";0.500000;0.000000;0.000000;0.500000;;";
- if (a < mesh->mNumVertices-1)
- mOutput << "," << endstr;
- else
- mOutput << ";" << endstr;
- }
- mOutput << startstr << "}" << endstr;
- }
- */
- PopTag();
- mOutput << startstr << "}" << endstr << endstr;
-
-}
-
-std::string XFileExporter::toXFileString(aiString &name)
-{
- std::string pref = ""; // node name prefix to prevent unexpected start of string
- std::string str = pref + std::string(name.C_Str());
- for (int i=0; i < (int) str.length(); ++i)
- {
- if ((str[i] >= '0' && str[i] <= '9') || // 0-9
- (str[i] >= 'A' && str[i] <= 'Z') || // A-Z
- (str[i] >= 'a' && str[i] <= 'z')) // a-z
- continue;
- str[i] = '_';
- }
- return str;
-}
-
-void XFileExporter::writePath(const aiString &path)
-{
- std::string str = std::string(path.C_Str());
- BaseImporter::ConvertUTF8toISO8859_1(str);
-
- while( str.find( "\\\\") != std::string::npos)
- str.replace( str.find( "\\\\"), 2, "\\");
-
- while( str.find( "\\") != std::string::npos)
- str.replace( str.find( "\\"), 1, "/");
-
- mOutput << str;
-
-}
-
-#endif
-#endif
diff --git a/src/3rdparty/assimp/code/XFileExporter.h b/src/3rdparty/assimp/code/XFileExporter.h
deleted file mode 100644
index e45fd7983..000000000
--- a/src/3rdparty/assimp/code/XFileExporter.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-@author: Richard Steffen, 2014
-
-----------------------------------------------------------------------
-*/
-
-/** @file XFileExporter.h
- * Declares the exporter class to write a scene to a Collada file
- */
-#ifndef AI_XFILEEXPORTER_H_INC
-#define AI_XFILEEXPORTER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/matrix4x4.h>
-#include <assimp/Exporter.hpp>
-#include <sstream>
-
-struct aiScene;
-struct aiNode;
-struct aiMesh;
-struct aiString;
-
-namespace Assimp {
-
-class IOSystem;
-
-
-/// Helper class to export a given scene to a X-file.
-/// Note: an xFile uses a left hand system. Assimp used a right hand system (OpenGL), therefore we have to transform everything
-class XFileExporter
-{
-public:
- /// Constructor for a specific scene to export
- XFileExporter(const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file, const ExportProperties* pProperties);
-
- /// Destructor
- virtual ~XFileExporter();
-
-protected:
- /// Starts writing the contents
- void WriteFile();
-
- /// Writes the asset header
- void WriteHeader();
-
- /// write a frame transform
- void WriteFrameTransform(aiMatrix4x4& m);
-
- /// Recursively writes the given node
- void WriteNode( aiNode* pNode );
-
- /// write a mesh entry of the scene
- void WriteMesh( aiMesh* mesh);
-
- /// Enters a new xml element, which increases the indentation
- void PushTag() { startstr.append( " "); }
-
- /// Leaves an element, decreasing the indentation
- void PopTag() {
- ai_assert( startstr.length() > 1);
- startstr.erase( startstr.length() - 2);
- }
-
-public:
- /// Stringstream to write all output into
- std::stringstream mOutput;
-
-protected:
-
- /// normalize the name to be accepted by xfile readers
- std::string toXFileString(aiString &name);
-
- /// hold the properties pointer
- const ExportProperties* mProperties;
-
- /// write a path
- void writePath(const aiString &path);
-
- /// 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;
-
- /// current line end string for simple stream insertion
- std::string endstr;
-
-};
-
-}
-
-#endif // !! AI_XFILEEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/XFileHelper.h b/src/3rdparty/assimp/code/XFileHelper.h
deleted file mode 100644
index e7c02c7c6..000000000
--- a/src/3rdparty/assimp/code/XFileHelper.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Defines the helper data structures for importing XFiles */
-#ifndef AI_XFILEHELPER_H_INC
-#define AI_XFILEHELPER_H_INC
-
-#include <string>
-#include <vector>
-#include <stdint.h>
-
-#include <assimp/types.h>
-#include <assimp/quaternion.h>
-#include <assimp/mesh.h>
-#include <assimp/anim.h>
-#include <assimp/Defines.h>
-
-namespace Assimp
-{
-namespace XFile
-{
-
-/** Helper structure representing a XFile mesh face */
-struct Face
-{
- std::vector<unsigned int> mIndices;
-};
-
-/** Helper structure representing a texture filename inside a material and its potential source */
-struct TexEntry
-{
- std::string mName;
- bool mIsNormalMap; // true if the texname was specified in a NormalmapFilename tag
-
- TexEntry() { mIsNormalMap = false; }
- TexEntry( const std::string& pName, bool pIsNormalMap = false)
- : mName( pName), mIsNormalMap( pIsNormalMap)
- { /* done */ }
-};
-
-/** Helper structure representing a XFile material */
-struct Material
-{
- std::string mName;
- bool mIsReference; // if true, mName holds a name by which the actual material can be found in the material list
- aiColor4D mDiffuse;
- ai_real mSpecularExponent;
- aiColor3D mSpecular;
- aiColor3D mEmissive;
- std::vector<TexEntry> mTextures;
-
- size_t sceneIndex; ///< the index under which it was stored in the scene's material list
-
- Material()
- : mIsReference(false),
- mSpecularExponent(),
- sceneIndex(SIZE_MAX)
- {}
-};
-
-/** Helper structure to represent a bone weight */
-struct BoneWeight
-{
- unsigned int mVertex;
- ai_real mWeight;
-};
-
-/** Helper structure to represent a bone in a mesh */
-struct Bone
-{
- std::string mName;
- std::vector<BoneWeight> mWeights;
- aiMatrix4x4 mOffsetMatrix;
-};
-
-/** Helper structure to represent an XFile mesh */
-struct Mesh
-{
- std::string mName;
- std::vector<aiVector3D> mPositions;
- std::vector<Face> mPosFaces;
- std::vector<aiVector3D> mNormals;
- std::vector<Face> mNormFaces;
- unsigned int mNumTextures;
- std::vector<aiVector2D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
- unsigned int mNumColorSets;
- std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- std::vector<unsigned int> mFaceMaterials;
- std::vector<Material> mMaterials;
-
- std::vector<Bone> mBones;
-
- explicit Mesh(const std::string &pName = "") { mName = pName; mNumTextures = 0; mNumColorSets = 0; }
-};
-
-/** Helper structure to represent a XFile frame */
-struct Node
-{
- std::string mName;
- aiMatrix4x4 mTrafoMatrix;
- Node* mParent;
- std::vector<Node*> mChildren;
- std::vector<Mesh*> mMeshes;
-
- Node() { mParent = NULL; }
- explicit Node( Node* pParent) { mParent = pParent; }
- ~Node()
- {
- for( unsigned int a = 0; a < mChildren.size(); a++)
- delete mChildren[a];
- for( unsigned int a = 0; a < mMeshes.size(); a++)
- delete mMeshes[a];
- }
-};
-
-struct MatrixKey
-{
- double mTime;
- aiMatrix4x4 mMatrix;
-};
-
-/** Helper structure representing a single animated bone in a XFile */
-struct AnimBone
-{
- std::string mBoneName;
- std::vector<aiVectorKey> mPosKeys; // either three separate key sequences for position, rotation, scaling
- std::vector<aiQuatKey> mRotKeys;
- std::vector<aiVectorKey> mScaleKeys;
- std::vector<MatrixKey> mTrafoKeys; // or a combined key sequence of transformation matrices.
-};
-
-/** Helper structure to represent an animation set in a XFile */
-struct Animation
-{
- std::string mName;
- std::vector<AnimBone*> mAnims;
-
- ~Animation()
- {
- for( unsigned int a = 0; a < mAnims.size(); a++)
- delete mAnims[a];
- }
-};
-
-/** Helper structure analogue to aiScene */
-struct Scene
-{
- Node* mRootNode;
-
- std::vector<Mesh*> mGlobalMeshes; // global meshes found outside of any frames
- std::vector<Material> mGlobalMaterials; // global materials found outside of any meshes.
-
- std::vector<Animation*> mAnims;
- unsigned int mAnimTicksPerSecond;
-
- Scene() { mRootNode = NULL; mAnimTicksPerSecond = 0; }
- ~Scene()
- {
- delete mRootNode;
- for( unsigned int a = 0; a < mGlobalMeshes.size(); a++)
- delete mGlobalMeshes[a];
- for( unsigned int a = 0; a < mAnims.size(); a++)
- delete mAnims[a];
- }
-};
-
-} // end of namespace XFile
-} // end of namespace Assimp
-
-#endif // AI_XFILEHELPER_H_INC
diff --git a/src/3rdparty/assimp/code/XFileImporter.cpp b/src/3rdparty/assimp/code/XFileImporter.cpp
deleted file mode 100644
index 00c32dcc2..000000000
--- a/src/3rdparty/assimp/code/XFileImporter.cpp
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 XFileImporter.cpp
- * @brief Implementation of the XFile importer class
- */
-
-
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-
-#include "XFileImporter.h"
-#include "XFileParser.h"
-#include "TinyFormatter.h"
-#include "ConvertToLHProcess.h"
-#include <assimp/Defines.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-#include <cctype>
-#include <memory>
-
-using namespace Assimp;
-using namespace Assimp::Formatter;
-
-static const aiImporterDesc desc = {
- "Direct3D XFile Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour,
- 1,
- 3,
- 1,
- 5,
- "x"
-};
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-XFileImporter::XFileImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-XFileImporter::~XFileImporter()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- std::string extension = GetExtension(pFile);
- if(extension == "x") {
- return true;
- }
- if (!extension.length() || checkSig) {
- uint32_t token[1];
- token[0] = AI_MAKE_MAGIC("xof ");
- return CheckMagicToken(pIOHandler,pFile,token,1,0);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get file extension list
-const aiImporterDesc* XFileImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
- // read file into memory
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
- if( file.get() == NULL)
- throw DeadlyImportError( "Failed to open file " + pFile + ".");
-
- size_t fileSize = file->FileSize();
- if( fileSize < 16)
- throw DeadlyImportError( "XFile is too small.");
-
- // in the hope that binary files will never start with a BOM ...
- mBuffer.resize( fileSize + 1);
- file->Read( &mBuffer.front(), 1, fileSize);
- ConvertToUTF8(mBuffer);
-
- // parse the file into a temporary representation
- XFileParser parser( mBuffer);
-
- // and create the proper return structures out of it
- CreateDataRepresentationFromImport( pScene, parser.GetImportedData());
-
- // if nothing came from it, report it as error
- if( !pScene->mRootNode)
- throw DeadlyImportError( "XFile is ill-formatted - no content imported.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// Constructs the return data structure out of the imported data.
-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);
-
- // copy nodes, extracting meshes and materials on the way
- pScene->mRootNode = CreateNodes( pScene, NULL, pData->mRootNode);
-
- // extract animations
- CreateAnimations( pScene, pData);
-
- // read the global meshes that were stored outside of any node
- if( pData->mGlobalMeshes.size() > 0)
- {
- // create a root node to hold them if there isn't any, yet
- if( pScene->mRootNode == NULL)
- {
- pScene->mRootNode = new aiNode;
- pScene->mRootNode->mName.Set( "$dummy_node");
- }
-
- // convert all global meshes and store them in the root node.
- // If there was one before, the global meshes now suddenly have its transformation matrix...
- // Don't know what to do there, I don't want to insert another node under the present root node
- // just to avoid this.
- CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes);
- }
-
- if (!pScene->mRootNode) {
- throw DeadlyImportError( "No root node" );
- }
-
- // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
- MakeLeftHandedProcess convertProcess;
- convertProcess.Execute( pScene);
-
- FlipWindingOrderProcess flipper;
- flipper.Execute(pScene);
-
- // finally: create a dummy material if not material was imported
- if( pScene->mNumMaterials == 0)
- {
- pScene->mNumMaterials = 1;
- // create the Material
- aiMaterial* mat = new aiMaterial;
- int shadeMode = (int) aiShadingMode_Gouraud;
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- // material colours
- int specExp = 1;
-
- aiColor3D clr = aiColor3D( 0, 0, 0);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_EMISSIVE);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_SPECULAR);
-
- clr = aiColor3D( 0.5f, 0.5f, 0.5f);
- mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_DIFFUSE);
- mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS);
-
- pScene->mMaterials = new aiMaterial*[1];
- pScene->mMaterials[0] = mat;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Recursively creates scene nodes from the imported hierarchy.
-aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFile::Node* pNode)
-{
- if( !pNode)
- return NULL;
-
- // create node
- aiNode* node = new aiNode;
- node->mName.length = pNode->mName.length();
- node->mParent = pParent;
- memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length());
- node->mName.data[node->mName.length] = 0;
- node->mTransformation = pNode->mTrafoMatrix;
-
- // convert meshes from the source node
- CreateMeshes( pScene, node, pNode->mMeshes);
-
- // handle childs
- if( pNode->mChildren.size() > 0)
- {
- node->mNumChildren = (unsigned int)pNode->mChildren.size();
- node->mChildren = new aiNode* [node->mNumChildren];
-
- for( unsigned int a = 0; a < pNode->mChildren.size(); a++)
- node->mChildren[a] = CreateNodes( pScene, node, pNode->mChildren[a]);
- }
-
- return node;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Creates the meshes for the given node.
-void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes)
-{
- if (pMeshes.empty()) {
- return;
- }
-
- // create a mesh for each mesh-material combination in the source node
- std::vector<aiMesh*> meshes;
- for( unsigned int a = 0; a < pMeshes.size(); a++)
- {
- 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);
- for( unsigned int b = 0; b < numMaterials; b++)
- {
- // collect the faces belonging to this material
- std::vector<unsigned int> faces;
- unsigned int numVertices = 0;
- if( sourceMesh->mFaceMaterials.size() > 0)
- {
- // if there is a per-face material defined, select the faces with the corresponding material
- for( unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); c++)
- {
- if( sourceMesh->mFaceMaterials[c] == b)
- {
- faces.push_back( c);
- numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
- }
- }
- } else
- {
- // if there is no per-face material, place everything into one mesh
- for( unsigned int c = 0; c < sourceMesh->mPosFaces.size(); c++)
- {
- faces.push_back( c);
- numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size();
- }
- }
-
- // no faces/vertices using this material? strange...
- if( numVertices == 0)
- continue;
-
- // create a submesh using this material
- aiMesh* mesh = new aiMesh;
- meshes.push_back( mesh);
-
- // 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)
- {
- mesh->mMaterialIndex = static_cast<unsigned int>(sourceMesh->mMaterials[b].sceneIndex);
- } else
- {
- mesh->mMaterialIndex = 0;
- }
-
- // Create properly sized data arrays in the mesh. We store unique vertices per face,
- // as specified
- mesh->mNumVertices = numVertices;
- mesh->mVertices = new aiVector3D[numVertices];
- mesh->mNumFaces = (unsigned int)faces.size();
- mesh->mFaces = new aiFace[mesh->mNumFaces];
-
- // name
- mesh->mName.Set(sourceMesh->mName);
-
- // normals?
- if( sourceMesh->mNormals.size() > 0)
- mesh->mNormals = new aiVector3D[numVertices];
- // texture coords
- for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++)
- {
- if( sourceMesh->mTexCoords[c].size() > 0)
- mesh->mTextureCoords[c] = new aiVector3D[numVertices];
- }
- // vertex colors
- for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++)
- {
- if( sourceMesh->mColors[c].size() > 0)
- mesh->mColors[c] = new aiColor4D[numVertices];
- }
-
- // now collect the vertex data of all data streams present in the imported mesh
- unsigned int newIndex = 0;
- std::vector<unsigned int> orgPoints; // from which original point each new vertex stems
- orgPoints.resize( numVertices, 0);
-
- for( unsigned int c = 0; c < faces.size(); c++)
- {
- unsigned int f = faces[c]; // index of the source face
- const XFile::Face& pf = sourceMesh->mPosFaces[f]; // position source face
-
- // create face. either triangle or triangle fan depending on the index count
- aiFace& df = mesh->mFaces[c]; // destination face
- df.mNumIndices = (unsigned int)pf.mIndices.size();
- df.mIndices = new unsigned int[ df.mNumIndices];
-
- // collect vertex data for indices of this face
- for( unsigned int d = 0; d < df.mNumIndices; d++)
- {
- df.mIndices[d] = newIndex;
- orgPoints[newIndex] = pf.mIndices[d];
-
- // Position
- mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]];
- // Normal, if present
- if( mesh->HasNormals())
- mesh->mNormals[newIndex] = sourceMesh->mNormals[sourceMesh->mNormFaces[f].mIndices[d]];
-
- // texture coord sets
- for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++)
- {
- if( mesh->HasTextureCoords( e))
- {
- aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]];
- mesh->mTextureCoords[e][newIndex] = aiVector3D( tex.x, 1.0f - tex.y, 0.0f);
- }
- }
- // vertex color sets
- for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; e++)
- if( mesh->HasVertexColors( e))
- mesh->mColors[e][newIndex] = sourceMesh->mColors[e][pf.mIndices[d]];
-
- newIndex++;
- }
- }
-
- // there should be as much new vertices as we calculated before
- ai_assert( newIndex == numVertices);
-
- // convert all bones of the source mesh which influence vertices in this newly created mesh
- const std::vector<XFile::Bone>& bones = sourceMesh->mBones;
- std::vector<aiBone*> newBones;
- for( unsigned int c = 0; c < bones.size(); c++)
- {
- const XFile::Bone& obone = bones[c];
- // set up a vertex-linear array of the weights for quick searching if a bone influences a vertex
- std::vector<ai_real> oldWeights( sourceMesh->mPositions.size(), 0.0);
- for( unsigned int d = 0; d < obone.mWeights.size(); d++)
- oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight;
-
- // collect all vertex weights that influence a vertex in the new mesh
- std::vector<aiVertexWeight> newWeights;
- newWeights.reserve( numVertices);
- for( unsigned int d = 0; d < orgPoints.size(); d++)
- {
- // does the new vertex stem from an old vertex which was influenced by this bone?
- ai_real w = oldWeights[orgPoints[d]];
- if( w > 0.0)
- newWeights.push_back( aiVertexWeight( d, w));
- }
-
- // if the bone has no weights in the newly created mesh, ignore it
- if( newWeights.size() == 0)
- continue;
-
- // create
- aiBone* nbone = new aiBone;
- newBones.push_back( nbone);
- // copy name and matrix
- nbone->mName.Set( obone.mName);
- nbone->mOffsetMatrix = obone.mOffsetMatrix;
- nbone->mNumWeights = (unsigned int)newWeights.size();
- nbone->mWeights = new aiVertexWeight[nbone->mNumWeights];
- for( unsigned int d = 0; d < newWeights.size(); d++)
- nbone->mWeights[d] = newWeights[d];
- }
-
- // store the bones in the mesh
- mesh->mNumBones = (unsigned int)newBones.size();
- if( newBones.size() > 0)
- {
- mesh->mBones = new aiBone*[mesh->mNumBones];
- std::copy( newBones.begin(), newBones.end(), mesh->mBones);
- }
- }
- }
-
- // reallocate scene mesh array to be large enough
- aiMesh** prevArray = pScene->mMeshes;
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes + meshes.size()];
- if( prevArray)
- {
- memcpy( pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof( aiMesh*));
- delete [] prevArray;
- }
-
- // allocate mesh index array in the node
- pNode->mNumMeshes = (unsigned int)meshes.size();
- pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
-
- // store all meshes in the mesh library of the scene and store their indices in the node
- for( unsigned int a = 0; a < meshes.size(); a++)
- {
- pScene->mMeshes[pScene->mNumMeshes] = meshes[a];
- pNode->mMeshes[a] = pScene->mNumMeshes;
- pScene->mNumMeshes++;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts the animations from the given imported data and creates them in the scene.
-void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData)
-{
- std::vector<aiAnimation*> newAnims;
-
- for( unsigned int a = 0; a < pData->mAnims.size(); a++)
- {
- const XFile::Animation* anim = pData->mAnims[a];
- // some exporters mock me with empty animation tags.
- if( anim->mAnims.size() == 0)
- continue;
-
- // create a new animation to hold the data
- aiAnimation* nanim = new aiAnimation;
- newAnims.push_back( nanim);
- nanim->mName.Set( anim->mName);
- // duration will be determined by the maximum length
- nanim->mDuration = 0;
- nanim->mTicksPerSecond = pData->mAnimTicksPerSecond;
- nanim->mNumChannels = (unsigned int)anim->mAnims.size();
- nanim->mChannels = new aiNodeAnim*[nanim->mNumChannels];
-
- for( unsigned int b = 0; b < anim->mAnims.size(); b++)
- {
- const XFile::AnimBone* bone = anim->mAnims[b];
- aiNodeAnim* nbone = new aiNodeAnim;
- nbone->mNodeName.Set( bone->mBoneName);
- nanim->mChannels[b] = nbone;
-
- // keyframes are given as combined transformation matrix keys
- if( bone->mTrafoKeys.size() > 0)
- {
- nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
- nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
- nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size();
- nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
-
- for( unsigned int c = 0; c < bone->mTrafoKeys.size(); c++)
- {
- // deconstruct each matrix into separate position, rotation and scaling
- double time = bone->mTrafoKeys[c].mTime;
- aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix;
-
- // extract position
- aiVector3D pos( trafo.a4, trafo.b4, trafo.c4);
-
- nbone->mPositionKeys[c].mTime = time;
- nbone->mPositionKeys[c].mValue = pos;
-
- // extract scaling
- aiVector3D scale;
- scale.x = aiVector3D( trafo.a1, trafo.b1, trafo.c1).Length();
- scale.y = aiVector3D( trafo.a2, trafo.b2, trafo.c2).Length();
- scale.z = aiVector3D( trafo.a3, trafo.b3, trafo.c3).Length();
- nbone->mScalingKeys[c].mTime = time;
- nbone->mScalingKeys[c].mValue = scale;
-
- // reconstruct rotation matrix without scaling
- aiMatrix3x3 rotmat(
- trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z,
- trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z,
- trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z);
-
- // and convert it into a quaternion
- nbone->mRotationKeys[c].mTime = time;
- nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
- }
-
- // longest lasting key sequence determines duration
- nanim->mDuration = std::max( nanim->mDuration, bone->mTrafoKeys.back().mTime);
- } else
- {
- // separate key sequences for position, rotation, scaling
- nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size();
- nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys];
- for( unsigned int c = 0; c < nbone->mNumPositionKeys; c++)
- {
- aiVector3D pos = bone->mPosKeys[c].mValue;
-
- nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime;
- nbone->mPositionKeys[c].mValue = pos;
- }
-
- // rotation
- nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size();
- nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys];
- for( unsigned int c = 0; c < nbone->mNumRotationKeys; c++)
- {
- aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix();
-
- nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime;
- nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat);
- nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion
- }
-
- // scaling
- nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size();
- nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys];
- for( unsigned int c = 0; c < nbone->mNumScalingKeys; c++)
- nbone->mScalingKeys[c] = bone->mScaleKeys[c];
-
- // longest lasting key sequence determines duration
- if( bone->mPosKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mPosKeys.back().mTime);
- if( bone->mRotKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mRotKeys.back().mTime);
- if( bone->mScaleKeys.size() > 0)
- nanim->mDuration = std::max( nanim->mDuration, bone->mScaleKeys.back().mTime);
- }
- }
- }
-
- // store all converted animations in the scene
- if( newAnims.size() > 0)
- {
- pScene->mNumAnimations = (unsigned int)newAnims.size();
- pScene->mAnimations = new aiAnimation* [pScene->mNumAnimations];
- for( unsigned int a = 0; a < newAnims.size(); a++)
- pScene->mAnimations[a] = newAnims[a];
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Converts all materials in the given array and stores them in the scene's material list.
-void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials)
-{
- // count the non-referrer materials in the array
- unsigned int numNewMaterials = 0;
- for( unsigned int a = 0; a < pMaterials.size(); a++)
- if( !pMaterials[a].mIsReference)
- numNewMaterials++;
-
- // resize the scene's material list to offer enough space for the new materials
- 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++)
- {
- XFile::Material& oldMat = pMaterials[a];
- if( oldMat.mIsReference)
- {
- // 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( format() << "Could not resolve global material reference \"" << oldMat.mName << "\"" );
- oldMat.sceneIndex = 0;
- }
-
- continue;
- }
-
- aiMaterial* mat = new aiMaterial;
- aiString name;
- name.Set( oldMat.mName);
- mat->AddProperty( &name, AI_MATKEY_NAME);
-
- // Shading model: hardcoded to PHONG, there is no such information in an XFile
- // FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix
- // for some models in the SDK (e.g. good old tiny.x)
- int shadeMode = (int)oldMat.mSpecularExponent == 0.0f
- ? aiShadingMode_Gouraud : aiShadingMode_Phong;
-
- mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
- // material colours
- // 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);
-
-
- // texture, if there is one
- if (1 == oldMat.mTextures.size())
- {
- const XFile::TexEntry& otex = oldMat.mTextures.back();
- if (otex.mName.length())
- {
- // if there is only one texture assume it contains the diffuse color
- aiString tex( otex.mName);
- if( otex.mIsNormalMap)
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(0));
- else
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0));
- }
- }
- else
- {
- // Otherwise ... try to search for typical strings in the
- // texture's file name like 'bump' or 'diffuse'
- unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0;
- for( unsigned int b = 0; b < oldMat.mTextures.size(); b++)
- {
- const XFile::TexEntry& otex = oldMat.mTextures[b];
- std::string sz = otex.mName;
- if (!sz.length())continue;
-
-
- // find the file name
- //const size_t iLen = sz.length();
- std::string::size_type s = sz.find_last_of("\\/");
- if (std::string::npos == s)
- s = 0;
-
- // cut off the file extension
- std::string::size_type sExt = sz.find_last_of('.');
- if (std::string::npos != sExt){
- sz[sExt] = '\0';
- }
-
- // convert to lower case for easier comparison
- for( unsigned int c = 0; c < sz.length(); c++)
- if( isalpha( sz[c]))
- sz[c] = tolower( sz[c]);
-
-
- // Place texture filename property under the corresponding name
- aiString tex( oldMat.mTextures[b].mName);
-
- // bump map
- if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++));
- } else
- if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++));
- } else
- if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++));
- } else
- if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++));
- } else
- if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s))
- {
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++));
- } else
- {
- // Assume it is a diffuse texture
- mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++));
- }
- }
- }
-
- pScene->mMaterials[pScene->mNumMaterials] = mat;
- oldMat.sceneIndex = pScene->mNumMaterials;
- pScene->mNumMaterials++;
- }
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
diff --git a/src/3rdparty/assimp/code/XFileImporter.h b/src/3rdparty/assimp/code/XFileImporter.h
deleted file mode 100644
index 0fa6b52eb..000000000
--- a/src/3rdparty/assimp/code/XFileImporter.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 XFileImporter.h
- * @brief Definition of the XFile importer class.
- */
-#ifndef AI_XFILEIMPORTER_H_INC
-#define AI_XFILEIMPORTER_H_INC
-
-#include <map>
-
-#include "XFileHelper.h"
-#include "BaseImporter.h"
-
-#include <assimp/types.h>
-
-struct aiNode;
-
-namespace Assimp {
-
-namespace XFile {
-struct Scene;
-struct Node;
-}
-
-// ---------------------------------------------------------------------------
-/** The XFileImporter is a worker class capable of importing a scene from a
- * DirectX file .x
- */
-class XFileImporter : public BaseImporter {
-public:
- XFileImporter();
- ~XFileImporter();
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool CheckSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details
- */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details
- */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Constructs the return data structure out of the imported data.
- * @param pScene The scene to construct the return data in.
- * @param pData The imported data in the internal temporary
- * representation.
- */
- void CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData);
-
- // -------------------------------------------------------------------
- /** Recursively creates scene nodes from the imported hierarchy.
- * The meshes and materials of the nodes will be extracted on the way.
- * @param pScene The scene to construct the return data in.
- * @param pParent The parent node where to create new child nodes
- * @param pNode The temporary node to copy.
- * @return The created node
- */
- aiNode* CreateNodes( aiScene* pScene, aiNode* pParent,
- const XFile::Node* pNode);
-
- // -------------------------------------------------------------------
- /** Converts all meshes in the given mesh array. Each mesh is split
- * up per material, the indices of the generated meshes are stored in
- * the node structure.
- * @param pScene The scene to construct the return data in.
- * @param pNode The target node structure that references the
- * constructed meshes.
- * @param pMeshes The array of meshes to convert
- */
- void CreateMeshes( aiScene* pScene, aiNode* pNode,
- const std::vector<XFile::Mesh*>& pMeshes);
-
- // -------------------------------------------------------------------
- /** Converts the animations from the given imported data and creates
- * them in the scene.
- * @param pScene The scene to hold to converted animations
- * @param pData The data to read the animations from
- */
- void CreateAnimations( aiScene* pScene, const XFile::Scene* pData);
-
- // -------------------------------------------------------------------
- /** Converts all materials in the given array and stores them in the
- * scene's material list.
- * @param pScene The scene to hold the converted materials.
- * @param pMaterials The material array to convert.
- */
- void ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials);
-
-protected:
- /** Buffer to hold the loaded file */
- std::vector<char> mBuffer;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_BASEIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/XFileParser.cpp b/src/3rdparty/assimp/code/XFileParser.cpp
deleted file mode 100644
index 1f8b8cbd3..000000000
--- a/src/3rdparty/assimp/code/XFileParser.cpp
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the XFile parser helper class */
-
-
-#ifndef ASSIMP_BUILD_NO_X_IMPORTER
-
-#include "XFileParser.h"
-#include "XFileHelper.h"
-#include "fast_atof.h"
-#include "Exceptional.h"
-#include "TinyFormatter.h"
-#include "ByteSwapper.h"
-#include "StringUtils.h"
-#include <assimp/DefaultLogger.hpp>
-
-
-using namespace Assimp;
-using namespace Assimp::XFile;
-using namespace Assimp::Formatter;
-
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
-
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include "../contrib/zlib/zlib.h"
-# endif
-
-// Magic identifier for MSZIP compressed data
-#define MSZIP_MAGIC 0x4B43
-#define MSZIP_BLOCK 32786
-
-// ------------------------------------------------------------------------------------------------
-// Dummy memory wrappers for use with zlib
-static void* dummy_alloc (void* /*opaque*/, unsigned int items, unsigned int size) {
- return ::operator new(items*size);
-}
-
-static void dummy_free (void* /*opaque*/, void* address) {
- return ::operator delete(address);
-}
-
-#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
-
-// ------------------------------------------------------------------------------------------------
-// Constructor. Creates a data structure out of the XFile given in the memory block.
-XFileParser::XFileParser( const std::vector<char>& pBuffer)
-{
- mMajorVersion = mMinorVersion = 0;
- mIsBinaryFormat = false;
- mBinaryNumCount = 0;
- P = End = NULL;
- mLineNumber = 0;
- mScene = NULL;
-
- // vector to store uncompressed file for INFLATE'd X files
- std::vector<char> uncompressed;
-
- // set up memory pointers
- P = &pBuffer.front();
- End = P + pBuffer.size() - 1;
-
- // check header
- if( strncmp( P, "xof ", 4) != 0)
- throw DeadlyImportError( "Header mismatch, file is not an XFile.");
-
- // read version. It comes in a four byte format such as "0302"
- mMajorVersion = (unsigned int)(P[4] - 48) * 10 + (unsigned int)(P[5] - 48);
- mMinorVersion = (unsigned int)(P[6] - 48) * 10 + (unsigned int)(P[7] - 48);
-
- bool compressed = false;
-
- // txt - pure ASCII text format
- if( strncmp( P + 8, "txt ", 4) == 0)
- mIsBinaryFormat = false;
-
- // bin - Binary format
- else if( strncmp( P + 8, "bin ", 4) == 0)
- mIsBinaryFormat = true;
-
- // tzip - Inflate compressed text format
- else if( strncmp( P + 8, "tzip", 4) == 0)
- {
- mIsBinaryFormat = false;
- compressed = true;
- }
- // bzip - Inflate compressed binary format
- else if( strncmp( P + 8, "bzip", 4) == 0)
- {
- mIsBinaryFormat = true;
- compressed = true;
- }
- else ThrowException( format() << "Unsupported xfile format '" <<
- P[8] << P[9] << P[10] << P[11] << "'");
-
- // float size
- mBinaryFloatSize = (unsigned int)(P[12] - 48) * 1000
- + (unsigned int)(P[13] - 48) * 100
- + (unsigned int)(P[14] - 48) * 10
- + (unsigned int)(P[15] - 48);
-
- if( mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
- ThrowException( format() << "Unknown float size " << mBinaryFloatSize << " specified in xfile header." );
-
- // 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
- if (compressed)
- {
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_X
- throw DeadlyImportError("Assimp was built without compressed X support");
-#else
- /* ///////////////////////////////////////////////////////////////////////
- * COMPRESSED X FILE FORMAT
- * ///////////////////////////////////////////////////////////////////////
- * [xhead]
- * 2 major
- * 2 minor
- * 4 type // bzip,tzip
- * [mszip_master_head]
- * 4 unkn // checksum?
- * 2 unkn // flags? (seems to be constant)
- * [mszip_head]
- * 2 ofs // offset to next section
- * 2 magic // 'CK'
- * ... ofs bytes of data
- * ... next mszip_head
- *
- * http://www.kdedevelopers.org/node/3181 has been very helpful.
- * ///////////////////////////////////////////////////////////////////////
- */
-
- // build a zlib stream
- z_stream stream;
- stream.opaque = NULL;
- stream.zalloc = &dummy_alloc;
- stream.zfree = &dummy_free;
- stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
-
- // initialize the inflation algorithm
- ::inflateInit2(&stream, -MAX_WBITS);
-
- // skip unknown data (checksum, flags?)
- P += 6;
-
- // First find out how much storage we'll need. Count sections.
- const char* P1 = P;
- unsigned int est_out = 0;
-
- while (P1 + 3 < End)
- {
- // read next offset
- uint16_t ofs = *((uint16_t*)P1);
- AI_SWAP2(ofs); P1 += 2;
-
- if (ofs >= MSZIP_BLOCK)
- throw DeadlyImportError("X: Invalid offset to next MSZIP compressed block");
-
- // check magic word
- uint16_t magic = *((uint16_t*)P1);
- AI_SWAP2(magic); P1 += 2;
-
- if (magic != MSZIP_MAGIC)
- throw DeadlyImportError("X: Unsupported compressed format, expected MSZIP header");
-
- // and advance to the next offset
- P1 += ofs;
- est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
- }
-
- // Allocate storage and terminating zero and do the actual uncompressing
- uncompressed.resize(est_out + 1);
- char* out = &uncompressed.front();
- while (P + 3 < End)
- {
- uint16_t ofs = *((uint16_t*)P);
- AI_SWAP2(ofs);
- P += 4;
-
- if (P + ofs > End + 2) {
- throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
- }
-
- // push data to the stream
- stream.next_in = (Bytef*)P;
- stream.avail_in = ofs;
- stream.next_out = (Bytef*)out;
- stream.avail_out = MSZIP_BLOCK;
-
- // and decompress the data ....
- int ret = ::inflate( &stream, Z_SYNC_FLUSH );
- if (ret != Z_OK && ret != Z_STREAM_END)
- throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
-
- ::inflateReset( &stream );
- ::inflateSetDictionary( &stream, (const Bytef*)out , MSZIP_BLOCK - stream.avail_out );
-
- // and advance to the next offset
- out += MSZIP_BLOCK - stream.avail_out;
- P += ofs;
- }
-
- // terminate zlib
- ::inflateEnd(&stream);
-
- // ok, update pointers to point to the uncompressed file data
- P = &uncompressed[0];
- End = out;
-
- // FIXME: we don't need the compressed data anymore, could release
- // it already for better memory usage. Consider breaking const-co.
- DefaultLogger::get()->info("Successfully decompressed MSZIP-compressed file");
-#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
- }
- else
- {
- // start reading here
- ReadUntilEndOfLine();
- }
-
- mScene = new Scene;
- ParseFile();
-
- // filter the imported hierarchy for some degenerated cases
- if( mScene->mRootNode) {
- FilterHierarchy( mScene->mRootNode);
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor. Destroys all imported data along with it
-XFileParser::~XFileParser()
-{
- // kill everything we created
- delete mScene;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseFile()
-{
- bool running = true;
- while( running )
- {
- // read name of next object
- std::string objectName = GetNextToken();
- if (objectName.length() == 0)
- break;
-
- // parse specific object
- if( objectName == "template")
- ParseDataObjectTemplate();
- else
- if( objectName == "Frame")
- ParseDataObjectFrame( NULL);
- else
- if( objectName == "Mesh")
- {
- // some meshes have no frames at all
- Mesh* mesh = new Mesh;
- ParseDataObjectMesh( mesh);
- mScene->mGlobalMeshes.push_back( mesh);
- } else
- if( objectName == "AnimTicksPerSecond")
- ParseDataObjectAnimTicksPerSecond();
- else
- if( objectName == "AnimationSet")
- ParseDataObjectAnimationSet();
- else
- if( objectName == "Material")
- {
- // Material outside of a mesh or node
- Material material;
- ParseDataObjectMaterial( &material);
- mScene->mGlobalMaterials.push_back( material);
- } else
- if( objectName == "}")
- {
- // whatever?
- DefaultLogger::get()->warn("} found in dataObject");
- } else
- {
- // unknown format
- DefaultLogger::get()->warn("Unknown data object in animation of .x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTemplate()
-{
- // parse a template data object. Currently not stored.
- std::string name;
- readHeadOfDataObject( &name);
-
- // read GUID
- std::string guid = GetNextToken();
-
- // read and ignore data members
- bool running = true;
- while ( running )
- {
- std::string s = GetNextToken();
-
- if( s == "}")
- break;
-
- if( s.length() == 0)
- ThrowException( "Unexpected end of file reached while parsing template definition");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectFrame( Node* pParent)
-{
- // A coordinate frame, or "frame of reference." The Frame template
- // is open and can contain any object. The Direct3D extensions (D3DX)
- // mesh-loading functions recognize Mesh, FrameTransformMatrix, and
- // Frame template instances as child objects when loading a Frame
- // instance.
- std::string name;
- readHeadOfDataObject(&name);
-
- // create a named node and place it at its parent, if given
- Node* node = new Node( pParent);
- node->mName = name;
- if( pParent)
- {
- pParent->mChildren.push_back( node);
- } else
- {
- // there might be multiple root nodes
- if( mScene->mRootNode != NULL)
- {
- // place a dummy root if not there
- if( mScene->mRootNode->mName != "$dummy_root")
- {
- Node* exroot = mScene->mRootNode;
- mScene->mRootNode = new Node( NULL);
- mScene->mRootNode->mName = "$dummy_root";
- mScene->mRootNode->mChildren.push_back( exroot);
- exroot->mParent = mScene->mRootNode;
- }
- // put the new node as its child instead
- mScene->mRootNode->mChildren.push_back( node);
- node->mParent = mScene->mRootNode;
- } else
- {
- // it's the first node imported. place it as root
- mScene->mRootNode = node;
- }
- }
-
- // Now inside a frame.
- // read tokens until closing brace is reached.
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if (objectName.size() == 0)
- ThrowException( "Unexpected end of file reached while parsing frame");
-
- if( objectName == "}")
- break; // frame finished
- else
- if( objectName == "Frame")
- ParseDataObjectFrame( node); // child frame
- else
- if( objectName == "FrameTransformMatrix")
- ParseDataObjectTransformationMatrix( node->mTrafoMatrix);
- else
- if( objectName == "Mesh")
- {
- Mesh* mesh = new Mesh(name);
- node->mMeshes.push_back( mesh);
- ParseDataObjectMesh( mesh);
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in frame in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix)
-{
- // read header, we're not interested if it has a name
- readHeadOfDataObject();
-
- // read its components
- pMatrix.a1 = ReadFloat(); pMatrix.b1 = ReadFloat();
- pMatrix.c1 = ReadFloat(); pMatrix.d1 = ReadFloat();
- pMatrix.a2 = ReadFloat(); pMatrix.b2 = ReadFloat();
- pMatrix.c2 = ReadFloat(); pMatrix.d2 = ReadFloat();
- pMatrix.a3 = ReadFloat(); pMatrix.b3 = ReadFloat();
- pMatrix.c3 = ReadFloat(); pMatrix.d3 = ReadFloat();
- pMatrix.a4 = ReadFloat(); pMatrix.b4 = ReadFloat();
- pMatrix.c4 = ReadFloat(); pMatrix.d4 = ReadFloat();
-
- // trailing symbols
- CheckForSemicolon();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
-{
- std::string name;
- readHeadOfDataObject( &name);
-
- // read vertex count
- unsigned int numVertices = ReadInt();
- pMesh->mPositions.resize( numVertices);
-
- // read vertices
- for( unsigned int a = 0; a < numVertices; a++)
- pMesh->mPositions[a] = ReadVector3();
-
- // read position faces
- unsigned int numPosFaces = ReadInt();
- pMesh->mPosFaces.resize( numPosFaces);
- for( unsigned int a = 0; a < numPosFaces; a++)
- {
- // read indices
- unsigned int numIndices = ReadInt();
- Face& face = pMesh->mPosFaces[a];
- for (unsigned int b = 0; b < numIndices; b++) {
- face.mIndices.push_back( ReadInt() );
- }
- TestForSeparator();
- }
-
- // here, other data objects may follow
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
-
- if( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh structure");
- else
- if( objectName == "}")
- break; // mesh finished
- else
- if( objectName == "MeshNormals")
- ParseDataObjectMeshNormals( pMesh);
- else
- if( objectName == "MeshTextureCoords")
- ParseDataObjectMeshTextureCoords( pMesh);
- else
- if( objectName == "MeshVertexColors")
- ParseDataObjectMeshVertexColors( pMesh);
- else
- if( objectName == "MeshMaterialList")
- ParseDataObjectMeshMaterialList( pMesh);
- else
- if( objectName == "VertexDuplicationIndices")
- ParseUnknownDataObject(); // we'll ignore vertex duplication indices
- else
- if( objectName == "XSkinMeshHeader")
- ParseDataObjectSkinMeshHeader( pMesh);
- else
- if( objectName == "SkinWeights")
- ParseDataObjectSkinWeights( pMesh);
- else
- {
- DefaultLogger::get()->warn("Unknown data object in mesh in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectSkinWeights( Mesh *pMesh)
-{
- readHeadOfDataObject();
-
- std::string transformNodeName;
- GetNextTokenAsString( transformNodeName);
-
- pMesh->mBones.push_back( Bone());
- Bone& bone = pMesh->mBones.back();
- bone.mName = transformNodeName;
-
- // read vertex weights
- unsigned int numWeights = ReadInt();
- bone.mWeights.reserve( numWeights);
-
- for( unsigned int a = 0; a < numWeights; a++)
- {
- BoneWeight weight;
- weight.mVertex = ReadInt();
- bone.mWeights.push_back( weight);
- }
-
- // read vertex weights
- for( unsigned int a = 0; a < numWeights; a++)
- bone.mWeights[a].mWeight = ReadFloat();
-
- // read matrix offset
- bone.mOffsetMatrix.a1 = ReadFloat(); bone.mOffsetMatrix.b1 = ReadFloat();
- bone.mOffsetMatrix.c1 = ReadFloat(); bone.mOffsetMatrix.d1 = ReadFloat();
- bone.mOffsetMatrix.a2 = ReadFloat(); bone.mOffsetMatrix.b2 = ReadFloat();
- bone.mOffsetMatrix.c2 = ReadFloat(); bone.mOffsetMatrix.d2 = ReadFloat();
- bone.mOffsetMatrix.a3 = ReadFloat(); bone.mOffsetMatrix.b3 = ReadFloat();
- bone.mOffsetMatrix.c3 = ReadFloat(); bone.mOffsetMatrix.d3 = ReadFloat();
- bone.mOffsetMatrix.a4 = ReadFloat(); bone.mOffsetMatrix.b4 = ReadFloat();
- bone.mOffsetMatrix.c4 = ReadFloat(); bone.mOffsetMatrix.d4 = ReadFloat();
-
- CheckForSemicolon();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectSkinMeshHeader( Mesh* /*pMesh*/ )
-{
- readHeadOfDataObject();
-
- /*unsigned int maxSkinWeightsPerVertex =*/ ReadInt();
- /*unsigned int maxSkinWeightsPerFace =*/ ReadInt();
- /*unsigned int numBonesInMesh = */ReadInt();
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
-{
- readHeadOfDataObject();
-
- // read count
- unsigned int numNormals = ReadInt();
- pMesh->mNormals.resize( numNormals);
-
- // read normal vectors
- for( unsigned int a = 0; a < numNormals; a++)
- pMesh->mNormals[a] = ReadVector3();
-
- // read normal indices
- unsigned int numFaces = ReadInt();
- if( numFaces != pMesh->mPosFaces.size())
- ThrowException( "Normal face count does not match vertex face count.");
-
- for( unsigned int a = 0; a < numFaces; a++)
- {
- unsigned int numIndices = ReadInt();
- pMesh->mNormFaces.push_back( Face());
- Face& face = pMesh->mNormFaces.back();
-
- for( unsigned int b = 0; b < numIndices; b++)
- face.mIndices.push_back( ReadInt());
-
- TestForSeparator();
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshTextureCoords( Mesh* pMesh)
-{
- readHeadOfDataObject();
- if( pMesh->mNumTextures + 1 > AI_MAX_NUMBER_OF_TEXTURECOORDS)
- ThrowException( "Too many sets of texture coordinates");
-
- std::vector<aiVector2D>& coords = pMesh->mTexCoords[pMesh->mNumTextures++];
-
- unsigned int numCoords = ReadInt();
- if( numCoords != pMesh->mPositions.size())
- ThrowException( "Texture coord count does not match vertex count");
-
- coords.resize( numCoords);
- for( unsigned int a = 0; a < numCoords; a++)
- coords[a] = ReadVector2();
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshVertexColors( Mesh* pMesh)
-{
- readHeadOfDataObject();
- if( pMesh->mNumColorSets + 1 > AI_MAX_NUMBER_OF_COLOR_SETS)
- ThrowException( "Too many colorsets");
- std::vector<aiColor4D>& colors = pMesh->mColors[pMesh->mNumColorSets++];
-
- unsigned int numColors = ReadInt();
- if( numColors != pMesh->mPositions.size())
- ThrowException( "Vertex color count does not match vertex count");
-
- colors.resize( numColors, aiColor4D( 0, 0, 0, 1));
- for( unsigned int a = 0; a < numColors; a++)
- {
- unsigned int index = ReadInt();
- if( index >= pMesh->mPositions.size())
- ThrowException( "Vertex color index out of bounds");
-
- colors[index] = ReadRGBA();
- // HACK: (thom) Maxon Cinema XPort plugin puts a third separator here, kwxPort puts a comma.
- // Ignore gracefully.
- if( !mIsBinaryFormat)
- {
- FindNextNoneWhiteSpace();
- if( *P == ';' || *P == ',')
- P++;
- }
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMeshMaterialList( Mesh* pMesh)
-{
- readHeadOfDataObject();
-
- // read material count
- /*unsigned int numMaterials =*/ ReadInt();
- // read non triangulated face material index count
- unsigned int numMatIndices = ReadInt();
-
- // some models have a material index count of 1... to be able to read them we
- // replicate this single material index on every face
- if( numMatIndices != pMesh->mPosFaces.size() && numMatIndices != 1)
- ThrowException( "Per-Face material index count does not match face count.");
-
- // read per-face material indices
- for( unsigned int a = 0; a < numMatIndices; a++)
- pMesh->mFaceMaterials.push_back( ReadInt());
-
- // in version 03.02, the face indices end with two semicolons.
- // commented out version check, as version 03.03 exported from blender also has 2 semicolons
- if( !mIsBinaryFormat) // && MajorVersion == 3 && MinorVersion <= 2)
- {
- if(P < End && *P == ';')
- ++P;
- }
-
- // if there was only a single material index, replicate it on all faces
- while( pMesh->mFaceMaterials.size() < pMesh->mPosFaces.size())
- pMesh->mFaceMaterials.push_back( pMesh->mFaceMaterials.front());
-
- // read following data objects
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh material list.");
- else
- if( objectName == "}")
- break; // material list finished
- else
- if( objectName == "{")
- {
- // template materials
- std::string matName = GetNextToken();
- Material material;
- material.mIsReference = true;
- material.mName = matName;
- pMesh->mMaterials.push_back( material);
-
- CheckForClosingBrace(); // skip }
- } else
- if( objectName == "Material")
- {
- pMesh->mMaterials.push_back( Material());
- ParseDataObjectMaterial( &pMesh->mMaterials.back());
- } else
- if( objectName == ";")
- {
- // ignore
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in material list in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectMaterial( Material* pMaterial)
-{
- std::string matName;
- readHeadOfDataObject( &matName);
- if( matName.empty())
- matName = std::string( "material") + to_string( mLineNumber );
- pMaterial->mName = matName;
- pMaterial->mIsReference = false;
-
- // read material values
- pMaterial->mDiffuse = ReadRGBA();
- pMaterial->mSpecularExponent = ReadFloat();
- pMaterial->mSpecular = ReadRGB();
- pMaterial->mEmissive = ReadRGB();
-
- // read other data objects
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if( objectName.size() == 0)
- ThrowException( "Unexpected end of file while parsing mesh material");
- else
- if( objectName == "}")
- break; // material finished
- else
- if( objectName == "TextureFilename" || objectName == "TextureFileName")
- {
- // some exporters write "TextureFileName" instead.
- std::string texname;
- ParseDataObjectTextureFilename( texname);
- pMaterial->mTextures.push_back( TexEntry( texname));
- } else
- if( objectName == "NormalmapFilename" || objectName == "NormalmapFileName")
- {
- // one exporter writes out the normal map in a separate filename tag
- std::string texname;
- ParseDataObjectTextureFilename( texname);
- pMaterial->mTextures.push_back( TexEntry( texname, true));
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in material in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimTicksPerSecond()
-{
- readHeadOfDataObject();
- mScene->mAnimTicksPerSecond = ReadInt();
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimationSet()
-{
- std::string animName;
- readHeadOfDataObject( &animName);
-
- Animation* anim = new Animation;
- mScene->mAnims.push_back( anim);
- anim->mName = animName;
-
- bool running = true;
- while ( running )
- {
- std::string objectName = GetNextToken();
- if( objectName.length() == 0)
- ThrowException( "Unexpected end of file while parsing animation set.");
- else
- if( objectName == "}")
- break; // animation set finished
- else
- if( objectName == "Animation")
- ParseDataObjectAnimation( anim);
- else
- {
- DefaultLogger::get()->warn("Unknown data object in animation set in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimation( Animation* pAnim)
-{
- readHeadOfDataObject();
- AnimBone* banim = new AnimBone;
- pAnim->mAnims.push_back( banim);
-
- bool running = true;
- while( running )
- {
- std::string objectName = GetNextToken();
-
- if( objectName.length() == 0)
- ThrowException( "Unexpected end of file while parsing animation.");
- else
- if( objectName == "}")
- break; // animation finished
- else
- if( objectName == "AnimationKey")
- ParseDataObjectAnimationKey( banim);
- else
- if( objectName == "AnimationOptions")
- ParseUnknownDataObject(); // not interested
- else
- if( objectName == "{")
- {
- // read frame name
- banim->mBoneName = GetNextToken();
- CheckForClosingBrace();
- } else
- {
- DefaultLogger::get()->warn("Unknown data object in animation in x file");
- ParseUnknownDataObject();
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectAnimationKey( AnimBone* pAnimBone)
-{
- readHeadOfDataObject();
-
- // read key type
- unsigned int keyType = ReadInt();
-
- // read number of keys
- unsigned int numKeys = ReadInt();
-
- for( unsigned int a = 0; a < numKeys; a++)
- {
- // read time
- unsigned int time = ReadInt();
-
- // read keys
- switch( keyType)
- {
- case 0: // rotation quaternion
- {
- // read count
- if( ReadInt() != 4)
- ThrowException( "Invalid number of arguments for quaternion key in animation");
-
- aiQuatKey key;
- key.mTime = double( time);
- key.mValue.w = ReadFloat();
- key.mValue.x = ReadFloat();
- key.mValue.y = ReadFloat();
- key.mValue.z = ReadFloat();
- pAnimBone->mRotKeys.push_back( key);
-
- CheckForSemicolon();
- break;
- }
-
- case 1: // scale vector
- case 2: // position vector
- {
- // read count
- if( ReadInt() != 3)
- ThrowException( "Invalid number of arguments for vector key in animation");
-
- aiVectorKey key;
- key.mTime = double( time);
- key.mValue = ReadVector3();
-
- if( keyType == 2)
- pAnimBone->mPosKeys.push_back( key);
- else
- pAnimBone->mScaleKeys.push_back( key);
-
- break;
- }
-
- case 3: // combined transformation matrix
- case 4: // denoted both as 3 or as 4
- {
- // read count
- if( ReadInt() != 16)
- ThrowException( "Invalid number of arguments for matrix key in animation");
-
- // read matrix
- MatrixKey key;
- key.mTime = double( time);
- key.mMatrix.a1 = ReadFloat(); key.mMatrix.b1 = ReadFloat();
- key.mMatrix.c1 = ReadFloat(); key.mMatrix.d1 = ReadFloat();
- key.mMatrix.a2 = ReadFloat(); key.mMatrix.b2 = ReadFloat();
- key.mMatrix.c2 = ReadFloat(); key.mMatrix.d2 = ReadFloat();
- key.mMatrix.a3 = ReadFloat(); key.mMatrix.b3 = ReadFloat();
- key.mMatrix.c3 = ReadFloat(); key.mMatrix.d3 = ReadFloat();
- key.mMatrix.a4 = ReadFloat(); key.mMatrix.b4 = ReadFloat();
- key.mMatrix.c4 = ReadFloat(); key.mMatrix.d4 = ReadFloat();
- pAnimBone->mTrafoKeys.push_back( key);
-
- CheckForSemicolon();
- break;
- }
-
- default:
- ThrowException( format() << "Unknown key type " << keyType << " in animation." );
- break;
- } // end switch
-
- // key separator
- CheckForSeparator();
- }
-
- CheckForClosingBrace();
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseDataObjectTextureFilename( std::string& pName)
-{
- readHeadOfDataObject();
- GetNextTokenAsString( pName);
- CheckForClosingBrace();
-
- // FIX: some files (e.g. AnimationTest.x) have "" as texture file name
- if (!pName.length())
- {
- DefaultLogger::get()->warn("Length of texture file name is zero. Skipping this texture.");
- }
-
- // some exporters write double backslash paths out. We simply replace them if we find them
- while( pName.find( "\\\\") != std::string::npos)
- pName.replace( pName.find( "\\\\"), 2, "\\");
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ParseUnknownDataObject()
-{
- // find opening delimiter
- bool running = true;
- while( running )
- {
- std::string t = GetNextToken();
- if( t.length() == 0)
- ThrowException( "Unexpected end of file while parsing unknown segment.");
-
- if( t == "{")
- break;
- }
-
- unsigned int counter = 1;
-
- // parse until closing delimiter
- while( counter > 0)
- {
- std::string t = GetNextToken();
-
- if( t.length() == 0)
- ThrowException( "Unexpected end of file while parsing unknown segment.");
-
- if( t == "{")
- ++counter;
- else
- if( t == "}")
- --counter;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for closing curly brace
-void XFileParser::CheckForClosingBrace()
-{
- if( GetNextToken() != "}")
- ThrowException( "Closing brace expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for one following semicolon
-void XFileParser::CheckForSemicolon()
-{
- if( mIsBinaryFormat)
- return;
-
- if( GetNextToken() != ";")
- ThrowException( "Semicolon expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-//! checks for a separator char, either a ',' or a ';'
-void XFileParser::CheckForSeparator()
-{
- if( mIsBinaryFormat)
- return;
-
- std::string token = GetNextToken();
- if( token != "," && token != ";")
- ThrowException( "Separator character (';' or ',') expected.");
-}
-
-// ------------------------------------------------------------------------------------------------
-// tests and possibly consumes a separator char, but does nothing if there was no separator
-void XFileParser::TestForSeparator()
-{
- if( mIsBinaryFormat)
- return;
-
- FindNextNoneWhiteSpace();
- if( P >= End)
- return;
-
- // test and skip
- if( *P == ';' || *P == ',')
- P++;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::readHeadOfDataObject( std::string* poName)
-{
- std::string nameOrBrace = GetNextToken();
- if( nameOrBrace != "{")
- {
- if( poName)
- *poName = nameOrBrace;
-
- if( GetNextToken() != "{")
- ThrowException( "Opening brace expected.");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string XFileParser::GetNextToken()
-{
- std::string s;
-
- // process binary-formatted file
- if( mIsBinaryFormat)
- {
- // in binary mode it will only return NAME and STRING token
- // and (correctly) skip over other tokens.
-
- if( End - P < 2) return s;
- unsigned int tok = ReadBinWord();
- unsigned int len;
-
- // standalone tokens
- switch( tok)
- {
- case 1:
- // name token
- if( End - P < 4) return s;
- len = ReadBinDWord();
- if( End - P < int(len)) return s;
- s = std::string(P, len);
- P += len;
- return s;
- case 2:
- // string token
- if( End - P < 4) return s;
- len = ReadBinDWord();
- if( End - P < int(len)) return s;
- s = std::string(P, len);
- P += (len + 2);
- return s;
- case 3:
- // integer token
- P += 4;
- return "<integer>";
- case 5:
- // GUID token
- P += 16;
- return "<guid>";
- case 6:
- if( End - P < 4) return s;
- len = ReadBinDWord();
- P += (len * 4);
- return "<int_list>";
- case 7:
- if( End - P < 4) return s;
- len = ReadBinDWord();
- P += (len * mBinaryFloatSize);
- return "<flt_list>";
- case 0x0a:
- return "{";
- case 0x0b:
- return "}";
- case 0x0c:
- return "(";
- case 0x0d:
- return ")";
- case 0x0e:
- return "[";
- case 0x0f:
- return "]";
- case 0x10:
- return "<";
- case 0x11:
- return ">";
- case 0x12:
- return ".";
- case 0x13:
- return ",";
- case 0x14:
- return ";";
- case 0x1f:
- return "template";
- case 0x28:
- return "WORD";
- case 0x29:
- return "DWORD";
- case 0x2a:
- return "FLOAT";
- case 0x2b:
- return "DOUBLE";
- case 0x2c:
- return "CHAR";
- case 0x2d:
- return "UCHAR";
- case 0x2e:
- return "SWORD";
- case 0x2f:
- return "SDWORD";
- case 0x30:
- return "void";
- case 0x31:
- return "string";
- case 0x32:
- return "unicode";
- case 0x33:
- return "cstring";
- case 0x34:
- return "array";
- }
- }
- // process text-formatted file
- else
- {
- FindNextNoneWhiteSpace();
- if( P >= End)
- return s;
-
- while( (P < End) && !isspace( (unsigned char) *P))
- {
- // either keep token delimiters when already holding a token, or return if first valid char
- if( *P == ';' || *P == '}' || *P == '{' || *P == ',')
- {
- if( !s.size())
- s.append( P++, 1);
- break; // stop for delimiter
- }
- s.append( P++, 1);
- }
- }
- return s;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::FindNextNoneWhiteSpace()
-{
- if( mIsBinaryFormat)
- return;
-
- bool running = true;
- while( running )
- {
- while( P < End && isspace( (unsigned char) *P))
- {
- if( *P == '\n')
- mLineNumber++;
- ++P;
- }
-
- if( P >= End)
- return;
-
- // check if this is a comment
- if( (P[0] == '/' && P[1] == '/') || P[0] == '#')
- ReadUntilEndOfLine();
- else
- break;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::GetNextTokenAsString( std::string& poString)
-{
- if( mIsBinaryFormat)
- {
- poString = GetNextToken();
- return;
- }
-
- FindNextNoneWhiteSpace();
- if( P >= End)
- ThrowException( "Unexpected end of file while parsing string");
-
- if( *P != '"')
- ThrowException( "Expected quotation mark.");
- ++P;
-
- while( P < End && *P != '"')
- poString.append( P++, 1);
-
- if( P >= End-1)
- ThrowException( "Unexpected end of file while parsing string");
-
- if( P[1] != ';' || P[0] != '"')
- ThrowException( "Expected quotation mark and semicolon at the end of a string.");
- P+=2;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XFileParser::ReadUntilEndOfLine()
-{
- if( mIsBinaryFormat)
- return;
-
- while( P < End)
- {
- if( *P == '\n' || *P == '\r')
- {
- ++P; mLineNumber++;
- return;
- }
-
- ++P;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned short XFileParser::ReadBinWord()
-{
- ai_assert(End - P >= 2);
- const unsigned char* q = (const unsigned char*) P;
- unsigned short tmp = q[0] | (q[1] << 8);
- P += 2;
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XFileParser::ReadBinDWord()
-{
- ai_assert(End - P >= 4);
- const unsigned char* q = (const unsigned char*) P;
- unsigned int tmp = q[0] | (q[1] << 8) | (q[2] << 16) | (q[3] << 24);
- P += 4;
- return tmp;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XFileParser::ReadInt()
-{
- if( mIsBinaryFormat)
- {
- if( mBinaryNumCount == 0 && End - P >= 2)
- {
- unsigned short tmp = ReadBinWord(); // 0x06 or 0x03
- if( tmp == 0x06 && End - P >= 4) // array of ints follows
- mBinaryNumCount = ReadBinDWord();
- else // single int follows
- mBinaryNumCount = 1;
- }
-
- --mBinaryNumCount;
- if ( End - P >= 4) {
- return ReadBinDWord();
- } else {
- P = End;
- return 0;
- }
- } else
- {
- FindNextNoneWhiteSpace();
-
- // TODO: consider using strtol10 instead???
-
- // check preceding minus sign
- bool isNegative = false;
- if( *P == '-')
- {
- isNegative = true;
- P++;
- }
-
- // at least one digit expected
- if( !isdigit( *P))
- ThrowException( "Number expected.");
-
- // read digits
- unsigned int number = 0;
- while( P < End)
- {
- if( !isdigit( *P))
- break;
- number = number * 10 + (*P - 48);
- P++;
- }
-
- CheckForSeparator();
- return isNegative ? ((unsigned int) -int( number)) : number;
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-ai_real XFileParser::ReadFloat()
-{
- if( mIsBinaryFormat)
- {
- if( mBinaryNumCount == 0 && End - P >= 2)
- {
- unsigned short tmp = ReadBinWord(); // 0x07 or 0x42
- if( tmp == 0x07 && End - P >= 4) // array of floats following
- mBinaryNumCount = ReadBinDWord();
- else // single float following
- mBinaryNumCount = 1;
- }
-
- --mBinaryNumCount;
- if( mBinaryFloatSize == 8)
- {
- if( End - P >= 8) {
- ai_real result = (ai_real) (*(double*) P);
- P += 8;
- return result;
- } else {
- P = End;
- return 0;
- }
- } else
- {
- if( End - P >= 4) {
- ai_real result = *(ai_real*) P;
- P += 4;
- return result;
- } else {
- P = End;
- return 0;
- }
- }
- }
-
- // text version
- FindNextNoneWhiteSpace();
- // check for various special strings to allow reading files from faulty exporters
- // I mean you, Blender!
- // Reading is safe because of the terminating zero
- if( strncmp( P, "-1.#IND00", 9) == 0 || strncmp( P, "1.#IND00", 8) == 0)
- {
- P += 9;
- CheckForSeparator();
- return 0.0;
- } else
- if( strncmp( P, "1.#QNAN0", 8) == 0)
- {
- P += 8;
- CheckForSeparator();
- return 0.0;
- }
-
- ai_real result = 0.0;
- P = fast_atoreal_move<ai_real>( P, result);
-
- CheckForSeparator();
-
- return result;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector2D XFileParser::ReadVector2()
-{
- aiVector2D vector;
- vector.x = ReadFloat();
- vector.y = ReadFloat();
- TestForSeparator();
-
- return vector;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector3D XFileParser::ReadVector3()
-{
- aiVector3D vector;
- vector.x = ReadFloat();
- vector.y = ReadFloat();
- vector.z = ReadFloat();
- TestForSeparator();
-
- return vector;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiColor4D XFileParser::ReadRGBA()
-{
- aiColor4D color;
- color.r = ReadFloat();
- color.g = ReadFloat();
- color.b = ReadFloat();
- color.a = ReadFloat();
- TestForSeparator();
-
- return color;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiColor3D XFileParser::ReadRGB()
-{
- aiColor3D color;
- color.r = ReadFloat();
- color.g = ReadFloat();
- color.b = ReadFloat();
- TestForSeparator();
-
- return color;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Throws an exception with a line number and the given text.
-AI_WONT_RETURN void XFileParser::ThrowException( const std::string& pText)
-{
- if( mIsBinaryFormat)
- throw DeadlyImportError( pText);
- else
- throw DeadlyImportError( format() << "Line " << mLineNumber << ": " << pText );
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Filters the imported hierarchy for some degenerated cases that some exporters produce.
-void XFileParser::FilterHierarchy( XFile::Node* pNode)
-{
- // if the node has just a single unnamed child containing a mesh, remove
- // the anonymous node between. The 3DSMax kwXport plugin seems to produce this
- // mess in some cases
- if( pNode->mChildren.size() == 1 && pNode->mMeshes.empty() )
- {
- XFile::Node* child = pNode->mChildren.front();
- if( child->mName.length() == 0 && child->mMeshes.size() > 0)
- {
- // transfer its meshes to us
- for( unsigned int a = 0; a < child->mMeshes.size(); a++)
- pNode->mMeshes.push_back( child->mMeshes[a]);
- child->mMeshes.clear();
-
- // transfer the transform as well
- pNode->mTrafoMatrix = pNode->mTrafoMatrix * child->mTrafoMatrix;
-
- // then kill it
- delete child;
- pNode->mChildren.clear();
- }
- }
-
- // recurse
- for( unsigned int a = 0; a < pNode->mChildren.size(); a++)
- FilterHierarchy( pNode->mChildren[a]);
-}
-
-#endif // !! ASSIMP_BUILD_NO_X_IMPORTER
diff --git a/src/3rdparty/assimp/code/XFileParser.h b/src/3rdparty/assimp/code/XFileParser.h
deleted file mode 100644
index ec823bac0..000000000
--- a/src/3rdparty/assimp/code/XFileParser.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Helper class to parse a XFile into a temporary structure */
-#ifndef AI_XFILEPARSER_H_INC
-#define AI_XFILEPARSER_H_INC
-
-#include <string>
-#include <vector>
-
-#include <assimp/types.h>
-
-namespace Assimp
-{
- namespace XFile
- {
- struct Node;
- struct Mesh;
- struct Scene;
- struct Material;
- struct Animation;
- struct AnimBone;
- }
-
-/** The XFileParser reads a XFile either in text or binary form and builds a temporary
- * data structure out of it.
- */
-class XFileParser
-{
-public:
- /** Constructor. Creates a data structure out of the XFile given in the memory block.
- * @param pBuffer Null-terminated memory buffer containing the XFile
- */
- explicit XFileParser( const std::vector<char>& pBuffer);
-
- /** Destructor. Destroys all imported data along with it */
- ~XFileParser();
-
- /** Returns the temporary representation of the imported data */
- XFile::Scene* GetImportedData() const { return mScene; }
-
-protected:
- void ParseFile();
- void ParseDataObjectTemplate();
- void ParseDataObjectFrame( XFile::Node *pParent);
- void ParseDataObjectTransformationMatrix( aiMatrix4x4& pMatrix);
- void ParseDataObjectMesh( XFile::Mesh* pMesh);
- void ParseDataObjectSkinWeights( XFile::Mesh* pMesh);
- void ParseDataObjectSkinMeshHeader( XFile::Mesh* pMesh);
- void ParseDataObjectMeshNormals( XFile::Mesh* pMesh);
- void ParseDataObjectMeshTextureCoords( XFile::Mesh* pMesh);
- void ParseDataObjectMeshVertexColors( XFile::Mesh* pMesh);
- void ParseDataObjectMeshMaterialList( XFile::Mesh* pMesh);
- void ParseDataObjectMaterial( XFile::Material* pMaterial);
- void ParseDataObjectAnimTicksPerSecond();
- void ParseDataObjectAnimationSet();
- void ParseDataObjectAnimation( XFile::Animation* pAnim);
- void ParseDataObjectAnimationKey( XFile::AnimBone *pAnimBone);
- void ParseDataObjectTextureFilename( std::string& pName);
- void ParseUnknownDataObject();
-
- //! places pointer to next begin of a token, and ignores comments
- void FindNextNoneWhiteSpace();
-
- //! returns next parseable token. Returns empty string if no token there
- std::string GetNextToken();
-
- //! reads header of dataobject including the opening brace.
- //! returns false if error happened, and writes name of object
- //! if there is one
- void readHeadOfDataObject( std::string* poName = NULL);
-
- //! checks for closing curly brace, throws exception if not there
- void CheckForClosingBrace();
-
- //! checks for one following semicolon, throws exception if not there
- void CheckForSemicolon();
-
- //! checks for a separator char, either a ',' or a ';'
- void CheckForSeparator();
-
- /// tests and possibly consumes a separator char, but does nothing if there was no separator
- void TestForSeparator();
-
- //! reads a x file style string
- void GetNextTokenAsString( std::string& poString);
-
- void ReadUntilEndOfLine();
-
- unsigned short ReadBinWord();
- unsigned int ReadBinDWord();
- unsigned int ReadInt();
- ai_real ReadFloat();
- aiVector2D ReadVector2();
- aiVector3D ReadVector3();
- aiColor3D ReadRGB();
- aiColor4D ReadRGBA();
-
- /** Throws an exception with a line number and the given text. */
- AI_WONT_RETURN void ThrowException( const std::string& pText) AI_WONT_RETURN_SUFFIX;
-
- /** Filters the imported hierarchy for some degenerated cases that some exporters produce.
- * @param pData The sub-hierarchy to filter
- */
- void FilterHierarchy( XFile::Node* pNode);
-
-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 in bytes, either 4 or 8
- // counter for number arrays in binary format
- unsigned int mBinaryNumCount;
-
- const char* P;
- const char* End;
-
- /// Line number when reading in text format
- unsigned int mLineNumber;
-
- /// Imported data
- XFile::Scene* mScene;
-};
-
-}
-#endif // AI_XFILEPARSER_H_INC
diff --git a/src/3rdparty/assimp/code/XGLLoader.cpp b/src/3rdparty/assimp/code/XGLLoader.cpp
deleted file mode 100644
index 8ef91afac..000000000
--- a/src/3rdparty/assimp/code/XGLLoader.cpp
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Implementation of the XGL/ZGL importer class */
-
-
-#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
-
-#include "XGLLoader.h"
-#include "ParsingUtils.h"
-#include "fast_atof.h"
-
-#include "StreamReader.h"
-#include "MemoryIOWrapper.h"
-#include <assimp/mesh.h>
-#include <assimp/scene.h>
-#include <assimp/importerdesc.h>
-#include <cctype>
-#include <memory>
-
-using namespace Assimp;
-using namespace irr;
-using namespace irr::io;
-
-// zlib is needed for compressed XGL files
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
-# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-# include <zlib.h>
-# else
-# include <contrib/zlib/zlib.h>
-# endif
-#endif
-
-
-// scopeguard for a malloc'ed buffer
-struct free_it
-{
- free_it(void* free) : free(free) {}
- ~free_it() {
- ::free(this->free);
- }
-
- void* free;
-};
-
-namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
- template<> const char* LogFunctions<XGLImporter>::Prefix()
- {
- static auto prefix = "XGL: ";
- return prefix;
- }
-}
-
-static const aiImporterDesc desc = {
- "XGL Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
- 0,
- 0,
- 0,
- 0,
- "xgl zgl"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-XGLImporter::XGLImporter()
-: m_reader( nullptr )
-, m_scene( nullptr ) {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-XGLImporter::~XGLImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns whether the class can handle the format of the given file.
-bool XGLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- /* NOTE: A simple check for the file extension is not enough
- * here. XGL and ZGL are ok, but xml is too generic
- * and might be collada as well. So open the file and
- * look for typical signal tokens.
- */
- const std::string extension = GetExtension(pFile);
-
- if (extension == "xgl" || extension == "zgl") {
- return true;
- }
- else if (extension == "xml" || checkSig) {
- ai_assert(pIOHandler != NULL);
-
- const char* tokens[] = {"<world>","<World>","<WORLD>"};
- return SearchFileHeaderForToken(pIOHandler,pFile,tokens,3);
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Get a list of all file extensions which are handled by this class
-const aiImporterDesc* XGLImporter::GetInfo () const
-{
- return &desc;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void XGLImporter::InternReadFile( const std::string& pFile,
- aiScene* pScene, IOSystem* pIOHandler)
-{
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
- Bytef* dest = NULL;
- free_it free_it_really(dest);
-#endif
-
- m_scene = pScene;
- std::shared_ptr<IOStream> stream( pIOHandler->Open( pFile, "rb"));
-
- // check whether we can read from the file
- if( stream.get() == NULL) {
- throw DeadlyImportError( "Failed to open XGL/ZGL file " + pFile + "");
- }
-
- // see if its compressed, if so uncompress it
- if (GetExtension(pFile) == "zgl") {
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_XGL
- ThrowException("Cannot read ZGL file since Assimp was built without compression support");
-#else
- std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
-
- // build a zlib stream
- z_stream zstream;
- zstream.opaque = Z_NULL;
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.data_type = Z_BINARY;
-
- // raw decompression without a zlib or gzip header
- inflateInit2(&zstream, -MAX_WBITS);
-
- // skip two extra bytes, zgl files do carry a crc16 upfront (I think)
- raw_reader->IncPtr(2);
-
- zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
- zstream.avail_in = raw_reader->GetRemainingSize();
-
- size_t total = 0l;
-
- // and decompress the data .... do 1k chunks in the hope that we won't kill the stack
- #define MYBLOCK 1024
- Bytef block[MYBLOCK];
- int ret;
- do {
- zstream.avail_out = MYBLOCK;
- zstream.next_out = block;
- ret = inflate(&zstream, Z_NO_FLUSH);
-
- if (ret != Z_STREAM_END && ret != Z_OK) {
- ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
- }
- const size_t have = MYBLOCK - zstream.avail_out;
- total += have;
- dest = reinterpret_cast<Bytef*>( realloc(dest,total) );
- memcpy(dest + total - have,block,have);
- }
- while (ret != Z_STREAM_END);
-
- // terminate zlib
- inflateEnd(&zstream);
-
- // replace the input stream with a memory stream
- stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(dest),total));
-#endif
- }
-
- // construct the irrXML parser
- CIrrXML_IOStreamReader st(stream.get());
- m_reader.reset( createIrrXMLReader( ( IFileReadCallBack* ) &st ) );
-
- // parse the XML file
- TempScope scope;
-
- while (ReadElement()) {
- if (!ASSIMP_stricmp(m_reader->getNodeName(),"world")) {
- ReadWorld(scope);
- }
- }
-
-
- std::vector<aiMesh*>& meshes = scope.meshes_linear;
- std::vector<aiMaterial*>& materials = scope.materials_linear;
- if(!meshes.size() || !materials.size()) {
- ThrowException("failed to extract data from XGL file, no meshes loaded");
- }
-
- // copy meshes
- m_scene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- m_scene->mMeshes = new aiMesh*[m_scene->mNumMeshes]();
- std::copy(meshes.begin(),meshes.end(),m_scene->mMeshes);
-
- // copy materials
- m_scene->mNumMaterials = static_cast<unsigned int>(materials.size());
- m_scene->mMaterials = new aiMaterial*[m_scene->mNumMaterials]();
- std::copy(materials.begin(),materials.end(),m_scene->mMaterials);
-
- if (scope.light) {
- m_scene->mNumLights = 1;
- m_scene->mLights = new aiLight*[1];
- m_scene->mLights[0] = scope.light;
-
- scope.light->mName = m_scene->mRootNode->mName;
- }
-
- scope.dismiss();
-}
-
-// ------------------------------------------------------------------------------------------------
-bool XGLImporter::ReadElement()
-{
- while(m_reader->read()) {
- if (m_reader->getNodeType() == EXN_ELEMENT) {
- return true;
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool XGLImporter::ReadElementUpToClosing(const char* closetag)
-{
- while(m_reader->read()) {
- if (m_reader->getNodeType() == EXN_ELEMENT) {
- return true;
- }
- else if (m_reader->getNodeType() == EXN_ELEMENT_END && !ASSIMP_stricmp(m_reader->getNodeName(),closetag)) {
- return false;
- }
- }
- LogError("unexpected EOF, expected closing <" + std::string(closetag) + "> tag");
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool XGLImporter::SkipToText()
-{
- while(m_reader->read()) {
- if (m_reader->getNodeType() == EXN_TEXT) {
- return true;
- }
- else if (m_reader->getNodeType() == EXN_ELEMENT || m_reader->getNodeType() == EXN_ELEMENT_END) {
- ThrowException("expected text contents but found another element (or element end)");
- }
- }
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-std::string XGLImporter::GetElementName()
-{
- const char* s = m_reader->getNodeName();
- size_t len = strlen(s);
-
- std::string ret;
- ret.resize(len);
-
- std::transform(s,s+len,ret.begin(),::tolower);
- return ret;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XGLImporter::ReadWorld(TempScope& scope)
-{
- while (ReadElementUpToClosing("world")) {
- const std::string& s = GetElementName();
- // XXX right now we'd skip <lighting> if it comes after
- // <object> or <mesh>
- if (s == "lighting") {
- ReadLighting(scope);
- }
- else if (s == "object" || s == "mesh" || s == "mat") {
- break;
- }
- }
-
-
- aiNode* const nd = ReadObject(scope,true,"world");
- if(!nd) {
- ThrowException("failure reading <world>");
- }
- if(!nd->mName.length) {
- nd->mName.Set("WORLD");
- }
-
- m_scene->mRootNode = nd;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XGLImporter::ReadLighting(TempScope& scope)
-{
- while (ReadElementUpToClosing("lighting")) {
- const std::string& s = GetElementName();
- if (s == "directionallight") {
- scope.light = ReadDirectionalLight();
- }
- else if (s == "ambient") {
- LogWarn("ignoring <ambient> tag");
- }
- else if (s == "spheremap") {
- LogWarn("ignoring <spheremap> tag");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-aiLight* XGLImporter::ReadDirectionalLight()
-{
- std::unique_ptr<aiLight> l(new aiLight());
- l->mType = aiLightSource_DIRECTIONAL;
-
- while (ReadElementUpToClosing("directionallight")) {
- const std::string& s = GetElementName();
- if (s == "direction") {
- l->mDirection = ReadVec3();
- }
- else if (s == "diffuse") {
- l->mColorDiffuse = ReadCol3();
- }
- else if (s == "specular") {
- l->mColorSpecular = ReadCol3();
- }
- }
- return l.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiNode* XGLImporter::ReadObject(TempScope& scope, bool skipFirst, const char* closetag)
-{
- std::unique_ptr<aiNode> nd(new aiNode());
- std::vector<aiNode*> children;
- std::vector<unsigned int> meshes;
-
- try {
- while (skipFirst || ReadElementUpToClosing(closetag)) {
- skipFirst = false;
-
- const std::string& s = GetElementName();
- if (s == "mesh") {
- const size_t prev = scope.meshes_linear.size();
- if(ReadMesh(scope)) {
- const size_t newc = scope.meshes_linear.size();
- for(size_t i = 0; i < newc-prev; ++i) {
- meshes.push_back(static_cast<unsigned int>(i+prev));
- }
- }
- }
- else if (s == "mat") {
- ReadMaterial(scope);
- }
- else if (s == "object") {
- children.push_back(ReadObject(scope));
- }
- else if (s == "objectref") {
- // XXX
- }
- else if (s == "meshref") {
- 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 == id; ++it) {
- // ok, this is n^2 and should get optimized one day
- aiMesh* const m = (*it).second;
-
- unsigned int i = 0, mcount = static_cast<unsigned int>(scope.meshes_linear.size());
- for(; i < mcount; ++i) {
- if (scope.meshes_linear[i] == m) {
- meshes.push_back(i);
- break;
- }
- }
-
- ai_assert(i < mcount);
- }
- }
- else if (s == "transform") {
- nd->mTransformation = ReadTrafo();
- }
- }
-
- } catch(...) {
- for(aiNode* ch : children) {
- delete ch;
- }
- throw;
- }
-
- // FIX: since we used std::multimap<> to keep meshes by id, mesh order now depends on the behaviour
- // of the multimap implementation with respect to the ordering of entries with same values.
- // C++11 gives the guarantee that it uses insertion order, before it is implementation-specific.
- // Sort by material id to always guarantee a deterministic result.
- std::sort(meshes.begin(), meshes.end(), SortMeshByMaterialId(scope));
-
- // link meshes to node
- nd->mNumMeshes = static_cast<unsigned int>(meshes.size());
- if (nd->mNumMeshes) {
- nd->mMeshes = new unsigned int[nd->mNumMeshes]();
- for(unsigned int i = 0; i < nd->mNumMeshes; ++i) {
- nd->mMeshes[i] = meshes[i];
- }
- }
-
- // link children to parent
- nd->mNumChildren = static_cast<unsigned int>(children.size());
- if (nd->mNumChildren) {
- nd->mChildren = new aiNode*[nd->mNumChildren]();
- for(unsigned int i = 0; i < nd->mNumChildren; ++i) {
- nd->mChildren[i] = children[i];
- children[i]->mParent = nd.get();
- }
- }
-
- return nd.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMatrix4x4 XGLImporter::ReadTrafo()
-{
- aiVector3D forward, up, right, position;
- float scale = 1.0f;
-
- while (ReadElementUpToClosing("transform")) {
- const std::string& s = GetElementName();
- if (s == "forward") {
- forward = ReadVec3();
- }
- else if (s == "up") {
- up = ReadVec3();
- }
- else if (s == "position") {
- position = ReadVec3();
- }
- if (s == "scale") {
- scale = ReadFloat();
- if(scale < 0.f) {
- // this is wrong, but we can leave the value and pass it to the caller
- LogError("found negative scaling in <transform>, ignoring");
- }
- }
- }
-
- aiMatrix4x4 m;
- if(forward.SquareLength() < 1e-4 || up.SquareLength() < 1e-4) {
- LogError("A direction vector in <transform> is zero, ignoring trafo");
- return m;
- }
-
- forward.Normalize();
- up.Normalize();
-
- right = forward ^ up;
- if (std::fabs(up * forward) > 1e-4) {
- // this is definitely wrong - a degenerate coordinate space ruins everything
- // so subtitute identity transform.
- LogError("<forward> and <up> vectors in <transform> are skewing, ignoring trafo");
- return m;
- }
-
- right *= scale;
- up *= scale;
- forward *= scale;
-
- m.a1 = right.x;
- m.b1 = right.y;
- m.c1 = right.z;
-
- m.a2 = up.x;
- m.b2 = up.y;
- m.c2 = up.z;
-
- m.a3 = forward.x;
- m.b3 = forward.y;
- m.c3 = forward.z;
-
- m.a4 = position.x;
- m.b4 = position.y;
- m.c4 = position.z;
-
- return m;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh* XGLImporter::ToOutputMesh(const TempMaterialMesh& m)
-{
- std::unique_ptr<aiMesh> mesh(new aiMesh());
-
- mesh->mNumVertices = static_cast<unsigned int>(m.positions.size());
- mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- std::copy(m.positions.begin(),m.positions.end(),mesh->mVertices);
-
- if(m.normals.size()) {
- mesh->mNormals = new aiVector3D[mesh->mNumVertices];
- std::copy(m.normals.begin(),m.normals.end(),mesh->mNormals);
- }
-
- if(m.uvs.size()) {
- mesh->mNumUVComponents[0] = 2;
- mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
-
- for(unsigned int i = 0; i < mesh->mNumVertices; ++i) {
- mesh->mTextureCoords[0][i] = aiVector3D(m.uvs[i].x,m.uvs[i].y,0.f);
- }
- }
-
- mesh->mNumFaces = static_cast<unsigned int>(m.vcounts.size());
- mesh->mFaces = new aiFace[m.vcounts.size()];
-
- unsigned int idx = 0;
- for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
- aiFace& f = mesh->mFaces[i];
- f.mNumIndices = m.vcounts[i];
- f.mIndices = new unsigned int[f.mNumIndices];
- for(unsigned int c = 0; c < f.mNumIndices; ++c) {
- f.mIndices[c] = idx++;
- }
- }
-
- ai_assert(idx == mesh->mNumVertices);
-
- mesh->mPrimitiveTypes = m.pflags;
- mesh->mMaterialIndex = m.matid;
- return mesh.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-bool XGLImporter::ReadMesh(TempScope& scope)
-{
- TempMesh t;
-
- std::map<unsigned int, TempMaterialMesh> bymat;
- const unsigned int mesh_id = ReadIDAttr();
-
- while (ReadElementUpToClosing("mesh")) {
- const std::string& s = GetElementName();
-
- if (s == "mat") {
- ReadMaterial(scope);
- }
- else if (s == "p") {
- if (!m_reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <p>, ignoring");
- }
- else {
- int id = m_reader->getAttributeValueAsInt("ID");
- t.points[id] = ReadVec3();
- }
- }
- else if (s == "n") {
- if (!m_reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <n>, ignoring");
- }
- else {
- int id = m_reader->getAttributeValueAsInt("ID");
- t.normals[id] = ReadVec3();
- }
- }
- else if (s == "tc") {
- if (!m_reader->getAttributeValue("ID")) {
- LogWarn("no ID attribute on <tc>, ignoring");
- }
- else {
- int id = m_reader->getAttributeValueAsInt("ID");
- t.uvs[id] = ReadVec2();
- }
- }
- else if (s == "f" || s == "l" || s == "p") {
- const unsigned int vcount = s == "f" ? 3 : (s == "l" ? 2 : 1);
-
- unsigned int mid = ~0u;
- TempFace tf[3];
- bool has[3] = {0};
-
- while (ReadElementUpToClosing(s.c_str())) {
- const std::string& s = GetElementName();
- if (s == "fv1" || s == "lv1" || s == "pv1") {
- ReadFaceVertex(t,tf[0]);
- has[0] = true;
- }
- else if (s == "fv2" || s == "lv2") {
- ReadFaceVertex(t,tf[1]);
- has[1] = true;
- }
- else if (s == "fv3") {
- ReadFaceVertex(t,tf[2]);
- has[2] = true;
- }
- else if (s == "mat") {
- if (mid != ~0u) {
- LogWarn("only one material tag allowed per <f>");
- }
- mid = ResolveMaterialRef(scope);
- }
- else if (s == "matref") {
- if (mid != ~0u) {
- LogWarn("only one material tag allowed per <f>");
- }
- mid = ResolveMaterialRef(scope);
- }
- }
-
- if (mid == ~0u) {
- ThrowException("missing material index");
- }
-
- bool nor = false;
- bool uv = false;
- for(unsigned int i = 0; i < vcount; ++i) {
- if (!has[i]) {
- ThrowException("missing face vertex data");
- }
-
- nor = nor || tf[i].has_normal;
- uv = uv || tf[i].has_uv;
- }
-
- if (mid >= (1<<30)) {
- LogWarn("material indices exhausted, this may cause errors in the output");
- }
- unsigned int meshId = mid | ((nor?1:0)<<31) | ((uv?1:0)<<30);
-
- TempMaterialMesh& mesh = bymat[meshId];
- mesh.matid = mid;
-
- for(unsigned int i = 0; i < vcount; ++i) {
- mesh.positions.push_back(tf[i].pos);
- if(nor) {
- mesh.normals.push_back(tf[i].normal);
- }
- if(uv) {
- mesh.uvs.push_back(tf[i].uv);
- }
-
- mesh.pflags |= 1 << (vcount-1);
- }
-
- mesh.vcounts.push_back(vcount);
- }
- }
-
- // finally extract output meshes and add them to the scope
- typedef std::pair<unsigned int, TempMaterialMesh> pairt;
- for(const pairt& p : bymat) {
- aiMesh* const m = ToOutputMesh(p.second);
- scope.meshes_linear.push_back(m);
-
- // if this is a definition, keep it on the stack
- if(mesh_id != ~0u) {
- scope.meshes.insert(std::pair<unsigned int, aiMesh*>(mesh_id,m));
- }
- }
-
- // no id == not a reference, insert this mesh right *here*
- return mesh_id == ~0u;
-}
-
-// ----------------------------------------------------------------------------------------------
-unsigned int XGLImporter::ResolveMaterialRef(TempScope& scope)
-{
- const std::string& s = GetElementName();
- if (s == "mat") {
- ReadMaterial(scope);
- return static_cast<unsigned int>(scope.materials_linear.size()-1);
- }
-
- const int id = ReadIndexFromText();
-
- std::map<unsigned int, aiMaterial*>::iterator it = scope.materials.find(id), end = scope.materials.end();
- if (it == end) {
- ThrowException("<matref> index out of range");
- }
-
- // ok, this is n^2 and should get optimized one day
- aiMaterial* const m = (*it).second;
-
- unsigned int i = 0, mcount = static_cast<unsigned int>(scope.materials_linear.size());
- for(; i < mcount; ++i) {
- if (scope.materials_linear[i] == m) {
- return i;
- }
- }
-
- ai_assert(false);
- return 0;
-}
-
-// ------------------------------------------------------------------------------------------------
-void XGLImporter::ReadMaterial(TempScope& scope)
-{
- const unsigned int mat_id = ReadIDAttr();
-
- std::unique_ptr<aiMaterial> mat(new aiMaterial());
- while (ReadElementUpToClosing("mat")) {
- const std::string& s = GetElementName();
- if (s == "amb") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);
- }
- else if (s == "diff") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
- }
- else if (s == "spec") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
- }
- else if (s == "emiss") {
- const aiColor3D c = ReadCol3();
- mat->AddProperty(&c,1,AI_MATKEY_COLOR_EMISSIVE);
- }
- else if (s == "alpha") {
- const float f = ReadFloat();
- mat->AddProperty(&f,1,AI_MATKEY_OPACITY);
- }
- else if (s == "shine") {
- const float f = ReadFloat();
- mat->AddProperty(&f,1,AI_MATKEY_SHININESS);
- }
- }
-
- scope.materials[mat_id] = mat.get();
- scope.materials_linear.push_back(mat.release());
-}
-
-
-// ----------------------------------------------------------------------------------------------
-void XGLImporter::ReadFaceVertex(const TempMesh& t, TempFace& out)
-{
- const std::string& end = GetElementName();
-
- bool havep = false;
- while (ReadElementUpToClosing(end.c_str())) {
- const std::string& s = GetElementName();
- if (s == "pref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector3D>::const_iterator it = t.points.find(id);
- if (it == t.points.end()) {
- ThrowException("point index out of range");
- }
-
- out.pos = (*it).second;
- havep = true;
- }
- else if (s == "nref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector3D>::const_iterator it = t.normals.find(id);
- if (it == t.normals.end()) {
- ThrowException("normal index out of range");
- }
-
- out.normal = (*it).second;
- out.has_normal = true;
- }
- else if (s == "tcref") {
- const unsigned int id = ReadIndexFromText();
- std::map<unsigned int, aiVector2D>::const_iterator it = t.uvs.find(id);
- if (it == t.uvs.end()) {
- ThrowException("uv index out of range");
- }
-
- out.uv = (*it).second;
- out.has_uv = true;
- }
- else if (s == "p") {
- out.pos = ReadVec3();
- }
- else if (s == "n") {
- out.normal = ReadVec3();
- }
- else if (s == "tc") {
- out.uv = ReadVec2();
- }
- }
-
- if (!havep) {
- ThrowException("missing <pref> in <fvN> element");
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XGLImporter::ReadIDAttr()
-{
- for(int i = 0, e = m_reader->getAttributeCount(); i < e; ++i) {
-
- if(!ASSIMP_stricmp(m_reader->getAttributeName(i),"id")) {
- return m_reader->getAttributeValueAsInt(i);
- }
- }
- return ~0u;
-}
-
-// ------------------------------------------------------------------------------------------------
-float XGLImporter::ReadFloat()
-{
- if(!SkipToText()) {
- LogError("unexpected EOF reading float element contents");
- return 0.f;
- }
- const char* s = m_reader->getNodeData(), *se;
-
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse float");
- return 0.f;
- }
-
- float t;
- se = fast_atoreal_move(s,t);
-
- if (se == s) {
- LogError("failed to read float text");
- return 0.f;
- }
-
- return t;
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int XGLImporter::ReadIndexFromText()
-{
- if(!SkipToText()) {
- LogError("unexpected EOF reading index element contents");
- return ~0u;
- }
- const char* s = m_reader->getNodeData(), *se;
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse index element");
- return ~0u;
- }
-
- const unsigned int t = strtoul10(s,&se);
-
- if (se == s) {
- LogError("failed to read index");
- return ~0u;
- }
-
- return t;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector2D XGLImporter::ReadVec2()
-{
- aiVector2D vec;
-
- if(!SkipToText()) {
- LogError("unexpected EOF reading vec2 contents");
- return vec;
- }
- const char* s = m_reader->getNodeData();
-
- for(int i = 0; i < 2; ++i) {
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse vec2");
- return vec;
- }
- vec[i] = fast_atof(&s);
-
- SkipSpaces(&s);
- if (i != 1 && *s != ',') {
- LogError("expected comma, failed to parse vec2");
- return vec;
- }
- ++s;
- }
-
- return vec;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiVector3D XGLImporter::ReadVec3()
-{
- aiVector3D vec;
-
- if(!SkipToText()) {
- LogError("unexpected EOF reading vec3 contents");
- return vec;
- }
- const char* s = m_reader->getNodeData();
-
- for(int i = 0; i < 3; ++i) {
- if(!SkipSpaces(&s)) {
- LogError("unexpected EOL, failed to parse vec3");
- return vec;
- }
- vec[i] = fast_atof(&s);
-
- SkipSpaces(&s);
- if (i != 2 && *s != ',') {
- LogError("expected comma, failed to parse vec3");
- return vec;
- }
- ++s;
- }
-
- return vec;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiColor3D XGLImporter::ReadCol3()
-{
- const aiVector3D& v = ReadVec3();
- if (v.x < 0.f || v.x > 1.0f || v.y < 0.f || v.y > 1.0f || v.z < 0.f || v.z > 1.0f) {
- LogWarn("color values out of range, ignoring");
- }
- return aiColor3D(v.x,v.y,v.z);
-}
-
-#endif
diff --git a/src/3rdparty/assimp/code/XGLLoader.h b/src/3rdparty/assimp/code/XGLLoader.h
deleted file mode 100644
index 97ae5f8a3..000000000
--- a/src/3rdparty/assimp/code/XGLLoader.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 XGLLoader.h
- * @brief Declaration of the .xgl/.zgl
- */
-#ifndef AI_XGLLOADER_H_INCLUDED
-#define AI_XGLLOADER_H_INCLUDED
-
-#include "BaseImporter.h"
-#include "irrXMLWrapper.h"
-#include "LogAux.h"
-#include <assimp/material.h>
-#include <assimp/Importer.hpp>
-#include <assimp/mesh.h>
-#include <assimp/light.h>
-#include <memory>
-#include <map>
-
-struct aiNode;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** XGL/ZGL importer.
- *
- * Spec: http://vizstream.aveva.com/release/vsplatform/XGLSpec.htm
- */
-class XGLImporter : public BaseImporter, public LogFunctions<XGLImporter>
-{
-public:
-
- XGLImporter();
- ~XGLImporter();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** Returns whether the class can handle the format of the given file.
- * See BaseImporter::CanRead() for details. */
- bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
- bool checkSig) const;
-
-protected:
-
- // -------------------------------------------------------------------
- /** Return importer meta information.
- * See #BaseImporter::GetInfo for the details */
- const aiImporterDesc* GetInfo () const;
-
- // -------------------------------------------------------------------
- /** Imports the given file into the given scene structure.
- * See BaseImporter::InternReadFile() for details */
- void InternReadFile( const std::string& pFile, aiScene* pScene,
- IOSystem* pIOHandler);
-
-private:
-
-
- struct TempScope
- {
- TempScope()
- : light()
- {}
-
- ~TempScope()
- {
- for(aiMesh* m : meshes_linear) {
- delete m;
- }
-
- for(aiMaterial* m : materials_linear) {
- delete m;
- }
-
- delete light;
- }
-
- void dismiss() {
- light = NULL;
- meshes_linear.clear();
- materials_linear.clear();
- meshes.clear();
- materials.clear();
- }
-
- std::multimap<unsigned int, aiMesh*> meshes;
- std::map<unsigned int, aiMaterial*> materials;
-
- std::vector<aiMesh*> meshes_linear;
- std::vector<aiMaterial*> materials_linear;
-
- aiLight* light;
- };
-
-
- struct SortMeshByMaterialId {
- SortMeshByMaterialId(const TempScope& scope) : scope(scope) {}
- bool operator()(unsigned int a, unsigned int b) const {
- return scope.meshes_linear[a]->mMaterialIndex < scope.meshes_linear[b]->mMaterialIndex;
- };
-
- const TempScope& scope;
- };
-
- struct TempMesh
- {
- std::map<unsigned int, aiVector3D> points;
- std::map<unsigned int, aiVector3D> normals;
- std::map<unsigned int, aiVector2D> uvs;
- };
-
- struct TempMaterialMesh
- {
- TempMaterialMesh()
- : pflags()
- , matid()
- {}
-
- std::vector<aiVector3D> positions, normals;
- std::vector<aiVector2D> uvs;
-
- std::vector<unsigned int> vcounts;
- unsigned int pflags;
- unsigned int matid;
- };
-
- struct TempFace
- {
- TempFace()
- : has_uv()
- , has_normal()
- {}
-
- aiVector3D pos;
- aiVector3D normal;
- aiVector2D uv;
- bool has_uv;
- bool has_normal;
- };
-
-private:
-
- void Cleanup();
-
- std::string GetElementName();
- bool ReadElement();
- bool ReadElementUpToClosing(const char* closetag);
- bool SkipToText();
- unsigned int ReadIDAttr();
-
- void ReadWorld(TempScope& scope);
- void ReadLighting(TempScope& scope);
- aiLight* ReadDirectionalLight();
- aiNode* ReadObject(TempScope& scope,bool skipFirst = false,const char* closetag = "object");
- bool ReadMesh(TempScope& scope);
- void ReadMaterial(TempScope& scope);
- aiVector2D ReadVec2();
- aiVector3D ReadVec3();
- aiColor3D ReadCol3();
- aiMatrix4x4 ReadTrafo();
- unsigned int ReadIndexFromText();
- float ReadFloat();
-
- aiMesh* ToOutputMesh(const TempMaterialMesh& m);
- void ReadFaceVertex(const TempMesh& t, TempFace& out);
- unsigned int ResolveMaterialRef(TempScope& scope);
-
-private:
- std::shared_ptr<irr::io::IrrXMLReader> m_reader;
- aiScene* m_scene;
-};
-
-} // end of namespace Assimp
-
-#endif // AI_IRRMESHIMPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/XMLTools.h b/src/3rdparty/assimp/code/XMLTools.h
deleted file mode 100644
index 5d31f885e..000000000
--- a/src/3rdparty/assimp/code/XMLTools.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_ASSIMP_XML_TOOLS_H
-#define INCLUDED_ASSIMP_XML_TOOLS_H
-
-#include <string>
-
-namespace Assimp {
- // XML escape the 5 XML special characters (",',<,> and &) in |data|
- // Based on http://stackoverflow.com/questions/5665231
- std::string XMLEscape(const std::string& data) {
- std::string buffer;
-
- const size_t size = data.size();
- buffer.reserve(size + size / 8);
- for(size_t i = 0; i < size; ++i) {
- const char c = data[i];
- switch(c) {
- case '&' :
- buffer.append("&amp;");
- break;
- case '\"':
- buffer.append("&quot;");
- break;
- case '\'':
- buffer.append("&apos;");
- break;
- case '<' :
- buffer.append("&lt;");
- break;
- case '>' :
- buffer.append("&gt;");
- break;
- default:
- buffer.append(&c, 1);
- break;
- }
- }
- return buffer;
- }
-}
-
-#endif // INCLUDED_ASSIMP_XML_TOOLS_H
diff --git a/src/3rdparty/assimp/code/assbin_chunks.h b/src/3rdparty/assimp/code/assbin_chunks.h
deleted file mode 100644
index 15e4af5e7..000000000
--- a/src/3rdparty/assimp/code/assbin_chunks.h
+++ /dev/null
@@ -1,196 +0,0 @@
-#ifndef INCLUDED_ASSBIN_CHUNKS_H
-#define INCLUDED_ASSBIN_CHUNKS_H
-
-#define ASSBIN_VERSION_MAJOR 1
-#define ASSBIN_VERSION_MINOR 0
-
-/**
-@page assfile .ASS File formats
-
-@section over Overview
-Assimp provides its own interchange format, which is intended to applications which need
-to serialize 3D-models and to reload them quickly. Assimp's file formats are designed to
-be read by Assimp itself. They encode additional information needed by Assimp to optimize
-its postprocessing pipeline. If you once apply specific steps to a scene, then save it
-and reread it from an ASS format using the same post processing settings, they won't
-be executed again.
-
-The format comes in two flavours: XML and binary - both of them hold a complete dump of
-the 'aiScene' data structure returned by the APIs. The focus for the binary format
-(<tt>.assbin</tt>) is fast loading. Optional deflate compression helps reduce file size. The XML
-flavour, <tt>.assxml</tt> or simply .xml, is just a plain-to-xml conversion of aiScene.
-
-ASSBIN is Assimp's binary interchange format. assimp_cmd (<tt>&lt;root&gt;/tools/assimp_cmd</tt>) is able to
-write it and the core library provides a loader for it.
-
-@section assxml XML File format
-
-The format is pretty much self-explanatory due to its similarity to the in-memory aiScene structure.
-With few exceptions, C structures are wrapped in XML elements.
-
-The DTD for ASSXML can be found in <tt>&lt;root&gt;/doc/AssXML_Scheme.xml</tt>. Or have look
-at the output files generated by assimp_cmd.
-
-@section assbin Binary file format
-
-The ASSBIN file format is composed of chunks to represent the hierarchical aiScene data structure.
-This makes the format extensible and allows backward-compatibility with future data structure
-versions. The <tt>&lt;root&gt;/code/assbin_chunks.h</tt> header contains some magic constants
-for use by stand-alone ASSBIN loaders. Also, Assimp's own file writer can be found
-in <tt>&lt;root&gt;/tools/assimp_cmd/WriteDumb.cpp</tt> (yes, the 'b' is no typo ...).
-
-@verbatim
-
--------------------------------------------------------------------------------
-1. File structure:
--------------------------------------------------------------------------------
-
-----------------------
-| Header (512 bytes) |
-----------------------
-| Variable chunks |
-----------------------
-
--------------------------------------------------------------------------------
-2. Definitions:
--------------------------------------------------------------------------------
-
-integer is four bytes wide, stored in little-endian byte order.
-short is two bytes wide, stored in little-endian byte order.
-byte is a single byte.
-string is an integer n followed by n UTF-8 characters, not terminated by zero
-float is an IEEE 754 single-precision floating-point value
-double is an IEEE 754 double-precision floating-point value
-t[n] is an array of n elements of type t
-
--------------------------------------------------------------------------------
-2. Header:
--------------------------------------------------------------------------------
-
-byte[44] Magic identification string for ASSBIN files.
- 'ASSIMP.binary'
-
-integer Major version of the Assimp library which wrote the file
-integer Minor version of the Assimp library which wrote the file
- match these against ASSBIN_VERSION_MAJOR and ASSBIN_VERSION_MINOR
-
-integer SVN revision of the Assimp library (intended for our internal
- debugging - if you write Ass files from your own APPs, set this value to 0.
-integer Assimp compile flags
-
-short 0 for normal files, 1 for shortened dumps for regression tests
- these should have the file extension assbin.regress
-
-short 1 if the data after the header is compressed with the DEFLATE algorithm,
- 0 for uncompressed files.
- For compressed files, the first integer after the header is
- always the uncompressed data size
-
-byte[256] Zero-terminated source file name, UTF-8
-byte[128] Zero-terminated command line parameters passed to assimp_cmd, UTF-8
-
-byte[64] Reserved for future use
----> Total length: 512 bytes
-
--------------------------------------------------------------------------------
-3. Chunks:
--------------------------------------------------------------------------------
-
-integer Magic chunk ID (ASSBIN_CHUNK_XXX)
-integer Chunk data length, in bytes
- (unknown chunks are possible, a good reader skips over them)
- (chunk-data-length does not include the first two integers)
-
-byte[n] chunk-data-length bytes of data, depending on the chunk type
-
-Chunks can contain nested chunks. Nested chunks are ALWAYS at the end of the chunk,
-their size is included in chunk-data-length.
-
-The chunk layout for all ASSIMP data structures is derived from their C declarations.
-The general 'rule' to get from Assimp headers to the serialized layout is:
-
- 1. POD members (i.e. aiMesh::mPrimitiveTypes, aiMesh::mNumVertices),
- in order of declaration.
-
- 2. Array-members (aiMesh::mFaces, aiMesh::mVertices, aiBone::mWeights),
- in order of declaration.
-
- 2. Object array members (i.e aiMesh::mBones, aiScene::mMeshes) are stored in
- subchunks directly following the data written in 1.) and 2.)
-
-
- Of course, there are some exceptions to this general order:
-
-[[aiScene]]
-
- - The root node holding the scene structure is naturally stored in
- a ASSBIN_CHUNK_AINODE subchunk following 1.) and 2.) (which is
- empty for aiScene).
-
-[[aiMesh]]
-
- - mTextureCoords and mNumUVComponents are serialized as follows:
-
- [number of used uv channels times]
- integer mNumUVComponents[n]
- float mTextureCoords[n][3]
-
- -> more than AI_MAX_TEXCOORD_CHANNELS can be stored. This allows Assimp
- builds with different settings for AI_MAX_TEXCOORD_CHANNELS to exchange
- data.
- -> the on-disk format always uses 3 floats to write UV coordinates.
- If mNumUVComponents[0] is 1, the corresponding mTextureCoords array
- consists of 3 floats.
-
- - The array member block of aiMesh is prefixed with an integer that specifies
- the kinds of vertex components actually present in the mesh. This is a
- bitwise combination of the ASSBIN_MESH_HAS_xxx constants.
-
-[[aiFace]]
-
- - mNumIndices is stored as short
- - mIndices are written as short, if aiMesh::mNumVertices<65536
-
-[[aiNode]]
-
- - mParent is omitted
-
-[[aiLight]]
-
- - mAttenuationXXX not written if aiLight::mType == aiLightSource_DIRECTIONAL
- - mAngleXXX not written if aiLight::mType != aiLightSource_SPOT
-
-[[aiMaterial]]
-
- - mNumAllocated is omitted, for obvious reasons :-)
-
-
- @endverbatim*/
-
-
-#define ASSBIN_HEADER_LENGTH 512
-
-// these are the magic chunk identifiers for the binary ASS file format
-#define ASSBIN_CHUNK_AICAMERA 0x1234
-#define ASSBIN_CHUNK_AILIGHT 0x1235
-#define ASSBIN_CHUNK_AITEXTURE 0x1236
-#define ASSBIN_CHUNK_AIMESH 0x1237
-#define ASSBIN_CHUNK_AINODEANIM 0x1238
-#define ASSBIN_CHUNK_AISCENE 0x1239
-#define ASSBIN_CHUNK_AIBONE 0x123a
-#define ASSBIN_CHUNK_AIANIMATION 0x123b
-#define ASSBIN_CHUNK_AINODE 0x123c
-#define ASSBIN_CHUNK_AIMATERIAL 0x123d
-#define ASSBIN_CHUNK_AIMATERIALPROPERTY 0x123e
-
-#define ASSBIN_MESH_HAS_POSITIONS 0x1
-#define ASSBIN_MESH_HAS_NORMALS 0x2
-#define ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS 0x4
-#define ASSBIN_MESH_HAS_TEXCOORD_BASE 0x100
-#define ASSBIN_MESH_HAS_COLOR_BASE 0x10000
-
-#define ASSBIN_MESH_HAS_TEXCOORD(n) (ASSBIN_MESH_HAS_TEXCOORD_BASE << n)
-#define ASSBIN_MESH_HAS_COLOR(n) (ASSBIN_MESH_HAS_COLOR_BASE << n)
-
-
-#endif // INCLUDED_ASSBIN_CHUNKS_H
diff --git a/src/3rdparty/assimp/code/fast_atof.h b/src/3rdparty/assimp/code/fast_atof.h
deleted file mode 100644
index 058a7ff87..000000000
--- a/src/3rdparty/assimp/code/fast_atof.h
+++ /dev/null
@@ -1,387 +0,0 @@
-#pragma once
-
-// Copyright (C) 2002-2007 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
-
-// ------------------------------------------------------------------------------------
-// Original description: (Schrompf)
-// Adapted to the ASSIMP library because the builtin atof indeed takes AGES to parse a
-// float inside a large string. Before parsing, it does a strlen on the given point.
-// Changes:
-// 22nd October 08 (Aramis_acg): Added temporary cast to double, added strtoul10_64
-// to ensure long numbers are handled correctly
-// ------------------------------------------------------------------------------------
-
-
-#ifndef __FAST_A_TO_F_H_INCLUDED__
-#define __FAST_A_TO_F_H_INCLUDED__
-
-#include <cmath>
-#include <limits>
-#include <stdint.h>
-#include <stdexcept>
-#include <assimp/defs.h>
-
-#include "StringComparison.h"
-#include <assimp/DefaultLogger.hpp>
-
-
-#ifdef _MSC_VER
-# include <stdint.h>
-#else
-# include <assimp/Compiler/pstdint.h>
-#endif
-
-namespace Assimp
-{
-
-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
-};
-
-
-// ------------------------------------------------------------------------------------
-// Convert a string in decimal format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtoul10( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in < '0' || *in > '9' )
- break;
-
- value = ( value * 10 ) + ( *in - '0' );
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a string in octal format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtoul8( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in < '0' || *in > '7' )
- break;
-
- value = ( value << 3 ) + ( *in - '0' );
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a string in hex format to a number
-// ------------------------------------------------------------------------------------
-inline unsigned int strtoul16( const char* in, const char** out=0)
-{
- unsigned int value = 0;
-
- bool running = true;
- while ( running )
- {
- if ( *in >= '0' && *in <= '9' )
- {
- value = ( value << 4u ) + ( *in - '0' );
- }
- else if (*in >= 'A' && *in <= 'F')
- {
- value = ( value << 4u ) + ( *in - 'A' ) + 10;
- }
- else if (*in >= 'a' && *in <= 'f')
- {
- value = ( value << 4u ) + ( *in - 'a' ) + 10;
- }
- else break;
- ++in;
- }
- if (out)*out = in;
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert just one hex digit
-// Return value is UINT_MAX if the input character is not a hex digit.
-// ------------------------------------------------------------------------------------
-inline unsigned int HexDigitToDecimal(char in)
-{
- unsigned int out = UINT_MAX;
- if (in >= '0' && in <= '9')
- out = in - '0';
-
- else if (in >= 'a' && in <= 'f')
- out = 10u + in - 'a';
-
- else if (in >= 'A' && in <= 'F')
- out = 10u + in - 'A';
-
- // return value is UINT_MAX if the input is not a hex digit
- return out;
-}
-
-// ------------------------------------------------------------------------------------
-// Convert a hex-encoded octet (2 characters, i.e. df or 1a).
-// ------------------------------------------------------------------------------------
-inline uint8_t HexOctetToDecimal(const char* in)
-{
- return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
-}
-
-
-// ------------------------------------------------------------------------------------
-// signed variant of strtoul10
-// ------------------------------------------------------------------------------------
-inline int strtol10( const char* in, const char** out=0)
-{
- bool inv = (*in=='-');
- if (inv || *in=='+')
- ++in;
-
- int value = strtoul10(in,out);
- if (inv) {
- value = -value;
- }
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// Parse a C++-like integer literal - hex and oct prefixes.
-// 0xNNNN - hex
-// 0NNN - oct
-// NNN - dec
-// ------------------------------------------------------------------------------------
-inline unsigned int strtoul_cppstyle( const char* in, const char** out=0)
-{
- if ('0' == in[0])
- {
- return 'x' == in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out);
- }
- return strtoul10(in, out);
-}
-
-// ------------------------------------------------------------------------------------
-// Special version of the function, providing higher accuracy and safety
-// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
-// ------------------------------------------------------------------------------------
-inline uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_inout=0)
-{
- 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 )
- {
- if ( *in < '0' || *in > '9' )
- break;
-
- const uint64_t new_value = ( value * 10 ) + ( *in - '0' );
-
- // numeric overflow, we rely on you
- if ( new_value < value ) {
- DefaultLogger::get()->warn( std::string( "Converting the string \"" ) + in + "\" into a value resulted in overflow." );
- return 0;
- }
- //throw std::overflow_error();
-
- value = new_value;
-
- ++in;
- ++cur;
-
- if (max_inout && *max_inout == cur) {
-
- if (out) { /* skip to end */
- while (*in >= '0' && *in <= '9')
- ++in;
- *out = in;
- }
-
- return value;
- }
- }
- if (out)
- *out = in;
-
- if (max_inout)
- *max_inout = cur;
-
- return value;
-}
-
-// ------------------------------------------------------------------------------------
-// signed variant of strtoul10_64
-// ------------------------------------------------------------------------------------
-inline int64_t strtol10_64(const char* in, const char** out = 0, unsigned int* max_inout = 0)
-{
- bool inv = (*in == '-');
- if (inv || *in == '+')
- ++in;
-
- int64_t value = strtoul10_64(in, out, max_inout);
- if (inv) {
- value = -value;
- }
- return value;
-}
-
-
-// Number of relevant decimals for floating-point parsing.
-#define AI_FAST_ATOF_RELAVANT_DECIMALS 15
-
-// ------------------------------------------------------------------------------------
-//! Provides a fast function for converting a string into a float,
-//! about 6 times faster than atof in win32.
-// 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, bool check_comma = true)
-{
- Real f = 0;
-
- bool inv = (*c == '-');
- if (inv || *c == '+') {
- ++c;
- }
-
- if ((c[0] == 'N' || c[0] == 'n') && ASSIMP_strincmp(c, "nan", 3) == 0)
- {
- out = std::numeric_limits<Real>::quiet_NaN();
- c += 3;
- return c;
- }
-
- if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inf", 3) == 0)
- {
- out = std::numeric_limits<Real>::infinity();
- if (inv) {
- out = -out;
- }
- c += 3;
- if ((c[0] == 'I' || c[0] == 'i') && ASSIMP_strincmp(c, "inity", 5) == 0)
- {
- c += 5;
- }
- return c;
- }
-
- if (!(c[0] >= '0' && c[0] <= '9') &&
- !((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9'))
- {
- throw std::invalid_argument("Cannot parse string "
- "as real number: does not start with digit "
- "or decimal point followed by digit.");
- }
-
- if (*c != '.' && (! check_comma || c[0] != ','))
- {
- f = static_cast<Real>( strtoul10_64 ( c, &c) );
- }
-
- if ((*c == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')
- {
- ++c;
-
- // NOTE: The original implementation is highly inaccurate here. The precision of a single
- // IEEE 754 float is not high enough, everything behind the 6th digit tends to be more
- // inaccurate than it would need to be. Casting to double seems to solve the problem.
- // strtol_64 is used to prevent integer overflow.
-
- // Another fix: this tends to become 0 for long numbers if we don't limit the maximum
- // number of digits to be read. AI_FAST_ATOF_RELAVANT_DECIMALS can be a value between
- // 1 and 15.
- unsigned int diff = AI_FAST_ATOF_RELAVANT_DECIMALS;
- double pl = static_cast<double>( strtoul10_64 ( c, &c, &diff ));
-
- pl *= fast_atof_table[diff];
- f += static_cast<Real>( pl );
- }
- // For backwards compatibility: eat trailing dots, but not trailing commas.
- else if (*c == '.') {
- ++c;
- }
-
- // A major 'E' must be allowed. Necessary for proper reading of some DXF files.
- // Thanks to Zhao Lei to point out that this if() must be outside the if (*c == '.' ..)
- if (*c == 'e' || *c == 'E') {
-
- ++c;
- const bool einv = (*c=='-');
- if (einv || *c=='+') {
- ++c;
- }
-
- // The reason float constants are used here is that we've seen cases where compilers
- // would perform such casts on compile-time constants at runtime, which would be
- // bad considering how frequently fast_atoreal_move<float> is called in Assimp.
- Real exp = static_cast<Real>( strtoul10_64(c, &c) );
- if (einv) {
- exp = -exp;
- }
- f *= std::pow(static_cast<Real>(10.0), exp);
- }
-
- if (inv) {
- f = -f;
- }
- out = f;
- return c;
-}
-
-// ------------------------------------------------------------------------------------
-// The same but more human.
-inline ai_real fast_atof(const char* c)
-{
- ai_real ret(0.0);
- fast_atoreal_move<ai_real>(c, ret);
- return ret;
-}
-
-
-inline ai_real fast_atof( const char* c, const char** cout)
-{
- ai_real ret(0.0);
- *cout = fast_atoreal_move<ai_real>(c, ret);
-
- return ret;
-}
-
-inline ai_real fast_atof( const char** inout)
-{
- ai_real ret(0.0);
- *inout = fast_atoreal_move<ai_real>(*inout, ret);
-
- return ret;
-}
-
-} // end of namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/code/glTF2Asset.h b/src/3rdparty/assimp/code/glTF2Asset.h
deleted file mode 100644
index cece307d9..000000000
--- a/src/3rdparty/assimp/code/glTF2Asset.h
+++ /dev/null
@@ -1,1131 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 glTFAsset.h
- * Declares a glTF class to handle gltf/glb files
- *
- * glTF Extensions Support:
- * KHR_materials_pbrSpecularGlossiness full
- */
-#ifndef GLTF2ASSET_H_INC
-#define GLTF2ASSET_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include <map>
-#include <string>
-#include <list>
-#include <vector>
-#include <algorithm>
-#include <stdexcept>
-
-#define RAPIDJSON_HAS_STDSTRING 1
-#include <rapidjson/rapidjson.h>
-#include <rapidjson/document.h>
-#include <rapidjson/error/en.h>
-
-#ifdef ASSIMP_API
-# include <memory>
-# include <assimp/DefaultIOSystem.h>
-# include "ByteSwapper.h"
-#else
-# include <memory>
-# define AI_SWAP4(p)
-# define ai_assert
-#endif
-
-
-#if _MSC_VER > 1500 || (defined __GNUC___)
-# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
-# else
-# define gltf_unordered_map map
-#endif
-
-#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
-# include <unordered_map>
-# if _MSC_VER > 1600
-# define gltf_unordered_map unordered_map
-# else
-# define gltf_unordered_map tr1::unordered_map
-# endif
-#endif
-
-#include "StringUtils.h"
-
-namespace glTF2
-{
-#ifdef ASSIMP_API
- using Assimp::IOStream;
- using Assimp::IOSystem;
- using std::shared_ptr;
-#else
- using std::shared_ptr;
-
- typedef std::runtime_error DeadlyImportError;
- typedef std::runtime_error DeadlyExportError;
-
- enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
- class IOSystem;
- class IOStream
- {
- FILE* f;
- public:
- IOStream(FILE* file) : f(file) {}
- ~IOStream() { fclose(f); f = 0; }
-
- size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
- size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
- int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
- size_t Tell() const { return ftell(f); }
-
- size_t FileSize() {
- long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
- return size_t((Seek(p, aiOrigin_SET), len));
- }
- };
-#endif
-
- using rapidjson::Value;
- using rapidjson::Document;
-
- class Asset;
- class AssetWriter;
-
- struct BufferView; // here due to cross-reference
- struct Texture;
- struct Skin;
-
- // Vec/matrix types, as raw float arrays
- typedef float (vec3)[3];
- typedef float (vec4)[4];
- typedef float (mat4)[16];
-
- namespace Util
- {
- void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
- size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
- inline size_t DecodeBase64(const char* in, uint8_t*& out)
- {
- return DecodeBase64(in, strlen(in), out);
- }
-
- struct DataURI
- {
- const char* mediaType;
- const char* charset;
- bool base64;
- const char* data;
- size_t dataLength;
- };
-
- //! Check if a uri is a data URI
- inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
- }
-
-
- //! Magic number for GLB files
- #define AI_GLB_MAGIC_NUMBER "glTF"
-
- #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
- #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
- #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
- #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
- #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0
- #define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0
- #define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
- #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
- #define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
-
- #define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
- #define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
- #define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid"
- #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag"
- #define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin"
-
- #define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
- #define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N
- #define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N
- #define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N
- #define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N
-
- #ifdef ASSIMP_API
- #include "./../include/assimp/Compiler/pushpack1.h"
- #endif
-
- //! For binary .glb files
- //! 12-byte header (+ the JSON + a "body" data section)
- struct GLB_Header
- {
- uint8_t magic[4]; //!< Magic number: "glTF"
- uint32_t version; //!< Version number (always 2 as of the last update)
- uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
- } PACK_STRUCT;
-
- struct GLB_Chunk
- {
- uint32_t chunkLength;
- uint32_t chunkType;
- } PACK_STRUCT;
-
- #ifdef ASSIMP_API
- #include "./../include/assimp/Compiler/poppack1.h"
- #endif
-
-
- //! Values for the GLB_Chunk::chunkType field
- enum ChunkType
- {
- ChunkType_JSON = 0x4E4F534A,
- ChunkType_BIN = 0x004E4942
- };
-
- //! Values for the mesh primitive modes
- enum PrimitiveMode
- {
- PrimitiveMode_POINTS = 0,
- PrimitiveMode_LINES = 1,
- PrimitiveMode_LINE_LOOP = 2,
- PrimitiveMode_LINE_STRIP = 3,
- PrimitiveMode_TRIANGLES = 4,
- PrimitiveMode_TRIANGLE_STRIP = 5,
- PrimitiveMode_TRIANGLE_FAN = 6
- };
-
- //! Values for the Accessor::componentType field
- enum ComponentType
- {
- ComponentType_BYTE = 5120,
- ComponentType_UNSIGNED_BYTE = 5121,
- ComponentType_SHORT = 5122,
- ComponentType_UNSIGNED_SHORT = 5123,
- ComponentType_UNSIGNED_INT = 5125,
- ComponentType_FLOAT = 5126
- };
-
- inline unsigned int ComponentTypeSize(ComponentType t)
- {
- switch (t) {
- case ComponentType_SHORT:
- case ComponentType_UNSIGNED_SHORT:
- return 2;
-
- case ComponentType_UNSIGNED_INT:
- case ComponentType_FLOAT:
- return 4;
-
- case ComponentType_BYTE:
- case ComponentType_UNSIGNED_BYTE:
- return 1;
- default:
- throw DeadlyImportError("GLTF: Unsupported Component Type " + to_string(t));
- }
- }
-
- //! Values for the BufferView::target field
- enum BufferViewTarget
- {
- BufferViewTarget_ARRAY_BUFFER = 34962,
- BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
- };
-
- //! Values for the Sampler::magFilter field
- enum class SamplerMagFilter: unsigned int
- {
- UNSET = 0,
- SamplerMagFilter_Nearest = 9728,
- SamplerMagFilter_Linear = 9729
- };
-
- //! Values for the Sampler::minFilter field
- enum class SamplerMinFilter: unsigned int
- {
- UNSET = 0,
- SamplerMinFilter_Nearest = 9728,
- SamplerMinFilter_Linear = 9729,
- SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
- SamplerMinFilter_Linear_Mipmap_Nearest = 9985,
- SamplerMinFilter_Nearest_Mipmap_Linear = 9986,
- SamplerMinFilter_Linear_Mipmap_Linear = 9987
- };
-
- //! Values for the Sampler::wrapS and Sampler::wrapT field
- enum class SamplerWrap: unsigned int
- {
- UNSET = 0,
- Clamp_To_Edge = 33071,
- Mirrored_Repeat = 33648,
- Repeat = 10497
- };
-
- //! Values for the Texture::format and Texture::internalFormat fields
- enum TextureFormat
- {
- TextureFormat_ALPHA = 6406,
- TextureFormat_RGB = 6407,
- TextureFormat_RGBA = 6408,
- TextureFormat_LUMINANCE = 6409,
- TextureFormat_LUMINANCE_ALPHA = 6410
- };
-
- //! Values for the Texture::target field
- enum TextureTarget
- {
- TextureTarget_TEXTURE_2D = 3553
- };
-
- //! Values for the Texture::type field
- enum TextureType
- {
- TextureType_UNSIGNED_BYTE = 5121,
- TextureType_UNSIGNED_SHORT_5_6_5 = 33635,
- TextureType_UNSIGNED_SHORT_4_4_4_4 = 32819,
- TextureType_UNSIGNED_SHORT_5_5_5_1 = 32820
- };
-
-
- //! Values for the Accessor::type field (helper class)
- class AttribType
- {
- public:
- enum Value
- { SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4 };
-
- private:
- static const size_t NUM_VALUES = static_cast<size_t>(MAT4)+1;
-
- struct Info
- { const char* name; unsigned int numComponents; };
-
- template<int N> struct data
- { static const Info infos[NUM_VALUES]; };
-
- public:
- inline static Value FromString(const char* str)
- {
- for (size_t i = 0; i < NUM_VALUES; ++i) {
- if (strcmp(data<0>::infos[i].name, str) == 0) {
- return static_cast<Value>(i);
- }
- }
- return SCALAR;
- }
-
- inline static const char* ToString(Value type)
- {
- return data<0>::infos[static_cast<size_t>(type)].name;
- }
-
- inline static unsigned int GetNumComponents(Value type)
- {
- return data<0>::infos[static_cast<size_t>(type)].numComponents;
- }
- };
-
- // must match the order of the AttribTypeTraits::Value enum!
- template<int N> const AttribType::Info
- AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
- { "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 }
- };
-
-
-
- //! A reference to one top-level object, which is valid
- //! until the Asset instance is destroyed
- template<class T>
- class Ref
- {
- std::vector<T*>* vector;
- unsigned int index;
-
- public:
- Ref() : vector(0), index(0) {}
- Ref(std::vector<T*>& vec, unsigned int idx) : vector(&vec), index(idx) {}
-
- inline unsigned int GetIndex() const
- { return index; }
-
- operator bool() const
- { return vector != 0; }
-
- T* operator->()
- { return (*vector)[index]; }
-
- T& operator*()
- { return *((*vector)[index]); }
- };
-
- //! Helper struct to represent values that might not be present
- template<class T>
- struct Nullable
- {
- T value;
- bool isPresent;
-
- Nullable() : isPresent(false) {}
- Nullable(T& val) : value(val), isPresent(true) {}
- };
-
-
- //! Base classe for all glTF top-level objects
- struct Object
- {
- int index; //!< The index of this object within its property container
- int oIndex; //!< The original index of this object defined in the JSON
- std::string id; //!< The globally unique ID used to reference this object
- std::string name; //!< The user-defined name of this object
-
- //! Objects marked as special are not exported (used to emulate the binary body buffer)
- virtual bool IsSpecial() const
- { return false; }
-
- virtual ~Object() {}
-
- //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
- static const char* TranslateId(Asset& /*r*/, const char* id)
- { return id; }
- };
-
- //
- // Classes for each glTF top-level object type
- //
-
- //! A typed view into a BufferView. A BufferView contains raw binary data.
- //! An accessor provides a typed view into a BufferView or a subset of a BufferView
- //! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
- struct Accessor : public Object
- {
- Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
- unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
- ComponentType componentType; //!< The datatype of components in the attribute. (required)
- unsigned int count; //!< The number of attributes referenced by this accessor. (required)
- AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
- std::vector<float> max; //!< Maximum value of each component in this attribute.
- std::vector<float> min; //!< Minimum value of each component in this attribute.
-
- unsigned int GetNumComponents();
- unsigned int GetBytesPerComponent();
- unsigned int GetElementSize();
-
- inline uint8_t* GetPointer();
-
- template<class T>
- bool ExtractData(T*& outData);
-
- void WriteData(size_t count, const void* src_buffer, size_t src_stride);
-
- //! Helper class to iterate the data
- class Indexer
- {
- friend struct Accessor;
-
- Accessor& accessor;
- uint8_t* data;
- size_t elemSize, stride;
-
- Indexer(Accessor& acc);
-
- public:
-
- //! Accesses the i-th value as defined by the accessor
- template<class T>
- T GetValue(int i);
-
- //! Accesses the i-th value as defined by the accessor
- inline unsigned int GetUInt(int i)
- {
- return GetValue<unsigned int>(i);
- }
-
- inline bool IsValid() const
- {
- return data != 0;
- }
- };
-
- inline Indexer GetIndexer()
- {
- return Indexer(*this);
- }
-
- Accessor() {}
- void Read(Value& obj, Asset& r);
- };
-
- //! A buffer points to binary geometry, animation, or skins.
- struct Buffer : public Object
- {
- /********************* Types *********************/
- public:
-
- enum Type
- {
- Type_arraybuffer,
- Type_text
- };
-
- /// \struct SEncodedRegion
- /// Descriptor of encoded region in "bufferView".
- struct SEncodedRegion
- {
- const size_t Offset;///< Offset from begin of "bufferView" to encoded region, in bytes.
- const size_t EncodedData_Length;///< Size of encoded region, in bytes.
- uint8_t* const DecodedData;///< Cached encoded data.
- const size_t DecodedData_Length;///< Size of decoded region, in bytes.
- const std::string ID;///< ID of the region.
-
- /// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
- /// Constructor.
- /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
- /// \param [in] pEncodedData_Length - size of encoded region, in bytes.
- /// \param [in] pDecodedData - pointer to decoded data array.
- /// \param [in] pDecodedData_Length - size of encoded region, in bytes.
- /// \param [in] pID - ID of the region.
- SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
- : Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID)
- {}
-
- /// \fn ~SEncodedRegion()
- /// Destructor.
- ~SEncodedRegion() { delete[] DecodedData; }
- };
-
- /******************* Variables *******************/
-
- //std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required)
- size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
- //std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")
-
- Type type;
-
- /// \var EncodedRegion_Current
- /// Pointer to currently active encoded region.
- /// Why not decoding all regions at once and not to set one buffer with decoded data?
- /// Yes, why not? Even "accessor" point to decoded data. I mean that fields "byteOffset", "byteStride" and "count" has values which describes decoded
- /// data array. But only in range of mesh while is active parameters from "compressedData". For another mesh accessors point to decoded data too. But
- /// offset is counted for another regions is encoded.
- /// Example. You have two meshes. For every of it you have 4 bytes of data. That data compressed to 2 bytes. So, you have buffer with encoded data:
- /// M1_E0, M1_E1, M2_E0, M2_E1.
- /// After decoding you'll get:
- /// M1_D0, M1_D1, M1_D2, M1_D3, M2_D0, M2_D1, M2_D2, M2_D3.
- /// "accessors" must to use values that point to decoded data - obviously. So, you'll expect "accessors" like
- /// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 4, byteLength: 4}
- /// but in real life you'll get:
- /// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
- /// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
- /// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
- /// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
- ///
- /// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
- /// exporter and importer. And, thanks to such way, there is no need to load whole file into memory.
- SEncodedRegion* EncodedRegion_Current;
-
- private:
-
- shared_ptr<uint8_t> mData; //!< Pointer to the data
- bool mIsSpecial; //!< Set to true for special cases (e.g. the body buffer)
-
- /// \var EncodedRegion_List
- /// List of encoded regions.
- std::list<SEncodedRegion*> EncodedRegion_List;
-
- /******************* Functions *******************/
-
- public:
-
- Buffer();
- ~Buffer();
-
- void Read(Value& obj, Asset& r);
-
- bool LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);
-
- /// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
- /// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
- /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
- /// \param [in] pEncodedData_Length - size of encoded region, in bytes.
- /// \param [in] pDecodedData - pointer to decoded data array.
- /// \param [in] pDecodedData_Length - size of encoded region, in bytes.
- /// \param [in] pID - ID of the region.
- void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID);
-
- /// \fn void EncodedRegion_SetCurrent(const std::string& pID)
- /// Select current encoded region by ID. \sa EncodedRegion_Current.
- /// \param [in] pID - ID of the region.
- void EncodedRegion_SetCurrent(const std::string& pID);
-
- /// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
- /// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
- /// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
- /// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
- /// \param [in] pReplace_Data - pointer to array with new data for buffer.
- /// \param [in] pReplace_Count - count of bytes in new data.
- /// \return true - if successfully replaced, false if input arguments is out of range.
- bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count);
-
- size_t AppendData(uint8_t* data, size_t length);
- void Grow(size_t amount);
-
- uint8_t* GetPointer()
- { return mData.get(); }
-
- void MarkAsSpecial()
- { mIsSpecial = true; }
-
- bool IsSpecial() const
- { return mIsSpecial; }
-
- std::string GetURI()
- { return std::string(this->id) + ".bin"; }
-
- static const char* TranslateId(Asset& r, const char* id);
- };
-
- //! A view into a buffer generally representing a subset of the buffer.
- struct BufferView : public Object
- {
- Ref<Buffer> buffer; //! The ID of the buffer. (required)
- size_t byteOffset; //! The offset into the buffer in bytes. (required)
- size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
- unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
-
- BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
-
- void Read(Value& obj, Asset& r);
- };
-
- struct Camera : public Object
- {
- enum Type
- {
- Perspective,
- Orthographic
- };
-
- Type type;
-
- union
- {
- struct {
- float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
- float yfov; //!<The floating - point vertical field of view in radians. (required)
- float zfar; //!<The floating - point distance to the far clipping plane. (required)
- float znear; //!< The floating - point distance to the near clipping plane. (required)
- } perspective;
-
- struct {
- float xmag; //! The floating-point horizontal magnification of the view. (required)
- float ymag; //! The floating-point vertical magnification of the view. (required)
- float zfar; //! The floating-point distance to the far clipping plane. (required)
- float znear; //! The floating-point distance to the near clipping plane. (required)
- } ortographic;
- } cameraProperties;
-
- Camera() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- //! Image data used to create a texture.
- struct Image : public Object
- {
- std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
-
- Ref<BufferView> bufferView;
-
- std::string mimeType;
-
- int width, height;
-
- private:
- uint8_t* mData;
- size_t mDataLength;
-
- public:
-
- Image();
- void Read(Value& obj, Asset& r);
-
- inline bool HasData() const
- { return mDataLength > 0; }
-
- inline size_t GetDataLength() const
- { return mDataLength; }
-
- inline const uint8_t* GetData() const
- { return mData; }
-
- inline uint8_t* StealData();
-
- inline void SetData(uint8_t* data, size_t length, Asset& r);
- };
-
- const vec4 defaultBaseColor = {1, 1, 1, 1};
- const vec3 defaultEmissiveFactor = {0, 0, 0};
- const vec4 defaultDiffuseFactor = {1, 1, 1, 1};
- const vec3 defaultSpecularFactor = {1, 1, 1};
-
- struct TextureInfo
- {
- Ref<Texture> texture;
- unsigned int index;
- unsigned int texCoord = 0;
- };
-
- struct NormalTextureInfo : TextureInfo
- {
- float scale = 1;
- };
-
- struct OcclusionTextureInfo : TextureInfo
- {
- float strength = 1;
- };
-
- struct PbrMetallicRoughness
- {
- vec4 baseColorFactor;
- TextureInfo baseColorTexture;
- TextureInfo metallicRoughnessTexture;
- float metallicFactor;
- float roughnessFactor;
- };
-
- struct PbrSpecularGlossiness
- {
- vec4 diffuseFactor;
- vec3 specularFactor;
- float glossinessFactor;
- TextureInfo diffuseTexture;
- TextureInfo specularGlossinessTexture;
-
- PbrSpecularGlossiness() { SetDefaults(); }
- void SetDefaults();
- };
-
- //! The material appearance of a primitive.
- struct Material : public Object
- {
- //PBR metallic roughness properties
- PbrMetallicRoughness pbrMetallicRoughness;
-
- //other basic material properties
- NormalTextureInfo normalTexture;
- OcclusionTextureInfo occlusionTexture;
- TextureInfo emissiveTexture;
- vec3 emissiveFactor;
- std::string alphaMode;
- float alphaCutoff;
- bool doubleSided;
-
- //extension: KHR_materials_pbrSpecularGlossiness
- Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;
-
- Material() { SetDefaults(); }
- void Read(Value& obj, Asset& r);
- void SetDefaults();
- };
-
- //! A set of primitives to be rendered. A node can contain one or more meshes. A node's transform places the mesh in the scene.
- struct Mesh : public Object
- {
- typedef std::vector< Ref<Accessor> > AccessorList;
-
- struct Primitive
- {
- PrimitiveMode mode;
-
- struct Attributes {
- AccessorList position, normal, tangent, texcoord, color, joint, jointmatrix, weight;
- } attributes;
-
- Ref<Accessor> indices;
-
- Ref<Material> material;
- };
-
- std::vector<Primitive> primitives;
-
- Mesh() {}
-
- /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
- /// Get mesh data from JSON-object and place them to root asset.
- /// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
- /// \param [out] pAsset_Root - reference to root assed where data will be stored.
- void Read(Value& pJSON_Object, Asset& pAsset_Root);
- };
-
- struct Node : public Object
- {
- std::vector< Ref<Node> > children;
- std::vector< Ref<Mesh> > meshes;
-
- Nullable<mat4> matrix;
- Nullable<vec3> translation;
- Nullable<vec4> rotation;
- Nullable<vec3> scale;
-
- Ref<Camera> camera;
-
- std::vector< Ref<Node> > skeletons; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy.
- Ref<Skin> skin; //!< The ID of the skin referenced by this node.
- std::string jointName; //!< Name used when this node is a joint in a skin.
-
- Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
-
- Node() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Program : public Object
- {
- Program() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- struct Sampler : public Object
- {
- SamplerMagFilter magFilter; //!< The texture magnification filter.
- SamplerMinFilter minFilter; //!< The texture minification filter.
- SamplerWrap wrapS; //!< The texture wrapping in the S direction.
- SamplerWrap wrapT; //!< The texture wrapping in the T direction.
-
- Sampler() { SetDefaults(); }
- void Read(Value& obj, Asset& r);
- void SetDefaults();
- };
-
- struct Scene : public Object
- {
- std::vector< Ref<Node> > nodes;
-
- Scene() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Shader : public Object
- {
- Shader() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Skin : public Object
- {
- Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order.
- Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
- std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
- std::string name; //!< The user-defined name of this object.
-
- Skin() {}
- void Read(Value& obj, Asset& r);
- };
-
- //! A texture and its sampler.
- struct Texture : public Object
- {
- Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
- Ref<Image> source; //!< The ID of the image used by this texture. (required)
-
- //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
- //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)
-
- //TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
- //TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)
-
- Texture() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Animation : public Object
- {
- struct AnimSampler {
- std::string id; //!< The ID of this sampler.
- std::string input; //!< The ID of a parameter in this animation to use as key-frame input.
- std::string interpolation; //!< Type of interpolation algorithm to use between key-frames.
- std::string output; //!< The ID of a parameter in this animation to use as key-frame output.
- };
-
- struct AnimChannel {
- int sampler; //!< The index of a sampler in the containing animation's samplers property.
-
- struct AnimTarget {
- Ref<Node> node; //!< The node to animate.
- std::string path; //!< The name of property of the node to animate ("translation", "rotation", or "scale").
- } target;
- };
-
- struct AnimParameters {
- Ref<Accessor> TIME; //!< Accessor reference to a buffer storing a array of floating point scalar values.
- Ref<Accessor> rotation; //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
- Ref<Accessor> scale; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
- Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
- };
-
- // AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
- // AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
- // AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data.
-
- std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
- AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
- std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
-
- Animation() {}
- void Read(Value& obj, Asset& r);
-
- //! Get accessor given an animation parameter name.
- Ref<Accessor> GetAccessor(std::string name) {
- if (name == "TIME") {
- return Parameters.TIME;
- } else if (name == "rotation") {
- return Parameters.rotation;
- } else if (name == "scale") {
- return Parameters.scale;
- } else if (name == "translation") {
- return Parameters.translation;
- }
- return Ref<Accessor>();
- }
- };
-
-
- //! Base class for LazyDict that acts as an interface
- class LazyDictBase
- {
- public:
- virtual ~LazyDictBase() {}
-
- virtual void AttachToDocument(Document& doc) = 0;
- virtual void DetachFromDocument() = 0;
-
- virtual void WriteObjects(AssetWriter& writer) = 0;
- };
-
-
- template<class T>
- class LazyDict;
-
- //! (Implemented in glTFAssetWriter.h)
- template<class T>
- void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
-
-
- //! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
- //! It is the owner the loaded objects, so when it is destroyed it also deletes them
- template<class T>
- class LazyDict : public LazyDictBase
- {
- friend class Asset;
- friend class AssetWriter;
-
- typedef typename std::gltf_unordered_map< unsigned int, unsigned int > Dict;
- typedef typename std::gltf_unordered_map< std::string, unsigned int > IdDict;
-
- std::vector<T*> mObjs; //! The read objects
- Dict mObjsByOIndex; //! The read objects accessible by original index
- IdDict mObjsById; //! The read objects accessible by id
- const char* mDictId; //! ID of the dictionary object
- const char* mExtId; //! ID of the extension defining the dictionary
- Value* mDict; //! JSON dictionary object
- Asset& mAsset; //! The asset instance
-
- void AttachToDocument(Document& doc);
- void DetachFromDocument();
-
- void WriteObjects(AssetWriter& writer)
- { WriteLazyDict<T>(*this, writer); }
-
- Ref<T> Add(T* obj);
-
- public:
- LazyDict(Asset& asset, const char* dictId, const char* extId = 0);
- ~LazyDict();
-
- Ref<T> Retrieve(unsigned int i);
-
- Ref<T> Get(unsigned int i);
- Ref<T> Get(const char* id);
-
- Ref<T> Create(const char* id);
- Ref<T> Create(const std::string& id)
- { return Create(id.c_str()); }
-
- unsigned int Remove(const char* id);
-
- inline unsigned int Size() const
- { return unsigned(mObjs.size()); }
-
- inline T& operator[](size_t i)
- { return *mObjs[i]; }
-
- };
-
-
- struct AssetMetadata
- {
- std::string copyright; //!< A copyright message suitable for display to credit the content creator.
- std::string generator; //!< Tool that generated this glTF model.Useful for debugging.
-
- struct {
- std::string api; //!< Specifies the target rendering API (default: "WebGL")
- std::string version; //!< Specifies the target rendering API (default: "1.0.3")
- } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
-
- std::string version; //!< The glTF format version
-
- void Read(Document& doc);
-
- AssetMetadata() : version("") {}
- };
-
- //
- // glTF Asset class
- //
-
- //! Root object for a glTF asset
- class Asset
- {
- typedef std::gltf_unordered_map<std::string, int> IdMap;
-
- template<class T>
- friend class LazyDict;
-
- friend struct Buffer; // To access OpenFile
-
- friend class AssetWriter;
-
- private:
- IOSystem* mIOSystem;
-
- std::string mCurrentAssetDir;
-
- size_t mSceneLength;
- size_t mBodyOffset, mBodyLength;
-
- std::vector<LazyDictBase*> mDicts;
-
- IdMap mUsedIds;
-
- Ref<Buffer> mBodyBuffer;
-
- Asset(Asset&);
- Asset& operator=(const Asset&);
-
- public:
-
- //! Keeps info about the enabled extensions
- struct Extensions
- {
- bool KHR_materials_pbrSpecularGlossiness;
-
- } extensionsUsed;
-
- AssetMetadata asset;
-
-
- // Dictionaries for each type of object
-
- LazyDict<Accessor> accessors;
- LazyDict<Animation> animations;
- LazyDict<Buffer> buffers;
- LazyDict<BufferView> bufferViews;
- LazyDict<Camera> cameras;
- LazyDict<Image> images;
- LazyDict<Material> materials;
- LazyDict<Mesh> meshes;
- LazyDict<Node> nodes;
- LazyDict<Sampler> samplers;
- LazyDict<Scene> scenes;
- LazyDict<Skin> skins;
- LazyDict<Texture> textures;
-
- Ref<Scene> scene;
-
- public:
- Asset(IOSystem* io = 0)
- : mIOSystem(io)
- , asset()
- , accessors (*this, "accessors")
- , animations (*this, "animations")
- , buffers (*this, "buffers")
- , bufferViews (*this, "bufferViews")
- , cameras (*this, "cameras")
- , images (*this, "images")
- , materials (*this, "materials")
- , meshes (*this, "meshes")
- , nodes (*this, "nodes")
- , samplers (*this, "samplers")
- , scenes (*this, "scenes")
- , skins (*this, "skins")
- , textures (*this, "textures")
- {
- memset(&extensionsUsed, 0, sizeof(extensionsUsed));
- }
-
- //! Main function
- void Load(const std::string& file, bool isBinary = false);
-
- //! Enables binary encoding on the asset
- void SetAsBinary();
-
- //! Search for an available name, starting from the given strings
- std::string FindUniqueID(const std::string& str, const char* suffix);
-
- Ref<Buffer> GetBodyBuffer()
- { return mBodyBuffer; }
-
- private:
- void ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData);
-
- void ReadExtensionsUsed(Document& doc);
-
- IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
- };
-
-}
-
-// Include the implementation of the methods
-#include "glTF2Asset.inl"
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // GLTF2ASSET_H_INC
diff --git a/src/3rdparty/assimp/code/glTF2Asset.inl b/src/3rdparty/assimp/code/glTF2Asset.inl
deleted file mode 100644
index 549df747e..000000000
--- a/src/3rdparty/assimp/code/glTF2Asset.inl
+++ /dev/null
@@ -1,1449 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "StringUtils.h"
-
-// Header files, Assimp
-#include <assimp/DefaultLogger.hpp>
-
-using namespace Assimp;
-
-namespace glTF2 {
-
-namespace {
-
- //
- // JSON Value reading helpers
- //
-
- template<class T>
- struct ReadHelper { static bool Read(Value& val, T& out) {
- return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
- }};
-
- template<> struct ReadHelper<bool> { static bool Read(Value& val, bool& out) {
- return val.IsBool() ? out = val.GetBool(), true : false;
- }};
-
- template<> struct ReadHelper<float> { static bool Read(Value& val, float& out) {
- return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
- }};
-
- template<unsigned int N> struct ReadHelper<float[N]> { static bool Read(Value& val, float (&out)[N]) {
- if (!val.IsArray() || val.Size() != N) return false;
- for (unsigned int i = 0; i < N; ++i) {
- if (val[i].IsNumber())
- out[i] = static_cast<float>(val[i].GetDouble());
- }
- return true;
- }};
-
- template<> struct ReadHelper<const char*> { static bool Read(Value& val, const char*& out) {
- return val.IsString() ? (out = val.GetString(), true) : false;
- }};
-
- template<> struct ReadHelper<std::string> { static bool Read(Value& val, std::string& out) {
- return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
- }};
-
- template<class T> struct ReadHelper< Nullable<T> > { static bool Read(Value& val, Nullable<T>& out) {
- return out.isPresent = ReadHelper<T>::Read(val, out.value);
- }};
-
- template<class T>
- inline static bool ReadValue(Value& val, T& out)
- {
- return ReadHelper<T>::Read(val, out);
- }
-
- template<class T>
- inline static bool ReadMember(Value& obj, const char* id, T& out)
- {
- Value::MemberIterator it = obj.FindMember(id);
- if (it != obj.MemberEnd()) {
- return ReadHelper<T>::Read(it->value, out);
- }
- return false;
- }
-
- template<class T>
- inline static T MemberOrDefault(Value& obj, const char* id, T defaultValue)
- {
- T out;
- return ReadMember(obj, id, out) ? out : defaultValue;
- }
-
- inline Value* FindMember(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd()) ? &it->value : 0;
- }
-
- inline Value* FindString(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
- }
-
- inline Value* FindNumber(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0;
- }
-
- inline Value* FindUInt(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsUint()) ? &it->value : 0;
- }
-
- inline Value* FindArray(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsArray()) ? &it->value : 0;
- }
-
- inline Value* FindObject(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : 0;
- }
-}
-
-//
-// LazyDict methods
-//
-
-template<class T>
-inline LazyDict<T>::LazyDict(Asset& asset, const char* dictId, const char* extId)
- : mDictId(dictId), mExtId(extId), mDict(0), mAsset(asset)
-{
- asset.mDicts.push_back(this); // register to the list of dictionaries
-}
-
-template<class T>
-inline LazyDict<T>::~LazyDict()
-{
- for (size_t i = 0; i < mObjs.size(); ++i) {
- delete mObjs[i];
- }
-}
-
-
-template<class T>
-inline void LazyDict<T>::AttachToDocument(Document& doc)
-{
- Value* container = 0;
-
- if (mExtId) {
- if (Value* exts = FindObject(doc, "extensions")) {
- container = FindObject(*exts, mExtId);
- }
- }
- else {
- container = &doc;
- }
-
- if (container) {
- mDict = FindArray(*container, mDictId);
- }
-}
-
-template<class T>
-inline void LazyDict<T>::DetachFromDocument()
-{
- mDict = 0;
-}
-
-template<class T>
-unsigned int LazyDict<T>::Remove(const char* id)
-{
- id = T::TranslateId(mAsset, id);
-
- typename IdDict::iterator it = mObjsById.find(id);
-
- if (it == mObjsById.end()) {
- throw DeadlyExportError("GLTF: Object with id \"" + std::string(id) + "\" is not found");
- }
-
- const unsigned int index = it->second;
-
- mAsset.mUsedIds[id] = false;
- mObjsById.erase(id);
- mObjsByOIndex.erase(index);
- mObjs.erase(mObjs.begin() + index);
-
- //update index of object in mObjs;
- for (unsigned int i = index; i < mObjs.size(); ++i) {
- T *obj = mObjs[i];
-
- obj->index = i;
- }
-
- for (IdDict::iterator it = mObjsById.begin(); it != mObjsById.end(); ++it) {
- if (it->second <= index) {
- continue;
- }
-
- mObjsById[it->first] = it->second - 1;
- }
-
- for (Dict::iterator it = mObjsByOIndex.begin(); it != mObjsByOIndex.end(); ++it) {
- if (it->second <= index) {
- continue;
- }
-
- mObjsByOIndex[it->first] = it->second - 1;
- }
-
- return index;
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Retrieve(unsigned int i)
-{
-
- typename Dict::iterator it = mObjsByOIndex.find(i);
- if (it != mObjsByOIndex.end()) {// already created?
- return Ref<T>(mObjs, it->second);
- }
-
- // read it from the JSON object
- if (!mDict) {
- throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
- }
-
- if (!mDict->IsArray()) {
- throw DeadlyImportError("GLTF: Field is not an array \"" + std::string(mDictId) + "\"");
- }
-
- Value &obj = (*mDict)[i];
-
- if (!obj.IsObject()) {
- throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
- }
-
- T* inst = new T();
- inst->id = std::string(mDictId) + "_" + to_string(i);
- inst->oIndex = i;
- ReadMember(obj, "name", inst->name);
- inst->Read(obj, mAsset);
-
- return Add(inst);
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Get(unsigned int i)
-{
-
- return Ref<T>(mObjs, i);
-
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Get(const char* id)
-{
- id = T::TranslateId(mAsset, id);
-
- typename IdDict::iterator it = mObjsById.find(id);
- if (it != mObjsById.end()) { // already created?
- return Ref<T>(mObjs, it->second);
- }
-
- return Ref<T>();
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Add(T* obj)
-{
- unsigned int idx = unsigned(mObjs.size());
- mObjs.push_back(obj);
- mObjsByOIndex[obj->oIndex] = idx;
- mObjsById[obj->id] = idx;
- mAsset.mUsedIds[obj->id] = true;
- return Ref<T>(mObjs, idx);
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Create(const char* id)
-{
- Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
- if (it != mAsset.mUsedIds.end()) {
- throw DeadlyImportError("GLTF: two objects with the same ID exist");
- }
- T* inst = new T();
- unsigned int idx = unsigned(mObjs.size());
- inst->id = id;
- inst->index = idx;
- inst->oIndex = idx;
- return Add(inst);
-}
-
-
-//
-// glTF dictionary objects methods
-//
-
-
-inline Buffer::Buffer()
- : byteLength(0), type(Type_arraybuffer), EncodedRegion_Current(nullptr), mIsSpecial(false)
-{ }
-
-inline Buffer::~Buffer()
-{
- for(SEncodedRegion* reg : EncodedRegion_List) delete reg;
-}
-
-inline const char* Buffer::TranslateId(Asset& /*r*/, const char* id)
-{
- return id;
-}
-
-inline void Buffer::Read(Value& obj, Asset& r)
-{
- size_t statedLength = MemberOrDefault<size_t>(obj, "byteLength", 0);
- byteLength = statedLength;
-
- Value* it = FindString(obj, "uri");
- if (!it) {
- if (statedLength > 0) {
- throw DeadlyImportError("GLTF: buffer with non-zero length missing the \"uri\" attribute");
- }
- return;
- }
-
- const char* uri = it->GetString();
-
- Util::DataURI dataURI;
- if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
- if (dataURI.base64) {
- uint8_t* data = 0;
- this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
- this->mData.reset(data, std::default_delete<uint8_t[]>());
-
- if (statedLength > 0 && this->byteLength != statedLength) {
- throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
- " bytes, but found " + to_string(dataURI.dataLength));
- }
- }
- else { // assume raw data
- if (statedLength != dataURI.dataLength) {
- throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
- " bytes, but found " + to_string(dataURI.dataLength));
- }
-
- this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
- memcpy( this->mData.get(), dataURI.data, dataURI.dataLength );
- }
- }
- else { // Local file
- if (byteLength > 0) {
- std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : "";
-
- IOStream* file = r.OpenFile(dir + uri, "rb");
- if (file) {
- bool ok = LoadFromStream(*file, byteLength);
- delete file;
-
- if (!ok)
- throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"" );
- }
- else {
- throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
- }
- }
- }
-}
-
-inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseOffset)
-{
- byteLength = length ? length : stream.FileSize();
-
- if (baseOffset) {
- stream.Seek(baseOffset, aiOrigin_SET);
- }
-
- mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
-
- if (stream.Read(mData.get(), byteLength, 1) != 1) {
- return false;
- }
- return true;
-}
-
-inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
-{
- // Check pointer to data
- if(pDecodedData == nullptr) throw DeadlyImportError("GLTF: for marking encoded region pointer to decoded data must be provided.");
-
- // Check offset
- if(pOffset > byteLength)
- {
- const uint8_t val_size = 32;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, "%llu", (long long)pOffset);
- throw DeadlyImportError(std::string("GLTF: incorrect offset value (") + val + ") for marking encoded region.");
- }
-
- // Check length
- if((pOffset + pEncodedData_Length) > byteLength)
- {
- const uint8_t val_size = 64;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, "%llu, %llu", (long long)pOffset, (long long)pEncodedData_Length);
- throw DeadlyImportError(std::string("GLTF: encoded region with offset/length (") + val + ") is out of range.");
- }
-
- // Add new region
- EncodedRegion_List.push_back(new SEncodedRegion(pOffset, pEncodedData_Length, pDecodedData, pDecodedData_Length, pID));
- // And set new value for "byteLength"
- byteLength += (pDecodedData_Length - pEncodedData_Length);
-}
-
-inline void Buffer::EncodedRegion_SetCurrent(const std::string& pID)
-{
- if((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;
-
- for(SEncodedRegion* reg : EncodedRegion_List)
- {
- if(reg->ID == pID)
- {
- EncodedRegion_Current = reg;
-
- return;
- }
-
- }
-
- throw DeadlyImportError("GLTF: EncodedRegion with ID: \"" + pID + "\" not found.");
-}
-
-inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
-{
-const size_t new_data_size = byteLength + pReplace_Count - pBufferData_Count;
-
-uint8_t* new_data;
-
- if((pBufferData_Count == 0) || (pReplace_Count == 0) || (pReplace_Data == nullptr)) return false;
-
- new_data = new uint8_t[new_data_size];
- // Copy data which place before replacing part.
- memcpy(new_data, mData.get(), pBufferData_Offset);
- // Copy new data.
- memcpy(&new_data[pBufferData_Offset], pReplace_Data, pReplace_Count);
- // Copy data which place after replacing part.
- memcpy(&new_data[pBufferData_Offset + pReplace_Count], &mData.get()[pBufferData_Offset + pBufferData_Count], pBufferData_Offset);
- // Apply new data
- mData.reset(new_data, std::default_delete<uint8_t[]>());
- byteLength = new_data_size;
-
- return true;
-}
-
-inline size_t Buffer::AppendData(uint8_t* data, size_t length)
-{
- size_t offset = this->byteLength;
- Grow(length);
- memcpy(mData.get() + offset, data, length);
- return offset;
-}
-
-inline void Buffer::Grow(size_t amount)
-{
- if (amount <= 0) return;
- uint8_t* b = new uint8_t[byteLength + amount];
- if (mData) memcpy(b, mData.get(), byteLength);
- mData.reset(b, std::default_delete<uint8_t[]>());
- byteLength += amount;
-}
-
-//
-// struct BufferView
-//
-
-inline void BufferView::Read(Value& obj, Asset& r)
-{
-
- if (Value* bufferVal = FindUInt(obj, "buffer")) {
- buffer = r.buffers.Retrieve(bufferVal->GetUint());
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- byteLength = MemberOrDefault(obj, "byteLength", 0u);
- byteStride = MemberOrDefault(obj, "byteStride", 0u);
-}
-
-//
-// struct Accessor
-//
-
-inline void Accessor::Read(Value& obj, Asset& r)
-{
-
- if (Value* bufferViewVal = FindUInt(obj, "bufferView")) {
- bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
- count = MemberOrDefault(obj, "count", 0u);
-
- const char* typestr;
- type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
-}
-
-inline unsigned int Accessor::GetNumComponents()
-{
- return AttribType::GetNumComponents(type);
-}
-
-inline unsigned int Accessor::GetBytesPerComponent()
-{
- return int(ComponentTypeSize(componentType));
-}
-
-inline unsigned int Accessor::GetElementSize()
-{
- return GetNumComponents() * GetBytesPerComponent();
-}
-
-inline uint8_t* Accessor::GetPointer()
-{
- if (!bufferView || !bufferView->buffer) return 0;
- uint8_t* basePtr = bufferView->buffer->GetPointer();
- if (!basePtr) return 0;
-
- size_t offset = byteOffset + bufferView->byteOffset;
-
- // Check if region is encoded.
- if(bufferView->buffer->EncodedRegion_Current != nullptr)
- {
- const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
- const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
-
- if((offset >= begin) && (offset < end))
- return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
- }
-
- return basePtr + offset;
-}
-
-namespace {
- inline void CopyData(size_t count,
- const uint8_t* src, size_t src_stride,
- uint8_t* dst, size_t dst_stride)
- {
- if (src_stride == dst_stride) {
- memcpy(dst, src, count * src_stride);
- }
- else {
- size_t sz = std::min(src_stride, dst_stride);
- for (size_t i = 0; i < count; ++i) {
- memcpy(dst, src, sz);
- if (sz < dst_stride) {
- memset(dst + sz, 0, dst_stride - sz);
- }
- src += src_stride;
- dst += dst_stride;
- }
- }
- }
-}
-
-template<class T>
-bool Accessor::ExtractData(T*& outData)
-{
- uint8_t* data = GetPointer();
- if (!data) return false;
-
- const size_t elemSize = GetElementSize();
- const size_t totalSize = elemSize * count;
-
- const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;
-
- const size_t targetElemSize = sizeof(T);
- ai_assert(elemSize <= targetElemSize);
-
- ai_assert(count*stride <= bufferView->byteLength);
-
- outData = new T[count];
- if (stride == elemSize && targetElemSize == elemSize) {
- memcpy(outData, data, totalSize);
- }
- else {
- for (size_t i = 0; i < count; ++i) {
- memcpy(outData + i, data + i*stride, elemSize);
- }
- }
-
- return true;
-}
-
-inline void Accessor::WriteData(size_t count, const void* src_buffer, size_t src_stride)
-{
- uint8_t* buffer_ptr = bufferView->buffer->GetPointer();
- size_t offset = byteOffset + bufferView->byteOffset;
-
- size_t dst_stride = GetNumComponents() * GetBytesPerComponent();
-
- const uint8_t* src = reinterpret_cast<const uint8_t*>(src_buffer);
- uint8_t* dst = reinterpret_cast< uint8_t*>(buffer_ptr + offset);
-
- ai_assert(dst + count*dst_stride <= buffer_ptr + bufferView->buffer->byteLength);
- CopyData(count, src, src_stride, dst, dst_stride);
-}
-
-
-
-inline Accessor::Indexer::Indexer(Accessor& acc)
- : accessor(acc)
- , data(acc.GetPointer())
- , elemSize(acc.GetElementSize())
- , stride(acc.bufferView && acc.bufferView->byteStride ? acc.bufferView->byteStride : elemSize)
-{
-
-}
-
-//! Accesses the i-th value as defined by the accessor
-template<class T>
-T Accessor::Indexer::GetValue(int i)
-{
- ai_assert(data);
- ai_assert(i*stride < accessor.bufferView->byteLength);
- T value = T();
- memcpy(&value, data + i*stride, elemSize);
- //value >>= 8 * (sizeof(T) - elemSize);
- return value;
-}
-
-inline Image::Image()
- : width(0)
- , height(0)
- , mData(0)
- , mDataLength(0)
-{
-
-}
-
-inline void Image::Read(Value& obj, Asset& /*r*/)
-{
- if (!mDataLength) {
- if (Value* uri = FindString(obj, "uri")) {
- const char* uristr = uri->GetString();
-
- Util::DataURI dataURI;
- if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
- mimeType = dataURI.mediaType;
- if (dataURI.base64) {
- mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, mData);
- }
- }
- else {
- this->uri = uristr;
- }
- }
- }
-}
-
-inline uint8_t* Image::StealData()
-{
- uint8_t* data = mData;
- mDataLength = 0;
- mData = 0;
- return data;
-}
-
-inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
-{
- Ref<Buffer> b = r.GetBodyBuffer();
- if (b) { // binary file: append to body
- std::string bvId = r.FindUniqueID(this->id, "imgdata");
- bufferView = r.bufferViews.Create(bvId);
-
- bufferView->buffer = b;
- bufferView->byteLength = length;
- bufferView->byteOffset = b->AppendData(data, length);
- }
- else { // text file: will be stored as a data uri
- this->mData = data;
- this->mDataLength = length;
- }
-}
-
-inline void Sampler::Read(Value& obj, Asset& /*r*/)
-{
- SetDefaults();
-
- ReadMember(obj, "name", name);
- ReadMember(obj, "magFilter", magFilter);
- ReadMember(obj, "minFilter", minFilter);
- ReadMember(obj, "wrapS", wrapS);
- ReadMember(obj, "wrapT", wrapT);
-}
-
-inline void Sampler::SetDefaults()
-{
- //only wrapping modes have defaults
- wrapS = SamplerWrap::Repeat;
- wrapT = SamplerWrap::Repeat;
- magFilter = SamplerMagFilter::UNSET;
- minFilter = SamplerMinFilter::UNSET;
-}
-
-inline void Texture::Read(Value& obj, Asset& r)
-{
- if (Value* sourceVal = FindUInt(obj, "source")) {
- source = r.images.Retrieve(sourceVal->GetUint());
- }
-
- if (Value* samplerVal = FindUInt(obj, "sampler")) {
- sampler = r.samplers.Retrieve(samplerVal->GetUint());
- }
-}
-
-namespace {
- inline void SetTextureProperties(Asset& r, Value* prop, TextureInfo& out)
- {
- if (Value* index = FindUInt(*prop, "index")) {
- out.texture = r.textures.Retrieve(index->GetUint());
- }
-
- if (Value* texcoord = FindUInt(*prop, "texCoord")) {
- out.texCoord = texcoord->GetUint();
- }
- }
-
- inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, TextureInfo& out)
- {
- if (Value* prop = FindMember(vals, propName)) {
- SetTextureProperties(r, prop, out);
- }
- }
-
- inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, NormalTextureInfo& out)
- {
- if (Value* prop = FindMember(vals, propName)) {
- SetTextureProperties(r, prop, out);
-
- if (Value* scale = FindNumber(*prop, "scale")) {
- out.scale = static_cast<float>(scale->GetDouble());
- }
- }
- }
-
- inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, OcclusionTextureInfo& out)
- {
- if (Value* prop = FindMember(vals, propName)) {
- SetTextureProperties(r, prop, out);
-
- if (Value* strength = FindNumber(*prop, "strength")) {
- out.strength = static_cast<float>(strength->GetDouble());
- }
- }
- }
-}
-
-inline void Material::Read(Value& material, Asset& r)
-{
- SetDefaults();
-
- if (Value* pbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) {
- ReadMember(*pbrMetallicRoughness, "baseColorFactor", this->pbrMetallicRoughness.baseColorFactor);
- ReadTextureProperty(r, *pbrMetallicRoughness, "baseColorTexture", this->pbrMetallicRoughness.baseColorTexture);
- ReadTextureProperty(r, *pbrMetallicRoughness, "metallicRoughnessTexture", this->pbrMetallicRoughness.metallicRoughnessTexture);
- ReadMember(*pbrMetallicRoughness, "metallicFactor", this->pbrMetallicRoughness.metallicFactor);
- ReadMember(*pbrMetallicRoughness, "roughnessFactor", this->pbrMetallicRoughness.roughnessFactor);
- }
-
- ReadTextureProperty(r, material, "normalTexture", this->normalTexture);
- ReadTextureProperty(r, material, "occlusionTexture", this->occlusionTexture);
- ReadTextureProperty(r, material, "emissiveTexture", this->emissiveTexture);
- ReadMember(material, "emissiveFactor", this->emissiveFactor);
-
- ReadMember(material, "doubleSided", this->doubleSided);
- ReadMember(material, "alphaMode", this->alphaMode);
- ReadMember(material, "alphaCutoff", this->alphaCutoff);
-
- if (Value* extensions = FindObject(material, "extensions")) {
- if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
- if (Value* pbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) {
- PbrSpecularGlossiness pbrSG;
-
- ReadMember(*pbrSpecularGlossiness, "diffuseFactor", pbrSG.diffuseFactor);
- ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", pbrSG.diffuseTexture);
- ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", pbrSG.specularGlossinessTexture);
- ReadMember(*pbrSpecularGlossiness, "specularFactor", pbrSG.specularFactor);
- ReadMember(*pbrSpecularGlossiness, "glossinessFactor", pbrSG.glossinessFactor);
-
- this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
- }
- }
- }
-}
-
-namespace {
- void SetVector(vec4& v, const float(&in)[4])
- { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; v[3] = in[3]; }
-
- void SetVector(vec3& v, const float(&in)[3])
- { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; }
-}
-
-inline void Material::SetDefaults()
-{
- //pbr materials
- SetVector(pbrMetallicRoughness.baseColorFactor, defaultBaseColor);
- pbrMetallicRoughness.metallicFactor = 1.0;
- pbrMetallicRoughness.roughnessFactor = 1.0;
-
- SetVector(emissiveFactor, defaultEmissiveFactor);
- alphaMode = "OPAQUE";
- alphaCutoff = 0.5;
- doubleSided = false;
-}
-
-inline void PbrSpecularGlossiness::SetDefaults()
-{
- //pbrSpecularGlossiness properties
- SetVector(diffuseFactor, defaultDiffuseFactor);
- SetVector(specularFactor, defaultSpecularFactor);
- glossinessFactor = 1.0;
-}
-
-namespace {
-
- template<int N>
- inline int Compare(const char* attr, const char (&str)[N]) {
- return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
- }
-
- inline bool GetAttribVector(Mesh::Primitive& p, const char* attr, Mesh::AccessorList*& v, int& pos)
- {
- if ((pos = Compare(attr, "POSITION"))) {
- v = &(p.attributes.position);
- }
- else if ((pos = Compare(attr, "NORMAL"))) {
- v = &(p.attributes.normal);
- }
- else if ((pos = Compare(attr, "TANGENT"))) {
- v = &(p.attributes.tangent);
- }
- else if ((pos = Compare(attr, "TEXCOORD"))) {
- v = &(p.attributes.texcoord);
- }
- else if ((pos = Compare(attr, "COLOR"))) {
- v = &(p.attributes.color);
- }
- else if ((pos = Compare(attr, "JOINT"))) {
- v = &(p.attributes.joint);
- }
- else if ((pos = Compare(attr, "JOINTMATRIX"))) {
- v = &(p.attributes.jointmatrix);
- }
- else if ((pos = Compare(attr, "WEIGHT"))) {
- v = &(p.attributes.weight);
- }
- else return false;
- return true;
- }
-}
-
-inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
-{
- if (Value* name = FindMember(pJSON_Object, "name")) {
- this->name = name->GetString();
- }
-
- /****************** Mesh primitives ******************/
- if (Value* primitives = FindArray(pJSON_Object, "primitives")) {
- this->primitives.resize(primitives->Size());
- for (unsigned int i = 0; i < primitives->Size(); ++i) {
- Value& primitive = (*primitives)[i];
-
- Primitive& prim = this->primitives[i];
- prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);
-
- if (Value* attrs = FindObject(primitive, "attributes")) {
- for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
- if (!it->value.IsUint()) continue;
- const char* attr = it->name.GetString();
- // Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
- // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
-
- int undPos = 0;
- Mesh::AccessorList* vec = 0;
- if (GetAttribVector(prim, attr, vec, undPos)) {
- size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
- if ((*vec).size() <= idx) (*vec).resize(idx + 1);
- (*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
- }
- }
- }
-
- if (Value* indices = FindUInt(primitive, "indices")) {
- prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
- }
-
- if (Value* material = FindUInt(primitive, "material")) {
- prim.material = pAsset_Root.materials.Retrieve(material->GetUint());
- }
- }
- }
-}
-
-inline void Camera::Read(Value& obj, Asset& /*r*/)
-{
- type = MemberOrDefault(obj, "type", Camera::Perspective);
-
- const char* subobjId = (type == Camera::Orthographic) ? "orthographic" : "perspective";
-
- Value* it = FindObject(obj, subobjId);
- if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
-
- if (type == Camera::Perspective) {
- cameraProperties.perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
- cameraProperties.perspective.yfov = MemberOrDefault(*it, "yfov", 3.1415f/2.f);
- cameraProperties.perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
- cameraProperties.perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
- }
- else {
- cameraProperties.ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f);
- cameraProperties.ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f);
- cameraProperties.ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f);
- cameraProperties.ortographic.znear = MemberOrDefault(obj, "znear", 0.01f);
- }
-}
-
-inline void Node::Read(Value& obj, Asset& r)
-{
-
- if (Value* children = FindArray(obj, "children")) {
- this->children.reserve(children->Size());
- for (unsigned int i = 0; i < children->Size(); ++i) {
- Value& child = (*children)[i];
- if (child.IsUint()) {
- // get/create the child node
- Ref<Node> chn = r.nodes.Retrieve(child.GetUint());
- if (chn) this->children.push_back(chn);
- }
- }
- }
-
- if (Value* matrix = FindArray(obj, "matrix")) {
- ReadValue(*matrix, this->matrix);
- }
- else {
- ReadMember(obj, "translation", translation);
- ReadMember(obj, "scale", scale);
- ReadMember(obj, "rotation", rotation);
- }
-
- if (Value* mesh = FindUInt(obj, "mesh")) {
- unsigned numMeshes = 1;
-
- this->meshes.reserve(numMeshes);
-
- Ref<Mesh> meshRef = r.meshes.Retrieve((*mesh).GetUint());
-
- if (meshRef) this->meshes.push_back(meshRef);
- }
-
- if (Value* camera = FindUInt(obj, "camera")) {
- this->camera = r.cameras.Retrieve(camera->GetUint());
- if (this->camera)
- this->camera->id = this->id;
- }
-}
-
-inline void Scene::Read(Value& obj, Asset& r)
-{
- if (Value* array = FindArray(obj, "nodes")) {
- for (unsigned int i = 0; i < array->Size(); ++i) {
- if (!(*array)[i].IsUint()) continue;
- Ref<Node> node = r.nodes.Retrieve((*array)[i].GetUint());
- if (node)
- this->nodes.push_back(node);
- }
- }
-}
-
-inline void AssetMetadata::Read(Document& doc)
-{
- if (Value* obj = FindObject(doc, "asset")) {
- ReadMember(*obj, "copyright", copyright);
- ReadMember(*obj, "generator", generator);
-
- if (Value* versionString = FindString(*obj, "version")) {
- version = versionString->GetString();
- } else if (Value* versionNumber = FindNumber (*obj, "version")) {
- char buf[4];
-
- ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
-
- version = buf;
- }
-
- if (Value* profile = FindObject(*obj, "profile")) {
- ReadMember(*profile, "api", this->profile.api);
- ReadMember(*profile, "version", this->profile.version);
- }
- }
-
- if (version.empty() || version[0] != '2') {
- throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
- }
-}
-
-//
-// Asset methods implementation
-//
-
-inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
-{
- GLB_Header header;
- if (stream.Read(&header, sizeof(header), 1) != 1) {
- throw DeadlyImportError("GLTF: Unable to read the file header");
- }
-
- if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
- throw DeadlyImportError("GLTF: Invalid binary glTF file");
- }
-
- AI_SWAP4(header.version);
- asset.version = to_string(header.version);
- if (header.version != 2) {
- throw DeadlyImportError("GLTF: Unsupported binary glTF version");
- }
-
- GLB_Chunk chunk;
- if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
- throw DeadlyImportError("GLTF: Unable to read JSON chunk");
- }
-
- AI_SWAP4(chunk.chunkLength);
- AI_SWAP4(chunk.chunkType);
-
- if (chunk.chunkType != ChunkType_JSON) {
- throw DeadlyImportError("GLTF: JSON chunk missing");
- }
-
- // read the scene data
-
- mSceneLength = chunk.chunkLength;
- sceneData.resize(mSceneLength + 1);
- sceneData[mSceneLength] = '\0';
-
- if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
- throw DeadlyImportError("GLTF: Could not read the file contents");
- }
-
- uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
- if (padding > 0) {
- stream.Seek(padding, aiOrigin_CUR);
- }
-
- AI_SWAP4(header.length);
- mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
- if (header.length >= mBodyOffset) {
- if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
- throw DeadlyImportError("GLTF: Unable to read BIN chunk");
- }
-
- AI_SWAP4(chunk.chunkLength);
- AI_SWAP4(chunk.chunkType);
-
- if (chunk.chunkType != ChunkType_BIN) {
- throw DeadlyImportError("GLTF: BIN chunk missing");
- }
-
- mBodyLength = chunk.chunkLength;
- }
- else {
- mBodyOffset = mBodyLength = 0;
- }
-}
-
-inline void Asset::Load(const std::string& pFile, bool isBinary)
-{
- mCurrentAssetDir.clear();
- int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
- if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);
-
- shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
- if (!stream) {
- throw DeadlyImportError("GLTF: Could not open file for reading");
- }
-
- // is binary? then read the header
- std::vector<char> sceneData;
- if (isBinary) {
- SetAsBinary(); // also creates the body buffer
- ReadBinaryHeader(*stream, sceneData);
- }
- else {
- mSceneLength = stream->FileSize();
- mBodyLength = 0;
-
-
- // read the scene data
-
- sceneData.resize(mSceneLength + 1);
- sceneData[mSceneLength] = '\0';
-
- if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
- throw DeadlyImportError("GLTF: Could not read the file contents");
- }
- }
-
-
- // parse the JSON document
-
- Document doc;
- doc.ParseInsitu(&sceneData[0]);
-
- if (doc.HasParseError()) {
- char buffer[32];
- ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
- throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": "
- + GetParseError_En(doc.GetParseError()));
- }
-
- if (!doc.IsObject()) {
- throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
- }
-
- // Fill the buffer instance for the current file embedded contents
- if (mBodyLength > 0) {
- if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
- throw DeadlyImportError("GLTF: Unable to read gltf file");
- }
- }
-
-
- // Load the metadata
- asset.Read(doc);
- ReadExtensionsUsed(doc);
-
- // Prepare the dictionaries
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->AttachToDocument(doc);
- }
-
- // Read the "scene" property, which specifies which scene to load
- // and recursively load everything referenced by it
- if (Value* scene = FindUInt(doc, "scene")) {
- unsigned int sceneIndex = scene->GetUint();
-
- Ref<Scene> s = scenes.Retrieve(sceneIndex);
-
- this->scene = s;
- }
-
- // Clean up
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->DetachFromDocument();
- }
-}
-
-inline void Asset::SetAsBinary()
-{
- if (!mBodyBuffer) {
- mBodyBuffer = buffers.Create("binary_glTF");
- mBodyBuffer->MarkAsSpecial();
- }
-}
-
-
-inline void Asset::ReadExtensionsUsed(Document& doc)
-{
- Value* extsUsed = FindArray(doc, "extensionsUsed");
- if (!extsUsed) return;
-
- std::gltf_unordered_map<std::string, bool> exts;
-
- for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
- if ((*extsUsed)[i].IsString()) {
- exts[(*extsUsed)[i].GetString()] = true;
- }
- }
-
- #define CHECK_EXT(EXT) \
- if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
-
- CHECK_EXT(KHR_materials_pbrSpecularGlossiness);
-
- #undef CHECK_EXT
-}
-
-inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool /*absolute*/)
-{
- #ifdef ASSIMP_API
- return mIOSystem->Open(path, mode);
- #else
- if (path.size() < 2) return 0;
- if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
- path = mCurrentAssetDir + path;
- }
- FILE* f = fopen(path.c_str(), mode);
- return f ? new IOStream(f) : 0;
- #endif
-}
-
-inline std::string Asset::FindUniqueID(const std::string& str, const char* suffix)
-{
- std::string id = str;
-
- if (!id.empty()) {
- if (mUsedIds.find(id) == mUsedIds.end())
- return id;
-
- id += "_";
- }
-
- id += suffix;
-
- Asset::IdMap::iterator it = mUsedIds.find(id);
- if (it == mUsedIds.end())
- return id;
-
- std::vector<char> buffer;
- buffer.resize(id.size() + 16);
- int offset = ai_snprintf(buffer.data(), buffer.size(), "%s_", id.c_str());
- for (int i = 0; it != mUsedIds.end(); ++i) {
- ai_snprintf(buffer.data() + offset, buffer.size() - offset, "%d", i);
- id = buffer.data();
- it = mUsedIds.find(id);
- }
-
- return id;
-}
-
-namespace Util {
-
- inline
- bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
- if ( NULL == const_uri ) {
- return false;
- }
-
- if (const_uri[0] != 0x10) { // we already parsed this uri?
- if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
- return false;
- }
-
- // set defaults
- out.mediaType = "text/plain";
- out.charset = "US-ASCII";
- out.base64 = false;
-
- char* uri = const_cast<char*>(const_uri);
- if (uri[0] != 0x10) {
- uri[0] = 0x10;
- uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
- size_t i = 5, j;
- if (uri[i] != ';' && uri[i] != ',') { // has media type?
- uri[1] = char(i);
- for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
- // nothing to do!
- }
- }
- while (uri[i] == ';' && i < uriLen) {
- uri[i++] = '\0';
- for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
- // nothing to do!
- }
-
- if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
- uri[2] = char(j + 8);
- } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
- uri[3] = char(j);
- }
- }
- if (i < uriLen) {
- uri[i++] = '\0';
- uri[4] = char(i);
- } else {
- uri[1] = uri[2] = uri[3] = 0;
- uri[4] = 5;
- }
- }
-
- if ( uri[ 1 ] != 0 ) {
- out.mediaType = uri + uri[ 1 ];
- }
- if ( uri[ 2 ] != 0 ) {
- out.charset = uri + uri[ 2 ];
- }
- if ( uri[ 3 ] != 0 ) {
- out.base64 = true;
- }
- out.data = uri + uri[4];
- out.dataLength = (uri + uriLen) - out.data;
-
- return true;
- }
-
- template<bool B>
- struct DATA
- {
- static const uint8_t tableDecodeBase64[128];
- };
-
- template<bool B>
- const uint8_t DATA<B>::tableDecodeBase64[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
- 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
- };
-
- inline char EncodeCharBase64(uint8_t b)
- {
- return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
- }
-
- inline uint8_t DecodeCharBase64(char c)
- {
- return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
- /*if (c >= 'A' && c <= 'Z') return c - 'A';
- if (c >= 'a' && c <= 'z') return c - 'a' + 26;
- if (c >= '0' && c <= '9') return c - '0' + 52;
- if (c == '+') return 62;
- if (c == '/') return 63;
- return 64; // '-' */
- }
-
- inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
- {
- ai_assert(inLength % 4 == 0);
-
- if (inLength < 4) {
- out = 0;
- return 0;
- }
-
- int nEquals = int(in[inLength - 1] == '=') +
- int(in[inLength - 2] == '=');
-
- size_t outLength = (inLength * 3) / 4 - nEquals;
- out = new uint8_t[outLength];
- memset(out, 0, outLength);
-
- size_t i, j = 0;
-
- for (i = 0; i + 4 < inLength; i += 4) {
- uint8_t b0 = DecodeCharBase64(in[i]);
- uint8_t b1 = DecodeCharBase64(in[i + 1]);
- uint8_t b2 = DecodeCharBase64(in[i + 2]);
- uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- out[j++] = (uint8_t)((b2 << 6) | b3);
- }
-
- {
- uint8_t b0 = DecodeCharBase64(in[i]);
- uint8_t b1 = DecodeCharBase64(in[i + 1]);
- uint8_t b2 = DecodeCharBase64(in[i + 2]);
- uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
- }
-
- return outLength;
- }
-
-
-
- inline void EncodeBase64(
- const uint8_t* in, size_t inLength,
- std::string& out)
- {
- size_t outLength = ((inLength + 2) / 3) * 4;
-
- size_t j = out.size();
- out.resize(j + outLength);
-
- for (size_t i = 0; i < inLength; i += 3) {
- uint8_t b = (in[i] & 0xFC) >> 2;
- out[j++] = EncodeCharBase64(b);
-
- b = (in[i] & 0x03) << 4;
- if (i + 1 < inLength) {
- b |= (in[i + 1] & 0xF0) >> 4;
- out[j++] = EncodeCharBase64(b);
-
- b = (in[i + 1] & 0x0F) << 2;
- if (i + 2 < inLength) {
- b |= (in[i + 2] & 0xC0) >> 6;
- out[j++] = EncodeCharBase64(b);
-
- b = in[i + 2] & 0x3F;
- out[j++] = EncodeCharBase64(b);
- }
- else {
- out[j++] = EncodeCharBase64(b);
- out[j++] = '=';
- }
- }
- else {
- out[j++] = EncodeCharBase64(b);
- out[j++] = '=';
- out[j++] = '=';
- }
- }
- }
-
-}
-
-} // ns glTF
diff --git a/src/3rdparty/assimp/code/glTF2AssetWriter.h b/src/3rdparty/assimp/code/glTF2AssetWriter.h
deleted file mode 100644
index bce2b1bd1..000000000
--- a/src/3rdparty/assimp/code/glTF2AssetWriter.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 glTFWriter.h
- * Declares a class to write gltf/glb files
- *
- * glTF Extensions Support:
- * KHR_materials_pbrSpecularGlossiness: full
- */
-#ifndef GLTF2ASSETWRITER_H_INC
-#define GLTF2ASSETWRITER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include "glTF2Asset.h"
-
-namespace glTF2
-{
-
-using rapidjson::MemoryPoolAllocator;
-
-class AssetWriter
-{
- template<class T>
- friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
-
-private:
-
- void WriteBinaryData(IOStream* outfile, size_t sceneLength);
-
- void WriteMetadata();
- void WriteExtensionsUsed();
-
- template<class T>
- void WriteObjects(LazyDict<T>& d);
-
-public:
- Document mDoc;
- Asset& mAsset;
-
- MemoryPoolAllocator<>& mAl;
-
- AssetWriter(Asset& asset);
-
- void WriteFile(const char* path);
-};
-
-}
-
-// Include the implementation of the methods
-#include "glTF2AssetWriter.inl"
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // GLTF2ASSETWRITER_H_INC
diff --git a/src/3rdparty/assimp/code/glTF2AssetWriter.inl b/src/3rdparty/assimp/code/glTF2AssetWriter.inl
deleted file mode 100644
index 8b2769a37..000000000
--- a/src/3rdparty/assimp/code/glTF2AssetWriter.inl
+++ /dev/null
@@ -1,638 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-#include <rapidjson/prettywriter.h>
-
-namespace glTF2 {
-
- using rapidjson::StringBuffer;
- using rapidjson::PrettyWriter;
- using rapidjson::Writer;
- using rapidjson::StringRef;
- using rapidjson::StringRef;
-
- namespace {
-
- template<size_t N>
- inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
- val.SetArray();
- val.Reserve(N, al);
- for (decltype(N) i = 0; i < N; ++i) {
- val.PushBack(r[i], al);
- }
- return val;
- }
-
- inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
- val.SetArray();
- val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
- for (unsigned int i = 0; i < r.size(); ++i) {
- val.PushBack(r[i], al);
- }
- return val;
- }
-
- inline Value& MakeValue(Value& val, float r, MemoryPoolAllocator<>& /*al*/) {
- val.SetDouble(r);
-
- return val;
- }
-
- template<class T>
- inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
- if (v.empty()) return;
- Value lst;
- lst.SetArray();
- lst.Reserve(unsigned(v.size()), al);
- for (size_t i = 0; i < v.size(); ++i) {
- lst.PushBack(v[i]->index, al);
- }
- obj.AddMember(StringRef(fieldId), lst, al);
- }
-
-
- }
-
- inline void Write(Value& obj, Accessor& a, AssetWriter& w)
- {
- obj.AddMember("bufferView", a.bufferView->index, w.mAl);
- obj.AddMember("byteOffset", a.byteOffset, w.mAl);
-
- obj.AddMember("componentType", int(a.componentType), w.mAl);
- obj.AddMember("count", a.count, w.mAl);
- obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
-
- Value vTmpMax, vTmpMin;
- obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
- obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
- }
-
- inline void Write(Value& obj, Animation& a, AssetWriter& w)
- {
- /****************** Channels *******************/
- Value channels;
- channels.SetArray();
- channels.Reserve(unsigned(a.Channels.size()), w.mAl);
-
- for (size_t i = 0; i < unsigned(a.Channels.size()); ++i) {
- Animation::AnimChannel& c = a.Channels[i];
- Value valChannel;
- valChannel.SetObject();
- {
- valChannel.AddMember("sampler", c.sampler, w.mAl);
-
- Value valTarget;
- valTarget.SetObject();
- {
- valTarget.AddMember("node", c.target.node->index, w.mAl);
- valTarget.AddMember("path", c.target.path, w.mAl);
- }
- valChannel.AddMember("target", valTarget, w.mAl);
- }
- channels.PushBack(valChannel, w.mAl);
- }
- obj.AddMember("channels", channels, w.mAl);
-
- /****************** Samplers *******************/
- Value valSamplers;
- valSamplers.SetArray();
-
- for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
- Animation::AnimSampler& s = a.Samplers[i];
- Value valSampler;
- valSampler.SetObject();
- {
- Ref<Accessor> inputAccessor = a.GetAccessor(s.input);
- Ref<Accessor> outputAccessor = a.GetAccessor(s.output);
- valSampler.AddMember("input", inputAccessor->index, w.mAl);
- valSampler.AddMember("interpolation", s.interpolation, w.mAl);
- valSampler.AddMember("output", outputAccessor->index, w.mAl);
- }
- valSamplers.PushBack(valSampler, w.mAl);
- }
- obj.AddMember("samplers", valSamplers, w.mAl);
- }
-
- inline void Write(Value& obj, Buffer& b, AssetWriter& w)
- {
- obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
- obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl);
- }
-
- inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
- {
- obj.AddMember("buffer", bv.buffer->index, w.mAl);
- obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
- obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
- if (bv.byteStride != 0) {
- obj.AddMember("byteStride", bv.byteStride, w.mAl);
- }
- obj.AddMember("target", int(bv.target), w.mAl);
- }
-
- inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Image& img, AssetWriter& w)
- {
- std::string uri;
- if (img.HasData()) {
- uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
- uri += ";base64,";
- Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
- }
- else {
- uri = img.uri;
- }
-
- obj.AddMember("uri", Value(uri, w.mAl).Move(), w.mAl);
- }
-
- namespace {
- inline void SetTexBasic(TextureInfo t, Value& tex, MemoryPoolAllocator<>& al)
- {
- tex.SetObject();
- tex.AddMember("index", t.texture->index, al);
-
- if (t.texCoord != 0) {
- tex.AddMember("texCoord", t.texCoord, al);
- }
- }
-
- inline void WriteTex(Value& obj, TextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
- {
-
- if (t.texture) {
- Value tex;
-
- SetTexBasic(t, tex, al);
-
- obj.AddMember(StringRef(propName), tex, al);
- }
- }
-
- inline void WriteTex(Value& obj, NormalTextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
- {
-
- if (t.texture) {
- Value tex;
-
- SetTexBasic(t, tex, al);
-
- if (t.scale != 1) {
- tex.AddMember("scale", t.scale, al);
- }
-
- obj.AddMember(StringRef(propName), tex, al);
- }
- }
-
- inline void WriteTex(Value& obj, OcclusionTextureInfo t, const char* propName, MemoryPoolAllocator<>& al)
- {
-
- if (t.texture) {
- Value tex;
-
- SetTexBasic(t, tex, al);
-
- if (t.strength != 1) {
- tex.AddMember("strength", t.strength, al);
- }
-
- obj.AddMember(StringRef(propName), tex, al);
- }
- }
-
- template<size_t N>
- inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, MemoryPoolAllocator<>& al)
- {
- Value arr;
- obj.AddMember(StringRef(propName), MakeValue(arr, prop, al), al);
- }
-
- template<size_t N>
- inline void WriteVec(Value& obj, float(&prop)[N], const char* propName, const float(&defaultVal)[N], MemoryPoolAllocator<>& al)
- {
- if (!std::equal(std::begin(prop), std::end(prop), std::begin(defaultVal))) {
- WriteVec(obj, prop, propName, al);
- }
- }
-
- inline void WriteFloat(Value& obj, float prop, const char* propName, MemoryPoolAllocator<>& al)
- {
- Value num;
- obj.AddMember(StringRef(propName), MakeValue(num, prop, al), al);
- }
- }
-
- inline void Write(Value& obj, Material& m, AssetWriter& w)
- {
- Value pbrMetallicRoughness;
- pbrMetallicRoughness.SetObject();
- {
- WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorTexture, "baseColorTexture", w.mAl);
- WriteTex(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicRoughnessTexture, "metallicRoughnessTexture", w.mAl);
- WriteVec(pbrMetallicRoughness, m.pbrMetallicRoughness.baseColorFactor, "baseColorFactor", defaultBaseColor, w.mAl);
-
- if (m.pbrMetallicRoughness.metallicFactor != 1) {
- WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.metallicFactor, "metallicFactor", w.mAl);
- }
-
- if (m.pbrMetallicRoughness.roughnessFactor != 1) {
- WriteFloat(pbrMetallicRoughness, m.pbrMetallicRoughness.roughnessFactor, "roughnessFactor", w.mAl);
- }
- }
-
- if (!pbrMetallicRoughness.ObjectEmpty()) {
- obj.AddMember("pbrMetallicRoughness", pbrMetallicRoughness, w.mAl);
- }
-
- WriteTex(obj, m.normalTexture, "normalTexture", w.mAl);
- WriteTex(obj, m.emissiveTexture, "emissiveTexture", w.mAl);
- WriteTex(obj, m.occlusionTexture, "occlusionTexture", w.mAl);
- WriteVec(obj, m.emissiveFactor, "emissiveFactor", defaultEmissiveFactor, w.mAl);
-
- if (m.alphaCutoff != 0.5) {
- WriteFloat(obj, m.alphaCutoff, "alphaCutoff", w.mAl);
- }
-
- if (m.alphaMode != "OPAQUE") {
- obj.AddMember("alphaMode", Value(m.alphaMode, w.mAl).Move(), w.mAl);
- }
-
- if (m.doubleSided) {
- obj.AddMember("doubleSided", m.doubleSided, w.mAl);
- }
-
- Value exts;
- exts.SetObject();
-
- if (m.pbrSpecularGlossiness.isPresent) {
- Value pbrSpecularGlossiness;
- pbrSpecularGlossiness.SetObject();
-
- PbrSpecularGlossiness &pbrSG = m.pbrSpecularGlossiness.value;
-
- //pbrSpecularGlossiness
- WriteVec(pbrSpecularGlossiness, pbrSG.diffuseFactor, "diffuseFactor", defaultDiffuseFactor, w.mAl);
- WriteVec(pbrSpecularGlossiness, pbrSG.specularFactor, "specularFactor", defaultSpecularFactor, w.mAl);
-
- if (pbrSG.glossinessFactor != 1) {
- WriteFloat(obj, pbrSG.glossinessFactor, "glossinessFactor", w.mAl);
- }
-
- WriteTex(pbrSpecularGlossiness, pbrSG.diffuseTexture, "diffuseTexture", w.mAl);
- WriteTex(pbrSpecularGlossiness, pbrSG.specularGlossinessTexture, "specularGlossinessTexture", w.mAl);
-
- if (!pbrSpecularGlossiness.ObjectEmpty()) {
- exts.AddMember("KHR_materials_pbrSpecularGlossiness", pbrSpecularGlossiness, w.mAl);
- }
- }
-
- if (!exts.ObjectEmpty()) {
- obj.AddMember("extensions", exts, w.mAl);
- }
- }
-
- namespace {
- inline void WriteAttrs(AssetWriter& w, Value& attrs, Mesh::AccessorList& lst,
- const char* semantic, bool forceNumber = false)
- {
- if (lst.empty()) return;
- if (lst.size() == 1 && !forceNumber) {
- attrs.AddMember(StringRef(semantic), lst[0]->index, w.mAl);
- }
- else {
- for (size_t i = 0; i < lst.size(); ++i) {
- char buffer[32];
- ai_snprintf(buffer, 32, "%s_%d", semantic, int(i));
- attrs.AddMember(Value(buffer, w.mAl).Move(), lst[i]->index, w.mAl);
- }
- }
- }
- }
-
- inline void Write(Value& obj, Mesh& m, AssetWriter& w)
- {
- /****************** Primitives *******************/
- Value primitives;
- primitives.SetArray();
- primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
-
- for (size_t i = 0; i < m.primitives.size(); ++i) {
- Mesh::Primitive& p = m.primitives[i];
- Value prim;
- prim.SetObject();
- {
- prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
-
- if (p.material)
- prim.AddMember("material", p.material->index, w.mAl);
-
- if (p.indices)
- prim.AddMember("indices", p.indices->index, w.mAl);
-
- Value attrs;
- attrs.SetObject();
- {
- WriteAttrs(w, attrs, p.attributes.position, "POSITION");
- WriteAttrs(w, attrs, p.attributes.normal, "NORMAL");
- WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD", true);
- WriteAttrs(w, attrs, p.attributes.color, "COLOR", true);
- WriteAttrs(w, attrs, p.attributes.joint, "JOINTS", true);
- WriteAttrs(w, attrs, p.attributes.weight, "WEIGHTS", true);
- }
- prim.AddMember("attributes", attrs, w.mAl);
- }
- primitives.PushBack(prim, w.mAl);
- }
-
- obj.AddMember("primitives", primitives, w.mAl);
- }
-
- inline void Write(Value& obj, Node& n, AssetWriter& w)
- {
-
- if (n.matrix.isPresent) {
- Value val;
- obj.AddMember("matrix", MakeValue(val, n.matrix.value, w.mAl).Move(), w.mAl);
- }
-
- if (n.translation.isPresent) {
- Value val;
- obj.AddMember("translation", MakeValue(val, n.translation.value, w.mAl).Move(), w.mAl);
- }
-
- if (n.scale.isPresent) {
- Value val;
- obj.AddMember("scale", MakeValue(val, n.scale.value, w.mAl).Move(), w.mAl);
- }
- if (n.rotation.isPresent) {
- Value val;
- obj.AddMember("rotation", MakeValue(val, n.rotation.value, w.mAl).Move(), w.mAl);
- }
-
- AddRefsVector(obj, "children", n.children, w.mAl);
-
- if (!n.meshes.empty()) {
- obj.AddMember("mesh", n.meshes[0]->index, w.mAl);
- }
-
- AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);
-
- if (n.skin) {
- obj.AddMember("skin", n.skin->index, w.mAl);
- }
-
- if (!n.jointName.empty()) {
- obj.AddMember("jointName", n.jointName, w.mAl);
- }
- }
-
- inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Sampler& b, AssetWriter& w)
- {
- if (!b.name.empty()) {
- obj.AddMember("name", b.name, w.mAl);
- }
-
- if (b.wrapS != SamplerWrap::UNSET && b.wrapS != SamplerWrap::Repeat) {
- obj.AddMember("wrapS", static_cast<unsigned int>(b.wrapS), w.mAl);
- }
-
- if (b.wrapT != SamplerWrap::UNSET && b.wrapT != SamplerWrap::Repeat) {
- obj.AddMember("wrapT", static_cast<unsigned int>(b.wrapT), w.mAl);
- }
-
- if (b.magFilter != SamplerMagFilter::UNSET) {
- obj.AddMember("magFilter", static_cast<unsigned int>(b.magFilter), w.mAl);
- }
-
- if (b.minFilter != SamplerMinFilter::UNSET) {
- obj.AddMember("minFilter", static_cast<unsigned int>(b.minFilter), w.mAl);
- }
- }
-
- inline void Write(Value& scene, Scene& s, AssetWriter& w)
- {
- AddRefsVector(scene, "nodes", s.nodes, w.mAl);
- }
-
- inline void Write(Value& /*obj*/, Shader& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Skin& b, AssetWriter& w)
- {
- /****************** jointNames *******************/
- Value vJointNames;
- vJointNames.SetArray();
- vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
-
- for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
- vJointNames.PushBack(b.jointNames[i]->index, w.mAl);
- }
- obj.AddMember("joints", vJointNames, w.mAl);
-
- if (b.bindShapeMatrix.isPresent) {
- Value val;
- obj.AddMember("bindShapeMatrix", MakeValue(val, b.bindShapeMatrix.value, w.mAl).Move(), w.mAl);
- }
-
- if (b.inverseBindMatrices) {
- obj.AddMember("inverseBindMatrices", b.inverseBindMatrices->index, w.mAl);
- }
-
- }
-
- inline void Write(Value& obj, Texture& tex, AssetWriter& w)
- {
- if (tex.source) {
- obj.AddMember("source", tex.source->index, w.mAl);
- }
- if (tex.sampler) {
- obj.AddMember("sampler", tex.sampler->index, w.mAl);
- }
- }
-
-
- inline AssetWriter::AssetWriter(Asset& a)
- : mDoc()
- , mAsset(a)
- , mAl(mDoc.GetAllocator())
- {
- mDoc.SetObject();
-
- WriteMetadata();
- WriteExtensionsUsed();
-
- // Dump the contents of the dictionaries
- for (size_t i = 0; i < a.mDicts.size(); ++i) {
- a.mDicts[i]->WriteObjects(*this);
- }
-
- // Add the target scene field
- if (mAsset.scene) {
- mDoc.AddMember("scene", mAsset.scene->index, mAl);
- }
- }
-
- inline void AssetWriter::WriteFile(const char* path)
- {
- std::unique_ptr<IOStream> jsonOutFile(mAsset.OpenFile(path, "wt", true));
-
- if (jsonOutFile == 0) {
- throw DeadlyExportError("Could not open output file: " + std::string(path));
- }
-
- StringBuffer docBuffer;
-
- PrettyWriter<StringBuffer> writer(docBuffer);
- mDoc.Accept(writer);
-
- if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
- throw DeadlyExportError("Failed to write scene data!");
- }
-
- // Write buffer data to separate .bin files
- for (unsigned int i = 0; i < mAsset.buffers.Size(); ++i) {
- Ref<Buffer> b = mAsset.buffers.Get(i);
-
- std::string binPath = b->GetURI();
-
- std::unique_ptr<IOStream> binOutFile(mAsset.OpenFile(binPath, "wb", true));
-
- if (binOutFile == 0) {
- throw DeadlyExportError("Could not open output file: " + binPath);
- }
-
- if (b->byteLength > 0) {
- if (binOutFile->Write(b->GetPointer(), b->byteLength, 1) != 1) {
- throw DeadlyExportError("Failed to write binary file: " + binPath);
- }
- }
- }
- }
-
- inline void AssetWriter::WriteMetadata()
- {
- Value asset;
- asset.SetObject();
- asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
- asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
- mDoc.AddMember("asset", asset, mAl);
- }
-
- inline void AssetWriter::WriteExtensionsUsed()
- {
- Value exts;
- exts.SetArray();
- {
- // This is used to export pbrSpecularGlossiness materials with GLTF 2.
- if (this->mAsset.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
- exts.PushBack(StringRef("KHR_materials_pbrSpecularGlossiness"), mAl);
- }
- }
-
- if (!exts.Empty())
- mDoc.AddMember("extensionsUsed", exts, mAl);
- }
-
- template<class T>
- void AssetWriter::WriteObjects(LazyDict<T>& d)
- {
- if (d.mObjs.empty()) return;
-
- Value* container = &mDoc;
-
- if (d.mExtId) {
- Value* exts = FindObject(mDoc, "extensions");
- if (!exts) {
- mDoc.AddMember("extensions", Value().SetObject().Move(), mDoc.GetAllocator());
- exts = FindObject(mDoc, "extensions");
- }
-
- if (!(container = FindObject(*exts, d.mExtId))) {
- exts->AddMember(StringRef(d.mExtId), Value().SetObject().Move(), mDoc.GetAllocator());
- container = FindObject(*exts, d.mExtId);
- }
- }
-
- Value* dict;
- if (!(dict = FindArray(*container, d.mDictId))) {
- container->AddMember(StringRef(d.mDictId), Value().SetArray().Move(), mDoc.GetAllocator());
- dict = FindArray(*container, d.mDictId);
- }
-
- for (size_t i = 0; i < d.mObjs.size(); ++i) {
- if (d.mObjs[i]->IsSpecial()) continue;
-
- Value obj;
- obj.SetObject();
-
- if (!d.mObjs[i]->name.empty()) {
- obj.AddMember("name", StringRef(d.mObjs[i]->name.c_str()), mAl);
- }
-
- Write(obj, *d.mObjs[i], *this);
-
- dict->PushBack(obj, mAl);
- }
- }
-
- template<class T>
- void WriteLazyDict(LazyDict<T>& d, AssetWriter& w)
- {
- w.WriteObjects(d);
- }
-
-}
-
-
diff --git a/src/3rdparty/assimp/code/glTF2Exporter.cpp b/src/3rdparty/assimp/code/glTF2Exporter.cpp
deleted file mode 100644
index c1a803c1f..000000000
--- a/src/3rdparty/assimp/code/glTF2Exporter.cpp
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
-
-#include "glTF2Exporter.h"
-
-#include "Exceptional.h"
-#include "StringComparison.h"
-#include "ByteSwapper.h"
-
-#include "SplitLargeMeshes.h"
-
-#include <assimp/SceneCombiner.h>
-#include <assimp/version.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-
-// Header files, standard library.
-#include <memory>
-#include <inttypes.h>
-
-#include "glTF2AssetWriter.h"
-
-using namespace rapidjson;
-
-using namespace Assimp;
-using namespace glTF2;
-
-namespace Assimp {
-
- // ------------------------------------------------------------------------------------------------
- // Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp
- void ExportSceneGLTF2(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
- {
- // invoke the exporter
- glTF2Exporter exporter(pFile, pIOSystem, pScene, pProperties, false);
- }
-
-} // end of namespace Assimp
-
-glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
- const ExportProperties* pProperties, bool /*isBinary*/)
- : mFilename(filename)
- , mIOSystem(pIOSystem)
- , mProperties(pProperties)
-{
- aiScene* sceneCopy_tmp;
- SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
- std::unique_ptr<aiScene> sceneCopy(sceneCopy_tmp);
-
- SplitLargeMeshesProcess_Triangle tri_splitter;
- tri_splitter.SetLimit(0xffff);
- tri_splitter.Execute(sceneCopy.get());
-
- SplitLargeMeshesProcess_Vertex vert_splitter;
- vert_splitter.SetLimit(0xffff);
- vert_splitter.Execute(sceneCopy.get());
-
- mScene = sceneCopy.get();
-
- mAsset.reset( new Asset( pIOSystem ) );
-
- ExportMetadata();
-
- ExportMaterials();
-
- if (mScene->mRootNode) {
- ExportNodeHierarchy(mScene->mRootNode);
- }
-
- ExportMeshes();
- MergeMeshes();
-
- ExportScene();
-
- ExportAnimations();
-
- AssetWriter writer(*mAsset);
-
- writer.WriteFile(filename);
-}
-
-/*
- * Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
- * Also converts from row-major to column-major storage.
- */
-static void CopyValue(const aiMatrix4x4& v, mat4& o)
-{
- o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
- o[ 4] = v.a2; o[ 5] = v.b2; o[ 6] = v.c2; o[ 7] = v.d2;
- o[ 8] = v.a3; o[ 9] = v.b3; o[10] = v.c3; o[11] = v.d3;
- o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
-}
-
-static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
-{
- o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
- o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
- o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
- o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
-}
-
-static void IdentityMatrix4(mat4& o)
-{
- o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
- o[ 4] = 0; o[ 5] = 1; o[ 6] = 0; o[ 7] = 0;
- o[ 8] = 0; o[ 9] = 0; o[10] = 1; o[11] = 0;
- o[12] = 0; o[13] = 0; o[14] = 0; o[15] = 1;
-}
-
-inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
- unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
-{
- if (!count || !data) return Ref<Accessor>();
-
- unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
- unsigned int numCompsOut = AttribType::GetNumComponents(typeOut);
- unsigned int bytesPerComp = ComponentTypeSize(compType);
-
- size_t offset = buffer->byteLength;
- // make sure offset is correctly byte-aligned, as required by spec
- size_t padding = offset % bytesPerComp;
- offset += padding;
- size_t length = count * numCompsOut * bytesPerComp;
- buffer->Grow(length + padding);
-
- // bufferView
- Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
- bv->buffer = buffer;
- bv->byteOffset = unsigned(offset);
- bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
- bv->byteStride = 0;
- bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
-
- // accessor
- Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
- acc->bufferView = bv;
- acc->byteOffset = 0;
- acc->componentType = compType;
- acc->count = count;
- acc->type = typeOut;
-
- // calculate min and max values
- {
- // Allocate and initialize with large values.
- float float_MAX = 10000000000000.0f;
- for (unsigned int i = 0 ; i < numCompsOut ; i++) {
- acc->min.push_back( float_MAX);
- acc->max.push_back(-float_MAX);
- }
-
- // Search and set extreme values.
- float valueTmp;
- for (unsigned int i = 0 ; i < count ; i++) {
- for (unsigned int j = 0 ; j < numCompsOut ; j++) {
- if (numCompsOut == 1) {
- valueTmp = static_cast<unsigned short*>(data)[i];
- } else {
- valueTmp = static_cast<aiVector3D*>(data)[i][j];
- }
-
- if (valueTmp < acc->min[j]) {
- acc->min[j] = valueTmp;
- }
- if (valueTmp > acc->max[j]) {
- acc->max[j] = valueTmp;
- }
- }
- }
- }
-
- // copy the data
- acc->WriteData(count, data, numCompsIn*bytesPerComp);
-
- return acc;
-}
-
-inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map)
-{
- switch (map) {
- case aiTextureMapMode_Clamp:
- wrap = SamplerWrap::Clamp_To_Edge;
- break;
- case aiTextureMapMode_Mirror:
- wrap = SamplerWrap::Mirrored_Repeat;
- break;
- case aiTextureMapMode_Wrap:
- case aiTextureMapMode_Decal:
- default:
- wrap = SamplerWrap::Repeat;
- break;
- };
-}
-
-void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture, aiTextureType tt, unsigned int slot)
-{
- aiString aId;
- std::string id;
- if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) {
- id = aId.C_Str();
- }
-
- if (Ref<Sampler> ref = mAsset->samplers.Get(id.c_str())) {
- texture->sampler = ref;
- } else {
- id = mAsset->FindUniqueID(id, "sampler");
-
- texture->sampler = mAsset->samplers.Create(id.c_str());
-
- aiTextureMapMode mapU, mapV;
- SamplerMagFilter filterMag;
- SamplerMinFilter filterMin;
-
- if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
- SetSamplerWrap(texture->sampler->wrapS, mapU);
- }
-
- if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
- SetSamplerWrap(texture->sampler->wrapT, mapV);
- }
-
- if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) {
- texture->sampler->magFilter = filterMag;
- }
-
- if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) {
- texture->sampler->minFilter = filterMin;
- }
-
- aiString name;
- if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) {
- texture->sampler->name = name.C_Str();
- }
- }
-}
-
-void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot)
-{
- std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
-
- mat->Get(textureKey.c_str(), tt, slot, prop);
-}
-
-void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot)
-{
- std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
-
- mat->Get(textureKey.c_str(), tt, slot, prop);
-}
-
-void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTextureType tt, unsigned int slot = 0)
-{
-
- if (mat->GetTextureCount(tt) > 0) {
- aiString tex;
-
- if (mat->Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
- std::string path = tex.C_Str();
-
- if (path.size() > 0) {
- if (path[0] != '*') {
- std::map<std::string, unsigned int>::iterator it = mTexturesByPath.find(path);
- if (it != mTexturesByPath.end()) {
- texture = mAsset->textures.Get(it->second);
- }
- }
-
- if (!texture) {
- std::string texId = mAsset->FindUniqueID("", "texture");
- texture = mAsset->textures.Create(texId);
- mTexturesByPath[path] = texture.GetIndex();
-
- std::string imgId = mAsset->FindUniqueID("", "image");
- texture->source = mAsset->images.Create(imgId);
-
- if (path[0] == '*') { // embedded
- aiTexture* tex = mScene->mTextures[atoi(&path[1])];
-
- uint8_t* data = reinterpret_cast<uint8_t*>(tex->pcData);
- texture->source->SetData(data, tex->mWidth, *mAsset);
-
- if (tex->achFormatHint[0]) {
- std::string mimeType = "image/";
- mimeType += (memcmp(tex->achFormatHint, "jpg", 3) == 0) ? "jpeg" : tex->achFormatHint;
- texture->source->mimeType = mimeType;
- }
- }
- else {
- texture->source->uri = path;
- }
-
- GetTexSampler(mat, texture, tt, slot);
- }
- }
- }
- }
-}
-
-void glTF2Exporter::GetMatTex(const aiMaterial* mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
-{
- Ref<Texture>& texture = prop.texture;
-
- GetMatTex(mat, texture, tt, slot);
-
- if (texture) {
- GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
- }
-}
-
-void glTF2Exporter::GetMatTex(const aiMaterial* mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
-{
- Ref<Texture>& texture = prop.texture;
-
- GetMatTex(mat, texture, tt, slot);
-
- if (texture) {
- GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
- GetMatTexProp(mat, prop.scale, "scale", tt, slot);
- }
-}
-
-void glTF2Exporter::GetMatTex(const aiMaterial* mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
-{
- Ref<Texture>& texture = prop.texture;
-
- GetMatTex(mat, texture, tt, slot);
-
- if (texture) {
- GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
- GetMatTexProp(mat, prop.strength, "strength", tt, slot);
- }
-}
-
-aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const char* propName, int type, int idx)
-{
- aiColor4D col;
- aiReturn result = mat->Get(propName, type, idx, col);
-
- if (result == AI_SUCCESS) {
- prop[0] = col.r; prop[1] = col.g; prop[2] = col.b; prop[3] = col.a;
- }
-
- return result;
-}
-
-aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* propName, int type, int idx)
-{
- aiColor3D col;
- aiReturn result = mat->Get(propName, type, idx, col);
-
- if (result == AI_SUCCESS) {
- prop[0] = col.r; prop[1] = col.g; prop[2] = col.b;
- }
-
- return result;
-}
-
-void glTF2Exporter::ExportMaterials()
-{
- aiString aiName;
- for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
- const aiMaterial* mat = mScene->mMaterials[i];
-
- std::string id = "material_" + to_string(i);
-
- Ref<Material> m = mAsset->materials.Create(id);
-
- std::string name;
- if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
- name = aiName.C_Str();
- }
- name = mAsset->FindUniqueID(name, "material");
-
- m->name = name;
-
- GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE);
-
- if (!m->pbrMetallicRoughness.baseColorTexture.texture) {
- //if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture
- GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_DIFFUSE);
- }
-
- GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
-
- if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR) != AI_SUCCESS) {
- // if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material.
- //a fallback to any diffuse color should be used instead
- GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
- }
-
- if (mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
- //if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
- m->pbrMetallicRoughness.metallicFactor = 0;
- }
-
- // get roughness if source is gltf2 file
- if (mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor) != AI_SUCCESS) {
- // otherwise, try to derive and convert from specular + shininess values
- aiColor4D specularColor;
- ai_real shininess;
-
- if (
- mat->Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
- mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
- ) {
- // convert specular color to luminance
- float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
- //normalize shininess (assuming max is 1000) with an inverse exponentional curve
- float normalizedShininess = std::sqrt(shininess / 1000);
-
- //clamp the shininess value between 0 and 1
- normalizedShininess = std::min(std::max(normalizedShininess, 0.0f), 1.0f);
- // low specular intensity values should produce a rough material even if shininess is high.
- normalizedShininess = normalizedShininess * specularIntensity;
-
- m->pbrMetallicRoughness.roughnessFactor = 1 - normalizedShininess;
- }
- }
-
- GetMatTex(mat, m->normalTexture, aiTextureType_NORMALS);
- GetMatTex(mat, m->occlusionTexture, aiTextureType_LIGHTMAP);
- GetMatTex(mat, m->emissiveTexture, aiTextureType_EMISSIVE);
- GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE);
-
- mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided);
- mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff);
-
- aiString alphaMode;
-
- if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
- m->alphaMode = alphaMode.C_Str();
- } else {
- float opacity;
-
- if (mat->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
- if (opacity < 1) {
- m->alphaMode = "BLEND";
- m->pbrMetallicRoughness.baseColorFactor[3] *= opacity;
- }
- }
- }
-
- bool hasPbrSpecularGlossiness = false;
- mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, hasPbrSpecularGlossiness);
-
- if (hasPbrSpecularGlossiness) {
-
- if (!mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
- mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
- }
-
- PbrSpecularGlossiness pbrSG;
-
- GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_COLOR_DIFFUSE);
- GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_COLOR_SPECULAR);
-
- if (mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
- float shininess;
-
- if (mat->Get(AI_MATKEY_SHININESS, shininess)) {
- pbrSG.glossinessFactor = shininess / 1000;
- }
- }
-
- GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE);
- GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_SPECULAR);
-
- m->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
- }
- }
-}
-
-/*
- * Search through node hierarchy and find the node containing the given meshID.
- * Returns true on success, and false otherwise.
- */
-bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
-{
- for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
- if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
- meshNode = nodeIn;
- return true;
- }
- }
-
- for (unsigned int i = 0; i < nodeIn->children.size(); ++i) {
- if(FindMeshNode(nodeIn->children[i], meshNode, meshID)) {
- return true;
- }
- }
-
- return false;
-}
-
-/*
- * Find the root joint of the skeleton.
- * Starts will any joint node and traces up the tree,
- * until a parent is found that does not have a jointName.
- * Returns the first parent Ref<Node> found that does not have a jointName.
- */
-Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
-{
- Ref<Node> startNodeRef;
- Ref<Node> parentNodeRef;
-
- // Arbitrarily use the first joint to start the search.
- startNodeRef = skinRef->jointNames[0];
- parentNodeRef = skinRef->jointNames[0];
-
- do {
- startNodeRef = parentNodeRef;
- parentNodeRef = startNodeRef->parent;
- } while (!parentNodeRef->jointName.empty());
-
- return parentNodeRef;
-}
-
-void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData)
-{
- if (aimesh->mNumBones < 1) {
- return;
- }
-
- // Store the vertex joint and weight data.
- const size_t NumVerts( aimesh->mNumVertices );
- vec4* vertexJointData = new vec4[ NumVerts ];
- vec4* vertexWeightData = new vec4[ NumVerts ];
- int* jointsPerVertex = new int[ NumVerts ];
- for (size_t i = 0; i < NumVerts; ++i) {
- jointsPerVertex[i] = 0;
- for (size_t j = 0; j < 4; ++j) {
- vertexJointData[i][j] = 0;
- vertexWeightData[i][j] = 0;
- }
- }
-
- for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) {
- const aiBone* aib = aimesh->mBones[idx_bone];
-
- // aib->mName =====> skinRef->jointNames
- // Find the node with id = mName.
- Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
- nodeRef->jointName = nodeRef->name;
-
- unsigned int jointNamesIndex = 0;
- bool addJointToJointNames = true;
- for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
- if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
- addJointToJointNames = false;
- jointNamesIndex = idx_joint;
- }
- }
-
- if (addJointToJointNames) {
- skinRef->jointNames.push_back(nodeRef);
-
- // aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
- aiMatrix4x4 tmpMatrix4;
- CopyValue(aib->mOffsetMatrix, tmpMatrix4);
- inverseBindMatricesData.push_back(tmpMatrix4);
- jointNamesIndex = static_cast<unsigned int>(inverseBindMatricesData.size() - 1);
- }
-
- // aib->mWeights =====> vertexWeightData
- for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
- unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
- float vertWeight = aib->mWeights[idx_weights].mWeight;
-
- // A vertex can only have at most four joint weights. Ignore all others.
- if (jointsPerVertex[vertexId] > 3) {
- continue;
- }
-
- vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
- vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
-
- jointsPerVertex[vertexId] += 1;
- }
-
- } // End: for-loop mNumMeshes
-
- Mesh::Primitive& p = meshRef->primitives.back();
- Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( vertexJointAccessor ) {
- p.attributes.joint.push_back( vertexJointAccessor );
- }
-
- Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( vertexWeightAccessor ) {
- p.attributes.weight.push_back( vertexWeightAccessor );
- }
- delete[] jointsPerVertex;
- delete[] vertexWeightData;
- delete[] vertexJointData;
-}
-
-void glTF2Exporter::ExportMeshes()
-{
- // Not for
- // using IndicesType = decltype(aiFace::mNumIndices);
- // But yes for
- // using IndicesType = unsigned short;
- // because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
- typedef unsigned short IndicesType;
-
- std::string fname = std::string(mFilename);
- std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
- std::string bufferId = mAsset->FindUniqueID("", bufferIdPrefix.c_str());
-
- Ref<Buffer> b = mAsset->GetBodyBuffer();
- if (!b) {
- b = mAsset->buffers.Create(bufferId);
- }
-
- //----------------------------------------
- // Initialize variables for the skin
- bool createSkin = false;
- for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
- const aiMesh* aim = mScene->mMeshes[idx_mesh];
- if(aim->HasBones()) {
- createSkin = true;
- break;
- }
- }
-
- Ref<Skin> skinRef;
- std::string skinName = mAsset->FindUniqueID("skin", "skin");
- std::vector<aiMatrix4x4> inverseBindMatricesData;
- if(createSkin) {
- skinRef = mAsset->skins.Create(skinName);
- skinRef->name = skinName;
- }
- //----------------------------------------
-
- for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
- const aiMesh* aim = mScene->mMeshes[idx_mesh];
-
- std::string name = aim->mName.C_Str();
-
- std::string meshId = mAsset->FindUniqueID(name, "mesh");
- Ref<Mesh> m = mAsset->meshes.Create(meshId);
- m->primitives.resize(1);
- Mesh::Primitive& p = m->primitives.back();
-
- m->name = name;
-
- p.material = mAsset->materials.Get(aim->mMaterialIndex);
-
- /******************* Vertices ********************/
- Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (v) p.attributes.position.push_back(v);
-
- /******************** Normals ********************/
- Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (n) p.attributes.normal.push_back(n);
-
- /************** Texture coordinates **************/
- for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- // Flip UV y coords
- if (aim -> mNumUVComponents[i] > 1) {
- for (unsigned int j = 0; j < aim->mNumVertices; ++j) {
- aim->mTextureCoords[i][j].y = 1 - aim->mTextureCoords[i][j].y;
- }
- }
-
- if (aim->mNumUVComponents[i] > 0) {
- AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
-
- Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, false);
- if (tc) p.attributes.texcoord.push_back(tc);
- }
- }
-
- /*************** Vertices indices ****************/
- if (aim->mNumFaces > 0) {
- std::vector<IndicesType> indices;
- unsigned int nIndicesPerFace = aim->mFaces[0].mNumIndices;
- indices.resize(aim->mNumFaces * nIndicesPerFace);
- for (size_t i = 0; i < aim->mNumFaces; ++i) {
- for (size_t j = 0; j < nIndicesPerFace; ++j) {
- indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]);
- }
- }
-
- p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, true);
- }
-
- switch (aim->mPrimitiveTypes) {
- case aiPrimitiveType_POLYGON:
- p.mode = PrimitiveMode_TRIANGLES; break; // TODO implement this
- case aiPrimitiveType_LINE:
- p.mode = PrimitiveMode_LINES; break;
- case aiPrimitiveType_POINT:
- p.mode = PrimitiveMode_POINTS; break;
- default: // aiPrimitiveType_TRIANGLE
- p.mode = PrimitiveMode_TRIANGLES;
- }
-
- /*************** Skins ****************/
- if(aim->HasBones()) {
- ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
- }
- }
-
- //----------------------------------------
- // Finish the skin
- // Create the Accessor for skinRef->inverseBindMatrices
- if (createSkin) {
- mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
- for ( unsigned int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
- CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
- }
-
- Ref<Accessor> invBindMatrixAccessor = ExportData(*mAsset, skinName, b, static_cast<unsigned int>(inverseBindMatricesData.size()), invBindMatrixData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
- if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
-
- // Identity Matrix =====> skinRef->bindShapeMatrix
- // Temporary. Hard-coded identity matrix here
- skinRef->bindShapeMatrix.isPresent = true;
- IdentityMatrix4(skinRef->bindShapeMatrix.value);
-
- // Find nodes that contain a mesh with bones and add "skeletons" and "skin" attributes to those nodes.
- Ref<Node> rootNode = mAsset->nodes.Get(unsigned(0));
- Ref<Node> meshNode;
- for (unsigned int meshIndex = 0; meshIndex < mAsset->meshes.Size(); ++meshIndex) {
- Ref<Mesh> mesh = mAsset->meshes.Get(meshIndex);
- bool hasBones = false;
- for (unsigned int i = 0; i < mesh->primitives.size(); ++i) {
- if (!mesh->primitives[i].attributes.weight.empty()) {
- hasBones = true;
- break;
- }
- }
- if (!hasBones) {
- continue;
- }
- std::string meshID = mesh->id;
- FindMeshNode(rootNode, meshNode, meshID);
- Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
- meshNode->skeletons.push_back(rootJoint);
- meshNode->skin = skinRef;
- }
- }
-}
-
-//merges a node's multiple meshes (with one primitive each) into one mesh with multiple primitives
-void glTF2Exporter::MergeMeshes()
-{
- for (unsigned int n = 0; n < mAsset->nodes.Size(); ++n) {
- Ref<Node> node = mAsset->nodes.Get(n);
-
- unsigned int nMeshes = static_cast<unsigned int>(node->meshes.size());
-
- //skip if it's 1 or less meshes per node
- if (nMeshes > 1) {
- Ref<Mesh> firstMesh = node->meshes.at(0);
-
- //loop backwards to allow easy removal of a mesh from a node once it's merged
- for (unsigned int m = nMeshes - 1; m >= 1; --m) {
- Ref<Mesh> mesh = node->meshes.at(m);
-
- //append this mesh's primitives to the first mesh's primitives
- firstMesh->primitives.insert(
- firstMesh->primitives.end(),
- mesh->primitives.begin(),
- mesh->primitives.end()
- );
-
- //remove the mesh from the list of meshes
- unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
-
- //find the presence of the removed mesh in other nodes
- for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
- Ref<Node> node = mAsset->nodes.Get(nn);
-
- for (unsigned int mm = 0; mm < node->meshes.size(); ++mm) {
- Ref<Mesh>& meshRef = node->meshes.at(mm);
- unsigned int meshIndex = meshRef.GetIndex();
-
- if (meshIndex == removedIndex) {
- node->meshes.erase(node->meshes.begin() + mm);
- } else if (meshIndex > removedIndex) {
- Ref<Mesh> newMeshRef = mAsset->meshes.Get(meshIndex - 1);
-
- meshRef = newMeshRef;
- }
- }
- }
- }
-
- //since we were looping backwards, reverse the order of merged primitives to their original order
- std::reverse(firstMesh->primitives.begin() + 1, firstMesh->primitives.end());
- }
- }
-}
-
-/*
- * Export the root node of the node hierarchy.
- * Calls ExportNode for all children.
- */
-unsigned int glTF2Exporter::ExportNodeHierarchy(const aiNode* n)
-{
- Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
-
- if (!n->mTransformation.IsIdentity()) {
- node->matrix.isPresent = true;
- CopyValue(n->mTransformation, node->matrix.value);
- }
-
- for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
- node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
- }
-
- for (unsigned int i = 0; i < n->mNumChildren; ++i) {
- unsigned int idx = ExportNode(n->mChildren[i], node);
- node->children.push_back(mAsset->nodes.Get(idx));
- }
-
- return node.GetIndex();
-}
-
-/*
- * Export node and recursively calls ExportNode for all children.
- * Since these nodes are not the root node, we also export the parent Ref<Node>
- */
-unsigned int glTF2Exporter::ExportNode(const aiNode* n, Ref<Node>& parent)
-{
- std::string name = mAsset->FindUniqueID(n->mName.C_Str(), "node");
- Ref<Node> node = mAsset->nodes.Create(name);
-
- node->parent = parent;
- node->name = name;
-
- if (!n->mTransformation.IsIdentity()) {
- node->matrix.isPresent = true;
- CopyValue(n->mTransformation, node->matrix.value);
- }
-
- for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
- node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
- }
-
- for (unsigned int i = 0; i < n->mNumChildren; ++i) {
- unsigned int idx = ExportNode(n->mChildren[i], node);
- node->children.push_back(mAsset->nodes.Get(idx));
- }
-
- return node.GetIndex();
-}
-
-
-void glTF2Exporter::ExportScene()
-{
- const char* sceneName = "defaultScene";
- Ref<Scene> scene = mAsset->scenes.Create(sceneName);
-
- // root node will be the first one exported (idx 0)
- if (mAsset->nodes.Size() > 0) {
- scene->nodes.push_back(mAsset->nodes.Get(0u));
- }
-
- // set as the default scene
- mAsset->scene = scene;
-}
-
-void glTF2Exporter::ExportMetadata()
-{
- AssetMetadata& asset = mAsset->asset;
- asset.version = "2.0";
-
- char buffer[256];
- ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
- aiGetVersionMajor(), aiGetVersionMinor(), aiGetVersionRevision());
-
- asset.generator = buffer;
-}
-
-inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animation>& animRef, Ref<Buffer>& buffer, const aiNodeAnim* nodeChannel, float ticksPerSecond)
-{
- // Loop over the data and check to see if it exactly matches an existing buffer.
- // If yes, then reference the existing corresponding accessor.
- // Otherwise, add to the buffer and create a new accessor.
-
- size_t counts[3] = {
- nodeChannel->mNumPositionKeys,
- nodeChannel->mNumScalingKeys,
- nodeChannel->mNumRotationKeys,
- };
- size_t numKeyframes = 1;
- for (int i = 0; i < 3; ++i) {
- if (counts[i] > numKeyframes) {
- numKeyframes = counts[i];
- }
- }
-
- //-------------------------------------------------------
- // Extract TIME parameter data.
- // Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys.
- if(nodeChannel->mNumPositionKeys > 0) {
- typedef float TimeType;
- std::vector<TimeType> timeData;
- timeData.resize(numKeyframes);
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
- // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
- // Check if we have to cast type here. e.g. uint16_t()
- timeData[i] = static_cast<float>(nodeChannel->mPositionKeys[frameIndex].mTime / ticksPerSecond);
- }
-
- Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
- if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
- }
-
- //-------------------------------------------------------
- // Extract translation parameter data
- if(nodeChannel->mNumPositionKeys > 0) {
- C_STRUCT aiVector3D* translationData = new aiVector3D[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
- translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue;
- }
-
- Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if ( tranAccessor ) {
- animRef->Parameters.translation = tranAccessor;
- }
- delete[] translationData;
- }
-
- //-------------------------------------------------------
- // Extract scale parameter data
- if(nodeChannel->mNumScalingKeys > 0) {
- C_STRUCT aiVector3D* scaleData = new aiVector3D[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumScalingKeys / numKeyframes;
- scaleData[i] = nodeChannel->mScalingKeys[frameIndex].mValue;
- }
-
- Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if ( scaleAccessor ) {
- animRef->Parameters.scale = scaleAccessor;
- }
- delete[] scaleData;
- }
-
- //-------------------------------------------------------
- // Extract rotation parameter data
- if(nodeChannel->mNumRotationKeys > 0) {
- vec4* rotationData = new vec4[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumRotationKeys / numKeyframes;
- rotationData[i][0] = nodeChannel->mRotationKeys[frameIndex].mValue.x;
- rotationData[i][1] = nodeChannel->mRotationKeys[frameIndex].mValue.y;
- rotationData[i][2] = nodeChannel->mRotationKeys[frameIndex].mValue.z;
- rotationData[i][3] = nodeChannel->mRotationKeys[frameIndex].mValue.w;
- }
-
- Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( rotAccessor ) {
- animRef->Parameters.rotation = rotAccessor;
- }
- delete[] rotationData;
- }
-}
-
-void glTF2Exporter::ExportAnimations()
-{
- Ref<Buffer> bufferRef = mAsset->buffers.Get(unsigned (0));
-
- for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
- const aiAnimation* anim = mScene->mAnimations[i];
-
- std::string nameAnim = "anim";
- if (anim->mName.length > 0) {
- nameAnim = anim->mName.C_Str();
- }
-
- for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
- const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
-
- // It appears that assimp stores this type of animation as multiple animations.
- // where each aiNodeAnim in mChannels animates a specific node.
- std::string name = nameAnim + "_" + to_string(channelIndex);
- name = mAsset->FindUniqueID(name, "animation");
- Ref<Animation> animRef = mAsset->animations.Create(name);
-
- // Parameters
- ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel, static_cast<float>(anim->mTicksPerSecond));
-
- for (unsigned int j = 0; j < 3; ++j) {
- std::string channelType;
- int channelSize;
- switch (j) {
- case 0:
- channelType = "rotation";
- channelSize = nodeChannel->mNumRotationKeys;
- break;
- case 1:
- channelType = "scale";
- channelSize = nodeChannel->mNumScalingKeys;
- break;
- case 2:
- channelType = "translation";
- channelSize = nodeChannel->mNumPositionKeys;
- break;
- }
-
- if (channelSize < 1) { continue; }
-
- Animation::AnimChannel tmpAnimChannel;
- Animation::AnimSampler tmpAnimSampler;
-
- tmpAnimChannel.sampler = static_cast<int>(animRef->Samplers.size());
- tmpAnimChannel.target.path = channelType;
- tmpAnimSampler.output = channelType;
- tmpAnimSampler.id = name + "_" + channelType;
-
- tmpAnimChannel.target.node = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
-
- tmpAnimSampler.input = "TIME";
- tmpAnimSampler.interpolation = "LINEAR";
-
- animRef->Channels.push_back(tmpAnimChannel);
- animRef->Samplers.push_back(tmpAnimSampler);
- }
-
- }
-
- // Assimp documentation staes this is not used (not implemented)
- // for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) {
- // const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex];
- // }
-
- } // End: for-loop mNumAnimations
-}
-
-
-#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/glTF2Exporter.h b/src/3rdparty/assimp/code/glTF2Exporter.h
deleted file mode 100644
index e9f7c113a..000000000
--- a/src/3rdparty/assimp/code/glTF2Exporter.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 GltfExporter.h
-* Declares the exporter class to write a scene to a gltf/glb file
-*/
-#ifndef AI_GLTF2EXPORTER_H_INC
-#define AI_GLTF2EXPORTER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include <assimp/types.h>
-#include <assimp/material.h>
-
-#include <sstream>
-#include <vector>
-#include <map>
-#include <memory>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-
-namespace glTF2
-{
- template<class T>
- class Ref;
-
- class Asset;
- struct TexProperty;
- struct TextureInfo;
- struct NormalTextureInfo;
- struct OcclusionTextureInfo;
- struct Node;
- struct Texture;
-
- // Vec/matrix types, as raw float arrays
- typedef float (vec3)[3];
- typedef float (vec4)[4];
-}
-
-namespace Assimp
-{
- class IOSystem;
- class IOStream;
- class ExportProperties;
-
- // ------------------------------------------------------------------------------------------------
- /** Helper class to export a given scene to an glTF file. */
- // ------------------------------------------------------------------------------------------------
- class glTF2Exporter
- {
- public:
- /// Constructor for a specific scene to export
- glTF2Exporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
- const ExportProperties* pProperties, bool binary);
-
- private:
-
- const char* mFilename;
- IOSystem* mIOSystem;
- const aiScene* mScene;
- const ExportProperties* mProperties;
-
- std::map<std::string, unsigned int> mTexturesByPath;
-
- std::shared_ptr<glTF2::Asset> mAsset;
-
- std::vector<unsigned char> mBodyData;
-
- void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
-
- void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
- void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
- void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
- void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
- void GetMatTex(const aiMaterial* mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
- void GetMatTex(const aiMaterial* mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
- void GetMatTex(const aiMaterial* mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
- aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx);
- aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx);
- void ExportMetadata();
- void ExportMaterials();
- void ExportMeshes();
- void MergeMeshes();
- unsigned int ExportNodeHierarchy(const aiNode* n);
- unsigned int ExportNode(const aiNode* node, glTF2::Ref<glTF2::Node>& parent);
- void ExportScene();
- void ExportAnimations();
- };
-
-}
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // AI_GLTF2EXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/glTF2Importer.cpp b/src/3rdparty/assimp/code/glTF2Importer.cpp
deleted file mode 100644
index 94e5ca3f1..000000000
--- a/src/3rdparty/assimp/code/glTF2Importer.cpp
+++ /dev/null
@@ -1,694 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include "glTF2Importer.h"
-#include "StringComparison.h"
-#include "StringUtils.h"
-
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-#include "MakeVerboseFormat.h"
-
-#include "glTF2Asset.h"
-// This is included here so WriteLazyDict<T>'s definition is found.
-#include "glTF2AssetWriter.h"
-#include <rapidjson/document.h>
-#include <rapidjson/rapidjson.h>
-
-using namespace Assimp;
-using namespace glTF2;
-
-
-//
-// glTF2Importer
-//
-
-static const aiImporterDesc desc = {
- "glTF2 Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
- 0,
- 0,
- 0,
- 0,
- "gltf glb"
-};
-
-glTF2Importer::glTF2Importer()
-: BaseImporter()
-, meshOffsets()
-, embeddedTexIdxs()
-, mScene( NULL ) {
- // empty
-}
-
-glTF2Importer::~glTF2Importer() {
- // empty
-}
-
-const aiImporterDesc* glTF2Importer::GetInfo() const
-{
- return &desc;
-}
-
-bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string &extension = GetExtension(pFile);
-
- if (extension != "gltf" && extension != "glb")
- return false;
-
- if (checkSig && pIOHandler) {
- glTF2::Asset asset(pIOHandler);
- try {
- asset.Load(pFile, extension == "glb");
- std::string version = asset.asset.version;
- return !version.empty() && version[0] == '2';
- } catch (...) {
- return false;
- }
- }
-
- return false;
-}
-
-
-//static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
-//{
-// out.r = v[0]; out.g = v[1]; out.b = v[2];
-//}
-
-static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
-{
- out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
-}
-
-/*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
-{
- out.r = v[0]; out.g = v[1]; out.b = v[2];
-}*/
-
-static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
-{
- out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
-}
-
-static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
-{
- out.x = v[0]; out.y = v[1]; out.z = v[2];
-}
-
-static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
-{
- out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
-}
-
-static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
-{
- o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
- o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
- o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
- o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
-
-inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
-{
- aiColor4D col;
- CopyValue(prop, col);
- mat->AddProperty(&col, 1, pKey, type, idx);
-}
-
-inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
-{
- aiColor4D col;
- CopyValue(prop, col);
- mat->AddProperty(&col, 1, pKey, type, idx);
-}
-
-inline void SetMaterialTextureProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF2::TextureInfo prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0)
-{
- if (prop.texture && prop.texture->source) {
- aiString uri(prop.texture->source->uri);
-
- int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()];
- if (texIdx != -1) { // embedded
- // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
- uri.data[0] = '*';
- uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx);
- }
-
- mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot));
- mat->AddProperty(&prop.texCoord, 1, _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, texType, texSlot);
-
- if (prop.texture->sampler) {
- Ref<Sampler> sampler = prop.texture->sampler;
-
- aiString name(sampler->name);
- aiString id(sampler->id);
-
- mat->AddProperty(&name, AI_MATKEY_GLTF_MAPPINGNAME(texType, texSlot));
- mat->AddProperty(&id, AI_MATKEY_GLTF_MAPPINGID(texType, texSlot));
-
- mat->AddProperty(&sampler->wrapS, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
- mat->AddProperty(&sampler->wrapT, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
-
- if (sampler->magFilter != SamplerMagFilter::UNSET) {
- mat->AddProperty(&sampler->magFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(texType, texSlot));
- }
-
- if (sampler->minFilter != SamplerMinFilter::UNSET) {
- mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot));
- }
- }
- }
-}
-
-void glTF2Importer::ImportMaterials(glTF2::Asset& r)
-{
- mScene->mNumMaterials = unsigned(r.materials.Size());
- mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
-
- for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
- aiMaterial* aimat = mScene->mMaterials[i] = new aiMaterial();
-
- Material& mat = r.materials[i];
-
- if (!mat.name.empty()) {
- aiString str(mat.name);
-
- aimat->AddProperty(&str, AI_MATKEY_NAME);
- }
-
- SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
- SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR);
-
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE);
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE);
-
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
-
- aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR);
- aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR);
-
- float roughnessAsShininess = (1 - mat.pbrMetallicRoughness.roughnessFactor) * 1000;
- aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS);
-
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS);
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP);
- SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE);
- SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE);
-
- aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED);
-
- aiString alphaMode(mat.alphaMode);
- aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
- aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF);
-
- //pbrSpecularGlossiness
- if (mat.pbrSpecularGlossiness.isPresent) {
- PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
-
- aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS);
- SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
- SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR);
-
- float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f;
- aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS);
- aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR);
-
- SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE);
-
- SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR);
- }
- }
-}
-
-
-static inline void SetFace(aiFace& face, int a)
-{
- face.mNumIndices = 1;
- face.mIndices = new unsigned int[1];
- face.mIndices[0] = a;
-}
-
-static inline void SetFace(aiFace& face, int a, int b)
-{
- face.mNumIndices = 2;
- face.mIndices = new unsigned int[2];
- face.mIndices[0] = a;
- face.mIndices[1] = b;
-}
-
-static inline void SetFace(aiFace& face, int a, int b, int c)
-{
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[3];
- face.mIndices[0] = a;
- face.mIndices[1] = b;
- face.mIndices[2] = c;
-}
-
-#ifdef ASSIMP_BUILD_DEBUG
-static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
-{
- for (unsigned i = 0; i < nFaces; ++i) {
- for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
- unsigned idx = faces[i].mIndices[j];
- if (idx >= nVerts)
- return false;
- }
- }
- return true;
-}
-#endif // ASSIMP_BUILD_DEBUG
-
-void glTF2Importer::ImportMeshes(glTF2::Asset& r)
-{
- std::vector<aiMesh*> meshes;
-
- unsigned int k = 0;
-
- for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
- Mesh& mesh = r.meshes[m];
-
- meshOffsets.push_back(k);
- k += unsigned(mesh.primitives.size());
-
- for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
- Mesh::Primitive& prim = mesh.primitives[p];
-
- aiMesh* aim = new aiMesh();
- meshes.push_back(aim);
-
- aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
-
- if (mesh.primitives.size() > 1) {
- size_t& len = aim->mName.length;
- aim->mName.data[len] = '-';
- len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
- }
-
- switch (prim.mode) {
- case PrimitiveMode_POINTS:
- aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
-
- case PrimitiveMode_LINES:
- case PrimitiveMode_LINE_LOOP:
- case PrimitiveMode_LINE_STRIP:
- aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
-
- case PrimitiveMode_TRIANGLES:
- case PrimitiveMode_TRIANGLE_STRIP:
- case PrimitiveMode_TRIANGLE_FAN:
- aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
-
- }
-
- Mesh::Primitive::Attributes& attr = prim.attributes;
-
- if (attr.position.size() > 0 && attr.position[0]) {
- aim->mNumVertices = attr.position[0]->count;
- attr.position[0]->ExtractData(aim->mVertices);
- }
-
- if (attr.normal.size() > 0 && attr.normal[0]) {
- attr.normal[0]->ExtractData(aim->mNormals);
-
- // only extract tangents if normals are present
- if (attr.tangent.size() > 0 && attr.tangent[0]) {
- // generate bitangents from normals and tangents according to spec
- struct Tangent
- {
- aiVector3D xyz;
- ai_real w;
- } *tangents = nullptr;
-
- attr.tangent[0]->ExtractData(tangents);
-
- aim->mTangents = new aiVector3D[aim->mNumVertices];
- aim->mBitangents = new aiVector3D[aim->mNumVertices];
-
- for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
- aim->mTangents[i] = tangents[i].xyz;
- aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
- }
-
- delete tangents;
- }
- }
-
- for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
- attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
- aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
-
- aiVector3D* values = aim->mTextureCoords[tc];
- for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
- values[i].y = 1 - values[i].y; // Flip Y coords
- }
- }
-
-
- if (prim.indices) {
- aiFace* faces = 0;
- unsigned int nFaces = 0;
-
- unsigned int count = prim.indices->count;
-
- Accessor::Indexer data = prim.indices->GetIndexer();
- ai_assert(data.IsValid());
-
- switch (prim.mode) {
- case PrimitiveMode_POINTS: {
- nFaces = count;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; ++i) {
- SetFace(faces[i], data.GetUInt(i));
- }
- break;
- }
-
- case PrimitiveMode_LINES: {
- nFaces = count / 2;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; i += 2) {
- SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
- }
- break;
- }
-
- case PrimitiveMode_LINE_LOOP:
- case PrimitiveMode_LINE_STRIP: {
- nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
- for (unsigned int i = 2; i < count; ++i) {
- SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
- }
- if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
- SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
- }
- break;
- }
-
- case PrimitiveMode_TRIANGLES: {
- nFaces = count / 3;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; i += 3) {
- SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
- }
- break;
- }
- case PrimitiveMode_TRIANGLE_STRIP: {
- nFaces = count - 2;
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
- for (unsigned int i = 3; i < count; ++i) {
- SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
- }
- break;
- }
- case PrimitiveMode_TRIANGLE_FAN:
- nFaces = count - 2;
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
- for (unsigned int i = 3; i < count; ++i) {
- SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
- }
- break;
- }
-
- if (faces) {
- aim->mFaces = faces;
- aim->mNumFaces = nFaces;
- ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
- }
- }
-
-
- if (prim.material) {
- aim->mMaterialIndex = prim.material.GetIndex();
- }
- }
- }
-
- meshOffsets.push_back(k);
-
- CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
-}
-
-void glTF2Importer::ImportCameras(glTF2::Asset& r)
-{
- if (!r.cameras.Size()) return;
-
- mScene->mNumCameras = r.cameras.Size();
- mScene->mCameras = new aiCamera*[r.cameras.Size()];
-
- for (size_t i = 0; i < r.cameras.Size(); ++i) {
- Camera& cam = r.cameras[i];
-
- aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
-
- if (cam.type == Camera::Perspective) {
-
- aicam->mAspect = cam.cameraProperties.perspective.aspectRatio;
- aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect;
- aicam->mClipPlaneFar = cam.cameraProperties.perspective.zfar;
- aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
- }
- else {
- // assimp does not support orthographic cameras
- }
- }
-}
-
-aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>& meshOffsets, glTF2::Ref<glTF2::Node>& ptr)
-{
- Node& node = *ptr;
-
- std::string nameOrId = node.name.empty() ? node.id : node.name;
-
- aiNode* ainode = new aiNode(nameOrId);
-
- if (!node.children.empty()) {
- ainode->mNumChildren = unsigned(node.children.size());
- ainode->mChildren = new aiNode*[ainode->mNumChildren];
-
- for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
- aiNode* child = ImportNode(pScene, r, meshOffsets, node.children[i]);
- child->mParent = ainode;
- ainode->mChildren[i] = child;
- }
- }
-
- aiMatrix4x4& matrix = ainode->mTransformation;
- if (node.matrix.isPresent) {
- CopyValue(node.matrix.value, matrix);
- }
- else {
- if (node.translation.isPresent) {
- aiVector3D trans;
- CopyValue(node.translation.value, trans);
- aiMatrix4x4 t;
- aiMatrix4x4::Translation(trans, t);
- matrix = matrix * t;
- }
-
- if (node.rotation.isPresent) {
- aiQuaternion rot;
- CopyValue(node.rotation.value, rot);
- matrix = matrix * aiMatrix4x4(rot.GetMatrix());
- }
-
- if (node.scale.isPresent) {
- aiVector3D scal(1.f);
- CopyValue(node.scale.value, scal);
- aiMatrix4x4 s;
- aiMatrix4x4::Scaling(scal, s);
- matrix = matrix * s;
- }
- }
-
- if (!node.meshes.empty()) {
- int count = 0;
- for (size_t i = 0; i < node.meshes.size(); ++i) {
- int idx = node.meshes[i].GetIndex();
- count += meshOffsets[idx + 1] - meshOffsets[idx];
- }
- ainode->mNumMeshes = count;
-
- ainode->mMeshes = new unsigned int[count];
-
- int k = 0;
- for (size_t i = 0; i < node.meshes.size(); ++i) {
- int idx = node.meshes[i].GetIndex();
- for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
- ainode->mMeshes[k] = j;
- }
- }
- }
-
- if (node.camera) {
- pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
- }
-
- return ainode;
-}
-
-void glTF2Importer::ImportNodes(glTF2::Asset& r)
-{
- if (!r.scene) return;
-
- std::vector< Ref<Node> > rootNodes = r.scene->nodes;
-
- // The root nodes
- unsigned int numRootNodes = unsigned(rootNodes.size());
- if (numRootNodes == 1) { // a single root node: use it
- mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
- }
- else if (numRootNodes > 1) { // more than one root node: create a fake root
- aiNode* root = new aiNode("ROOT");
- root->mChildren = new aiNode*[numRootNodes];
- for (unsigned int i = 0; i < numRootNodes; ++i) {
- aiNode* node = ImportNode(mScene, r, meshOffsets, rootNodes[i]);
- node->mParent = root;
- root->mChildren[root->mNumChildren++] = node;
- }
- mScene->mRootNode = root;
- }
-
- //if (!mScene->mRootNode) {
- // mScene->mRootNode = new aiNode("EMPTY");
- //}
-}
-
-void glTF2Importer::ImportEmbeddedTextures(glTF2::Asset& r)
-{
- embeddedTexIdxs.resize(r.images.Size(), -1);
-
- int numEmbeddedTexs = 0;
- for (size_t i = 0; i < r.images.Size(); ++i) {
- if (r.images[i].HasData())
- numEmbeddedTexs += 1;
- }
-
- if (numEmbeddedTexs == 0)
- return;
-
- mScene->mTextures = new aiTexture*[numEmbeddedTexs];
-
- // Add the embedded textures
- for (size_t i = 0; i < r.images.Size(); ++i) {
- Image img = r.images[i];
- if (!img.HasData()) continue;
-
- int idx = mScene->mNumTextures++;
- embeddedTexIdxs[i] = idx;
-
- aiTexture* tex = mScene->mTextures[idx] = new aiTexture();
-
- size_t length = img.GetDataLength();
- void* data = img.StealData();
-
- tex->mWidth = static_cast<unsigned int>(length);
- tex->mHeight = 0;
- tex->pcData = reinterpret_cast<aiTexel*>(data);
-
- if (!img.mimeType.empty()) {
- const char* ext = strchr(img.mimeType.c_str(), '/') + 1;
- if (ext) {
- if (strcmp(ext, "jpeg") == 0) ext = "jpg";
-
- size_t len = strlen(ext);
- if (len <= 3) {
- strcpy(tex->achFormatHint, ext);
- }
- }
- }
- }
-}
-
-void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
-
- this->mScene = pScene;
-
- // read the asset file
- glTF2::Asset asset(pIOHandler);
- asset.Load(pFile, GetExtension(pFile) == "glb");
-
- //
- // Copy the data out
- //
-
- ImportEmbeddedTextures(asset);
- ImportMaterials(asset);
-
- ImportMeshes(asset);
-
- ImportCameras(asset);
-
- ImportNodes(asset);
-
- // TODO: it does not split the loaded vertices, should it?
- //pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- MakeVerboseFormatProcess process;
- process.Execute(pScene);
-
-
- if (pScene->mNumMeshes == 0) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
diff --git a/src/3rdparty/assimp/code/glTF2Importer.h b/src/3rdparty/assimp/code/glTF2Importer.h
deleted file mode 100644
index 6be7131d1..000000000
--- a/src/3rdparty/assimp/code/glTF2Importer.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_GLTF2IMPORTER_H_INC
-#define AI_GLTF2IMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include <assimp/DefaultIOSystem.h>
-
-struct aiNode;
-
-
-namespace glTF2
-{
- class Asset;
-}
-
-namespace Assimp {
-
-/**
- * Load the glTF2 format.
- * https://github.com/KhronosGroup/glTF/tree/master/specification
- */
-class glTF2Importer : public BaseImporter{
-public:
- glTF2Importer();
- virtual ~glTF2Importer();
- virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
-
-protected:
- virtual const aiImporterDesc* GetInfo() const;
- virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
-
-private:
-
- std::vector<unsigned int> meshOffsets;
-
- std::vector<int> embeddedTexIdxs;
-
- aiScene* mScene;
-
- void ImportEmbeddedTextures(glTF2::Asset& a);
- void ImportMaterials(glTF2::Asset& a);
- void ImportMeshes(glTF2::Asset& a);
- void ImportCameras(glTF2::Asset& a);
- void ImportLights(glTF2::Asset& a);
- void ImportNodes(glTF2::Asset& a);
-
-};
-
-} // Namespace assimp
-
-#endif // AI_GLTF2IMPORTER_H_INC
-
diff --git a/src/3rdparty/assimp/code/glTFAsset.h b/src/3rdparty/assimp/code/glTFAsset.h
deleted file mode 100644
index 0c3de16a5..000000000
--- a/src/3rdparty/assimp/code/glTFAsset.h
+++ /dev/null
@@ -1,1196 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 glTFAsset.h
- * Declares a glTF class to handle gltf/glb files
- *
- * glTF Extensions Support:
- * KHR_binary_glTF: full
- * KHR_materials_common: full
- */
-#ifndef GLTFASSET_H_INC
-#define GLTFASSET_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include <map>
-#include <string>
-#include <list>
-#include <vector>
-#include <algorithm>
-#include <stdexcept>
-
-#define RAPIDJSON_HAS_STDSTRING 1
-#include <rapidjson/rapidjson.h>
-#include <rapidjson/document.h>
-#include <rapidjson/error/en.h>
-
-#ifdef ASSIMP_API
-# include <memory>
-# include <assimp/DefaultIOSystem.h>
-# include "ByteSwapper.h"
-#else
-# include <memory>
-# define AI_SWAP4(p)
-# define ai_assert
-#endif
-
-
-#if _MSC_VER > 1500 || (defined __GNUC___)
-# define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
-# else
-# define gltf_unordered_map map
-#endif
-
-#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
-# include <unordered_map>
-# if _MSC_VER > 1600
-# define gltf_unordered_map unordered_map
-# else
-# define gltf_unordered_map tr1::unordered_map
-# endif
-#endif
-
-namespace glTF
-{
-#ifdef ASSIMP_API
- using Assimp::IOStream;
- using Assimp::IOSystem;
- using std::shared_ptr;
-#else
- using std::shared_ptr;
-
- typedef std::runtime_error DeadlyImportError;
- typedef std::runtime_error DeadlyExportError;
-
- enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
- class IOSystem;
- class IOStream
- {
- FILE* f;
- public:
- IOStream(FILE* file) : f(file) {}
- ~IOStream() { fclose(f); f = 0; }
-
- size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
- size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
- int Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
- size_t Tell() const { return ftell(f); }
-
- size_t FileSize() {
- long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
- return size_t((Seek(p, aiOrigin_SET), len));
- }
- };
-#endif
-
- using rapidjson::Value;
- using rapidjson::Document;
-
- class Asset;
- class AssetWriter;
-
- struct BufferView; // here due to cross-reference
- struct Texture;
- struct Light;
- struct Skin;
-
-
- // Vec/matrix types, as raw float arrays
- typedef float (vec3)[3];
- typedef float (vec4)[4];
- typedef float (mat4)[16];
-
-
- namespace Util
- {
- void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
- size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
- inline size_t DecodeBase64(const char* in, uint8_t*& out)
- {
- return DecodeBase64(in, strlen(in), out);
- }
-
- struct DataURI
- {
- const char* mediaType;
- const char* charset;
- bool base64;
- const char* data;
- size_t dataLength;
- };
-
- //! Check if a uri is a data URI
- inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
- }
-
-
- //! Magic number for GLB files
- #define AI_GLB_MAGIC_NUMBER "glTF"
-
- #ifdef ASSIMP_API
- #include "./../include/assimp/Compiler/pushpack1.h"
- #endif
-
- //! For the KHR_binary_glTF extension (binary .glb file)
- //! 20-byte header (+ the JSON + a "body" data section)
- struct GLB_Header
- {
- uint8_t magic[4]; //!< Magic number: "glTF"
- uint32_t version; //!< Version number (always 1 as of the last update)
- uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
- uint32_t sceneLength; //!< Length, in bytes, of the glTF scene
- uint32_t sceneFormat; //!< Specifies the format of the glTF scene (see the SceneFormat enum)
- } PACK_STRUCT;
-
- #ifdef ASSIMP_API
- #include "./../include/assimp/Compiler/poppack1.h"
- #endif
-
-
- //! Values for the GLB_Header::sceneFormat field
- enum SceneFormat
- {
- SceneFormat_JSON = 0
- };
-
- //! Values for the mesh primitive modes
- enum PrimitiveMode
- {
- PrimitiveMode_POINTS = 0,
- PrimitiveMode_LINES = 1,
- PrimitiveMode_LINE_LOOP = 2,
- PrimitiveMode_LINE_STRIP = 3,
- PrimitiveMode_TRIANGLES = 4,
- PrimitiveMode_TRIANGLE_STRIP = 5,
- PrimitiveMode_TRIANGLE_FAN = 6
- };
-
- //! Values for the Accessor::componentType field
- enum ComponentType
- {
- ComponentType_BYTE = 5120,
- ComponentType_UNSIGNED_BYTE = 5121,
- ComponentType_SHORT = 5122,
- ComponentType_UNSIGNED_SHORT = 5123,
- ComponentType_UNSIGNED_INT = 5125,
- ComponentType_FLOAT = 5126
- };
-
- inline unsigned int ComponentTypeSize(ComponentType t)
- {
- switch (t) {
- case ComponentType_SHORT:
- case ComponentType_UNSIGNED_SHORT:
- return 2;
-
- case ComponentType_UNSIGNED_INT:
- case ComponentType_FLOAT:
- return 4;
-
- case ComponentType_BYTE:
- case ComponentType_UNSIGNED_BYTE:
- return 1;
- default:
- std::string err = "GLTF: Unsupported Component Type ";
- err += t;
- throw DeadlyImportError(err);
- }
- }
-
- //! Values for the BufferView::target field
- enum BufferViewTarget
- {
- BufferViewTarget_ARRAY_BUFFER = 34962,
- BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
- };
-
- //! Values for the Sampler::magFilter field
- enum SamplerMagFilter
- {
- SamplerMagFilter_Nearest = 9728,
- SamplerMagFilter_Linear = 9729
- };
-
- //! Values for the Sampler::minFilter field
- enum SamplerMinFilter
- {
- SamplerMinFilter_Nearest = 9728,
- SamplerMinFilter_Linear = 9729,
- SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
- SamplerMinFilter_Linear_Mipmap_Nearest = 9985,
- SamplerMinFilter_Nearest_Mipmap_Linear = 9986,
- SamplerMinFilter_Linear_Mipmap_Linear = 9987
- };
-
- //! Values for the Sampler::wrapS and Sampler::wrapT field
- enum SamplerWrap
- {
- SamplerWrap_Clamp_To_Edge = 33071,
- SamplerWrap_Mirrored_Repeat = 33648,
- SamplerWrap_Repeat = 10497
- };
-
- //! Values for the Texture::format and Texture::internalFormat fields
- enum TextureFormat
- {
- TextureFormat_ALPHA = 6406,
- TextureFormat_RGB = 6407,
- TextureFormat_RGBA = 6408,
- TextureFormat_LUMINANCE = 6409,
- TextureFormat_LUMINANCE_ALPHA = 6410
- };
-
- //! Values for the Texture::target field
- enum TextureTarget
- {
- TextureTarget_TEXTURE_2D = 3553
- };
-
- //! Values for the Texture::type field
- enum TextureType
- {
- TextureType_UNSIGNED_BYTE = 5121,
- TextureType_UNSIGNED_SHORT_5_6_5 = 33635,
- TextureType_UNSIGNED_SHORT_4_4_4_4 = 32819,
- TextureType_UNSIGNED_SHORT_5_5_5_1 = 32820
- };
-
-
- //! Values for the Accessor::type field (helper class)
- class AttribType
- {
- public:
- enum Value
- { SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4 };
-
- private:
- static const size_t NUM_VALUES = static_cast<size_t>(MAT4)+1;
-
- struct Info
- { const char* name; unsigned int numComponents; };
-
- template<int N> struct data
- { static const Info infos[NUM_VALUES]; };
-
- public:
- inline static Value FromString(const char* str)
- {
- for (size_t i = 0; i < NUM_VALUES; ++i) {
- if (strcmp(data<0>::infos[i].name, str) == 0) {
- return static_cast<Value>(i);
- }
- }
- return SCALAR;
- }
-
- inline static const char* ToString(Value type)
- {
- return data<0>::infos[static_cast<size_t>(type)].name;
- }
-
- inline static unsigned int GetNumComponents(Value type)
- {
- return data<0>::infos[static_cast<size_t>(type)].numComponents;
- }
- };
-
- // must match the order of the AttribTypeTraits::Value enum!
- template<int N> const AttribType::Info
- AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
- { "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 }
- };
-
-
-
- //! A reference to one top-level object, which is valid
- //! until the Asset instance is destroyed
- template<class T>
- class Ref
- {
- std::vector<T*>* vector;
- unsigned int index;
-
- public:
- Ref() : vector(0), index(0) {}
- Ref(std::vector<T*>& vec, unsigned int idx) : vector(&vec), index(idx) {}
-
- inline unsigned int GetIndex() const
- { return index; }
-
- operator bool() const
- { return vector != 0; }
-
- T* operator->()
- { return (*vector)[index]; }
-
- T& operator*()
- { return *((*vector)[index]); }
- };
-
- //! Helper struct to represent values that might not be present
- template<class T>
- struct Nullable
- {
- T value;
- bool isPresent;
-
- Nullable() : isPresent(false) {}
- Nullable(T& val) : value(val), isPresent(true) {}
- };
-
-
- //! Base classe for all glTF top-level objects
- struct Object
- {
- std::string id; //!< The globally unique ID used to reference this object
- std::string name; //!< The user-defined name of this object
-
- //! Objects marked as special are not exported (used to emulate the binary body buffer)
- virtual bool IsSpecial() const
- { return false; }
-
- virtual ~Object() {}
-
- //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
- static const char* TranslateId(Asset& /*r*/, const char* id)
- { return id; }
- };
-
- //
- // Classes for each glTF top-level object type
- //
-
- //! A typed view into a BufferView. A BufferView contains raw binary data.
- //! An accessor provides a typed view into a BufferView or a subset of a BufferView
- //! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
- struct Accessor : public Object
- {
- Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
- unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
- unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
- ComponentType componentType; //!< The datatype of components in the attribute. (required)
- unsigned int count; //!< The number of attributes referenced by this accessor. (required)
- AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
- std::vector<float> max; //!< Maximum value of each component in this attribute.
- std::vector<float> min; //!< Minimum value of each component in this attribute.
-
- unsigned int GetNumComponents();
- unsigned int GetBytesPerComponent();
- unsigned int GetElementSize();
-
- inline uint8_t* GetPointer();
-
- template<class T>
- bool ExtractData(T*& outData);
-
- void WriteData(size_t count, const void* src_buffer, size_t src_stride);
-
- //! Helper class to iterate the data
- class Indexer
- {
- friend struct Accessor;
-
- Accessor& accessor;
- uint8_t* data;
- size_t elemSize, stride;
-
- Indexer(Accessor& acc);
-
- public:
-
- //! Accesses the i-th value as defined by the accessor
- template<class T>
- T GetValue(int i);
-
- //! Accesses the i-th value as defined by the accessor
- inline unsigned int GetUInt(int i)
- {
- return GetValue<unsigned int>(i);
- }
-
- inline bool IsValid() const
- {
- return data != 0;
- }
- };
-
- inline Indexer GetIndexer()
- {
- return Indexer(*this);
- }
-
- Accessor() {}
- void Read(Value& obj, Asset& r);
- };
-
- //! A buffer points to binary geometry, animation, or skins.
- struct Buffer : public Object
- {
- /********************* Types *********************/
- public:
-
- enum Type
- {
- Type_arraybuffer,
- Type_text
- };
-
- /// \struct SEncodedRegion
- /// Descriptor of encoded region in "bufferView".
- struct SEncodedRegion
- {
- const size_t Offset;///< Offset from begin of "bufferView" to encoded region, in bytes.
- const size_t EncodedData_Length;///< Size of encoded region, in bytes.
- uint8_t* const DecodedData;///< Cached encoded data.
- const size_t DecodedData_Length;///< Size of decoded region, in bytes.
- const std::string ID;///< ID of the region.
-
- /// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
- /// Constructor.
- /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
- /// \param [in] pEncodedData_Length - size of encoded region, in bytes.
- /// \param [in] pDecodedData - pointer to decoded data array.
- /// \param [in] pDecodedData_Length - size of encoded region, in bytes.
- /// \param [in] pID - ID of the region.
- SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
- : Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID)
- {}
-
- /// \fn ~SEncodedRegion()
- /// Destructor.
- ~SEncodedRegion() { delete [] DecodedData; }
- };
-
- /******************* Variables *******************/
-
- //std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required)
- size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
- //std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")
-
- Type type;
-
- /// \var EncodedRegion_Current
- /// Pointer to currently active encoded region.
- /// Why not decoding all regions at once and not to set one buffer with decoded data?
- /// Yes, why not? Even "accessor" point to decoded data. I mean that fields "byteOffset", "byteStride" and "count" has values which describes decoded
- /// data array. But only in range of mesh while is active parameters from "compressedData". For another mesh accessors point to decoded data too. But
- /// offset is counted for another regions is encoded.
- /// Example. You have two meshes. For every of it you have 4 bytes of data. That data compressed to 2 bytes. So, you have buffer with encoded data:
- /// M1_E0, M1_E1, M2_E0, M2_E1.
- /// After decoding you'll get:
- /// M1_D0, M1_D1, M1_D2, M1_D3, M2_D0, M2_D1, M2_D2, M2_D3.
- /// "accessors" must to use values that point to decoded data - obviously. So, you'll expect "accessors" like
- /// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 4, byteLength: 4}
- /// but in real life you'll get:
- /// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
- /// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
- /// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
- /// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
- ///
- /// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
- /// exporter and importer. And, thanks to such way, there is no need to load whole file into memory.
- SEncodedRegion* EncodedRegion_Current;
-
- private:
-
- shared_ptr<uint8_t> mData; //!< Pointer to the data
- bool mIsSpecial; //!< Set to true for special cases (e.g. the body buffer)
-
- /// \var EncodedRegion_List
- /// List of encoded regions.
- std::list<SEncodedRegion*> EncodedRegion_List;
-
- /******************* Functions *******************/
-
- public:
-
- Buffer();
- ~Buffer();
-
- void Read(Value& obj, Asset& r);
-
- bool LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);
-
- /// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
- /// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
- /// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
- /// \param [in] pEncodedData_Length - size of encoded region, in bytes.
- /// \param [in] pDecodedData - pointer to decoded data array.
- /// \param [in] pDecodedData_Length - size of encoded region, in bytes.
- /// \param [in] pID - ID of the region.
- void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID);
-
- /// \fn void EncodedRegion_SetCurrent(const std::string& pID)
- /// Select current encoded region by ID. \sa EncodedRegion_Current.
- /// \param [in] pID - ID of the region.
- void EncodedRegion_SetCurrent(const std::string& pID);
-
- /// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
- /// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
- /// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
- /// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
- /// \param [in] pReplace_Data - pointer to array with new data for buffer.
- /// \param [in] pReplace_Count - count of bytes in new data.
- /// \return true - if successfully replaced, false if input arguments is out of range.
- bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count);
-
- size_t AppendData(uint8_t* data, size_t length);
- void Grow(size_t amount);
-
- uint8_t* GetPointer()
- { return mData.get(); }
-
- void MarkAsSpecial()
- { mIsSpecial = true; }
-
- bool IsSpecial() const
- { return mIsSpecial; }
-
- std::string GetURI()
- { return std::string(this->id) + ".bin"; }
-
- static const char* TranslateId(Asset& r, const char* id);
- };
-
- //! A view into a buffer generally representing a subset of the buffer.
- struct BufferView : public Object
- {
- Ref<Buffer> buffer; //! The ID of the buffer. (required)
- size_t byteOffset; //! The offset into the buffer in bytes. (required)
- size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
-
- BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
-
- void Read(Value& obj, Asset& r);
- };
-
- struct Camera : public Object
- {
- enum Type
- {
- Perspective,
- Orthographic
- };
-
- Type type;
-
- union
- {
- struct {
- float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
- float yfov; //!<The floating - point vertical field of view in radians. (required)
- float zfar; //!<The floating - point distance to the far clipping plane. (required)
- float znear; //!< The floating - point distance to the near clipping plane. (required)
- } perspective;
-
- struct {
- float xmag; //! The floating-point horizontal magnification of the view. (required)
- float ymag; //! The floating-point vertical magnification of the view. (required)
- float zfar; //! The floating-point distance to the far clipping plane. (required)
- float znear; //! The floating-point distance to the near clipping plane. (required)
- } ortographic;
- };
-
- Camera() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- //! Image data used to create a texture.
- struct Image : public Object
- {
- std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)
-
- Ref<BufferView> bufferView;
-
- std::string mimeType;
-
- int width, height;
-
- private:
- uint8_t* mData;
- size_t mDataLength;
-
- public:
-
- Image();
- void Read(Value& obj, Asset& r);
-
- inline bool HasData() const
- { return mDataLength > 0; }
-
- inline size_t GetDataLength() const
- { return mDataLength; }
-
- inline const uint8_t* GetData() const
- { return mData; }
-
- inline uint8_t* StealData();
-
- inline void SetData(uint8_t* data, size_t length, Asset& r);
- };
-
- //! Holds a material property that can be a texture or a color
- struct TexProperty
- {
- Ref<Texture> texture;
- vec4 color;
- };
-
- //! The material appearance of a primitive.
- struct Material : public Object
- {
- //Ref<Sampler> source; //!< The ID of the technique.
- //std::gltf_unordered_map<std::string, std::string> values; //!< A dictionary object of parameter values.
-
- //! Techniques defined by KHR_materials_common
- enum Technique
- {
- Technique_undefined = 0,
- Technique_BLINN,
- Technique_PHONG,
- Technique_LAMBERT,
- Technique_CONSTANT
- };
-
- TexProperty ambient;
- TexProperty diffuse;
- TexProperty specular;
- TexProperty emission;
-
- bool doubleSided;
- bool transparent;
- float transparency;
- float shininess;
-
- Technique technique;
-
- Material() { SetDefaults(); }
- void Read(Value& obj, Asset& r);
- void SetDefaults();
- };
-
- //! A set of primitives to be rendered. A node can contain one or more meshes. A node's transform places the mesh in the scene.
- struct Mesh : public Object
- {
- typedef std::vector< Ref<Accessor> > AccessorList;
-
- struct Primitive
- {
- PrimitiveMode mode;
-
- struct Attributes {
- AccessorList position, normal, texcoord, color, joint, jointmatrix, weight;
- } attributes;
-
- Ref<Accessor> indices;
-
- Ref<Material> material;
- };
-
- /// \struct SExtension
- /// Extension used for mesh.
- struct SExtension
- {
- /// \enum EType
- /// Type of extension.
- enum EType
- {
- #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- Compression_Open3DGC,///< Compression of mesh data using Open3DGC algorithm.
- #endif
-
- Unknown
- };
-
- EType Type;///< Type of extension.
-
- /// \fn SExtension
- /// Constructor.
- /// \param [in] pType - type of extension.
- SExtension(const EType pType)
- : Type(pType)
- {}
-
- virtual ~SExtension() {
- // empty
- }
- };
-
- #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- /// \struct SCompression_Open3DGC
- /// Compression of mesh data using Open3DGC algorithm.
- struct SCompression_Open3DGC : public SExtension
- {
- using SExtension::Type;
-
- std::string Buffer;///< ID of "buffer" used for storing compressed data.
- size_t Offset;///< Offset in "bufferView" where compressed data are stored.
- size_t Count;///< Count of elements in compressed data. Is always equivalent to size in bytes: look comments for "Type" and "Component_Type".
- bool Binary;///< If true then "binary" mode is used for coding, if false - "ascii" mode.
- size_t IndicesCount;///< Count of indices in mesh.
- size_t VerticesCount;///< Count of vertices in mesh.
- // AttribType::Value Type;///< Is always "SCALAR".
- // ComponentType Component_Type;///< Is always "ComponentType_UNSIGNED_BYTE" (5121).
-
- /// \fn SCompression_Open3DGC
- /// Constructor.
- SCompression_Open3DGC()
- : SExtension(Compression_Open3DGC) {
- // empty
- }
-
- virtual ~SCompression_Open3DGC() {
- // empty
- }
- };
- #endif
-
- std::vector<Primitive> primitives;
- std::list<SExtension*> Extension;///< List of extensions used in mesh.
-
- Mesh() {}
-
- /// \fn ~Mesh()
- /// Destructor.
- ~Mesh() { for(std::list<SExtension*>::iterator it = Extension.begin(), it_end = Extension.end(); it != it_end; it++) { delete *it; }; }
-
- /// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
- /// Get mesh data from JSON-object and place them to root asset.
- /// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
- /// \param [out] pAsset_Root - reference to root assed where data will be stored.
- void Read(Value& pJSON_Object, Asset& pAsset_Root);
-
- #ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- /// \fn void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root)
- /// Decode part of "buffer" which encoded with Open3DGC algorithm.
- /// \param [in] pCompression_Open3DGC - reference to structure which describe encoded region.
- /// \param [out] pAsset_Root - reference to root assed where data will be stored.
- void Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root);
- #endif
- };
-
- struct Node : public Object
- {
- std::vector< Ref<Node> > children;
- std::vector< Ref<Mesh> > meshes;
-
- Nullable<mat4> matrix;
- Nullable<vec3> translation;
- Nullable<vec4> rotation;
- Nullable<vec3> scale;
-
- Ref<Camera> camera;
- Ref<Light> light;
-
- std::vector< Ref<Node> > skeletons; //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy.
- Ref<Skin> skin; //!< The ID of the skin referenced by this node.
- std::string jointName; //!< Name used when this node is a joint in a skin.
-
- Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
-
- Node() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Program : public Object
- {
- Program() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- struct Sampler : public Object
- {
- SamplerMagFilter magFilter; //!< The texture magnification filter. (required)
- SamplerMinFilter minFilter; //!< The texture minification filter. (required)
- SamplerWrap wrapS; //!< The texture wrapping in the S direction. (required)
- SamplerWrap wrapT; //!< The texture wrapping in the T direction. (required)
-
- Sampler() {}
- void Read(Value& obj, Asset& r);
- void SetDefaults();
- };
-
- struct Scene : public Object
- {
- std::vector< Ref<Node> > nodes;
-
- Scene() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Shader : public Object
- {
- Shader() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Skin : public Object
- {
- Nullable<mat4> bindShapeMatrix; //!< Floating-point 4x4 transformation matrix stored in column-major order.
- Ref<Accessor> inverseBindMatrices; //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
- std::vector<Ref<Node>> jointNames; //!< Joint names of the joints (nodes with a jointName property) in this skin.
- std::string name; //!< The user-defined name of this object.
-
- Skin() {}
- void Read(Value& obj, Asset& r);
- };
-
- struct Technique : public Object
- {
- struct Parameters
- {
-
- };
-
- struct States
- {
-
- };
-
- struct Functions
- {
-
- };
-
- Technique() {}
- void Read(Value& obj, Asset& r);
- };
-
- //! A texture and its sampler.
- struct Texture : public Object
- {
- Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
- Ref<Image> source; //!< The ID of the image used by this texture. (required)
-
- //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
- //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)
-
- //TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
- //TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)
-
- Texture() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- //! A light (from KHR_materials_common extension)
- struct Light : public Object
- {
- enum Type
- {
- Type_undefined,
- Type_ambient,
- Type_directional,
- Type_point,
- Type_spot
- };
-
- Type type;
-
- vec4 color;
- float distance;
- float constantAttenuation;
- float linearAttenuation;
- float quadraticAttenuation;
- float falloffAngle;
- float falloffExponent;
-
- Light() {}
- void Read(Value& obj, Asset& r);
-
- void SetDefaults();
- };
-
- struct Animation : public Object
- {
- struct AnimSampler {
- std::string id; //!< The ID of this sampler.
- std::string input; //!< The ID of a parameter in this animation to use as key-frame input.
- std::string interpolation; //!< Type of interpolation algorithm to use between key-frames.
- std::string output; //!< The ID of a parameter in this animation to use as key-frame output.
- };
-
- struct AnimChannel {
- std::string sampler; //!< The ID of one sampler present in the containing animation's samplers property.
-
- struct AnimTarget {
- Ref<Node> id; //!< The ID of the node to animate.
- std::string path; //!< The name of property of the node to animate ("translation", "rotation", or "scale").
- } target;
- };
-
- struct AnimParameters {
- Ref<Accessor> TIME; //!< Accessor reference to a buffer storing a array of floating point scalar values.
- Ref<Accessor> rotation; //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
- Ref<Accessor> scale; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
- Ref<Accessor> translation; //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
- };
-
- // AnimChannel Channels[3]; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
- // AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
- // AnimSampler Samplers[3]; //!< The parameterized inputs representing the key-frame data.
-
- std::vector<AnimChannel> Channels; //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
- AnimParameters Parameters; //!< The samplers that interpolate between the key-frames.
- std::vector<AnimSampler> Samplers; //!< The parameterized inputs representing the key-frame data.
-
- Animation() {}
- void Read(Value& obj, Asset& r);
- };
-
-
- //! Base class for LazyDict that acts as an interface
- class LazyDictBase
- {
- public:
- virtual ~LazyDictBase() {}
-
- virtual void AttachToDocument(Document& doc) = 0;
- virtual void DetachFromDocument() = 0;
-
- virtual void WriteObjects(AssetWriter& writer) = 0;
- };
-
-
- template<class T>
- class LazyDict;
-
- //! (Implemented in glTFAssetWriter.h)
- template<class T>
- void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
-
-
- //! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
- //! It is the owner the loaded objects, so when it is destroyed it also deletes them
- template<class T>
- class LazyDict : public LazyDictBase
- {
- friend class Asset;
- friend class AssetWriter;
-
- typedef typename std::gltf_unordered_map< std::string, unsigned int > Dict;
-
- std::vector<T*> mObjs; //! The read objects
- Dict mObjsById; //! The read objects accessible by id
- const char* mDictId; //! ID of the dictionary object
- const char* mExtId; //! ID of the extension defining the dictionary
- Value* mDict; //! JSON dictionary object
- Asset& mAsset; //! The asset instance
-
- void AttachToDocument(Document& doc);
- void DetachFromDocument();
-
- void WriteObjects(AssetWriter& writer)
- { WriteLazyDict<T>(*this, writer); }
-
- Ref<T> Add(T* obj);
-
- public:
- LazyDict(Asset& asset, const char* dictId, const char* extId = 0);
- ~LazyDict();
-
- Ref<T> Get(const char* id);
- Ref<T> Get(unsigned int i);
- Ref<T> Get(const std::string& pID) { return Get(pID.c_str()); }
-
- Ref<T> Create(const char* id);
- Ref<T> Create(const std::string& id)
- { return Create(id.c_str()); }
-
- inline unsigned int Size() const
- { return unsigned(mObjs.size()); }
-
- inline T& operator[](size_t i)
- { return *mObjs[i]; }
-
- };
-
-
- struct AssetMetadata
- {
- std::string copyright; //!< A copyright message suitable for display to credit the content creator.
- std::string generator; //!< Tool that generated this glTF model.Useful for debugging.
- bool premultipliedAlpha; //!< Specifies if the shaders were generated with premultiplied alpha. (default: false)
-
- struct {
- std::string api; //!< Specifies the target rendering API (default: "WebGL")
- std::string version; //!< Specifies the target rendering API (default: "1.0.3")
- } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})
-
- std::string version; //!< The glTF format version (should be 1.0)
-
- void Read(Document& doc);
-
- AssetMetadata()
- : premultipliedAlpha(false)
- , version("")
- {
- }
- };
-
- //
- // glTF Asset class
- //
-
- //! Root object for a glTF asset
- class Asset
- {
- typedef std::gltf_unordered_map<std::string, int> IdMap;
-
- template<class T>
- friend class LazyDict;
-
- friend struct Buffer; // To access OpenFile
-
- friend class AssetWriter;
-
- private:
- IOSystem* mIOSystem;
-
- std::string mCurrentAssetDir;
-
- size_t mSceneLength;
- size_t mBodyOffset, mBodyLength;
-
- std::vector<LazyDictBase*> mDicts;
-
- IdMap mUsedIds;
-
- Ref<Buffer> mBodyBuffer;
-
- Asset(Asset&);
- Asset& operator=(const Asset&);
-
- public:
-
- //! Keeps info about the enabled extensions
- struct Extensions
- {
- bool KHR_binary_glTF;
- bool KHR_materials_common;
-
- } extensionsUsed;
-
- AssetMetadata asset;
-
-
- // Dictionaries for each type of object
-
- LazyDict<Accessor> accessors;
- LazyDict<Animation> animations;
- LazyDict<Buffer> buffers;
- LazyDict<BufferView> bufferViews;
- LazyDict<Camera> cameras;
- LazyDict<Image> images;
- LazyDict<Material> materials;
- LazyDict<Mesh> meshes;
- LazyDict<Node> nodes;
- //LazyDict<Program> programs;
- LazyDict<Sampler> samplers;
- LazyDict<Scene> scenes;
- //LazyDict<Shader> shaders;
- LazyDict<Skin> skins;
- //LazyDict<Technique> techniques;
- LazyDict<Texture> textures;
-
- LazyDict<Light> lights; // KHR_materials_common ext
-
- Ref<Scene> scene;
-
- public:
- Asset(IOSystem* io = 0)
- : mIOSystem(io)
- , asset()
- , accessors (*this, "accessors")
- , animations (*this, "animations")
- , buffers (*this, "buffers")
- , bufferViews (*this, "bufferViews")
- , cameras (*this, "cameras")
- , images (*this, "images")
- , materials (*this, "materials")
- , meshes (*this, "meshes")
- , nodes (*this, "nodes")
- //, programs (*this, "programs")
- , samplers (*this, "samplers")
- , scenes (*this, "scenes")
- //, shaders (*this, "shaders")
- , skins (*this, "skins")
- //, techniques (*this, "techniques")
- , textures (*this, "textures")
- , lights (*this, "lights", "KHR_materials_common")
- {
- memset(&extensionsUsed, 0, sizeof(extensionsUsed));
- }
-
- //! Main function
- void Load(const std::string& file, bool isBinary = false);
-
- //! Enables the "KHR_binary_glTF" extension on the asset
- void SetAsBinary();
-
- //! Search for an available name, starting from the given strings
- std::string FindUniqueID(const std::string& str, const char* suffix);
-
- Ref<Buffer> GetBodyBuffer()
- { return mBodyBuffer; }
-
- private:
- void ReadBinaryHeader(IOStream& stream);
-
- void ReadExtensionsUsed(Document& doc);
-
-
- IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
- };
-
-}
-
-// Include the implementation of the methods
-#include "glTFAsset.inl"
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // GLTFASSET_H_INC
diff --git a/src/3rdparty/assimp/code/glTFAsset.inl b/src/3rdparty/assimp/code/glTFAsset.inl
deleted file mode 100644
index a5d74f5a0..000000000
--- a/src/3rdparty/assimp/code/glTFAsset.inl
+++ /dev/null
@@ -1,1645 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include "StringUtils.h"
-#include <iomanip>
-
-// Header files, Assimp
-#include <assimp/DefaultLogger.hpp>
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- // Header files, Open3DGC.
-# include <Open3DGC/o3dgcSC3DMCDecoder.h>
-#endif
-
-using namespace Assimp;
-
-namespace glTF {
-
-namespace {
-
- //
- // JSON Value reading helpers
- //
-
- template<class T>
- struct ReadHelper { static bool Read(Value& val, T& out) {
- return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
- }};
-
- template<> struct ReadHelper<bool> { static bool Read(Value& val, bool& out) {
- return val.IsBool() ? out = val.GetBool(), true : false;
- }};
-
- template<> struct ReadHelper<float> { static bool Read(Value& val, float& out) {
- return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
- }};
-
- template<unsigned int N> struct ReadHelper<float[N]> { static bool Read(Value& val, float (&out)[N]) {
- if (!val.IsArray() || val.Size() != N) return false;
- for (unsigned int i = 0; i < N; ++i) {
- if (val[i].IsNumber())
- out[i] = static_cast<float>(val[i].GetDouble());
- }
- return true;
- }};
-
- template<> struct ReadHelper<const char*> { static bool Read(Value& val, const char*& out) {
- return val.IsString() ? (out = val.GetString(), true) : false;
- }};
-
- template<> struct ReadHelper<std::string> { static bool Read(Value& val, std::string& out) {
- return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
- }};
-
- template<class T> struct ReadHelper< Nullable<T> > { static bool Read(Value& val, Nullable<T>& out) {
- return out.isPresent = ReadHelper<T>::Read(val, out.value);
- }};
-
- template<class T>
- inline static bool ReadValue(Value& val, T& out)
- {
- return ReadHelper<T>::Read(val, out);
- }
-
- template<class T>
- inline static bool ReadMember(Value& obj, const char* id, T& out)
- {
- Value::MemberIterator it = obj.FindMember(id);
- if (it != obj.MemberEnd()) {
- return ReadHelper<T>::Read(it->value, out);
- }
- return false;
- }
-
- template<class T>
- inline static T MemberOrDefault(Value& obj, const char* id, T defaultValue)
- {
- T out;
- return ReadMember(obj, id, out) ? out : defaultValue;
- }
-
- inline Value* FindMember(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd()) ? &it->value : 0;
- }
-
- inline Value* FindString(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
- }
-
- inline Value* FindNumber(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0;
- }
-
- inline Value* FindArray(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsArray()) ? &it->value : 0;
- }
-
- inline Value* FindObject(Value& val, const char* id)
- {
- Value::MemberIterator it = val.FindMember(id);
- return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : 0;
- }
-}
-
-//
-// LazyDict methods
-//
-
-template<class T>
-inline LazyDict<T>::LazyDict(Asset& asset, const char* dictId, const char* extId)
- : mDictId(dictId), mExtId(extId), mDict(0), mAsset(asset)
-{
- asset.mDicts.push_back(this); // register to the list of dictionaries
-}
-
-template<class T>
-inline LazyDict<T>::~LazyDict()
-{
- for (size_t i = 0; i < mObjs.size(); ++i) {
- delete mObjs[i];
- }
-}
-
-
-template<class T>
-inline void LazyDict<T>::AttachToDocument(Document& doc)
-{
- Value* container = 0;
-
- if (mExtId) {
- if (Value* exts = FindObject(doc, "extensions")) {
- container = FindObject(*exts, mExtId);
- }
- }
- else {
- container = &doc;
- }
-
- if (container) {
- mDict = FindObject(*container, mDictId);
- }
-}
-
-template<class T>
-inline void LazyDict<T>::DetachFromDocument()
-{
- mDict = 0;
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Get(unsigned int i)
-{
- return Ref<T>(mObjs, i);
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Get(const char* id)
-{
- id = T::TranslateId(mAsset, id);
-
- typename Dict::iterator it = mObjsById.find(id);
- if (it != mObjsById.end()) { // already created?
- return Ref<T>(mObjs, it->second);
- }
-
- // read it from the JSON object
- if (!mDict) {
- throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
- }
-
- Value::MemberIterator obj = mDict->FindMember(id);
- if (obj == mDict->MemberEnd()) {
- throw DeadlyImportError("GLTF: Missing object with id \"" + std::string(id) + "\" in \"" + mDictId + "\"");
- }
- if (!obj->value.IsObject()) {
- throw DeadlyImportError("GLTF: Object with id \"" + std::string(id) + "\" is not a JSON object");
- }
-
- // create an instance of the given type
- T* inst = new T();
- inst->id = id;
- ReadMember(obj->value, "name", inst->name);
- inst->Read(obj->value, mAsset);
- return Add(inst);
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Add(T* obj)
-{
- unsigned int idx = unsigned(mObjs.size());
- mObjs.push_back(obj);
- mObjsById[obj->id] = idx;
- mAsset.mUsedIds[obj->id] = true;
- return Ref<T>(mObjs, idx);
-}
-
-template<class T>
-Ref<T> LazyDict<T>::Create(const char* id)
-{
- Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
- if (it != mAsset.mUsedIds.end()) {
- throw DeadlyImportError("GLTF: two objects with the same ID exist");
- }
- T* inst = new T();
- inst->id = id;
- return Add(inst);
-}
-
-
-//
-// glTF dictionary objects methods
-//
-
-
-inline Buffer::Buffer()
- : byteLength(0), type(Type_arraybuffer), EncodedRegion_Current(nullptr), mIsSpecial(false)
-{ }
-
-inline Buffer::~Buffer()
-{
- for(SEncodedRegion* reg : EncodedRegion_List) delete reg;
-}
-
-inline const char* Buffer::TranslateId(Asset& r, const char* id)
-{
- // Compatibility with old spec
- if (r.extensionsUsed.KHR_binary_glTF && strcmp(id, "KHR_binary_glTF") == 0) {
- return "binary_glTF";
- }
-
- return id;
-}
-
-inline void Buffer::Read(Value& obj, Asset& r)
-{
- size_t statedLength = MemberOrDefault<size_t>(obj, "byteLength", 0);
- byteLength = statedLength;
-
- Value* it = FindString(obj, "uri");
- if (!it) {
- if (statedLength > 0) {
- throw DeadlyImportError("GLTF: buffer with non-zero length missing the \"uri\" attribute");
- }
- return;
- }
-
- const char* uri = it->GetString();
-
- Util::DataURI dataURI;
- if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
- if (dataURI.base64) {
- uint8_t* data = 0;
- this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
- this->mData.reset(data);
-
- if (statedLength > 0 && this->byteLength != statedLength) {
- throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
- " bytes, but found " + to_string(dataURI.dataLength));
- }
- }
- else { // assume raw data
- if (statedLength != dataURI.dataLength) {
- throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
- " bytes, but found " + to_string(dataURI.dataLength));
- }
-
- this->mData.reset(new uint8_t[dataURI.dataLength]);
- memcpy( this->mData.get(), dataURI.data, dataURI.dataLength );
- }
- }
- else { // Local file
- if (byteLength > 0) {
- std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : "";
-
- IOStream* file = r.OpenFile(dir + uri, "rb");
- if (file) {
- bool ok = LoadFromStream(*file, byteLength);
- delete file;
-
- if (!ok)
- throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"" );
- }
- else {
- throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
- }
- }
- }
-}
-
-inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseOffset)
-{
- byteLength = length ? length : stream.FileSize();
-
- if (baseOffset) {
- stream.Seek(baseOffset, aiOrigin_SET);
- }
-
- mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());
-
- if (stream.Read(mData.get(), byteLength, 1) != 1) {
- return false;
- }
- return true;
-}
-
-inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
-{
- // Check pointer to data
- if(pDecodedData == nullptr) throw DeadlyImportError("GLTF: for marking encoded region pointer to decoded data must be provided.");
-
- // Check offset
- if(pOffset > byteLength)
- {
- const uint8_t val_size = 32;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, "%llu", (long long)pOffset);
- throw DeadlyImportError(std::string("GLTF: incorrect offset value (") + val + ") for marking encoded region.");
- }
-
- // Check length
- if((pOffset + pEncodedData_Length) > byteLength)
- {
- const uint8_t val_size = 64;
-
- char val[val_size];
-
- ai_snprintf(val, val_size, "%llu, %llu", (long long)pOffset, (long long)pEncodedData_Length);
- throw DeadlyImportError(std::string("GLTF: encoded region with offset/length (") + val + ") is out of range.");
- }
-
- // Add new region
- EncodedRegion_List.push_back(new SEncodedRegion(pOffset, pEncodedData_Length, pDecodedData, pDecodedData_Length, pID));
- // And set new value for "byteLength"
- byteLength += (pDecodedData_Length - pEncodedData_Length);
-}
-
-inline void Buffer::EncodedRegion_SetCurrent(const std::string& pID)
-{
- if((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;
-
- for(SEncodedRegion* reg : EncodedRegion_List)
- {
- if(reg->ID == pID)
- {
- EncodedRegion_Current = reg;
-
- return;
- }
-
- }
-
- throw DeadlyImportError("GLTF: EncodedRegion with ID: \"" + pID + "\" not found.");
-}
-
-inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
-{
-const size_t new_data_size = byteLength + pReplace_Count - pBufferData_Count;
-
-uint8_t* new_data;
-
- if((pBufferData_Count == 0) || (pReplace_Count == 0) || (pReplace_Data == nullptr)) return false;
-
- new_data = new uint8_t[new_data_size];
- // Copy data which place before replacing part.
- memcpy(new_data, mData.get(), pBufferData_Offset);
- // Copy new data.
- memcpy(&new_data[pBufferData_Offset], pReplace_Data, pReplace_Count);
- // Copy data which place after replacing part.
- memcpy(&new_data[pBufferData_Offset + pReplace_Count], &mData.get()[pBufferData_Offset + pBufferData_Count], pBufferData_Offset);
- // Apply new data
- mData.reset(new_data);
- byteLength = new_data_size;
-
- return true;
-}
-
-inline size_t Buffer::AppendData(uint8_t* data, size_t length)
-{
- size_t offset = this->byteLength;
- Grow(length);
- memcpy(mData.get() + offset, data, length);
- return offset;
-}
-
-inline void Buffer::Grow(size_t amount)
-{
- if (amount <= 0) return;
- uint8_t* b = new uint8_t[byteLength + amount];
- if (mData) memcpy(b, mData.get(), byteLength);
- mData.reset(b);
- byteLength += amount;
-}
-
-//
-// struct BufferView
-//
-
-inline void BufferView::Read(Value& obj, Asset& r)
-{
- const char* bufferId = MemberOrDefault<const char*>(obj, "buffer", 0);
- if (bufferId) {
- buffer = r.buffers.Get(bufferId);
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- byteLength = MemberOrDefault(obj, "byteLength", 0u);
-}
-
-//
-// struct Accessor
-//
-
-inline void Accessor::Read(Value& obj, Asset& r)
-{
- const char* bufferViewId = MemberOrDefault<const char*>(obj, "bufferView", 0);
- if (bufferViewId) {
- bufferView = r.bufferViews.Get(bufferViewId);
- }
-
- byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
- byteStride = MemberOrDefault(obj, "byteStride", 0u);
- componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
- count = MemberOrDefault(obj, "count", 0u);
-
- const char* typestr;
- type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
-}
-
-inline unsigned int Accessor::GetNumComponents()
-{
- return AttribType::GetNumComponents(type);
-}
-
-inline unsigned int Accessor::GetBytesPerComponent()
-{
- return int(ComponentTypeSize(componentType));
-}
-
-inline unsigned int Accessor::GetElementSize()
-{
- return GetNumComponents() * GetBytesPerComponent();
-}
-
-inline uint8_t* Accessor::GetPointer()
-{
- if (!bufferView || !bufferView->buffer) return 0;
- uint8_t* basePtr = bufferView->buffer->GetPointer();
- if (!basePtr) return 0;
-
- size_t offset = byteOffset + bufferView->byteOffset;
-
- // Check if region is encoded.
- if(bufferView->buffer->EncodedRegion_Current != nullptr)
- {
- const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
- const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;
-
- if((offset >= begin) && (offset < end))
- return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
- }
-
- return basePtr + offset;
-}
-
-namespace {
- inline void CopyData(size_t count,
- const uint8_t* src, size_t src_stride,
- uint8_t* dst, size_t dst_stride)
- {
- if (src_stride == dst_stride) {
- memcpy(dst, src, count * src_stride);
- }
- else {
- size_t sz = std::min(src_stride, dst_stride);
- for (size_t i = 0; i < count; ++i) {
- memcpy(dst, src, sz);
- if (sz < dst_stride) {
- memset(dst + sz, 0, dst_stride - sz);
- }
- src += src_stride;
- dst += dst_stride;
- }
- }
- }
-}
-
-template<class T>
-bool Accessor::ExtractData(T*& outData)
-{
- uint8_t* data = GetPointer();
- if (!data) return false;
-
- const size_t elemSize = GetElementSize();
- const size_t totalSize = elemSize * count;
-
- const size_t stride = byteStride ? byteStride : elemSize;
-
- const size_t targetElemSize = sizeof(T);
- ai_assert(elemSize <= targetElemSize);
-
- ai_assert(count*stride <= bufferView->byteLength);
-
- outData = new T[count];
- if (stride == elemSize && targetElemSize == elemSize) {
- memcpy(outData, data, totalSize);
- }
- else {
- for (size_t i = 0; i < count; ++i) {
- memcpy(outData + i, data + i*stride, elemSize);
- }
- }
-
- return true;
-}
-
-inline void Accessor::WriteData(size_t count, const void* src_buffer, size_t src_stride)
-{
- uint8_t* buffer_ptr = bufferView->buffer->GetPointer();
- size_t offset = byteOffset + bufferView->byteOffset;
-
- size_t dst_stride = GetNumComponents() * GetBytesPerComponent();
-
- const uint8_t* src = reinterpret_cast<const uint8_t*>(src_buffer);
- uint8_t* dst = reinterpret_cast< uint8_t*>(buffer_ptr + offset);
-
- ai_assert(dst + count*dst_stride <= buffer_ptr + bufferView->buffer->byteLength);
- CopyData(count, src, src_stride, dst, dst_stride);
-}
-
-
-
-inline Accessor::Indexer::Indexer(Accessor& acc)
- : accessor(acc)
- , data(acc.GetPointer())
- , elemSize(acc.GetElementSize())
- , stride(acc.byteStride ? acc.byteStride : elemSize)
-{
-
-}
-
-//! Accesses the i-th value as defined by the accessor
-template<class T>
-T Accessor::Indexer::GetValue(int i)
-{
- ai_assert(data);
- ai_assert(i*stride < accessor.bufferView->byteLength);
- T value = T();
- memcpy(&value, data + i*stride, elemSize);
- //value >>= 8 * (sizeof(T) - elemSize);
- return value;
-}
-
-inline Image::Image()
- : width(0)
- , height(0)
- , mData(0)
- , mDataLength(0)
-{
-
-}
-
-inline void Image::Read(Value& obj, Asset& r)
-{
- // Check for extensions first (to detect binary embedded data)
- if (Value* extensions = FindObject(obj, "extensions")) {
- if (r.extensionsUsed.KHR_binary_glTF) {
- if (Value* ext = FindObject(*extensions, "KHR_binary_glTF")) {
-
- width = MemberOrDefault(*ext, "width", 0);
- height = MemberOrDefault(*ext, "height", 0);
-
- ReadMember(*ext, "mimeType", mimeType);
-
- const char* bufferViewId;
- if (ReadMember(*ext, "bufferView", bufferViewId)) {
- Ref<BufferView> bv = r.bufferViews.Get(bufferViewId);
- if (bv) {
- mDataLength = bv->byteLength;
- mData = new uint8_t[mDataLength];
- memcpy(mData, bv->buffer->GetPointer() + bv->byteOffset, mDataLength);
- }
- }
- }
- }
- }
-
- if (!mDataLength) {
- if (Value* uri = FindString(obj, "uri")) {
- const char* uristr = uri->GetString();
-
- Util::DataURI dataURI;
- if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
- mimeType = dataURI.mediaType;
- if (dataURI.base64) {
- mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, mData);
- }
- }
- else {
- this->uri = uristr;
- }
- }
- }
-}
-
-inline uint8_t* Image::StealData()
-{
- uint8_t* data = mData;
- mDataLength = 0;
- mData = 0;
- return data;
-}
-
-inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
-{
- Ref<Buffer> b = r.GetBodyBuffer();
- if (b) { // binary file: append to body
- std::string bvId = r.FindUniqueID(this->id, "imgdata");
- bufferView = r.bufferViews.Create(bvId);
-
- bufferView->buffer = b;
- bufferView->byteLength = length;
- bufferView->byteOffset = b->AppendData(data, length);
- }
- else { // text file: will be stored as a data uri
- this->mData = data;
- this->mDataLength = length;
- }
-}
-
-inline void Sampler::Read(Value& obj, Asset& /*r*/)
-{
- SetDefaults();
-
- ReadMember(obj, "magFilter", magFilter);
- ReadMember(obj, "minFilter", minFilter);
- ReadMember(obj, "wrapS", wrapS);
- ReadMember(obj, "wrapT", wrapT);
-}
-
-inline void Sampler::SetDefaults()
-{
- magFilter = SamplerMagFilter_Linear;
- minFilter = SamplerMinFilter_Linear;
- wrapS = SamplerWrap_Repeat;
- wrapT = SamplerWrap_Repeat;
-}
-
-inline void Texture::Read(Value& obj, Asset& r)
-{
- const char* sourcestr;
- if (ReadMember(obj, "source", sourcestr)) {
- source = r.images.Get(sourcestr);
- }
-
- const char* samplerstr;
- if (ReadMember(obj, "sampler", samplerstr)) {
- sampler = r.samplers.Get(samplerstr);
- }
-}
-
-namespace {
- inline void ReadMaterialProperty(Asset& r, Value& vals, const char* propName, TexProperty& out)
- {
- if (Value* prop = FindMember(vals, propName)) {
- if (prop->IsString()) {
- out.texture = r.textures.Get(prop->GetString());
- }
- else {
- ReadValue(*prop, out.color);
- }
- }
- }
-}
-
-inline void Material::Read(Value& material, Asset& r)
-{
- SetDefaults();
-
- if (Value* values = FindObject(material, "values")) {
- ReadMaterialProperty(r, *values, "ambient", this->ambient);
- ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
- ReadMaterialProperty(r, *values, "specular", this->specular);
-
- ReadMember(*values, "transparency", transparency);
- ReadMember(*values, "shininess", shininess);
- }
-
- if (Value* extensions = FindObject(material, "extensions")) {
- if (r.extensionsUsed.KHR_materials_common) {
- if (Value* ext = FindObject(*extensions, "KHR_materials_common")) {
- if (Value* tnq = FindString(*ext, "technique")) {
- const char* t = tnq->GetString();
- if (strcmp(t, "BLINN") == 0) technique = Technique_BLINN;
- else if (strcmp(t, "PHONG") == 0) technique = Technique_PHONG;
- else if (strcmp(t, "LAMBERT") == 0) technique = Technique_LAMBERT;
- else if (strcmp(t, "CONSTANT") == 0) technique = Technique_CONSTANT;
- }
-
- if (Value* values = FindObject(*ext, "values")) {
- ReadMaterialProperty(r, *values, "ambient", this->ambient);
- ReadMaterialProperty(r, *values, "diffuse", this->diffuse);
- ReadMaterialProperty(r, *values, "specular", this->specular);
-
- ReadMember(*values, "doubleSided", doubleSided);
- ReadMember(*values, "transparent", transparent);
- ReadMember(*values, "transparency", transparency);
- ReadMember(*values, "shininess", shininess);
- }
- }
- }
- }
-}
-
-namespace {
- void SetVector(vec4& v, float x, float y, float z, float w)
- { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
-}
-
-inline void Material::SetDefaults()
-{
- SetVector(ambient.color, 0, 0, 0, 1);
- SetVector(diffuse.color, 0, 0, 0, 1);
- SetVector(specular.color, 0, 0, 0, 1);
- SetVector(emission.color, 0, 0, 0, 1);
-
- doubleSided = false;
- transparent = false;
- transparency = 1.0;
- shininess = 0.0;
-
- technique = Technique_undefined;
-}
-
-namespace {
-
- template<int N>
- inline int Compare(const char* attr, const char (&str)[N]) {
- return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
- }
-
- inline bool GetAttribVector(Mesh::Primitive& p, const char* attr, Mesh::AccessorList*& v, int& pos)
- {
- if ((pos = Compare(attr, "POSITION"))) {
- v = &(p.attributes.position);
- }
- else if ((pos = Compare(attr, "NORMAL"))) {
- v = &(p.attributes.normal);
- }
- else if ((pos = Compare(attr, "TEXCOORD"))) {
- v = &(p.attributes.texcoord);
- }
- else if ((pos = Compare(attr, "COLOR"))) {
- v = &(p.attributes.color);
- }
- else if ((pos = Compare(attr, "JOINT"))) {
- v = &(p.attributes.joint);
- }
- else if ((pos = Compare(attr, "JOINTMATRIX"))) {
- v = &(p.attributes.jointmatrix);
- }
- else if ((pos = Compare(attr, "WEIGHT"))) {
- v = &(p.attributes.weight);
- }
- else return false;
- return true;
- }
-}
-
-inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
-{
- /****************** Mesh primitives ******************/
- if (Value* primitives = FindArray(pJSON_Object, "primitives")) {
- this->primitives.resize(primitives->Size());
- for (unsigned int i = 0; i < primitives->Size(); ++i) {
- Value& primitive = (*primitives)[i];
-
- Primitive& prim = this->primitives[i];
- prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);
-
- if (Value* attrs = FindObject(primitive, "attributes")) {
- for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
- if (!it->value.IsString()) continue;
- const char* attr = it->name.GetString();
- // Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
- // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
-
- int undPos = 0;
- Mesh::AccessorList* vec = 0;
- if (GetAttribVector(prim, attr, vec, undPos)) {
- size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
- if ((*vec).size() <= idx) (*vec).resize(idx + 1);
- (*vec)[idx] = pAsset_Root.accessors.Get(it->value.GetString());
- }
- }
- }
-
- if (Value* indices = FindString(primitive, "indices")) {
- prim.indices = pAsset_Root.accessors.Get(indices->GetString());
- }
-
- if (Value* material = FindString(primitive, "material")) {
- prim.material = pAsset_Root.materials.Get(material->GetString());
- }
- }
- }
-
- /****************** Mesh extensions ******************/
- Value* json_extensions = FindObject(pJSON_Object, "extensions");
-
- if(json_extensions == nullptr) goto mr_skip_extensions;
-
- for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); it_memb++)
- {
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- if(it_memb->name.GetString() == std::string("Open3DGC-compression"))
- {
- // Search for compressed data.
- // Compressed data contain description of part of "buffer" which is encoded. This part must be decoded and
- // new data will replace old encoded part by request. In fact \"compressedData\" is kind of "accessor" structure.
- Value* comp_data = FindObject(it_memb->value, "compressedData");
-
- if(comp_data == nullptr) throw DeadlyImportError("GLTF: \"Open3DGC-compression\" must has \"compressedData\".");
-
- DefaultLogger::get()->info("GLTF: Decompressing Open3DGC data.");
-
- /************** Read data from JSON-document **************/
- #define MESH_READ_COMPRESSEDDATA_MEMBER(pFieldName, pOut) \
- if(!ReadMember(*comp_data, pFieldName, pOut)) \
- { \
- throw DeadlyImportError(std::string("GLTF: \"compressedData\" must has \"") + pFieldName + "\"."); \
- }
-
- const char* mode_str;
- const char* type_str;
- ComponentType component_type;
- SCompression_Open3DGC* ext_o3dgc = new SCompression_Open3DGC;
-
- MESH_READ_COMPRESSEDDATA_MEMBER("buffer", ext_o3dgc->Buffer);
- MESH_READ_COMPRESSEDDATA_MEMBER("byteOffset", ext_o3dgc->Offset);
- MESH_READ_COMPRESSEDDATA_MEMBER("componentType", component_type);
- MESH_READ_COMPRESSEDDATA_MEMBER("type", type_str);
- MESH_READ_COMPRESSEDDATA_MEMBER("count", ext_o3dgc->Count);
- MESH_READ_COMPRESSEDDATA_MEMBER("mode", mode_str);
- MESH_READ_COMPRESSEDDATA_MEMBER("indicesCount", ext_o3dgc->IndicesCount);
- MESH_READ_COMPRESSEDDATA_MEMBER("verticesCount", ext_o3dgc->VerticesCount);
-
- #undef MESH_READ_COMPRESSEDDATA_MEMBER
-
- // Check some values
- if(strcmp(type_str, "SCALAR")) throw DeadlyImportError("GLTF: only \"SCALAR\" type is supported for compressed data.");
- if(component_type != ComponentType_UNSIGNED_BYTE) throw DeadlyImportError("GLTF: only \"UNSIGNED_BYTE\" component type is supported for compressed data.");
-
- // Set read/write data mode.
- if(strcmp(mode_str, "binary") == 0)
- ext_o3dgc->Binary = true;
- else if(strcmp(mode_str, "ascii") == 0)
- ext_o3dgc->Binary = false;
- else
- throw DeadlyImportError(std::string("GLTF: for compressed data supported modes is: \"ascii\", \"binary\". Not the: \"") + mode_str + "\".");
-
- /************************ Decoding ************************/
- Decode_O3DGC(*ext_o3dgc, pAsset_Root);
- Extension.push_back(ext_o3dgc);// store info in mesh extensions list.
- }// if(it_memb->name.GetString() == "Open3DGC-compression")
- else
-#endif
- {
- throw DeadlyImportError(std::string("GLTF: Unknown mesh extension: \"") + it_memb->name.GetString() + "\".");
- }
- }// for(Value::MemberIterator it_memb = json_extensions->MemberBegin(); it_memb != json_extensions->MemberEnd(); json_extensions++)
-
-mr_skip_extensions:
-
- return;// After label some operators must be present.
-}
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
-inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC& pCompression_Open3DGC, Asset& pAsset_Root)
-{
-typedef unsigned short IndicesType;///< \sa glTFExporter::ExportMeshes.
-
-o3dgc::SC3DMCDecoder<IndicesType> decoder;
-o3dgc::IndexedFaceSet<IndicesType> ifs;
-o3dgc::BinaryStream bstream;
-uint8_t* decoded_data;
-size_t decoded_data_size = 0;
-Ref<Buffer> buf = pAsset_Root.buffers.Get(pCompression_Open3DGC.Buffer);
-
- // Read data from buffer and place it in BinaryStream for decoder.
- // Just "Count" because always is used type equivalent to uint8_t.
- bstream.LoadFromBuffer(&buf->GetPointer()[pCompression_Open3DGC.Offset], static_cast<unsigned long>(pCompression_Open3DGC.Count));
-
- // After decoding header we can get size of primitives.
- if(decoder.DecodeHeader(ifs, bstream) != o3dgc::O3DGC_OK) throw DeadlyImportError("GLTF: can not decode Open3DGC header.");
-
- /****************** Get sizes of arrays and check sizes ******************/
- // Note. See "Limitations for meshes when using Open3DGC-compression".
-
- // Indices
- size_t size_coordindex = ifs.GetNCoordIndex() * 3;// See float attributes note.
-
- if(primitives[0].indices->count != size_coordindex)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (" + std::to_string(size_coordindex) +
- ") not equal to uncompressed (" + std::to_string(primitives[0].indices->count) + ").");
-
- size_coordindex *= sizeof(IndicesType);
- // Coordinates
- size_t size_coord = ifs.GetNCoord();// See float attributes note.
-
- if(primitives[0].attributes.position[0]->count != size_coord)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (" + std::to_string(size_coord) +
- ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.position[0]->count) + ").");
-
- size_coord *= 3 * sizeof(float);
- // Normals
- size_t size_normal = ifs.GetNNormal();// See float attributes note.
-
- if(primitives[0].attributes.normal[0]->count != size_normal)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (" + std::to_string(size_normal) +
- ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.normal[0]->count) + ").");
-
- size_normal *= 3 * sizeof(float);
- // Additional attributes.
- std::vector<size_t> size_floatattr;
- std::vector<size_t> size_intattr;
-
- size_floatattr.resize(ifs.GetNumFloatAttributes());
- size_intattr.resize(ifs.GetNumIntAttributes());
-
- decoded_data_size = size_coordindex + size_coord + size_normal;
- for(size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++)
- {
- // size = number_of_elements * components_per_element * size_of_component.
- // Note. But as you can see above, at first we are use this variable in meaning "count". After checking count of objects...
- size_t tval = ifs.GetNFloatAttribute(static_cast<unsigned long>(idx));
-
- switch(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx)))
- {
- case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD:
- // Check situation when encoded data contain texture coordinates but primitive not.
- if(idx_texcoord < primitives[0].attributes.texcoord.size())
- {
- if(primitives[0].attributes.texcoord[idx]->count != tval)
- throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (" + std::to_string(tval) +
- ") not equal to uncompressed (" + std::to_string(primitives[0].attributes.texcoord[idx]->count) + ").");
-
- idx_texcoord++;
- }
- else
- {
- ifs.SetNFloatAttribute(static_cast<unsigned long>(idx), 0ul);// Disable decoding this attribute.
- }
-
- break;
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
- }
-
- tval *= ifs.GetFloatAttributeDim(static_cast<unsigned long>(idx)) * sizeof(o3dgc::Real);// After checking count of objects we can get size of array.
- size_floatattr[idx] = tval;
- decoded_data_size += tval;
- }
-
- for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++)
- {
- // size = number_of_elements * components_per_element * size_of_component. See float attributes note.
- size_t tval = ifs.GetNIntAttribute(static_cast<unsigned long>(idx));
- switch( ifs.GetIntAttributeType(static_cast<unsigned long>(idx) ) )
- {
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
- break;
-
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
- }
-
- tval *= ifs.GetIntAttributeDim(static_cast<unsigned long>(idx)) * sizeof(long);// See float attributes note.
- size_intattr[idx] = tval;
- decoded_data_size += tval;
- }
-
- // Create array for decoded data.
- decoded_data = new uint8_t[decoded_data_size];
-
- /****************** Set right array regions for decoder ******************/
-
- auto get_buf_offset = [](Ref<Accessor>& pAccessor) -> size_t { return pAccessor->byteOffset + pAccessor->bufferView->byteOffset; };
-
- // Indices
- ifs.SetCoordIndex((IndicesType* const)(decoded_data + get_buf_offset(primitives[0].indices)));
- // Coordinates
- ifs.SetCoord((o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.position[0])));
- // Normals
- if(size_normal)
- {
- ifs.SetNormal((o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.normal[0])));
- }
-
- for(size_t idx = 0, idx_end = size_floatattr.size(), idx_texcoord = 0; idx < idx_end; idx++)
- {
- switch(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx)))
- {
- case o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD:
- if(idx_texcoord < primitives[0].attributes.texcoord.size())
- {
- // See above about absent attributes.
- ifs.SetFloatAttribute(static_cast<unsigned long>(idx), (o3dgc::Real* const)(decoded_data + get_buf_offset(primitives[0].attributes.texcoord[idx])));
- idx_texcoord++;
- }
-
- break;
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: " + to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
- }
- }
-
- for(size_t idx = 0, idx_end = size_intattr.size(); idx < idx_end; idx++) {
- switch(ifs.GetIntAttributeType(static_cast<unsigned int>(idx))) {
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID:
- case o3dgc::O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID:
- break;
-
- // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
- default:
- throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: " + to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
- }
- }
-
- //
- // Decode data
- //
- if ( decoder.DecodePayload( ifs, bstream ) != o3dgc::O3DGC_OK ) {
- throw DeadlyImportError( "GLTF: can not decode Open3DGC data." );
- }
-
- // Set encoded region for "buffer".
- buf->EncodedRegion_Mark(pCompression_Open3DGC.Offset, pCompression_Open3DGC.Count, decoded_data, decoded_data_size, id);
- // No. Do not delete "output_data". After calling "EncodedRegion_Mark" bufferView is owner of "output_data".
- // "delete [] output_data;"
-}
-#endif
-
-inline void Camera::Read(Value& obj, Asset& /*r*/)
-{
- type = MemberOrDefault(obj, "type", Camera::Perspective);
-
- const char* subobjId = (type == Camera::Orthographic) ? "ortographic" : "perspective";
-
- Value* it = FindObject(obj, subobjId);
- if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
-
- if (type == Camera::Perspective) {
- perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
- perspective.yfov = MemberOrDefault(*it, "yfov", 3.1415f/2.f);
- perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
- perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
- }
- else {
- ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f);
- ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f);
- ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f);
- ortographic.znear = MemberOrDefault(obj, "znear", 0.01f);
- }
-}
-
-inline void Light::Read(Value& obj, Asset& /*r*/)
-{
- SetDefaults();
-
- if (Value* type = FindString(obj, "type")) {
- const char* t = type->GetString();
- if (strcmp(t, "ambient") == 0) this->type = Type_ambient;
- else if (strcmp(t, "directional") == 0) this->type = Type_directional;
- else if (strcmp(t, "point") == 0) this->type = Type_point;
- else if (strcmp(t, "spot") == 0) this->type = Type_spot;
-
- if (this->type != Type_undefined) {
- if (Value* vals = FindString(obj, t)) {
- ReadMember(*vals, "color", color);
-
- ReadMember(*vals, "constantAttenuation", constantAttenuation);
- ReadMember(*vals, "linearAttenuation", linearAttenuation);
- ReadMember(*vals, "quadraticAttenuation", quadraticAttenuation);
- ReadMember(*vals, "distance", distance);
-
- ReadMember(*vals, "falloffAngle", falloffAngle);
- ReadMember(*vals, "falloffExponent", falloffExponent);
- }
- }
- }
-}
-
-inline void Light::SetDefaults()
-{
- #ifndef M_PI
- const float M_PI = 3.14159265358979323846f;
- #endif
-
- type = Type_undefined;
-
- SetVector(color, 0.f, 0.f, 0.f, 1.f);
-
- constantAttenuation = 0.f;
- linearAttenuation = 1.f;
- quadraticAttenuation = 1.f;
- distance = 0.f;
-
- falloffAngle = static_cast<float>(M_PI / 2.f);
- falloffExponent = 0.f;
-}
-
-inline void Node::Read(Value& obj, Asset& r)
-{
- if (Value* children = FindArray(obj, "children")) {
- this->children.reserve(children->Size());
- for (unsigned int i = 0; i < children->Size(); ++i) {
- Value& child = (*children)[i];
- if (child.IsString()) {
- // get/create the child node
- Ref<Node> chn = r.nodes.Get(child.GetString());
- if (chn) this->children.push_back(chn);
- }
- }
- }
-
-
- if (Value* matrix = FindArray(obj, "matrix")) {
- ReadValue(*matrix, this->matrix);
- }
- else {
- ReadMember(obj, "translation", translation);
- ReadMember(obj, "scale", scale);
- ReadMember(obj, "rotation", rotation);
- }
-
- if (Value* meshes = FindArray(obj, "meshes")) {
- unsigned numMeshes = (unsigned)meshes->Size();
-
- std::vector<unsigned int> meshList;
-
- this->meshes.reserve(numMeshes);
- for (unsigned i = 0; i < numMeshes; ++i) {
- if ((*meshes)[i].IsString()) {
- Ref<Mesh> mesh = r.meshes.Get((*meshes)[i].GetString());
- if (mesh) this->meshes.push_back(mesh);
- }
- }
- }
-
- if (Value* camera = FindString(obj, "camera")) {
- this->camera = r.cameras.Get(camera->GetString());
- if (this->camera)
- this->camera->id = this->id;
- }
-
- // TODO load "skeletons", "skin", "jointName"
-
- if (Value* extensions = FindObject(obj, "extensions")) {
- if (r.extensionsUsed.KHR_materials_common) {
-
- if (Value* ext = FindObject(*extensions, "KHR_materials_common")) {
- if (Value* light = FindString(*ext, "light")) {
- this->light = r.lights.Get(light->GetString());
- }
- }
-
- }
- }
-}
-
-inline void Scene::Read(Value& obj, Asset& r)
-{
- if (Value* array = FindArray(obj, "nodes")) {
- for (unsigned int i = 0; i < array->Size(); ++i) {
- if (!(*array)[i].IsString()) continue;
- Ref<Node> node = r.nodes.Get((*array)[i].GetString());
- if (node)
- this->nodes.push_back(node);
- }
- }
-}
-
-
-inline void AssetMetadata::Read(Document& doc)
-{
- // read the version, etc.
- if (Value* obj = FindObject(doc, "asset")) {
- ReadMember(*obj, "copyright", copyright);
- ReadMember(*obj, "generator", generator);
-
- premultipliedAlpha = MemberOrDefault(*obj, "premultipliedAlpha", false);
-
- if (Value* versionString = FindString(*obj, "version")) {
- version = versionString->GetString();
- } else if (Value* versionNumber = FindNumber (*obj, "version")) {
- char buf[4];
-
- ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());
-
- version = buf;
- }
-
- if (Value* profile = FindObject(*obj, "profile")) {
- ReadMember(*profile, "api", this->profile.api);
- ReadMember(*profile, "version", this->profile.version);
- }
- }
-
- if (version.empty() || version[0] != '1') {
- throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
- }
-}
-
-
-
-//
-// Asset methods implementation
-//
-
-inline void Asset::ReadBinaryHeader(IOStream& stream)
-{
- GLB_Header header;
- if (stream.Read(&header, sizeof(header), 1) != 1) {
- throw DeadlyImportError("GLTF: Unable to read the file header");
- }
-
- if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
- throw DeadlyImportError("GLTF: Invalid binary glTF file");
- }
-
- AI_SWAP4(header.version);
- asset.version = to_string(header.version);
- if (header.version != 1) {
- throw DeadlyImportError("GLTF: Unsupported binary glTF version");
- }
-
- AI_SWAP4(header.sceneFormat);
- if (header.sceneFormat != SceneFormat_JSON) {
- throw DeadlyImportError("GLTF: Unsupported binary glTF scene format");
- }
-
- AI_SWAP4(header.length);
- AI_SWAP4(header.sceneLength);
-
- mSceneLength = static_cast<size_t>(header.sceneLength);
-
- mBodyOffset = sizeof(header)+mSceneLength;
- mBodyOffset = (mBodyOffset + 3) & ~3; // Round up to next multiple of 4
-
- mBodyLength = header.length - mBodyOffset;
-}
-
-inline void Asset::Load(const std::string& pFile, bool isBinary)
-{
- mCurrentAssetDir.clear();
- int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
- if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);
-
- shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
- if (!stream) {
- throw DeadlyImportError("GLTF: Could not open file for reading");
- }
-
- // is binary? then read the header
- if (isBinary) {
- SetAsBinary(); // also creates the body buffer
- ReadBinaryHeader(*stream);
- }
- else {
- mSceneLength = stream->FileSize();
- mBodyLength = 0;
- }
-
-
- // read the scene data
-
- std::vector<char> sceneData(mSceneLength + 1);
- sceneData[mSceneLength] = '\0';
-
- if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
- throw DeadlyImportError("GLTF: Could not read the file contents");
- }
-
-
- // parse the JSON document
-
- Document doc;
- doc.ParseInsitu(&sceneData[0]);
-
- if (doc.HasParseError()) {
- char buffer[32];
- ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
- throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": "
- + GetParseError_En(doc.GetParseError()));
- }
-
- if (!doc.IsObject()) {
- throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
- }
-
- // Fill the buffer instance for the current file embedded contents
- if (mBodyLength > 0) {
- if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
- throw DeadlyImportError("GLTF: Unable to read gltf file");
- }
- }
-
-
- // Load the metadata
- asset.Read(doc);
- ReadExtensionsUsed(doc);
-
- // Prepare the dictionaries
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->AttachToDocument(doc);
- }
-
-
-
- // Read the "scene" property, which specifies which scene to load
- // and recursively load everything referenced by it
- if (Value* scene = FindString(doc, "scene")) {
- this->scene = scenes.Get(scene->GetString());
- }
-
- // Clean up
- for (size_t i = 0; i < mDicts.size(); ++i) {
- mDicts[i]->DetachFromDocument();
- }
-}
-
-inline void Asset::SetAsBinary()
-{
- if (!extensionsUsed.KHR_binary_glTF) {
- extensionsUsed.KHR_binary_glTF = true;
- mBodyBuffer = buffers.Create("binary_glTF");
- mBodyBuffer->MarkAsSpecial();
- }
-}
-
-
-inline void Asset::ReadExtensionsUsed(Document& doc)
-{
- Value* extsUsed = FindArray(doc, "extensionsUsed");
- if (!extsUsed) return;
-
- std::gltf_unordered_map<std::string, bool> exts;
-
- for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
- if ((*extsUsed)[i].IsString()) {
- exts[(*extsUsed)[i].GetString()] = true;
- }
- }
-
- #define CHECK_EXT(EXT) \
- if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;
-
- CHECK_EXT(KHR_binary_glTF);
- CHECK_EXT(KHR_materials_common);
-
- #undef CHECK_EXT
-}
-
-inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool /*absolute*/)
-{
- #ifdef ASSIMP_API
- return mIOSystem->Open(path, mode);
- #else
- if (path.size() < 2) return 0;
- if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
- path = mCurrentAssetDir + path;
- }
- FILE* f = fopen(path.c_str(), mode);
- return f ? new IOStream(f) : 0;
- #endif
-}
-
-inline std::string Asset::FindUniqueID(const std::string& str, const char* suffix)
-{
- std::string id = str;
-
- if (!id.empty()) {
- if (mUsedIds.find(id) == mUsedIds.end())
- return id;
-
- id += "_";
- }
-
- id += suffix;
-
- Asset::IdMap::iterator it = mUsedIds.find(id);
- if (it == mUsedIds.end())
- return id;
-
- char buffer[256];
- int offset = ai_snprintf(buffer, sizeof(buffer), "%s_", id.c_str());
- for (int i = 0; it != mUsedIds.end(); ++i) {
- ai_snprintf(buffer + offset, sizeof(buffer) - offset, "%d", i);
- id = buffer;
- it = mUsedIds.find(id);
- }
-
- return id;
-}
-
-namespace Util {
-
- inline
- bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
- if ( NULL == const_uri ) {
- return false;
- }
-
- if (const_uri[0] != 0x10) { // we already parsed this uri?
- if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
- return false;
- }
-
- // set defaults
- out.mediaType = "text/plain";
- out.charset = "US-ASCII";
- out.base64 = false;
-
- char* uri = const_cast<char*>(const_uri);
- if (uri[0] != 0x10) {
- uri[0] = 0x10;
- uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
- size_t i = 5, j;
- if (uri[i] != ';' && uri[i] != ',') { // has media type?
- uri[1] = char(i);
- for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
- // nothing to do!
- }
- }
- while (uri[i] == ';' && i < uriLen) {
- uri[i++] = '\0';
- for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
- // nothing to do!
- }
-
- if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
- uri[2] = char(j + 8);
- } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
- uri[3] = char(j);
- }
- }
- if (i < uriLen) {
- uri[i++] = '\0';
- uri[4] = char(i);
- } else {
- uri[1] = uri[2] = uri[3] = 0;
- uri[4] = 5;
- }
- }
-
- if ( uri[ 1 ] != 0 ) {
- out.mediaType = uri + uri[ 1 ];
- }
- if ( uri[ 2 ] != 0 ) {
- out.charset = uri + uri[ 2 ];
- }
- if ( uri[ 3 ] != 0 ) {
- out.base64 = true;
- }
- out.data = uri + uri[4];
- out.dataLength = (uri + uriLen) - out.data;
-
- return true;
- }
-
- template<bool B>
- struct DATA
- {
- static const uint8_t tableDecodeBase64[128];
- };
-
- template<bool B>
- const uint8_t DATA<B>::tableDecodeBase64[128] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 64, 0, 0,
- 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
- 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
- };
-
- inline char EncodeCharBase64(uint8_t b)
- {
- return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
- }
-
- inline uint8_t DecodeCharBase64(char c)
- {
- return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
- /*if (c >= 'A' && c <= 'Z') return c - 'A';
- if (c >= 'a' && c <= 'z') return c - 'a' + 26;
- if (c >= '0' && c <= '9') return c - '0' + 52;
- if (c == '+') return 62;
- if (c == '/') return 63;
- return 64; // '-' */
- }
-
- inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
- {
- ai_assert(inLength % 4 == 0);
-
- if (inLength < 4) {
- out = 0;
- return 0;
- }
-
- int nEquals = int(in[inLength - 1] == '=') +
- int(in[inLength - 2] == '=');
-
- size_t outLength = (inLength * 3) / 4 - nEquals;
- out = new uint8_t[outLength];
- memset(out, 0, outLength);
-
- size_t i, j = 0;
-
- for (i = 0; i + 4 < inLength; i += 4) {
- uint8_t b0 = DecodeCharBase64(in[i]);
- uint8_t b1 = DecodeCharBase64(in[i + 1]);
- uint8_t b2 = DecodeCharBase64(in[i + 2]);
- uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- out[j++] = (uint8_t)((b2 << 6) | b3);
- }
-
- {
- uint8_t b0 = DecodeCharBase64(in[i]);
- uint8_t b1 = DecodeCharBase64(in[i + 1]);
- uint8_t b2 = DecodeCharBase64(in[i + 2]);
- uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
- out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
- if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
- if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
- }
-
- return outLength;
- }
-
-
-
- inline void EncodeBase64(
- const uint8_t* in, size_t inLength,
- std::string& out)
- {
- size_t outLength = ((inLength + 2) / 3) * 4;
-
- size_t j = out.size();
- out.resize(j + outLength);
-
- for (size_t i = 0; i < inLength; i += 3) {
- uint8_t b = (in[i] & 0xFC) >> 2;
- out[j++] = EncodeCharBase64(b);
-
- b = (in[i] & 0x03) << 4;
- if (i + 1 < inLength) {
- b |= (in[i + 1] & 0xF0) >> 4;
- out[j++] = EncodeCharBase64(b);
-
- b = (in[i + 1] & 0x0F) << 2;
- if (i + 2 < inLength) {
- b |= (in[i + 2] & 0xC0) >> 6;
- out[j++] = EncodeCharBase64(b);
-
- b = in[i + 2] & 0x3F;
- out[j++] = EncodeCharBase64(b);
- }
- else {
- out[j++] = EncodeCharBase64(b);
- out[j++] = '=';
- }
- }
- else {
- out[j++] = EncodeCharBase64(b);
- out[j++] = '=';
- out[j++] = '=';
- }
- }
- }
-
-}
-
-} // ns glTF
diff --git a/src/3rdparty/assimp/code/glTFAssetWriter.h b/src/3rdparty/assimp/code/glTFAssetWriter.h
deleted file mode 100644
index 186d32a15..000000000
--- a/src/3rdparty/assimp/code/glTFAssetWriter.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 glTFWriter.h
- * Declares a class to write gltf/glb files
- *
- * glTF Extensions Support:
- * KHR_binary_glTF: full
- * KHR_materials_common: full
- */
-#ifndef GLTFASSETWRITER_H_INC
-#define GLTFASSETWRITER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include "glTFAsset.h"
-
-namespace glTF
-{
-
-using rapidjson::MemoryPoolAllocator;
-
-class AssetWriter
-{
- template<class T>
- friend void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);
-
-private:
-
- void WriteBinaryData(IOStream* outfile, size_t sceneLength);
-
- void WriteMetadata();
- void WriteExtensionsUsed();
-
- template<class T>
- void WriteObjects(LazyDict<T>& d);
-
-public:
- Document mDoc;
- Asset& mAsset;
-
- MemoryPoolAllocator<>& mAl;
-
- AssetWriter(Asset& asset);
-
- void WriteFile(const char* path);
- void WriteGLBFile(const char* path);
-};
-
-}
-
-// Include the implementation of the methods
-#include "glTFAssetWriter.inl"
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // GLTFASSETWRITER_H_INC
diff --git a/src/3rdparty/assimp/code/glTFAssetWriter.inl b/src/3rdparty/assimp/code/glTFAssetWriter.inl
deleted file mode 100644
index 485abc4f6..000000000
--- a/src/3rdparty/assimp/code/glTFAssetWriter.inl
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
-
-----------------------------------------------------------------------
-*/
-
-#include <rapidjson/stringbuffer.h>
-#include <rapidjson/writer.h>
-#include <rapidjson/prettywriter.h>
-
-namespace glTF {
-
- using rapidjson::StringBuffer;
- using rapidjson::PrettyWriter;
- using rapidjson::Writer;
- using rapidjson::StringRef;
- using rapidjson::StringRef;
-
- namespace {
-
- template<size_t N>
- inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
- val.SetArray();
- val.Reserve(N, al);
- for (decltype(N) i = 0; i < N; ++i) {
- val.PushBack(r[i], al);
- }
- return val;
- }
-
- inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
- val.SetArray();
- val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
- for (unsigned int i = 0; i < r.size(); ++i) {
- val.PushBack(r[i], al);
- }
- return val;
- }
-
- template<class T>
- inline void AddRefsVector(Value& obj, const char* fieldId, std::vector< Ref<T> >& v, MemoryPoolAllocator<>& al) {
- if (v.empty()) return;
- Value lst;
- lst.SetArray();
- lst.Reserve(unsigned(v.size()), al);
- for (size_t i = 0; i < v.size(); ++i) {
- lst.PushBack(StringRef(v[i]->id), al);
- }
- obj.AddMember(StringRef(fieldId), lst, al);
- }
-
-
- }
-
- inline void Write(Value& obj, Accessor& a, AssetWriter& w)
- {
- obj.AddMember("bufferView", Value(a.bufferView->id, w.mAl).Move(), w.mAl);
- obj.AddMember("byteOffset", a.byteOffset, w.mAl);
- obj.AddMember("byteStride", a.byteStride, w.mAl);
- obj.AddMember("componentType", int(a.componentType), w.mAl);
- obj.AddMember("count", a.count, w.mAl);
- obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
-
- Value vTmpMax, vTmpMin;
- obj.AddMember("max", MakeValue(vTmpMax, a.max, w.mAl), w.mAl);
- obj.AddMember("min", MakeValue(vTmpMin, a.min, w.mAl), w.mAl);
- }
-
- inline void Write(Value& obj, Animation& a, AssetWriter& w)
- {
- /****************** Channels *******************/
- Value channels;
- channels.SetArray();
- channels.Reserve(unsigned(a.Channels.size()), w.mAl);
-
- for (size_t i = 0; i < unsigned(a.Channels.size()); ++i) {
- Animation::AnimChannel& c = a.Channels[i];
- Value valChannel;
- valChannel.SetObject();
- {
- valChannel.AddMember("sampler", c.sampler, w.mAl);
-
- Value valTarget;
- valTarget.SetObject();
- {
- valTarget.AddMember("id", StringRef(c.target.id->id), w.mAl);
- valTarget.AddMember("path", c.target.path, w.mAl);
- }
- valChannel.AddMember("target", valTarget, w.mAl);
- }
- channels.PushBack(valChannel, w.mAl);
- }
- obj.AddMember("channels", channels, w.mAl);
-
- /****************** Parameters *******************/
- Value valParameters;
- valParameters.SetObject();
- {
- if (a.Parameters.TIME) {
- valParameters.AddMember("TIME", StringRef(a.Parameters.TIME->id), w.mAl);
- }
- if (a.Parameters.rotation) {
- valParameters.AddMember("rotation", StringRef(a.Parameters.rotation->id), w.mAl);
- }
- if (a.Parameters.scale) {
- valParameters.AddMember("scale", StringRef(a.Parameters.scale->id), w.mAl);
- }
- if (a.Parameters.translation) {
- valParameters.AddMember("translation", StringRef(a.Parameters.translation->id), w.mAl);
- }
- }
- obj.AddMember("parameters", valParameters, w.mAl);
-
- /****************** Samplers *******************/
- Value valSamplers;
- valSamplers.SetObject();
-
- for (size_t i = 0; i < unsigned(a.Samplers.size()); ++i) {
- Animation::AnimSampler& s = a.Samplers[i];
- Value valSampler;
- valSampler.SetObject();
- {
- valSampler.AddMember("input", s.input, w.mAl);
- valSampler.AddMember("interpolation", s.interpolation, w.mAl);
- valSampler.AddMember("output", s.output, w.mAl);
- }
- valSamplers.AddMember(StringRef(s.id), valSampler, w.mAl);
- }
- obj.AddMember("samplers", valSamplers, w.mAl);
- }
-
- inline void Write(Value& obj, Buffer& b, AssetWriter& w)
- {
- const char* type;
- switch (b.type) {
- case Buffer::Type_text:
- type = "text"; break;
- default:
- type = "arraybuffer";
- }
-
- obj.AddMember("byteLength", static_cast<uint64_t>(b.byteLength), w.mAl);
- obj.AddMember("type", StringRef(type), w.mAl);
- obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl);
- }
-
- inline void Write(Value& obj, BufferView& bv, AssetWriter& w)
- {
- obj.AddMember("buffer", Value(bv.buffer->id, w.mAl).Move(), w.mAl);
- obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
- obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
- obj.AddMember("target", int(bv.target), w.mAl);
- }
-
- inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Image& img, AssetWriter& w)
- {
- std::string uri;
- if (w.mAsset.extensionsUsed.KHR_binary_glTF && img.bufferView) {
- Value exts, ext;
- exts.SetObject();
- ext.SetObject();
-
- ext.AddMember("bufferView", StringRef(img.bufferView->id), w.mAl);
-
- if (!img.mimeType.empty())
- ext.AddMember("mimeType", StringRef(img.mimeType), w.mAl);
-
- exts.AddMember("KHR_binary_glTF", ext, w.mAl);
- obj.AddMember("extensions", exts, w.mAl);
- return;
- }
- else if (img.HasData()) {
- uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
- uri += ";base64,";
- Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
- }
- else {
- uri = img.uri;
- }
-
- obj.AddMember("uri", Value(uri, w.mAl).Move(), w.mAl);
- }
-
- namespace {
- inline void WriteColorOrTex(Value& obj, TexProperty& prop, const char* propName, MemoryPoolAllocator<>& al)
- {
- if (prop.texture)
- obj.AddMember(StringRef(propName), Value(prop.texture->id, al).Move(), al);
- else {
- Value col;
- obj.AddMember(StringRef(propName), MakeValue(col, prop.color, al), al);
- }
- }
- }
-
- inline void Write(Value& obj, Material& m, AssetWriter& w)
- {
- Value v;
- v.SetObject();
- {
- WriteColorOrTex(v, m.ambient, "ambient", w.mAl);
- WriteColorOrTex(v, m.diffuse, "diffuse", w.mAl);
- WriteColorOrTex(v, m.specular, "specular", w.mAl);
- WriteColorOrTex(v, m.emission, "emission", w.mAl);
-
- if (m.transparent)
- v.AddMember("transparency", m.transparency, w.mAl);
-
- v.AddMember("shininess", m.shininess, w.mAl);
- }
- obj.AddMember("values", v, w.mAl);
- }
-
- namespace {
- inline void WriteAttrs(AssetWriter& w, Value& attrs, Mesh::AccessorList& lst,
- const char* semantic, bool forceNumber = false)
- {
- if (lst.empty()) return;
- if (lst.size() == 1 && !forceNumber) {
- attrs.AddMember(StringRef(semantic), Value(lst[0]->id, w.mAl).Move(), w.mAl);
- }
- else {
- for (size_t i = 0; i < lst.size(); ++i) {
- char buffer[32];
- ai_snprintf(buffer, 32, "%s_%d", semantic, int(i));
- attrs.AddMember(Value(buffer, w.mAl).Move(), Value(lst[i]->id, w.mAl).Move(), w.mAl);
- }
- }
- }
- }
-
- inline void Write(Value& obj, Mesh& m, AssetWriter& w)
- {
- /********************* Name **********************/
- obj.AddMember("name", m.name, w.mAl);
-
- /**************** Mesh extensions ****************/
- if(m.Extension.size() > 0)
- {
- Value json_extensions;
-
- json_extensions.SetObject();
- for(Mesh::SExtension* ptr_ext : m.Extension)
- {
- switch(ptr_ext->Type)
- {
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- case Mesh::SExtension::EType::Compression_Open3DGC:
- {
- Value json_comp_data;
- Mesh::SCompression_Open3DGC* ptr_ext_comp = (Mesh::SCompression_Open3DGC*)ptr_ext;
-
- // filling object "compressedData"
- json_comp_data.SetObject();
- json_comp_data.AddMember("buffer", ptr_ext_comp->Buffer, w.mAl);
- json_comp_data.AddMember("byteOffset", ptr_ext_comp->Offset, w.mAl);
- json_comp_data.AddMember("componentType", 5121, w.mAl);
- json_comp_data.AddMember("type", "SCALAR", w.mAl);
- json_comp_data.AddMember("count", ptr_ext_comp->Count, w.mAl);
- if(ptr_ext_comp->Binary)
- json_comp_data.AddMember("mode", "binary", w.mAl);
- else
- json_comp_data.AddMember("mode", "ascii", w.mAl);
-
- json_comp_data.AddMember("indicesCount", ptr_ext_comp->IndicesCount, w.mAl);
- json_comp_data.AddMember("verticesCount", ptr_ext_comp->VerticesCount, w.mAl);
- // filling object "Open3DGC-compression"
- Value json_o3dgc;
-
- json_o3dgc.SetObject();
- json_o3dgc.AddMember("compressedData", json_comp_data, w.mAl);
- // add member to object "extensions"
- json_extensions.AddMember("Open3DGC-compression", json_o3dgc, w.mAl);
- }
-
- break;
-#endif
- default:
- throw DeadlyImportError("GLTF: Can not write mesh: unknown mesh extension, only Open3DGC is supported.");
- }// switch(ptr_ext->Type)
- }// for(Mesh::SExtension* ptr_ext : m.Extension)
-
- // Add extensions to mesh
- obj.AddMember("extensions", json_extensions, w.mAl);
- }// if(m.Extension.size() > 0)
-
- /****************** Primitives *******************/
- Value primitives;
- primitives.SetArray();
- primitives.Reserve(unsigned(m.primitives.size()), w.mAl);
-
- for (size_t i = 0; i < m.primitives.size(); ++i) {
- Mesh::Primitive& p = m.primitives[i];
- Value prim;
- prim.SetObject();
- {
- prim.AddMember("mode", Value(int(p.mode)).Move(), w.mAl);
-
- if (p.material)
- prim.AddMember("material", p.material->id, w.mAl);
-
- if (p.indices)
- prim.AddMember("indices", Value(p.indices->id, w.mAl).Move(), w.mAl);
-
- Value attrs;
- attrs.SetObject();
- {
- WriteAttrs(w, attrs, p.attributes.position, "POSITION");
- WriteAttrs(w, attrs, p.attributes.normal, "NORMAL");
- WriteAttrs(w, attrs, p.attributes.texcoord, "TEXCOORD", true);
- WriteAttrs(w, attrs, p.attributes.color, "COLOR");
- WriteAttrs(w, attrs, p.attributes.joint, "JOINT");
- WriteAttrs(w, attrs, p.attributes.jointmatrix, "JOINTMATRIX");
- WriteAttrs(w, attrs, p.attributes.weight, "WEIGHT");
- }
- prim.AddMember("attributes", attrs, w.mAl);
- }
- primitives.PushBack(prim, w.mAl);
- }
-
- obj.AddMember("primitives", primitives, w.mAl);
- }
-
- inline void Write(Value& obj, Node& n, AssetWriter& w)
- {
-
- if (n.matrix.isPresent) {
- Value val;
- obj.AddMember("matrix", MakeValue(val, n.matrix.value, w.mAl).Move(), w.mAl);
- }
-
- if (n.translation.isPresent) {
- Value val;
- obj.AddMember("translation", MakeValue(val, n.translation.value, w.mAl).Move(), w.mAl);
- }
-
- if (n.scale.isPresent) {
- Value val;
- obj.AddMember("scale", MakeValue(val, n.scale.value, w.mAl).Move(), w.mAl);
- }
- if (n.rotation.isPresent) {
- Value val;
- obj.AddMember("rotation", MakeValue(val, n.rotation.value, w.mAl).Move(), w.mAl);
- }
-
- AddRefsVector(obj, "children", n.children, w.mAl);
-
- AddRefsVector(obj, "meshes", n.meshes, w.mAl);
-
- AddRefsVector(obj, "skeletons", n.skeletons, w.mAl);
-
- if (n.skin) {
- obj.AddMember("skin", Value(n.skin->id, w.mAl).Move(), w.mAl);
- }
-
- if (!n.jointName.empty()) {
- obj.AddMember("jointName", n.jointName, w.mAl);
- }
- }
-
- inline void Write(Value& /*obj*/, Program& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Sampler& b, AssetWriter& w)
- {
- if (b.wrapS) {
- obj.AddMember("wrapS", b.wrapS, w.mAl);
- }
- if (b.wrapT) {
- obj.AddMember("wrapT", b.wrapT, w.mAl);
- }
- if (b.magFilter) {
- obj.AddMember("magFilter", b.magFilter, w.mAl);
- }
- if (b.minFilter) {
- obj.AddMember("minFilter", b.minFilter, w.mAl);
- }
- }
-
- inline void Write(Value& scene, Scene& s, AssetWriter& w)
- {
- AddRefsVector(scene, "nodes", s.nodes, w.mAl);
- }
-
- inline void Write(Value& /*obj*/, Shader& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Skin& b, AssetWriter& w)
- {
- /****************** jointNames *******************/
- Value vJointNames;
- vJointNames.SetArray();
- vJointNames.Reserve(unsigned(b.jointNames.size()), w.mAl);
-
- for (size_t i = 0; i < unsigned(b.jointNames.size()); ++i) {
- vJointNames.PushBack(StringRef(b.jointNames[i]->jointName), w.mAl);
- }
- obj.AddMember("jointNames", vJointNames, w.mAl);
-
- if (b.bindShapeMatrix.isPresent) {
- Value val;
- obj.AddMember("bindShapeMatrix", MakeValue(val, b.bindShapeMatrix.value, w.mAl).Move(), w.mAl);
- }
-
- if (b.inverseBindMatrices) {
- obj.AddMember("inverseBindMatrices", Value(b.inverseBindMatrices->id, w.mAl).Move(), w.mAl);
- }
-
- }
-
- inline void Write(Value& /*obj*/, Technique& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
- inline void Write(Value& obj, Texture& tex, AssetWriter& w)
- {
- if (tex.source) {
- obj.AddMember("source", Value(tex.source->id, w.mAl).Move(), w.mAl);
- }
- if (tex.sampler) {
- obj.AddMember("sampler", Value(tex.sampler->id, w.mAl).Move(), w.mAl);
- }
- }
-
- inline void Write(Value& /*obj*/, Light& /*b*/, AssetWriter& /*w*/)
- {
-
- }
-
-
- inline AssetWriter::AssetWriter(Asset& a)
- : mDoc()
- , mAsset(a)
- , mAl(mDoc.GetAllocator())
- {
- mDoc.SetObject();
-
- WriteMetadata();
- WriteExtensionsUsed();
-
- // Dump the contents of the dictionaries
- for (size_t i = 0; i < a.mDicts.size(); ++i) {
- a.mDicts[i]->WriteObjects(*this);
- }
-
- // Add the target scene field
- if (mAsset.scene) {
- mDoc.AddMember("scene", StringRef(mAsset.scene->id), mAl);
- }
- }
-
- inline void AssetWriter::WriteFile(const char* path)
- {
- std::unique_ptr<IOStream> jsonOutFile(mAsset.OpenFile(path, "wt", true));
-
- if (jsonOutFile == 0) {
- throw DeadlyExportError("Could not open output file: " + std::string(path));
- }
-
- StringBuffer docBuffer;
-
- PrettyWriter<StringBuffer> writer(docBuffer);
- mDoc.Accept(writer);
-
- if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
- throw DeadlyExportError("Failed to write scene data!");
- }
-
- // Write buffer data to separate .bin files
- for (unsigned int i = 0; i < mAsset.buffers.Size(); ++i) {
- Ref<Buffer> b = mAsset.buffers.Get(i);
-
- std::string binPath = b->GetURI();
-
- std::unique_ptr<IOStream> binOutFile(mAsset.OpenFile(binPath, "wb", true));
-
- if (binOutFile == 0) {
- throw DeadlyExportError("Could not open output file: " + binPath);
- }
-
- if (b->byteLength > 0) {
- if (binOutFile->Write(b->GetPointer(), b->byteLength, 1) != 1) {
- throw DeadlyExportError("Failed to write binary file: " + binPath);
- }
- }
- }
- }
-
- inline void AssetWriter::WriteGLBFile(const char* path)
- {
- std::unique_ptr<IOStream> outfile(mAsset.OpenFile(path, "wb", true));
-
- if (outfile == 0) {
- throw DeadlyExportError("Could not open output file: " + std::string(path));
- }
-
- // we will write the header later, skip its size
- outfile->Seek(sizeof(GLB_Header), aiOrigin_SET);
-
- StringBuffer docBuffer;
- Writer<StringBuffer> writer(docBuffer);
- mDoc.Accept(writer);
-
- if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
- throw DeadlyExportError("Failed to write scene data!");
- }
-
- WriteBinaryData(outfile.get(), docBuffer.GetSize());
- }
-
- inline void AssetWriter::WriteBinaryData(IOStream* outfile, size_t sceneLength)
- {
- //
- // write the body data
- //
-
- size_t bodyLength = 0;
- if (Ref<Buffer> b = mAsset.GetBodyBuffer()) {
- bodyLength = b->byteLength;
-
- if (bodyLength > 0) {
- size_t bodyOffset = sizeof(GLB_Header) + sceneLength;
- bodyOffset = (bodyOffset + 3) & ~3; // Round up to next multiple of 4
-
- outfile->Seek(bodyOffset, aiOrigin_SET);
-
- if (outfile->Write(b->GetPointer(), b->byteLength, 1) != 1) {
- throw DeadlyExportError("Failed to write body data!");
- }
- }
- }
-
- //
- // write the header
- //
-
- GLB_Header header;
- memcpy(header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic));
-
- header.version = 1;
- AI_SWAP4(header.version);
-
- header.length = uint32_t(sizeof(header) + sceneLength + bodyLength);
- AI_SWAP4(header.length);
-
- header.sceneLength = uint32_t(sceneLength);
- AI_SWAP4(header.sceneLength);
-
- header.sceneFormat = SceneFormat_JSON;
- AI_SWAP4(header.sceneFormat);
-
- outfile->Seek(0, aiOrigin_SET);
-
- if (outfile->Write(&header, 1, sizeof(header)) != sizeof(header)) {
- throw DeadlyExportError("Failed to write the header!");
- }
- }
-
-
- inline void AssetWriter::WriteMetadata()
- {
- Value asset;
- asset.SetObject();
- asset.AddMember("version", Value(mAsset.asset.version, mAl).Move(), mAl);
- asset.AddMember("generator", Value(mAsset.asset.generator, mAl).Move(), mAl);
- mDoc.AddMember("asset", asset, mAl);
- }
-
- inline void AssetWriter::WriteExtensionsUsed()
- {
- Value exts;
- exts.SetArray();
- {
- if (false)
- exts.PushBack(StringRef("KHR_binary_glTF"), mAl);
-
- if (false)
- exts.PushBack(StringRef("KHR_materials_common"), mAl);
- }
-
- if (!exts.Empty())
- mDoc.AddMember("extensionsUsed", exts, mAl);
- }
-
- template<class T>
- void AssetWriter::WriteObjects(LazyDict<T>& d)
- {
- if (d.mObjs.empty()) return;
-
- Value* container = &mDoc;
-
- if (d.mExtId) {
- Value* exts = FindObject(mDoc, "extensions");
- if (!exts) {
- mDoc.AddMember("extensions", Value().SetObject().Move(), mDoc.GetAllocator());
- exts = FindObject(mDoc, "extensions");
- }
-
- if (!(container = FindObject(*exts, d.mExtId))) {
- exts->AddMember(StringRef(d.mExtId), Value().SetObject().Move(), mDoc.GetAllocator());
- container = FindObject(*exts, d.mExtId);
- }
- }
-
- Value* dict;
- if (!(dict = FindObject(*container, d.mDictId))) {
- container->AddMember(StringRef(d.mDictId), Value().SetObject().Move(), mDoc.GetAllocator());
- dict = FindObject(*container, d.mDictId);
- }
-
- for (size_t i = 0; i < d.mObjs.size(); ++i) {
- if (d.mObjs[i]->IsSpecial()) continue;
-
- Value obj;
- obj.SetObject();
-
- if (!d.mObjs[i]->name.empty()) {
- obj.AddMember("name", StringRef(d.mObjs[i]->name.c_str()), mAl);
- }
-
- Write(obj, *d.mObjs[i], *this);
-
- dict->AddMember(StringRef(d.mObjs[i]->id), obj, mAl);
- }
- }
-
- template<class T>
- void WriteLazyDict(LazyDict<T>& d, AssetWriter& w)
- {
- w.WriteObjects(d);
- }
-
-}
-
-
diff --git a/src/3rdparty/assimp/code/glTFExporter.cpp b/src/3rdparty/assimp/code/glTFExporter.cpp
deleted file mode 100644
index d88081884..000000000
--- a/src/3rdparty/assimp/code/glTFExporter.cpp
+++ /dev/null
@@ -1,1007 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_EXPORT
-#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
-
-#include "glTFExporter.h"
-
-#include "Exceptional.h"
-#include "StringComparison.h"
-#include "ByteSwapper.h"
-
-#include "SplitLargeMeshes.h"
-
-#include <assimp/SceneCombiner.h>
-#include <assimp/version.h>
-#include <assimp/IOSystem.hpp>
-#include <assimp/Exporter.hpp>
-#include <assimp/material.h>
-#include <assimp/scene.h>
-
-// Header files, standard library.
-#include <memory>
-#include <inttypes.h>
-
-#include "glTFAssetWriter.h"
-
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- // Header files, Open3DGC.
-# include <Open3DGC/o3dgcSC3DMCEncoder.h>
-#endif
-
-using namespace rapidjson;
-
-using namespace Assimp;
-using namespace glTF;
-
-namespace Assimp {
-
- // ------------------------------------------------------------------------------------------------
- // Worker function for exporting a scene to GLTF. Prototyped and registered in Exporter.cpp
- void ExportSceneGLTF(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
- {
- // invoke the exporter
- glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, false);
- }
-
- // ------------------------------------------------------------------------------------------------
- // Worker function for exporting a scene to GLB. Prototyped and registered in Exporter.cpp
- void ExportSceneGLB(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
- {
- // invoke the exporter
- glTFExporter exporter(pFile, pIOSystem, pScene, pProperties, true);
- }
-
-} // end of namespace Assimp
-
-glTFExporter::glTFExporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
- const ExportProperties* pProperties, bool isBinary)
- : mFilename(filename)
- , mIOSystem(pIOSystem)
- , mProperties(pProperties)
-{
- aiScene* sceneCopy_tmp;
- SceneCombiner::CopyScene(&sceneCopy_tmp, pScene);
- std::unique_ptr<aiScene> sceneCopy(sceneCopy_tmp);
-
- SplitLargeMeshesProcess_Triangle tri_splitter;
- tri_splitter.SetLimit(0xffff);
- tri_splitter.Execute(sceneCopy.get());
-
- SplitLargeMeshesProcess_Vertex vert_splitter;
- vert_splitter.SetLimit(0xffff);
- vert_splitter.Execute(sceneCopy.get());
-
- mScene = sceneCopy.get();
-
- mAsset.reset( new glTF::Asset( pIOSystem ) );
-
- if (isBinary) {
- mAsset->SetAsBinary();
- }
-
- ExportMetadata();
-
- //for (unsigned int i = 0; i < pScene->mNumCameras; ++i) {}
-
- //for (unsigned int i = 0; i < pScene->mNumLights; ++i) {}
-
- ExportMaterials();
-
- if (mScene->mRootNode) {
- ExportNodeHierarchy(mScene->mRootNode);
- }
-
- ExportMeshes();
-
- //for (unsigned int i = 0; i < pScene->mNumTextures; ++i) {}
-
- ExportScene();
-
- ExportAnimations();
-
- glTF::AssetWriter writer(*mAsset);
-
- if (isBinary) {
- writer.WriteGLBFile(filename);
- } else {
- writer.WriteFile(filename);
- }
-}
-
-/*
- * Copy a 4x4 matrix from struct aiMatrix to typedef mat4.
- * Also converts from row-major to column-major storage.
- */
-static void CopyValue(const aiMatrix4x4& v, glTF::mat4& o)
-{
- o[ 0] = v.a1; o[ 1] = v.b1; o[ 2] = v.c1; o[ 3] = v.d1;
- o[ 4] = v.a2; o[ 5] = v.b2; o[ 6] = v.c2; o[ 7] = v.d2;
- o[ 8] = v.a3; o[ 9] = v.b3; o[10] = v.c3; o[11] = v.d3;
- o[12] = v.a4; o[13] = v.b4; o[14] = v.c4; o[15] = v.d4;
-}
-
-static void CopyValue(const aiMatrix4x4& v, aiMatrix4x4& o)
-{
- o.a1 = v.a1; o.a2 = v.a2; o.a3 = v.a3; o.a4 = v.a4;
- o.b1 = v.b1; o.b2 = v.b2; o.b3 = v.b3; o.b4 = v.b4;
- o.c1 = v.c1; o.c2 = v.c2; o.c3 = v.c3; o.c4 = v.c4;
- o.d1 = v.d1; o.d2 = v.d2; o.d3 = v.d3; o.d4 = v.d4;
-}
-
-static void IdentityMatrix4(glTF::mat4& o)
-{
- o[ 0] = 1; o[ 1] = 0; o[ 2] = 0; o[ 3] = 0;
- o[ 4] = 0; o[ 5] = 1; o[ 6] = 0; o[ 7] = 0;
- o[ 8] = 0; o[ 9] = 0; o[10] = 1; o[11] = 0;
- o[12] = 0; o[13] = 0; o[14] = 0; o[15] = 1;
-}
-
-inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& buffer,
- unsigned int count, void* data, AttribType::Value typeIn, AttribType::Value typeOut, ComponentType compType, bool isIndices = false)
-{
- if (!count || !data) return Ref<Accessor>();
-
- unsigned int numCompsIn = AttribType::GetNumComponents(typeIn);
- unsigned int numCompsOut = AttribType::GetNumComponents(typeOut);
- unsigned int bytesPerComp = ComponentTypeSize(compType);
-
- size_t offset = buffer->byteLength;
- // make sure offset is correctly byte-aligned, as required by spec
- size_t padding = offset % bytesPerComp;
- offset += padding;
- size_t length = count * numCompsOut * bytesPerComp;
- buffer->Grow(length + padding);
-
- // bufferView
- Ref<BufferView> bv = a.bufferViews.Create(a.FindUniqueID(meshName, "view"));
- bv->buffer = buffer;
- bv->byteOffset = unsigned(offset);
- bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
- bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
-
- // accessor
- Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
- acc->bufferView = bv;
- acc->byteOffset = 0;
- acc->byteStride = 0;
- acc->componentType = compType;
- acc->count = count;
- acc->type = typeOut;
-
- // calculate min and max values
- {
- // Allocate and initialize with large values.
- float float_MAX = 10000000000000.0f;
- for (unsigned int i = 0 ; i < numCompsOut ; i++) {
- acc->min.push_back( float_MAX);
- acc->max.push_back(-float_MAX);
- }
-
- // Search and set extreme values.
- float valueTmp;
- for (unsigned int i = 0 ; i < count ; i++) {
- for (unsigned int j = 0 ; j < numCompsOut ; j++) {
- if (numCompsOut == 1) {
- valueTmp = static_cast<unsigned short*>(data)[i];
- } else {
- valueTmp = static_cast<aiVector3D*>(data)[i][j];
- }
-
- if (valueTmp < acc->min[j]) {
- acc->min[j] = valueTmp;
- }
- if (valueTmp > acc->max[j]) {
- acc->max[j] = valueTmp;
- }
- }
- }
- }
-
- // copy the data
- acc->WriteData(count, data, numCompsIn*bytesPerComp);
-
- return acc;
-}
-
-namespace {
- void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) {
- if (mat->Get(propName, type, idx, val) == AI_SUCCESS) {}
- }
-}
-
-void glTFExporter::GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop)
-{
- std::string samplerId = mAsset->FindUniqueID("", "sampler");
- prop.texture->sampler = mAsset->samplers.Create(samplerId);
-
- aiTextureMapMode mapU, mapV;
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0),(int*)&mapU);
- aiGetMaterialInteger(mat,AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0),(int*)&mapV);
-
- switch (mapU) {
- case aiTextureMapMode_Wrap:
- prop.texture->sampler->wrapS = SamplerWrap_Repeat;
- break;
- case aiTextureMapMode_Clamp:
- prop.texture->sampler->wrapS = SamplerWrap_Clamp_To_Edge;
- break;
- case aiTextureMapMode_Mirror:
- prop.texture->sampler->wrapS = SamplerWrap_Mirrored_Repeat;
- break;
- case aiTextureMapMode_Decal:
- default:
- prop.texture->sampler->wrapS = SamplerWrap_Repeat;
- break;
- };
-
- switch (mapV) {
- case aiTextureMapMode_Wrap:
- prop.texture->sampler->wrapT = SamplerWrap_Repeat;
- break;
- case aiTextureMapMode_Clamp:
- prop.texture->sampler->wrapT = SamplerWrap_Clamp_To_Edge;
- break;
- case aiTextureMapMode_Mirror:
- prop.texture->sampler->wrapT = SamplerWrap_Mirrored_Repeat;
- break;
- case aiTextureMapMode_Decal:
- default:
- prop.texture->sampler->wrapT = SamplerWrap_Repeat;
- break;
- };
-
- // Hard coded Texture filtering options because I do not know where to find them in the aiMaterial.
- prop.texture->sampler->magFilter = SamplerMagFilter_Linear;
- prop.texture->sampler->minFilter = SamplerMinFilter_Linear;
-}
-
-void glTFExporter::GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt)
-{
- aiString tex;
- aiColor4D col;
- if (mat->GetTextureCount(tt) > 0) {
- if (mat->Get(AI_MATKEY_TEXTURE(tt, 0), tex) == AI_SUCCESS) {
- std::string path = tex.C_Str();
-
- if (path.size() > 0) {
- if (path[0] != '*') {
- std::map<std::string, unsigned int>::iterator it = mTexturesByPath.find(path);
- if (it != mTexturesByPath.end()) {
- prop.texture = mAsset->textures.Get(it->second);
- }
- }
-
- if (!prop.texture) {
- std::string texId = mAsset->FindUniqueID("", "texture");
- prop.texture = mAsset->textures.Create(texId);
- mTexturesByPath[path] = prop.texture.GetIndex();
-
- std::string imgId = mAsset->FindUniqueID("", "image");
- prop.texture->source = mAsset->images.Create(imgId);
-
- if (path[0] == '*') { // embedded
- aiTexture* tex = mScene->mTextures[atoi(&path[1])];
-
- uint8_t* data = reinterpret_cast<uint8_t*>(tex->pcData);
- prop.texture->source->SetData(data, tex->mWidth, *mAsset);
-
- if (tex->achFormatHint[0]) {
- std::string mimeType = "image/";
- mimeType += (memcmp(tex->achFormatHint, "jpg", 3) == 0) ? "jpeg" : tex->achFormatHint;
- prop.texture->source->mimeType = mimeType;
- }
- }
- else {
- prop.texture->source->uri = path;
- }
-
- GetTexSampler(mat, prop);
- }
- }
- }
- }
-
- if (mat->Get(propName, type, idx, col) == AI_SUCCESS) {
- prop.color[0] = col.r; prop.color[1] = col.g; prop.color[2] = col.b; prop.color[3] = col.a;
- }
-}
-
-
-void glTFExporter::ExportMaterials()
-{
- aiString aiName;
- for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
- const aiMaterial* mat = mScene->mMaterials[i];
-
-
- std::string name;
- if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
- name = aiName.C_Str();
- }
- name = mAsset->FindUniqueID(name, "material");
-
- Ref<Material> m = mAsset->materials.Create(name);
-
- GetMatColorOrTex(mat, m->ambient, AI_MATKEY_COLOR_AMBIENT, aiTextureType_AMBIENT);
- GetMatColorOrTex(mat, m->diffuse, AI_MATKEY_COLOR_DIFFUSE, aiTextureType_DIFFUSE);
- GetMatColorOrTex(mat, m->specular, AI_MATKEY_COLOR_SPECULAR, aiTextureType_SPECULAR);
- GetMatColorOrTex(mat, m->emission, AI_MATKEY_COLOR_EMISSIVE, aiTextureType_EMISSIVE);
-
- m->transparent = mat->Get(AI_MATKEY_OPACITY, m->transparency) == aiReturn_SUCCESS && m->transparency != 1.0;
-
- GetMatScalar(mat, m->shininess, AI_MATKEY_SHININESS);
- }
-}
-
-/*
- * Search through node hierarchy and find the node containing the given meshID.
- * Returns true on success, and false otherwise.
- */
-bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
-{
- for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
- if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
- meshNode = nodeIn;
- return true;
- }
- }
-
- for (unsigned int i = 0; i < nodeIn->children.size(); ++i) {
- if(FindMeshNode(nodeIn->children[i], meshNode, meshID)) {
- return true;
- }
- }
-
- return false;
-}
-
-/*
- * Find the root joint of the skeleton.
- * Starts will any joint node and traces up the tree,
- * until a parent is found that does not have a jointName.
- * Returns the first parent Ref<Node> found that does not have a jointName.
- */
-Ref<Node> FindSkeletonRootJoint(Ref<Skin>& skinRef)
-{
- Ref<Node> startNodeRef;
- Ref<Node> parentNodeRef;
-
- // Arbitrarily use the first joint to start the search.
- startNodeRef = skinRef->jointNames[0];
- parentNodeRef = skinRef->jointNames[0];
-
- do {
- startNodeRef = parentNodeRef;
- parentNodeRef = startNodeRef->parent;
- } while (!parentNodeRef->jointName.empty());
-
- return parentNodeRef;
-}
-
-void ExportSkin(Asset& mAsset, const aiMesh* aimesh, Ref<Mesh>& meshRef, Ref<Buffer>& bufferRef, Ref<Skin>& skinRef, std::vector<aiMatrix4x4>& inverseBindMatricesData)
-{
- if (aimesh->mNumBones < 1) {
- return;
- }
-
- // Store the vertex joint and weight data.
- const size_t NumVerts( aimesh->mNumVertices );
- vec4* vertexJointData = new vec4[ NumVerts ];
- vec4* vertexWeightData = new vec4[ NumVerts ];
- int* jointsPerVertex = new int[ NumVerts ];
- for (size_t i = 0; i < NumVerts; ++i) {
- jointsPerVertex[i] = 0;
- for (size_t j = 0; j < 4; ++j) {
- vertexJointData[i][j] = 0;
- vertexWeightData[i][j] = 0;
- }
- }
-
- for (unsigned int idx_bone = 0; idx_bone < aimesh->mNumBones; ++idx_bone) {
- const aiBone* aib = aimesh->mBones[idx_bone];
-
- // aib->mName =====> skinRef->jointNames
- // Find the node with id = mName.
- Ref<Node> nodeRef = mAsset.nodes.Get(aib->mName.C_Str());
- nodeRef->jointName = nodeRef->id;
-
- unsigned int jointNamesIndex = 0;
- bool addJointToJointNames = true;
- for ( unsigned int idx_joint = 0; idx_joint < skinRef->jointNames.size(); ++idx_joint) {
- if (skinRef->jointNames[idx_joint]->jointName.compare(nodeRef->jointName) == 0) {
- addJointToJointNames = false;
- jointNamesIndex = idx_joint;
- }
- }
-
- if (addJointToJointNames) {
- skinRef->jointNames.push_back(nodeRef);
-
- // aib->mOffsetMatrix =====> skinRef->inverseBindMatrices
- aiMatrix4x4 tmpMatrix4;
- CopyValue(aib->mOffsetMatrix, tmpMatrix4);
- inverseBindMatricesData.push_back(tmpMatrix4);
- jointNamesIndex = static_cast<unsigned int>(inverseBindMatricesData.size() - 1);
- }
-
- // aib->mWeights =====> vertexWeightData
- for (unsigned int idx_weights = 0; idx_weights < aib->mNumWeights; ++idx_weights) {
- unsigned int vertexId = aib->mWeights[idx_weights].mVertexId;
- float vertWeight = aib->mWeights[idx_weights].mWeight;
-
- // A vertex can only have at most four joint weights. Ignore all others.
- if (jointsPerVertex[vertexId] > 3) {
- continue;
- }
-
- vertexJointData[vertexId][jointsPerVertex[vertexId]] = static_cast<float>(jointNamesIndex);
- vertexWeightData[vertexId][jointsPerVertex[vertexId]] = vertWeight;
-
- jointsPerVertex[vertexId] += 1;
- }
-
- } // End: for-loop mNumMeshes
-
- Mesh::Primitive& p = meshRef->primitives.back();
- Ref<Accessor> vertexJointAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexJointData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( vertexJointAccessor ) {
- p.attributes.joint.push_back( vertexJointAccessor );
- }
-
- Ref<Accessor> vertexWeightAccessor = ExportData(mAsset, skinRef->id, bufferRef, aimesh->mNumVertices, vertexWeightData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( vertexWeightAccessor ) {
- p.attributes.weight.push_back( vertexWeightAccessor );
- }
- delete[] jointsPerVertex;
- delete[] vertexWeightData;
- delete[] vertexJointData;
-}
-
-void glTFExporter::ExportMeshes()
-{
- // Not for
- // using IndicesType = decltype(aiFace::mNumIndices);
- // But yes for
- // using IndicesType = unsigned short;
- // because "ComponentType_UNSIGNED_SHORT" used for indices. And it's a maximal type according to glTF specification.
- typedef unsigned short IndicesType;
-
- // Variables needed for compression. BEGIN.
- // Indices, not pointers - because pointer to buffer is changing while writing to it.
- size_t idx_srcdata_begin = 0; // Index of buffer before writing mesh data. Also, index of begin of coordinates array in buffer.
- size_t idx_srcdata_normal = SIZE_MAX;// Index of begin of normals array in buffer. SIZE_MAX - mean that mesh has no normals.
- std::vector<size_t> idx_srcdata_tc;// Array of indices. Every index point to begin of texture coordinates array in buffer.
- size_t idx_srcdata_ind;// Index of begin of coordinates indices array in buffer.
- bool comp_allow;// Point that data of current mesh can be compressed.
- // Variables needed for compression. END.
-
- std::string fname = std::string(mFilename);
- std::string bufferIdPrefix = fname.substr(0, fname.rfind(".gltf"));
- std::string bufferId = mAsset->FindUniqueID("", bufferIdPrefix.c_str());
-
- Ref<Buffer> b = mAsset->GetBodyBuffer();
- if (!b) {
- b = mAsset->buffers.Create(bufferId);
- }
-
- //----------------------------------------
- // Initialize variables for the skin
- bool createSkin = false;
- for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
- const aiMesh* aim = mScene->mMeshes[idx_mesh];
- if(aim->HasBones()) {
- createSkin = true;
- break;
- }
- }
-
- Ref<Skin> skinRef;
- std::string skinName = mAsset->FindUniqueID("skin", "skin");
- std::vector<aiMatrix4x4> inverseBindMatricesData;
- if(createSkin) {
- skinRef = mAsset->skins.Create(skinName);
- skinRef->name = skinName;
- }
- //----------------------------------------
-
- for (unsigned int idx_mesh = 0; idx_mesh < mScene->mNumMeshes; ++idx_mesh) {
- const aiMesh* aim = mScene->mMeshes[idx_mesh];
-
- // Check if compressing requested and mesh can be encoded.
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- comp_allow = mProperties->GetPropertyBool("extensions.Open3DGC.use", false);
-#else
- comp_allow = false;
-#endif
-
- if(comp_allow && (aim->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) && (aim->mNumVertices > 0) && (aim->mNumFaces > 0))
- {
- idx_srcdata_tc.clear();
- idx_srcdata_tc.reserve(AI_MAX_NUMBER_OF_TEXTURECOORDS);
- }
- else
- {
- std::string msg;
-
- if(aim->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
- msg = "all primitives of the mesh must be a triangles.";
- else
- msg = "mesh must has vertices and faces.";
-
- DefaultLogger::get()->warn("GLTF: can not use Open3DGC-compression: " + msg);
- comp_allow = false;
- }
-
- std::string meshId = mAsset->FindUniqueID(aim->mName.C_Str(), "mesh");
- Ref<Mesh> m = mAsset->meshes.Create(meshId);
- m->primitives.resize(1);
- Mesh::Primitive& p = m->primitives.back();
-
- p.material = mAsset->materials.Get(aim->mMaterialIndex);
-
- /******************* Vertices ********************/
- // If compression is used then you need parameters of uncompressed region: begin and size. At this step "begin" is stored.
- if(comp_allow) idx_srcdata_begin = b->byteLength;
-
- Ref<Accessor> v = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mVertices, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (v) p.attributes.position.push_back(v);
-
- /******************** Normals ********************/
- if(comp_allow && (aim->mNormals != 0)) idx_srcdata_normal = b->byteLength;// Store index of normals array.
-
- Ref<Accessor> n = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mNormals, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if (n) p.attributes.normal.push_back(n);
-
- /************** Texture coordinates **************/
- for (int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
- // Flip UV y coords
- if (aim -> mNumUVComponents[i] > 1) {
- for (unsigned int j = 0; j < aim->mNumVertices; ++j) {
- aim->mTextureCoords[i][j].y = 1 - aim->mTextureCoords[i][j].y;
- }
- }
-
- if (aim->mNumUVComponents[i] > 0) {
- AttribType::Value type = (aim->mNumUVComponents[i] == 2) ? AttribType::VEC2 : AttribType::VEC3;
-
- if(comp_allow) idx_srcdata_tc.push_back(b->byteLength);// Store index of texture coordinates array.
-
- Ref<Accessor> tc = ExportData(*mAsset, meshId, b, aim->mNumVertices, aim->mTextureCoords[i], AttribType::VEC3, type, ComponentType_FLOAT, false);
- if (tc) p.attributes.texcoord.push_back(tc);
- }
- }
-
- /*************** Vertices indices ****************/
- idx_srcdata_ind = b->byteLength;// Store index of indices array.
-
- if (aim->mNumFaces > 0) {
- std::vector<IndicesType> indices;
- unsigned int nIndicesPerFace = aim->mFaces[0].mNumIndices;
- indices.resize(aim->mNumFaces * nIndicesPerFace);
- for (size_t i = 0; i < aim->mNumFaces; ++i) {
- for (size_t j = 0; j < nIndicesPerFace; ++j) {
- indices[i*nIndicesPerFace + j] = uint16_t(aim->mFaces[i].mIndices[j]);
- }
- }
-
- p.indices = ExportData(*mAsset, meshId, b, unsigned(indices.size()), &indices[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_UNSIGNED_SHORT, true);
- }
-
- switch (aim->mPrimitiveTypes) {
- case aiPrimitiveType_POLYGON:
- p.mode = PrimitiveMode_TRIANGLES; break; // TODO implement this
- case aiPrimitiveType_LINE:
- p.mode = PrimitiveMode_LINES; break;
- case aiPrimitiveType_POINT:
- p.mode = PrimitiveMode_POINTS; break;
- default: // aiPrimitiveType_TRIANGLE
- p.mode = PrimitiveMode_TRIANGLES;
- }
-
- /*************** Skins ****************/
- if(aim->HasBones()) {
- ExportSkin(*mAsset, aim, m, b, skinRef, inverseBindMatricesData);
- }
-
- /****************** Compression ******************/
- ///TODO: animation: weights, joints.
- if(comp_allow)
- {
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- // Only one type of compression supported at now - Open3DGC.
- //
- o3dgc::BinaryStream bs;
- o3dgc::SC3DMCEncoder<IndicesType> encoder;
- o3dgc::IndexedFaceSet<IndicesType> comp_o3dgc_ifs;
- o3dgc::SC3DMCEncodeParams comp_o3dgc_params;
-
- //
- // Fill data for encoder.
- //
- // Quantization
- unsigned quant_coord = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.POSITION", 12);
- unsigned quant_normal = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.NORMAL", 10);
- unsigned quant_texcoord = mProperties->GetPropertyInteger("extensions.Open3DGC.quantization.TEXCOORD", 10);
-
- // Prediction
- o3dgc::O3DGCSC3DMCPredictionMode prediction_position = o3dgc::O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION;
- o3dgc::O3DGCSC3DMCPredictionMode prediction_normal = o3dgc::O3DGC_SC3DMC_SURF_NORMALS_PREDICTION;
- o3dgc::O3DGCSC3DMCPredictionMode prediction_texcoord = o3dgc::O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION;
-
- // IndexedFacesSet: "Crease angle", "solid", "convex" are set to default.
- comp_o3dgc_ifs.SetCCW(true);
- comp_o3dgc_ifs.SetIsTriangularMesh(true);
- comp_o3dgc_ifs.SetNumFloatAttributes(0);
- // Coordinates
- comp_o3dgc_params.SetCoordQuantBits(quant_coord);
- comp_o3dgc_params.SetCoordPredMode(prediction_position);
- comp_o3dgc_ifs.SetNCoord(aim->mNumVertices);
- comp_o3dgc_ifs.SetCoord((o3dgc::Real* const)&b->GetPointer()[idx_srcdata_begin]);
- // Normals
- if(idx_srcdata_normal != SIZE_MAX)
- {
- comp_o3dgc_params.SetNormalQuantBits(quant_normal);
- comp_o3dgc_params.SetNormalPredMode(prediction_normal);
- comp_o3dgc_ifs.SetNNormal(aim->mNumVertices);
- comp_o3dgc_ifs.SetNormal((o3dgc::Real* const)&b->GetPointer()[idx_srcdata_normal]);
- }
-
- // Texture coordinates
- for(size_t num_tc = 0; num_tc < idx_srcdata_tc.size(); num_tc++)
- {
- size_t num = comp_o3dgc_ifs.GetNumFloatAttributes();
-
- comp_o3dgc_params.SetFloatAttributeQuantBits(static_cast<unsigned long>(num), quant_texcoord);
- comp_o3dgc_params.SetFloatAttributePredMode(static_cast<unsigned long>(num), prediction_texcoord);
- comp_o3dgc_ifs.SetNFloatAttribute(static_cast<unsigned long>(num), aim->mNumVertices);// number of elements.
- comp_o3dgc_ifs.SetFloatAttributeDim(static_cast<unsigned long>(num), aim->mNumUVComponents[num_tc]);// components per element: aiVector3D => x * float
- comp_o3dgc_ifs.SetFloatAttributeType(static_cast<unsigned long>(num), o3dgc::O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD);
- comp_o3dgc_ifs.SetFloatAttribute(static_cast<unsigned long>(num), (o3dgc::Real* const)&b->GetPointer()[idx_srcdata_tc[num_tc]]);
- comp_o3dgc_ifs.SetNumFloatAttributes(static_cast<unsigned long>(num + 1));
- }
-
- // Coordinates indices
- comp_o3dgc_ifs.SetNCoordIndex(aim->mNumFaces);
- comp_o3dgc_ifs.SetCoordIndex((IndicesType* const)&b->GetPointer()[idx_srcdata_ind]);
- // Prepare to enconding
- comp_o3dgc_params.SetNumFloatAttributes(comp_o3dgc_ifs.GetNumFloatAttributes());
- if(mProperties->GetPropertyBool("extensions.Open3DGC.binary", true))
- comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_BINARY);
- else
- comp_o3dgc_params.SetStreamType(o3dgc::O3DGC_STREAM_TYPE_ASCII);
-
- comp_o3dgc_ifs.ComputeMinMax(o3dgc::O3DGC_SC3DMC_MAX_ALL_DIMS);
- //
- // Encoding
- //
- encoder.Encode(comp_o3dgc_params, comp_o3dgc_ifs, bs);
- // Replace data in buffer.
- b->ReplaceData(idx_srcdata_begin, b->byteLength - idx_srcdata_begin, bs.GetBuffer(), bs.GetSize());
- //
- // Add information about extension to mesh.
- //
- // Create extension structure.
- Mesh::SCompression_Open3DGC* ext = new Mesh::SCompression_Open3DGC;
-
- // Fill it.
- ext->Buffer = b->id;
- ext->Offset = idx_srcdata_begin;
- ext->Count = b->byteLength - idx_srcdata_begin;
- ext->Binary = mProperties->GetPropertyBool("extensions.Open3DGC.binary");
- ext->IndicesCount = comp_o3dgc_ifs.GetNCoordIndex() * 3;
- ext->VerticesCount = comp_o3dgc_ifs.GetNCoord();
- // And assign to mesh.
- m->Extension.push_back(ext);
-#endif
- }// if(comp_allow)
- }// for (unsigned int i = 0; i < mScene->mNumMeshes; ++i)
-
- //----------------------------------------
- // Finish the skin
- // Create the Accessor for skinRef->inverseBindMatrices
- if (createSkin) {
- mat4* invBindMatrixData = new mat4[inverseBindMatricesData.size()];
- for ( unsigned int idx_joint = 0; idx_joint < inverseBindMatricesData.size(); ++idx_joint) {
- CopyValue(inverseBindMatricesData[idx_joint], invBindMatrixData[idx_joint]);
- }
-
- Ref<Accessor> invBindMatrixAccessor = ExportData(*mAsset, skinName, b, static_cast<unsigned int>(inverseBindMatricesData.size()), invBindMatrixData, AttribType::MAT4, AttribType::MAT4, ComponentType_FLOAT);
- if (invBindMatrixAccessor) skinRef->inverseBindMatrices = invBindMatrixAccessor;
-
- // Identity Matrix =====> skinRef->bindShapeMatrix
- // Temporary. Hard-coded identity matrix here
- skinRef->bindShapeMatrix.isPresent = true;
- IdentityMatrix4(skinRef->bindShapeMatrix.value);
-
- // Find node that contains this mesh and add "skeletons" and "skin" attributes to that node.
- Ref<Node> rootNode = mAsset->nodes.Get(unsigned(0));
- Ref<Node> meshNode;
- std::string meshID = mAsset->meshes.Get(unsigned(0))->id;
- FindMeshNode(rootNode, meshNode, meshID);
-
- Ref<Node> rootJoint = FindSkeletonRootJoint(skinRef);
- meshNode->skeletons.push_back(rootJoint);
- meshNode->skin = skinRef;
- }
-}
-
-/*
- * Export the root node of the node hierarchy.
- * Calls ExportNode for all children.
- */
-unsigned int glTFExporter::ExportNodeHierarchy(const aiNode* n)
-{
- Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
-
- if (!n->mTransformation.IsIdentity()) {
- node->matrix.isPresent = true;
- CopyValue(n->mTransformation, node->matrix.value);
- }
-
- for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
- node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
- }
-
- for (unsigned int i = 0; i < n->mNumChildren; ++i) {
- unsigned int idx = ExportNode(n->mChildren[i], node);
- node->children.push_back(mAsset->nodes.Get(idx));
- }
-
- return node.GetIndex();
-}
-
-/*
- * Export node and recursively calls ExportNode for all children.
- * Since these nodes are not the root node, we also export the parent Ref<Node>
- */
-unsigned int glTFExporter::ExportNode(const aiNode* n, Ref<Node>& parent)
-{
- Ref<Node> node = mAsset->nodes.Create(mAsset->FindUniqueID(n->mName.C_Str(), "node"));
-
- node->parent = parent;
-
- if (!n->mTransformation.IsIdentity()) {
- node->matrix.isPresent = true;
- CopyValue(n->mTransformation, node->matrix.value);
- }
-
- for (unsigned int i = 0; i < n->mNumMeshes; ++i) {
- node->meshes.push_back(mAsset->meshes.Get(n->mMeshes[i]));
- }
-
- for (unsigned int i = 0; i < n->mNumChildren; ++i) {
- unsigned int idx = ExportNode(n->mChildren[i], node);
- node->children.push_back(mAsset->nodes.Get(idx));
- }
-
- return node.GetIndex();
-}
-
-
-void glTFExporter::ExportScene()
-{
- const char* sceneName = "defaultScene";
- Ref<Scene> scene = mAsset->scenes.Create(sceneName);
-
- // root node will be the first one exported (idx 0)
- if (mAsset->nodes.Size() > 0) {
- scene->nodes.push_back(mAsset->nodes.Get(0u));
- }
-
- // set as the default scene
- mAsset->scene = scene;
-}
-
-void glTFExporter::ExportMetadata()
-{
- glTF::AssetMetadata& asset = mAsset->asset;
- asset.version = "1.0";
-
- char buffer[256];
- ai_snprintf(buffer, 256, "Open Asset Import Library (assimp v%d.%d.%d)",
- aiGetVersionMajor(), aiGetVersionMinor(), aiGetVersionRevision());
-
- asset.generator = buffer;
-}
-
-inline void ExtractAnimationData(Asset& mAsset, std::string& animId, Ref<Animation>& animRef, Ref<Buffer>& buffer, const aiNodeAnim* nodeChannel, float ticksPerSecond)
-{
- // Loop over the data and check to see if it exactly matches an existing buffer.
- // If yes, then reference the existing corresponding accessor.
- // Otherwise, add to the buffer and create a new accessor.
-
- size_t counts[3] = {
- nodeChannel->mNumPositionKeys,
- nodeChannel->mNumScalingKeys,
- nodeChannel->mNumRotationKeys,
- };
- size_t numKeyframes = 1;
- for (int i = 0; i < 3; ++i) {
- if (counts[i] > numKeyframes) {
- numKeyframes = counts[i];
- }
- }
-
- //-------------------------------------------------------
- // Extract TIME parameter data.
- // Check if the timeStamps are the same for mPositionKeys, mRotationKeys, and mScalingKeys.
- if(nodeChannel->mNumPositionKeys > 0) {
- typedef float TimeType;
- std::vector<TimeType> timeData;
- timeData.resize(numKeyframes);
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
- // mTime is measured in ticks, but GLTF time is measured in seconds, so convert.
- // Check if we have to cast type here. e.g. uint16_t()
- timeData[i] = static_cast<float>(nodeChannel->mPositionKeys[frameIndex].mTime / ticksPerSecond);
- }
-
- Ref<Accessor> timeAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), &timeData[0], AttribType::SCALAR, AttribType::SCALAR, ComponentType_FLOAT);
- if (timeAccessor) animRef->Parameters.TIME = timeAccessor;
- }
-
- //-------------------------------------------------------
- // Extract translation parameter data
- if(nodeChannel->mNumPositionKeys > 0) {
- C_STRUCT aiVector3D* translationData = new aiVector3D[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumPositionKeys / numKeyframes;
- translationData[i] = nodeChannel->mPositionKeys[frameIndex].mValue;
- }
-
- Ref<Accessor> tranAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), translationData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if ( tranAccessor ) {
- animRef->Parameters.translation = tranAccessor;
- }
- delete[] translationData;
- }
-
- //-------------------------------------------------------
- // Extract scale parameter data
- if(nodeChannel->mNumScalingKeys > 0) {
- C_STRUCT aiVector3D* scaleData = new aiVector3D[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumScalingKeys / numKeyframes;
- scaleData[i] = nodeChannel->mScalingKeys[frameIndex].mValue;
- }
-
- Ref<Accessor> scaleAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), scaleData, AttribType::VEC3, AttribType::VEC3, ComponentType_FLOAT);
- if ( scaleAccessor ) {
- animRef->Parameters.scale = scaleAccessor;
- }
- delete[] scaleData;
- }
-
- //-------------------------------------------------------
- // Extract rotation parameter data
- if(nodeChannel->mNumRotationKeys > 0) {
- vec4* rotationData = new vec4[numKeyframes];
- for (size_t i = 0; i < numKeyframes; ++i) {
- size_t frameIndex = i * nodeChannel->mNumRotationKeys / numKeyframes;
- rotationData[i][0] = nodeChannel->mRotationKeys[frameIndex].mValue.x;
- rotationData[i][1] = nodeChannel->mRotationKeys[frameIndex].mValue.y;
- rotationData[i][2] = nodeChannel->mRotationKeys[frameIndex].mValue.z;
- rotationData[i][3] = nodeChannel->mRotationKeys[frameIndex].mValue.w;
- }
-
- Ref<Accessor> rotAccessor = ExportData(mAsset, animId, buffer, static_cast<unsigned int>(numKeyframes), rotationData, AttribType::VEC4, AttribType::VEC4, ComponentType_FLOAT);
- if ( rotAccessor ) {
- animRef->Parameters.rotation = rotAccessor;
- }
- delete[] rotationData;
- }
-}
-
-void glTFExporter::ExportAnimations()
-{
- Ref<Buffer> bufferRef = mAsset->buffers.Get(unsigned (0));
-
- for (unsigned int i = 0; i < mScene->mNumAnimations; ++i) {
- const aiAnimation* anim = mScene->mAnimations[i];
-
- std::string nameAnim = "anim";
- if (anim->mName.length > 0) {
- nameAnim = anim->mName.C_Str();
- }
-
- for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
- const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
-
- // It appears that assimp stores this type of animation as multiple animations.
- // where each aiNodeAnim in mChannels animates a specific node.
- std::string name = nameAnim + "_" + to_string(channelIndex);
- name = mAsset->FindUniqueID(name, "animation");
- Ref<Animation> animRef = mAsset->animations.Create(name);
-
- /******************* Parameters ********************/
- ExtractAnimationData(*mAsset, name, animRef, bufferRef, nodeChannel, static_cast<float>(anim->mTicksPerSecond));
-
- for (unsigned int j = 0; j < 3; ++j) {
- std::string channelType;
- int channelSize;
- switch (j) {
- case 0:
- channelType = "rotation";
- channelSize = nodeChannel->mNumRotationKeys;
- break;
- case 1:
- channelType = "scale";
- channelSize = nodeChannel->mNumScalingKeys;
- break;
- case 2:
- channelType = "translation";
- channelSize = nodeChannel->mNumPositionKeys;
- break;
- }
-
- if (channelSize < 1) { continue; }
-
- Animation::AnimChannel tmpAnimChannel;
- Animation::AnimSampler tmpAnimSampler;
-
- tmpAnimChannel.sampler = name + "_" + channelType;
- tmpAnimChannel.target.path = channelType;
- tmpAnimSampler.output = channelType;
- tmpAnimSampler.id = name + "_" + channelType;
-
- tmpAnimChannel.target.id = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());
-
- tmpAnimSampler.input = "TIME";
- tmpAnimSampler.interpolation = "LINEAR";
-
- animRef->Channels.push_back(tmpAnimChannel);
- animRef->Samplers.push_back(tmpAnimSampler);
- }
-
- }
-
- // Assimp documentation staes this is not used (not implemented)
- // for (unsigned int channelIndex = 0; channelIndex < anim->mNumMeshChannels; ++channelIndex) {
- // const aiMeshAnim* meshChannel = anim->mMeshChannels[channelIndex];
- // }
-
- } // End: for-loop mNumAnimations
-}
-
-
-#endif // ASSIMP_BUILD_NO_GLTF_EXPORTER
-#endif // ASSIMP_BUILD_NO_EXPORT
diff --git a/src/3rdparty/assimp/code/glTFExporter.h b/src/3rdparty/assimp/code/glTFExporter.h
deleted file mode 100644
index c813fff44..000000000
--- a/src/3rdparty/assimp/code/glTFExporter.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 GltfExporter.h
-* Declares the exporter class to write a scene to a gltf/glb file
-*/
-#ifndef AI_GLTFEXPORTER_H_INC
-#define AI_GLTFEXPORTER_H_INC
-
-#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include <assimp/types.h>
-#include <assimp/material.h>
-
-#include <sstream>
-#include <vector>
-#include <map>
-#include <memory>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-
-namespace glTF
-{
- template<class T>
- class Ref;
-
- class Asset;
- struct TexProperty;
- struct Node;
-}
-
-namespace Assimp
-{
- class IOSystem;
- class IOStream;
- class ExportProperties;
-
- // ------------------------------------------------------------------------------------------------
- /** Helper class to export a given scene to an glTF file. */
- // ------------------------------------------------------------------------------------------------
- class glTFExporter
- {
- public:
- /// Constructor for a specific scene to export
- glTFExporter(const char* filename, IOSystem* pIOSystem, const aiScene* pScene,
- const ExportProperties* pProperties, bool binary);
-
- private:
-
- const char* mFilename;
- IOSystem* mIOSystem;
- const aiScene* mScene;
- const ExportProperties* mProperties;
-
- std::map<std::string, unsigned int> mTexturesByPath;
-
- std::shared_ptr<glTF::Asset> mAsset;
-
- std::vector<unsigned char> mBodyData;
-
- void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
-
- void GetTexSampler(const aiMaterial* mat, glTF::TexProperty& prop);
- void GetMatColorOrTex(const aiMaterial* mat, glTF::TexProperty& prop, const char* propName, int type, int idx, aiTextureType tt);
- void ExportMetadata();
- void ExportMaterials();
- void ExportMeshes();
- unsigned int ExportNodeHierarchy(const aiNode* n);
- unsigned int ExportNode(const aiNode* node, glTF::Ref<glTF::Node>& parent);
- void ExportScene();
- void ExportAnimations();
- };
-
-}
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#endif // AI_GLTFEXPORTER_H_INC
diff --git a/src/3rdparty/assimp/code/glTFImporter.cpp b/src/3rdparty/assimp/code/glTFImporter.cpp
deleted file mode 100644
index 5d1b5afab..000000000
--- a/src/3rdparty/assimp/code/glTFImporter.cpp
+++ /dev/null
@@ -1,683 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ASSIMP_BUILD_NO_GLTF_IMPORTER
-
-#include "glTFImporter.h"
-#include "StringComparison.h"
-#include "StringUtils.h"
-
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-#include <assimp/DefaultLogger.hpp>
-#include <assimp/importerdesc.h>
-
-#include <memory>
-
-#include "MakeVerboseFormat.h"
-
-#include "glTFAsset.h"
-// This is included here so WriteLazyDict<T>'s definition is found.
-#include "glTFAssetWriter.h"
-
-using namespace Assimp;
-using namespace glTF;
-
-
-//
-// glTFImporter
-//
-
-static const aiImporterDesc desc = {
- "glTF Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour
- | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
- 0,
- 0,
- 0,
- 0,
- "gltf glb"
-};
-
-glTFImporter::glTFImporter()
-: BaseImporter()
-, meshOffsets()
-, embeddedTexIdxs()
-, mScene( NULL ) {
- // empty
-}
-
-glTFImporter::~glTFImporter() {
- // empty
-}
-
-const aiImporterDesc* glTFImporter::GetInfo() const
-{
- return &desc;
-}
-
-bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
- const std::string &extension = GetExtension(pFile);
-
- if (extension != "gltf" && extension != "glb")
- return false;
-
- if (checkSig && pIOHandler) {
- glTF::Asset asset(pIOHandler);
- try {
- asset.Load(pFile, extension == "glb");
- std::string version = asset.asset.version;
- return !version.empty() && version[0] == '1';
- } catch (...) {
- return false;
- }
- }
-
- return false;
-}
-
-
-
-//static void CopyValue(const glTF::vec3& v, aiColor3D& out)
-//{
-// out.r = v[0]; out.g = v[1]; out.b = v[2];
-//}
-
-static void CopyValue(const glTF::vec4& v, aiColor4D& out)
-{
- out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
-}
-
-static void CopyValue(const glTF::vec4& v, aiColor3D& out)
-{
- out.r = v[0]; out.g = v[1]; out.b = v[2];
-}
-
-static void CopyValue(const glTF::vec3& v, aiVector3D& out)
-{
- out.x = v[0]; out.y = v[1]; out.z = v[2];
-}
-
-static void CopyValue(const glTF::vec4& v, aiQuaternion& out)
-{
- out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
-}
-
-static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
-{
- o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
- o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
- o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
- o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
-
-inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
- aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
-{
- if (prop.texture) {
- if (prop.texture->source) {
- aiString uri(prop.texture->source->uri);
-
- int texIdx = embeddedTexIdxs[prop.texture->source.GetIndex()];
- if (texIdx != -1) { // embedded
- // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
- uri.data[0] = '*';
- uri.length = 1 + ASSIMP_itoa10(uri.data + 1, MAXLEN - 1, texIdx);
- }
-
- mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
- }
- }
- else {
- aiColor4D col;
- CopyValue(prop.color, col);
- mat->AddProperty(&col, 1, pKey, type, idx);
- }
-}
-
-void glTFImporter::ImportMaterials(glTF::Asset& r)
-{
- mScene->mNumMaterials = unsigned(r.materials.Size());
- mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
-
- for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
- aiMaterial* aimat = mScene->mMaterials[i] = new aiMaterial();
-
- Material& mat = r.materials[i];
-
- /*if (!mat.name.empty())*/ {
- aiString str(mat.id /*mat.name*/);
- aimat->AddProperty(&str, AI_MATKEY_NAME);
- }
-
- SetMaterialColorProperty(embeddedTexIdxs, r, mat.diffuse, aimat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE);
- SetMaterialColorProperty(embeddedTexIdxs, r, mat.specular, aimat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR);
- SetMaterialColorProperty(embeddedTexIdxs, r, mat.ambient, aimat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
-
- if (mat.shininess > 0.f) {
- aimat->AddProperty(&mat.shininess, 1, AI_MATKEY_SHININESS);
- }
- }
-
- if (mScene->mNumMaterials == 0) {
- mScene->mNumMaterials = 1;
- mScene->mMaterials = new aiMaterial*[1];
- mScene->mMaterials[0] = new aiMaterial();
- }
-}
-
-
-static inline void SetFace(aiFace& face, int a)
-{
- face.mNumIndices = 1;
- face.mIndices = new unsigned int[1];
- face.mIndices[0] = a;
-}
-
-static inline void SetFace(aiFace& face, int a, int b)
-{
- face.mNumIndices = 2;
- face.mIndices = new unsigned int[2];
- face.mIndices[0] = a;
- face.mIndices[1] = b;
-}
-
-static inline void SetFace(aiFace& face, int a, int b, int c)
-{
- face.mNumIndices = 3;
- face.mIndices = new unsigned int[3];
- face.mIndices[0] = a;
- face.mIndices[1] = b;
- face.mIndices[2] = c;
-}
-
-#ifdef ASSIMP_BUILD_DEBUG
-static inline bool CheckValidFacesIndices(aiFace* faces, unsigned nFaces, unsigned nVerts)
-{
- for (unsigned i = 0; i < nFaces; ++i) {
- for (unsigned j = 0; j < faces[i].mNumIndices; ++j) {
- unsigned idx = faces[i].mIndices[j];
- if (idx >= nVerts)
- return false;
- }
- }
- return true;
-}
-#endif // ASSIMP_BUILD_DEBUG
-
-void glTFImporter::ImportMeshes(glTF::Asset& r)
-{
- std::vector<aiMesh*> meshes;
-
- unsigned int k = 0;
-
- for (unsigned int m = 0; m < r.meshes.Size(); ++m) {
- Mesh& mesh = r.meshes[m];
-
- // Check if mesh extensions is used
- if(mesh.Extension.size() > 0)
- {
- for(Mesh::SExtension* cur_ext : mesh.Extension)
- {
-#ifdef ASSIMP_IMPORTER_GLTF_USE_OPEN3DGC
- if(cur_ext->Type == Mesh::SExtension::EType::Compression_Open3DGC)
- {
- // Limitations for meshes when using Open3DGC-compression.
- // It's a current limitation of sp... Specification have not this part still - about mesh compression. Why only one primitive?
- // Because glTF is very flexibly. But in fact it ugly flexible. Every primitive can has own set of accessors and accessors can
- // point to a-a-a-a-any part of buffer (through bufferview of course) and even to another buffer. We know that "Open3DGC-compression"
- // is applicable only to part of buffer. As we can't guaranty continuity of the data for decoder, we will limit quantity of primitives.
- // Yes indices, coordinates etc. still can br stored in different buffers, but with current specification it's a exporter problem.
- // Also primitive can has only one of "POSITION", "NORMAL" and less then "AI_MAX_NUMBER_OF_TEXTURECOORDS" of "TEXCOORD". All accessor
- // of primitive must point to one continuous region of the buffer.
- if(mesh.primitives.size() > 2) throw DeadlyImportError("GLTF: When using Open3DGC compression then only one primitive per mesh are allowed.");
-
- Mesh::SCompression_Open3DGC* o3dgc_ext = (Mesh::SCompression_Open3DGC*)cur_ext;
- Ref<Buffer> buf = r.buffers.Get(o3dgc_ext->Buffer);
-
- buf->EncodedRegion_SetCurrent(mesh.id);
- }
- else
-#endif
- {
- throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"" + to_string(cur_ext->Type) +
- "\"), only Open3DGC is supported.");
- }
- }
- }// if(mesh.Extension.size() > 0)
-
- meshOffsets.push_back(k);
- k += unsigned(mesh.primitives.size());
-
- for (unsigned int p = 0; p < mesh.primitives.size(); ++p) {
- Mesh::Primitive& prim = mesh.primitives[p];
-
- aiMesh* aim = new aiMesh();
- meshes.push_back(aim);
-
- aim->mName = mesh.id;
- if (mesh.primitives.size() > 1) {
- size_t& len = aim->mName.length;
- aim->mName.data[len] = '-';
- len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
- }
-
- switch (prim.mode) {
- case PrimitiveMode_POINTS:
- aim->mPrimitiveTypes |= aiPrimitiveType_POINT;
- break;
-
- case PrimitiveMode_LINES:
- case PrimitiveMode_LINE_LOOP:
- case PrimitiveMode_LINE_STRIP:
- aim->mPrimitiveTypes |= aiPrimitiveType_LINE;
- break;
-
- case PrimitiveMode_TRIANGLES:
- case PrimitiveMode_TRIANGLE_STRIP:
- case PrimitiveMode_TRIANGLE_FAN:
- aim->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
- break;
- }
-
- Mesh::Primitive::Attributes& attr = prim.attributes;
-
- if (attr.position.size() > 0 && attr.position[0]) {
- aim->mNumVertices = attr.position[0]->count;
- attr.position[0]->ExtractData(aim->mVertices);
- }
-
- if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals);
-
- for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
- attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
- aim->mNumUVComponents[tc] = attr.texcoord[tc]->GetNumComponents();
-
- aiVector3D* values = aim->mTextureCoords[tc];
- for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
- values[i].y = 1 - values[i].y; // Flip Y coords
- }
- }
-
-
- if (prim.indices) {
- aiFace* faces = 0;
- unsigned int nFaces = 0;
-
- unsigned int count = prim.indices->count;
-
- Accessor::Indexer data = prim.indices->GetIndexer();
- ai_assert(data.IsValid());
-
- switch (prim.mode) {
- case PrimitiveMode_POINTS: {
- nFaces = count;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; ++i) {
- SetFace(faces[i], data.GetUInt(i));
- }
- break;
- }
-
- case PrimitiveMode_LINES: {
- nFaces = count / 2;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; i += 2) {
- SetFace(faces[i / 2], data.GetUInt(i), data.GetUInt(i + 1));
- }
- break;
- }
-
- case PrimitiveMode_LINE_LOOP:
- case PrimitiveMode_LINE_STRIP: {
- nFaces = count - ((prim.mode == PrimitiveMode_LINE_STRIP) ? 1 : 0);
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1));
- for (unsigned int i = 2; i < count; ++i) {
- SetFace(faces[i - 1], faces[i - 2].mIndices[1], data.GetUInt(i));
- }
- if (prim.mode == PrimitiveMode_LINE_LOOP) { // close the loop
- SetFace(faces[count - 1], faces[count - 2].mIndices[1], faces[0].mIndices[0]);
- }
- break;
- }
-
- case PrimitiveMode_TRIANGLES: {
- nFaces = count / 3;
- faces = new aiFace[nFaces];
- for (unsigned int i = 0; i < count; i += 3) {
- SetFace(faces[i / 3], data.GetUInt(i), data.GetUInt(i + 1), data.GetUInt(i + 2));
- }
- break;
- }
- case PrimitiveMode_TRIANGLE_STRIP: {
- nFaces = count - 2;
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
- for (unsigned int i = 3; i < count; ++i) {
- SetFace(faces[i - 2], faces[i - 1].mIndices[1], faces[i - 1].mIndices[2], data.GetUInt(i));
- }
- break;
- }
- case PrimitiveMode_TRIANGLE_FAN:
- nFaces = count - 2;
- faces = new aiFace[nFaces];
- SetFace(faces[0], data.GetUInt(0), data.GetUInt(1), data.GetUInt(2));
- for (unsigned int i = 3; i < count; ++i) {
- SetFace(faces[i - 2], faces[0].mIndices[0], faces[i - 1].mIndices[2], data.GetUInt(i));
- }
- break;
- }
-
- if (faces) {
- aim->mFaces = faces;
- aim->mNumFaces = nFaces;
- ai_assert(CheckValidFacesIndices(faces, nFaces, aim->mNumVertices));
- }
- }
-
-
- if (prim.material) {
- aim->mMaterialIndex = prim.material.GetIndex();
- }
- }
- }
-
- meshOffsets.push_back(k);
-
- CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
-}
-
-void glTFImporter::ImportCameras(glTF::Asset& r)
-{
- if (!r.cameras.Size()) return;
-
- mScene->mNumCameras = r.cameras.Size();
- mScene->mCameras = new aiCamera*[r.cameras.Size()];
-
- for (size_t i = 0; i < r.cameras.Size(); ++i) {
- Camera& cam = r.cameras[i];
-
- aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
-
- if (cam.type == Camera::Perspective) {
-
- aicam->mAspect = cam.perspective.aspectRatio;
- aicam->mHorizontalFOV = cam.perspective.yfov * aicam->mAspect;
- aicam->mClipPlaneFar = cam.perspective.zfar;
- aicam->mClipPlaneNear = cam.perspective.znear;
- }
- else {
- // assimp does not support orthographic cameras
- }
- }
-}
-
-void glTFImporter::ImportLights(glTF::Asset& r)
-{
- if (!r.lights.Size()) return;
-
- mScene->mNumLights = r.lights.Size();
- mScene->mLights = new aiLight*[r.lights.Size()];
-
- for (size_t i = 0; i < r.lights.Size(); ++i) {
- Light& l = r.lights[i];
-
- aiLight* ail = mScene->mLights[i] = new aiLight();
-
- switch (l.type) {
- case Light::Type_directional:
- ail->mType = aiLightSource_DIRECTIONAL; break;
-
- case Light::Type_spot:
- ail->mType = aiLightSource_SPOT; break;
-
- case Light::Type_ambient:
- ail->mType = aiLightSource_AMBIENT; break;
-
- default: // Light::Type_point
- ail->mType = aiLightSource_POINT; break;
- }
-
- CopyValue(l.color, ail->mColorAmbient);
- CopyValue(l.color, ail->mColorDiffuse);
- CopyValue(l.color, ail->mColorSpecular);
-
- ail->mAngleOuterCone = l.falloffAngle;
- ail->mAngleInnerCone = l.falloffExponent; // TODO fix this, it does not look right at all
-
- ail->mAttenuationConstant = l.constantAttenuation;
- ail->mAttenuationLinear = l.linearAttenuation;
- ail->mAttenuationQuadratic = l.quadraticAttenuation;
- }
-}
-
-
-aiNode* ImportNode(aiScene* pScene, glTF::Asset& r, std::vector<unsigned int>& meshOffsets, glTF::Ref<glTF::Node>& ptr)
-{
- Node& node = *ptr;
-
- aiNode* ainode = new aiNode(node.id);
-
- if (!node.children.empty()) {
- ainode->mNumChildren = unsigned(node.children.size());
- ainode->mChildren = new aiNode*[ainode->mNumChildren];
-
- for (unsigned int i = 0; i < ainode->mNumChildren; ++i) {
- aiNode* child = ImportNode(pScene, r, meshOffsets, node.children[i]);
- child->mParent = ainode;
- ainode->mChildren[i] = child;
- }
- }
-
- aiMatrix4x4& matrix = ainode->mTransformation;
- if (node.matrix.isPresent) {
- CopyValue(node.matrix.value, matrix);
- }
- else {
- if (node.translation.isPresent) {
- aiVector3D trans;
- CopyValue(node.translation.value, trans);
- aiMatrix4x4 t;
- aiMatrix4x4::Translation(trans, t);
- matrix = t * matrix;
- }
-
- if (node.scale.isPresent) {
- aiVector3D scal(1.f);
- CopyValue(node.scale.value, scal);
- aiMatrix4x4 s;
- aiMatrix4x4::Scaling(scal, s);
- matrix = s * matrix;
- }
-
-
- if (node.rotation.isPresent) {
- aiQuaternion rot;
- CopyValue(node.rotation.value, rot);
- matrix = aiMatrix4x4(rot.GetMatrix()) * matrix;
- }
- }
-
- if (!node.meshes.empty()) {
- int count = 0;
- for (size_t i = 0; i < node.meshes.size(); ++i) {
- int idx = node.meshes[i].GetIndex();
- count += meshOffsets[idx + 1] - meshOffsets[idx];
- }
-
- ainode->mNumMeshes = count;
- ainode->mMeshes = new unsigned int[count];
-
- int k = 0;
- for (size_t i = 0; i < node.meshes.size(); ++i) {
- int idx = node.meshes[i].GetIndex();
- for (unsigned int j = meshOffsets[idx]; j < meshOffsets[idx + 1]; ++j, ++k) {
- ainode->mMeshes[k] = j;
- }
- }
- }
-
- if (node.camera) {
- pScene->mCameras[node.camera.GetIndex()]->mName = ainode->mName;
- }
-
- if (node.light) {
- pScene->mLights[node.light.GetIndex()]->mName = ainode->mName;
- }
-
- return ainode;
-}
-
-void glTFImporter::ImportNodes(glTF::Asset& r)
-{
- if (!r.scene) return;
-
- std::vector< Ref<Node> > rootNodes = r.scene->nodes;
-
- // The root nodes
- unsigned int numRootNodes = unsigned(rootNodes.size());
- if (numRootNodes == 1) { // a single root node: use it
- mScene->mRootNode = ImportNode(mScene, r, meshOffsets, rootNodes[0]);
- }
- else if (numRootNodes > 1) { // more than one root node: create a fake root
- aiNode* root = new aiNode("ROOT");
- root->mChildren = new aiNode*[numRootNodes];
- for (unsigned int i = 0; i < numRootNodes; ++i) {
- aiNode* node = ImportNode(mScene, r, meshOffsets, rootNodes[i]);
- node->mParent = root;
- root->mChildren[root->mNumChildren++] = node;
- }
- mScene->mRootNode = root;
- }
-
- //if (!mScene->mRootNode) {
- // mScene->mRootNode = new aiNode("EMPTY");
- //}
-}
-
-void glTFImporter::ImportEmbeddedTextures(glTF::Asset& r)
-{
- embeddedTexIdxs.resize(r.images.Size(), -1);
-
- int numEmbeddedTexs = 0;
- for (size_t i = 0; i < r.images.Size(); ++i) {
- if (r.images[i].HasData())
- numEmbeddedTexs += 1;
- }
-
- if (numEmbeddedTexs == 0)
- return;
-
- mScene->mTextures = new aiTexture*[numEmbeddedTexs];
-
- // Add the embedded textures
- for (size_t i = 0; i < r.images.Size(); ++i) {
- Image img = r.images[i];
- if (!img.HasData()) continue;
-
- int idx = mScene->mNumTextures++;
- embeddedTexIdxs[i] = idx;
-
- aiTexture* tex = mScene->mTextures[idx] = new aiTexture();
-
- size_t length = img.GetDataLength();
- void* data = img.StealData();
-
- tex->mWidth = static_cast<unsigned int>(length);
- tex->mHeight = 0;
- tex->pcData = reinterpret_cast<aiTexel*>(data);
-
- if (!img.mimeType.empty()) {
- const char* ext = strchr(img.mimeType.c_str(), '/') + 1;
- if (ext) {
- if (strcmp(ext, "jpeg") == 0) ext = "jpg";
-
- size_t len = strlen(ext);
- if (len <= 3) {
- strcpy(tex->achFormatHint, ext);
- }
- }
- }
- }
-}
-
-void glTFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
-
- this->mScene = pScene;
-
- // read the asset file
- glTF::Asset asset(pIOHandler);
- asset.Load(pFile, GetExtension(pFile) == "glb");
-
-
- //
- // Copy the data out
- //
-
- ImportEmbeddedTextures(asset);
- ImportMaterials(asset);
-
- ImportMeshes(asset);
-
- ImportCameras(asset);
- ImportLights(asset);
-
- ImportNodes(asset);
-
- // TODO: it does not split the loaded vertices, should it?
- //pScene->mFlags |= AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
- MakeVerboseFormatProcess process;
- process.Execute(pScene);
-
-
- if (pScene->mNumMeshes == 0) {
- pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
- }
-}
-
-#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER
-
diff --git a/src/3rdparty/assimp/code/glTFImporter.h b/src/3rdparty/assimp/code/glTFImporter.h
deleted file mode 100644
index 46f450f86..000000000
--- a/src/3rdparty/assimp/code/glTFImporter.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 AI_GLTFIMPORTER_H_INC
-#define AI_GLTFIMPORTER_H_INC
-
-#include "BaseImporter.h"
-#include <assimp/DefaultIOSystem.h>
-
-struct aiNode;
-
-
-namespace glTF
-{
- class Asset;
-}
-
-namespace Assimp {
-
-/**
- * Load the glTF format.
- * https://github.com/KhronosGroup/glTF/tree/master/specification
- */
-class glTFImporter : public BaseImporter{
-public:
- glTFImporter();
- virtual ~glTFImporter();
- virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig ) const;
-
-protected:
- virtual const aiImporterDesc* GetInfo() const;
- virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler );
-
-private:
-
- std::vector<unsigned int> meshOffsets;
-
- std::vector<int> embeddedTexIdxs;
-
- aiScene* mScene;
-
- void ImportEmbeddedTextures(glTF::Asset& a);
- void ImportMaterials(glTF::Asset& a);
- void ImportMeshes(glTF::Asset& a);
- void ImportCameras(glTF::Asset& a);
- void ImportLights(glTF::Asset& a);
- void ImportNodes(glTF::Asset& a);
-
-};
-
-} // Namespace assimp
-
-#endif // AI_GLTFIMPORTER_H_INC
-
diff --git a/src/3rdparty/assimp/code/irrXMLWrapper.h b/src/3rdparty/assimp/code/irrXMLWrapper.h
deleted file mode 100644
index bbda7c0f0..000000000
--- a/src/3rdparty/assimp/code/irrXMLWrapper.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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_IRRXML_WRAPPER
-#define INCLUDED_AI_IRRXML_WRAPPER
-
-// some long includes ....
-#include <irrXML.h>
-#include "./../include/assimp/IOStream.hpp"
-#include "BaseImporter.h"
-#include <vector>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------------
-/** @brief Utility class to make IrrXML work together with our custom IO system
- * See the IrrXML docs for more details.
- *
- * Construct IrrXML-Reader in BaseImporter::InternReadFile():
- * @code
- * // open the file
- * std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
- * if( file.get() == NULL) {
- * throw DeadlyImportError( "Failed to open file " + pFile + ".");
- * }
- *
- * // generate a XML reader for it
- * std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
- * mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
- * if( !mReader) {
- * ThrowException( "xxxx: Unable to open file.");
- * }
- * @endcode
- **/
-class CIrrXML_IOStreamReader : public irr::io::IFileReadCallBack {
-public:
-
- // ----------------------------------------------------------------------------------
- //! Construction from an existing IOStream
- explicit CIrrXML_IOStreamReader(IOStream* _stream)
- : stream (_stream)
- , t (0)
- {
-
- // 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 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 = static_cast<unsigned int>(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);
- }
-
- // ----------------------------------------------------------------------------------
- //! Virtual destructor
- virtual ~CIrrXML_IOStreamReader() {}
-
- // ----------------------------------------------------------------------------------
- //! Reads an amount of bytes from the file.
- /** @param buffer: Pointer to output buffer.
- * @param sizeToRead: Amount of bytes to read
- * @return Returns how much bytes were read. */
- virtual int read(void* buffer, int sizeToRead) {
- if(sizeToRead<0) {
- return 0;
- }
- if(t+sizeToRead>data.size()) {
- sizeToRead = static_cast<int>(data.size()-t);
- }
-
- memcpy(buffer,&data.front()+t,sizeToRead);
-
- t += sizeToRead;
- return sizeToRead;
- }
-
- // ----------------------------------------------------------------------------------
- //! Returns size of file in bytes
- virtual int getSize() {
- return (int)data.size();
- }
-
-private:
- IOStream* stream;
- std::vector<char> data;
- size_t t;
-
-}; // ! class CIrrXML_IOStreamReader
-
-} // ! Assimp
-
-#endif // !! INCLUDED_AI_IRRXML_WRAPPER
diff --git a/src/3rdparty/assimp/code/qnan.h b/src/3rdparty/assimp/code/qnan.h
deleted file mode 100644
index fcff16b74..000000000
--- a/src/3rdparty/assimp/code/qnan.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 qnan.h
- * @brief Some utilities for our dealings with qnans.
- *
- * @note Some loaders use qnans to mark invalid values tempoarily, also
- * Assimp explicitly enforces undefined normals to be set to qnan.
- * qnan utilities are available in standard libraries (C99 for example)
- * but last time I checked compiler coverage was so bad that I decided
- * to reinvent the wheel.
- */
-
-#ifndef AI_QNAN_H_INCLUDED
-#define AI_QNAN_H_INCLUDED
-
-#include <assimp/defs.h>
-#include <limits>
-#include <stdint.h>
-
-// ---------------------------------------------------------------------------
-/** Data structure to represent the bit pattern of a 32 Bit
- * IEEE 754 floating-point number. */
-union _IEEESingle
-{
- float Float;
- struct
- {
- uint32_t Frac : 23;
- uint32_t Exp : 8;
- uint32_t Sign : 1;
- } IEEE;
-};
-
-// ---------------------------------------------------------------------------
-/** Data structure to represent the bit pattern of a 64 Bit
- * IEEE 754 floating-point number. */
-union _IEEEDouble
-{
- double Double;
- struct
- {
- uint64_t Frac : 52;
- uint64_t Exp : 11;
- uint64_t Sign : 1;
- } IEEE;
-};
-
-// ---------------------------------------------------------------------------
-/** Check whether a given float is qNaN.
- * @param in Input value */
-AI_FORCE_INLINE bool is_qnan(float in)
-{
- // the straightforward solution does not work:
- // return (in != in);
- // compiler generates code like this
- // load <in> to <register-with-different-width>
- // compare <register-with-different-width> against <in>
-
- // FIXME: Use <float> stuff instead? I think fpclassify needs C99
- return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1 &&
- reinterpret_cast<_IEEESingle*>(&in)->IEEE.Frac);
-}
-
-// ---------------------------------------------------------------------------
-/** Check whether a given double is qNaN.
- * @param in Input value */
-AI_FORCE_INLINE bool is_qnan(double in)
-{
- // the straightforward solution does not work:
- // return (in != in);
- // compiler generates code like this
- // load <in> to <register-with-different-width>
- // compare <register-with-different-width> against <in>
-
- // FIXME: Use <float> stuff instead? I think fpclassify needs C99
- return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1 &&
- reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Frac);
-}
-
-// ---------------------------------------------------------------------------
-/** @brief check whether a float is either NaN or (+/-) INF.
- *
- * Denorms return false, they're treated like normal values.
- * @param in Input value */
-AI_FORCE_INLINE bool is_special_float(float in)
-{
- return (reinterpret_cast<_IEEESingle*>(&in)->IEEE.Exp == (1u << 8)-1);
-}
-
-// ---------------------------------------------------------------------------
-/** @brief check whether a double is either NaN or (+/-) INF.
- *
- * Denorms return false, they're treated like normal values.
- * @param in Input value */
-AI_FORCE_INLINE bool is_special_float(double in)
-{
- return (reinterpret_cast<_IEEEDouble*>(&in)->IEEE.Exp == (1u << 11)-1);
-}
-
-// ---------------------------------------------------------------------------
-/** Check whether a float is NOT qNaN.
- * @param in Input value */
-template<class TReal>
-AI_FORCE_INLINE bool is_not_qnan(TReal in)
-{
- return !is_qnan(in);
-}
-
-// ---------------------------------------------------------------------------
-/** @brief Get a fresh qnan. */
-AI_FORCE_INLINE ai_real get_qnan()
-{
- return std::numeric_limits<ai_real>::quiet_NaN();
-}
-
-#endif // !! AI_QNAN_H_INCLUDED
diff --git a/src/3rdparty/assimp/code/res/assimp.rc b/src/3rdparty/assimp/code/res/assimp.rc
deleted file mode 100644
index 0fe98c05d..000000000
--- a/src/3rdparty/assimp/code/res/assimp.rc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Microsoft Visual C++ generated resource script.
-//
-#include "resource.h"
-#include "..\..\revision.h"
-
-#define APSTUDIO_READONLY_SYMBOLS
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 2 resource.
-//
-#define APSTUDIO_HIDDEN_SYMBOLS
-#include "windows.h"
-#undef APSTUDIO_HIDDEN_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-#undef APSTUDIO_READONLY_SYMBOLS
-
-/////////////////////////////////////////////////////////////////////////////
-// Deutsch (Deutschland) resources
-
-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU)
-#ifdef _WIN32
-LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
-#pragma code_page(1252)
-#endif //_WIN32
-
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// Version
-//
-
-VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,1,SVNRevision, 0
- PRODUCTVERSION 1,1,SVNRevision,0
- FILEFLAGSMASK 0x17L
-#ifdef _DEBUG
- FILEFLAGS 0x1L
-#else
- FILEFLAGS 0x0L
-#endif
- FILEOS 0x4L
- FILETYPE 0x7L
- FILESUBTYPE 0x0L
-BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040704b0"
- BEGIN
- VALUE "Comments", "Licensed under a 3-clause BSD license"
- VALUE "CompanyName", "assimp team"
- VALUE "FileDescription", "Open Asset Import Library"
- VALUE "FileVersion", 1,1,SVNRevision,0
- VALUE "InternalName", "assimp "
- VALUE "LegalCopyright", "Copyright (C) 2006-2010"
- VALUE "OriginalFilename", "assimpNN.dll"
- VALUE "ProductName", "Open Asset Import Library"
- VALUE "ProductVersion", 1,1,SVNRevision,0
- ,0
- END
- END
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x407, 1200
- END
-END
-
-#endif // Deutsch (Deutschland) resources
-/////////////////////////////////////////////////////////////////////////////
-
-
-#ifndef APSTUDIO_INVOKED
-/////////////////////////////////////////////////////////////////////////////
-//
-// Generated from the TEXTINCLUDE 3 resource.
-//
-
-/////////////////////////////////////////////////////////////////////////////
-#endif // not APSTUDIO_INVOKED
-
diff --git a/src/3rdparty/assimp/code/res/resource.h b/src/3rdparty/assimp/code/res/resource.h
deleted file mode 100644
index 37d39284f..000000000
--- a/src/3rdparty/assimp/code/res/resource.h
+++ /dev/null
@@ -1,14 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by assimp.rc
-
-// Nächste Standardwerte für neue Objekte
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE 101
-#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1001
-#define _APS_NEXT_SYMED_VALUE 101
-#endif
-#endif
diff --git a/src/3rdparty/assimp/code/scene.cpp b/src/3rdparty/assimp/code/scene.cpp
deleted file mode 100644
index 467a2895d..000000000
--- a/src/3rdparty/assimp/code/scene.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
----------------------------------------------------------------------------
-*/
-#include <assimp/scene.h>
-
-aiNode::aiNode()
-: mName("")
-, mParent(NULL)
-, mNumChildren(0)
-, mChildren(NULL)
-, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
- // empty
-}
-
-aiNode::aiNode(const std::string& name)
-: mName(name)
-, mParent(NULL)
-, mNumChildren(0)
-, mChildren(NULL)
-, mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
- // empty
-}
-
-/** Destructor */
-aiNode::~aiNode() {
- // delete all children recursively
- // to make sure we won't crash if the data is invalid ...
- if (mChildren && mNumChildren)
- {
- for (unsigned int a = 0; a < mNumChildren; a++)
- delete mChildren[a];
- }
- delete[] mChildren;
- delete[] mMeshes;
- delete mMetaData;
-}
-
-const aiNode *aiNode::FindNode(const char* name) const {
- if (nullptr == name) {
- return nullptr;
- }
- 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 nullptr;
-}
-
-aiNode *aiNode::FindNode(const char* name) {
- if (!::strcmp(mName.data, name))return this;
- for (unsigned int i = 0; i < mNumChildren; ++i)
- {
- aiNode* const p = mChildren[i]->FindNode(name);
- if (p) {
- return p;
- }
- }
- // there is definitely no sub-node with this name
- return nullptr;
-}
-
-void aiNode::addChildren(unsigned int numChildren, aiNode **children) {
- if (nullptr == children || 0 == numChildren) {
- return;
- }
-
- for (unsigned int i = 0; i < numChildren; i++) {
- aiNode *child = children[i];
- if (nullptr != child) {
- child->mParent = this;
- }
- }
-
- if (mNumChildren > 0) {
- aiNode **tmp = new aiNode*[mNumChildren];
- ::memcpy(tmp, mChildren, sizeof(aiNode*) * mNumChildren);
- delete[] mChildren;
- mChildren = new aiNode*[mNumChildren + numChildren];
- ::memcpy(mChildren, tmp, sizeof(aiNode*) * mNumChildren);
- ::memcpy(&mChildren[mNumChildren], children, sizeof(aiNode*)* numChildren);
- mNumChildren += numChildren;
- delete[] tmp;
- }
- else {
- mChildren = new aiNode*[numChildren];
- for (unsigned int i = 0; i < numChildren; i++) {
- mChildren[i] = children[i];
- }
- mNumChildren = numChildren;
- }
-}
diff --git a/src/3rdparty/assimp/include/assimp/config.h b/src/3rdparty/assimp/config.h
index f881c56b4..088a5d053 100644
--- a/src/3rdparty/assimp/include/assimp/config.h
+++ b/src/3rdparty/assimp/config.h
@@ -3,7 +3,8 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
-Copyright (c) 2006-2017, assimp team
+Copyright (c) 2006-2018, assimp team
+
All rights reserved.
@@ -55,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* #aiSetImportPropertyFloat,
* #aiSetImportPropertyString
*/
+#pragma once
#ifndef AI_CONFIG_H_INC
#define AI_CONFIG_H_INC
@@ -496,6 +498,13 @@ enum aiComponent
#define AI_CONFIG_PP_FID_ANIM_ACCURACY \
"PP_FID_ANIM_ACCURACY"
+// ---------------------------------------------------------------------------
+/** @brief Input parameter to the #aiProcess_FindInvalidData step:
+ * Set to true to ignore texture coordinates. This may be useful if you have
+ * to assign different kind of textures like one for the summer or one for the winter.
+ */
+#define AI_CONFIG_PP_FID_IGNORE_TEXTURECOORDS \
+ "PP_FID_IGNORE_TEXTURECOORDS"
// TransformUVCoords evaluates UV scalings
#define AI_UVTRAFO_SCALING 0x1
@@ -640,17 +649,30 @@ enum aiComponent
#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
"IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
-
-
// ---------------------------------------------------------------------------
-/** @brief Set whether the fbx importer will search for embedded loaded textures, where no embedded texture data is provided.
+/** @brief Set whether the fbx importer will use the legacy embedded texture naming.
*
* The default value is false (0)
* Property type: bool
*/
-#define AI_CONFIG_IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES \
- "IMPORT_FBX_SEARCH_EMBEDDED_TEXTURES"
-
+#define AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING \
+ "AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING"
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the importer shall not remove empty bones.
+ *
+ * Empty bone are often used to define connections for other models.
+ */
+#define AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES \
+ "AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Set wether the FBX importer shall convert the unit from cm to m.
+ */
+#define AI_CONFIG_FBX_CONVERT_TO_M \
+ "AI_CONFIG_FBX_CONVERT_TO_M"
+
// ---------------------------------------------------------------------------
/** @brief Set the vertex animation keyframe to be imported
*
@@ -673,6 +695,12 @@ enum aiComponent
#define AI_CONFIG_IMPORT_SMD_KEYFRAME "IMPORT_SMD_KEYFRAME"
#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME "IMPORT_UNREAL_KEYFRAME"
+// ---------------------------------------------------------------------------
+/** Smd load multiple animations
+ *
+ * Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_SMD_LOAD_ANIMATION_LIST "IMPORT_SMD_LOAD_ANIMATION_LIST"
// ---------------------------------------------------------------------------
/** @brief Configures the AC loader to collect all surfaces which have the
@@ -934,6 +962,16 @@ enum aiComponent
*/
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the Collada loader should use Collada names as node names.
+ *
+ * If this property is set to true, the Collada names will be used as the
+ * node name. The default is to use the id tag (resp. sid tag, if no id tag is present)
+ * instead.
+ * Property type: Bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES "IMPORT_COLLADA_USE_COLLADA_NAMES"
+
// ---------- All the Export defines ------------
/** @brief Specifies the xfile use double for real values of float
@@ -944,6 +982,11 @@ enum aiComponent
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
/**
+ *
+ */
+#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
+
+/**
* @brief Specifies a gobal key factor for scale, float value
*/
#define AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY "GLOBAL_SCALE_FACTOR"
@@ -952,6 +995,12 @@ enum aiComponent
# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
#endif // !! AI_DEBONE_THRESHOLD
+#define AI_CONFIG_APP_SCALE_KEY "APP_SCALE_FACTOR"
+
+#if (!defined AI_CONFIG_APP_SCALE_KEY)
+# define AI_CONFIG_APP_SCALE_KEY 1.0
+#endif // AI_CONFIG_APP_SCALE_KEY
+
// ---------- All the Build/Compile-time defines ------------
/** @brief Specifies if double precision is supported inside assimp
@@ -959,6 +1008,6 @@ enum aiComponent
* Property type: Bool. Default value: undefined.
*/
-//#cmakedefine ASSIMP_DOUBLE_PRECISION 1
+/* #undef ASSIMP_DOUBLE_PRECISION */
#endif // !! AI_CONFIG_H_INC
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcAdjacencyInfo.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcAdjacencyInfo.h
deleted file mode 100644
index 72fe3d4c6..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcAdjacencyInfo.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_ADJACENCY_INFO_H
-#define O3DGC_ADJACENCY_INFO_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- const long O3DGC_MIN_NEIGHBORS_SIZE = 128;
- const long O3DGC_MIN_NUM_NEIGHBORS_SIZE = 16;
- //!
- class AdjacencyInfo
- {
- public:
- //! Constructor.
- AdjacencyInfo(long numNeighborsSize = O3DGC_MIN_NUM_NEIGHBORS_SIZE,
- long neighborsSize = O3DGC_MIN_NUM_NEIGHBORS_SIZE)
- {
- m_numElements = 0;
- m_neighborsSize = neighborsSize;
- m_numNeighborsSize = numNeighborsSize;
- m_numNeighbors = new long [m_numNeighborsSize];
- m_neighbors = new long [m_neighborsSize ];
- };
- //! Destructor.
- ~AdjacencyInfo(void)
- {
- delete [] m_neighbors;
- delete [] m_numNeighbors;
- };
- O3DGCErrorCode Allocate(long numNeighborsSize, long neighborsSize)
- {
- m_numElements = numNeighborsSize;
- if (neighborsSize > m_neighborsSize)
- {
- delete [] m_numNeighbors;
- m_neighborsSize = neighborsSize;
- m_numNeighbors = new long [m_numNeighborsSize];
- }
- if (numNeighborsSize > m_numNeighborsSize)
- {
- delete [] m_neighbors;
- m_numNeighborsSize = numNeighborsSize;
- m_neighbors = new long [m_neighborsSize];
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode AllocateNumNeighborsArray(long numElements)
- {
- if (numElements > m_numNeighborsSize)
- {
- delete [] m_numNeighbors;
- m_numNeighborsSize = numElements;
- m_numNeighbors = new long [m_numNeighborsSize];
- }
- m_numElements = numElements;
- return O3DGC_OK;
- }
- O3DGCErrorCode AllocateNeighborsArray()
- {
- for(long i = 1; i < m_numElements; ++i)
- {
- m_numNeighbors[i] += m_numNeighbors[i-1];
- }
- if (m_numNeighbors[m_numElements-1] > m_neighborsSize)
- {
- delete [] m_neighbors;
- m_neighborsSize = m_numNeighbors[m_numElements-1];
- m_neighbors = new long [m_neighborsSize];
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode ClearNumNeighborsArray()
- {
- memset(m_numNeighbors, 0x00, sizeof(long) * m_numElements);
- return O3DGC_OK;
- }
- O3DGCErrorCode ClearNeighborsArray()
- {
- memset(m_neighbors, 0xFF, sizeof(long) * m_neighborsSize);
- return O3DGC_OK;
- }
- O3DGCErrorCode AddNeighbor(long element, long neighbor)
- {
- assert(m_numNeighbors[element] <= m_numNeighbors[m_numElements-1]);
- long p0 = Begin(element);
- long p1 = End(element);
- for(long p = p0; p < p1; p++)
- {
- if (m_neighbors[p] == -1)
- {
- m_neighbors[p] = neighbor;
- return O3DGC_OK;
- }
- }
- return O3DGC_ERROR_BUFFER_FULL;
- }
- long Begin(long element) const
- {
- assert(element < m_numElements);
- assert(element >= 0);
- return (element>0)?m_numNeighbors[element-1]:0;
- }
- long End(long element) const
- {
- assert(element < m_numElements);
- assert(element >= 0);
- return m_numNeighbors[element];
- }
- long GetNeighbor(long element) const
- {
- assert(element < m_neighborsSize);
- assert(element >= 0);
- return m_neighbors[element];
- }
- long GetNumNeighbors(long element) const
- {
- return End(element) - Begin(element);
- }
- long * GetNumNeighborsBuffer() { return m_numNeighbors;}
- long * GetNeighborsBuffer() { return m_neighbors;}
-
- private:
- long m_neighborsSize; // actual allocated size for m_neighbors
- long m_numNeighborsSize; // actual allocated size for m_numNeighbors
- long m_numElements; // number of elements
- long * m_neighbors; //
- long * m_numNeighbors; //
- };
-}
-#endif // O3DGC_ADJACENCY_INFO_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.cpp b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.cpp
deleted file mode 100644
index 3597ec39a..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.cpp
+++ /dev/null
@@ -1,865 +0,0 @@
-/*
-Copyright (c) 2004 Amir Said (said@ieee.org) & William A. Pearlman (pearlw@ecse.rpi.edu)
-All rights reserved.
-
-Redistribution and use 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.
-
-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 HOLDER 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.
-
-*/
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// **************************** -
-// ARITHMETIC CODING EXAMPLES -
-// **************************** -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// Fast arithmetic coding implementation -
-// -> 32-bit variables, 32-bit product, periodic updates, table decoding -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// Version 1.00 - April 25, 2004 -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// WARNING -
-// ========= -
-// -
-// The only purpose of this program is to demonstrate the basic principles -
-// of arithmetic coding. It is provided as is, without any express or -
-// implied warranty, without even the warranty of fitness for any particular -
-// purpose, or that the implementations are correct. -
-// -
-// Permission to copy and redistribute this code is hereby granted, provided -
-// that this warning and copyright notices are not removed or altered. -
-// -
-// Copyright (c) 2004 by Amir Said (said@ieee.org) & -
-// William A. Pearlman (pearlw@ecse.rpi.edu) -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// A description of the arithmetic coding method used here is available in -
-// -
-// Lossless Compression Handbook, ed. K. Sayood -
-// Chapter 5: Arithmetic Coding (A. Said), pp. 101-152, Academic Press, 2003 -
-// -
-// A. Said, Introduction to Arithetic Coding Theory and Practice -
-// HP Labs report HPL-2004-76 - http://www.hpl.hp.com/techreports/ -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-// - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-#include <stdlib.h>
-#include "o3dgcArithmeticCodec.h"
-
-namespace o3dgc
-{
- // - - Constants - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- const unsigned AC__MinLength = 0x01000000U; // threshold for renormalization
- const unsigned AC__MaxLength = 0xFFFFFFFFU; // maximum AC interval length
-
- // Maximum values for binary models
- const unsigned BM__LengthShift = 13; // length bits discarded before mult.
- const unsigned BM__MaxCount = 1 << BM__LengthShift; // for adaptive models
-
- // Maximum values for general models
- const unsigned DM__LengthShift = 15; // length bits discarded before mult.
- const unsigned DM__MaxCount = 1 << DM__LengthShift; // for adaptive models
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- static void AC_Error(const char * msg)
- {
- fprintf(stderr, "\n\n -> Arithmetic coding error: ");
- fputs(msg, stderr);
- fputs("\n Execution terminated!\n", stderr);
- getchar();
- exit(1);
- }
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Coding implementations - - - - - - - - - - - - - - - - - - - - - - - -
-
- inline void Arithmetic_Codec::propagate_carry(void)
- {
- unsigned char * p; // carry propagation on compressed data buffer
- for (p = ac_pointer - 1; *p == 0xFFU; p--) *p = 0;
- ++*p;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- inline void Arithmetic_Codec::renorm_enc_interval(void)
- {
- do { // output and discard top byte
- *ac_pointer++ = (unsigned char)(base >> 24);
- base <<= 8;
- } while ((length <<= 8) < AC__MinLength); // length multiplied by 256
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- inline void Arithmetic_Codec::renorm_dec_interval(void)
- {
- do { // read least-significant byte
- value = (value << 8) | unsigned(*++ac_pointer);
- } while ((length <<= 8) < AC__MinLength); // length multiplied by 256
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::put_bit(unsigned bit)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
-
- length >>= 1; // halve interval
- if (bit) {
- unsigned init_base = base;
- base += length; // move base
- if (init_base > base) propagate_carry(); // overflow = carry
- }
-
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::get_bit(void)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
-
- length >>= 1; // halve interval
- unsigned bit = (value >= length); // decode bit
- if (bit) value -= length; // move base
-
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- return bit; // return data bit value
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::put_bits(unsigned data, unsigned bits)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits");
- if (data >= (1U << bits)) AC_Error("invalid data");
- #endif
-
- unsigned init_base = base;
- base += data * (length >>= bits); // new interval base and length
-
- if (init_base > base) propagate_carry(); // overflow = carry
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::get_bits(unsigned bits)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- if ((bits < 1) || (bits > 20)) AC_Error("invalid number of bits");
- #endif
-
- unsigned s = value / (length >>= bits); // decode symbol, change length
-
- value -= length * s; // update interval
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- return s;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::encode(unsigned bit,
- Static_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
-
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- // update interval
- if (bit == 0)
- length = x;
- else {
- unsigned init_base = base;
- base += x;
- length -= x;
- if (init_base > base) propagate_carry(); // overflow = carry
- }
-
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::decode(Static_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
-
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- unsigned bit = (value >= x); // decision
- // update & shift interval
- if (bit == 0)
- length = x;
- else {
- value -= x; // shifted interval base = 0
- length -= x;
- }
-
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- return bit; // return data bit value
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::encode(unsigned bit,
- Adaptive_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- #endif
-
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- // update interval
- if (bit == 0) {
- length = x;
- ++M.bit_0_count;
- }
- else {
- unsigned init_base = base;
- base += x;
- length -= x;
- if (init_base > base) propagate_carry(); // overflow = carry
- }
-
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
-
- if (--M.bits_until_update == 0) M.update(); // periodic model update
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::decode(Adaptive_Bit_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
-
- unsigned x = M.bit_0_prob * (length >> BM__LengthShift); // product l x p0
- unsigned bit = (value >= x); // decision
- // update interval
- if (bit == 0) {
- length = x;
- ++M.bit_0_count;
- }
- else {
- value -= x;
- length -= x;
- }
-
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- if (--M.bits_until_update == 0) M.update(); // periodic model update
-
- return bit; // return data bit value
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::encode(unsigned data,
- Static_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if (data >= M.data_symbols) AC_Error("invalid data symbol");
- #endif
-
- unsigned x, init_base = base;
- // compute products
- if (data == M.last_symbol) {
- x = M.distribution[data] * (length >> DM__LengthShift);
- base += x; // update interval
- length -= x; // no product needed
- }
- else {
- x = M.distribution[data] * (length >>= DM__LengthShift);
- base += x; // update interval
- length = M.distribution[data+1] * length - x;
- }
-
- if (init_base > base) propagate_carry(); // overflow = carry
-
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::decode(Static_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
-
- unsigned n, s, x, y = length;
-
- if (M.decoder_table) { // use table look-up for faster decoding
-
- unsigned dv = value / (length >>= DM__LengthShift);
- unsigned t = dv >> M.table_shift;
-
- s = M.decoder_table[t]; // initial decision based on table look-up
- n = M.decoder_table[t+1] + 1;
-
- while (n > s + 1) { // finish with bisection search
- unsigned m = (s + n) >> 1;
- if (M.distribution[m] > dv) n = m; else s = m;
- }
- // compute products
- x = M.distribution[s] * length;
- if (s != M.last_symbol) y = M.distribution[s+1] * length;
- }
-
- else { // decode using only multiplications
-
- x = s = 0;
- length >>= DM__LengthShift;
- unsigned m = (n = M.data_symbols) >> 1;
- // decode via bisection search
- do {
- unsigned z = length * M.distribution[m];
- if (z > value) {
- n = m;
- y = z; // value is smaller
- }
- else {
- s = m;
- x = z; // value is larger or equal
- }
- } while ((m = (s + n) >> 1) != s);
- }
-
- value -= x; // update interval
- length = y - x;
-
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- return s;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::encode(unsigned data,
- Adaptive_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 1) AC_Error("encoder not initialized");
- if (data >= M.data_symbols)
- {
- AC_Error("invalid data symbol");
- }
- #endif
-
- unsigned x, init_base = base;
- // compute products
- if (data == M.last_symbol) {
- x = M.distribution[data] * (length >> DM__LengthShift);
- base += x; // update interval
- length -= x; // no product needed
- }
- else {
- x = M.distribution[data] * (length >>= DM__LengthShift);
- base += x; // update interval
- length = M.distribution[data+1] * length - x;
- }
-
- if (init_base > base) propagate_carry(); // overflow = carry
-
- if (length < AC__MinLength) renorm_enc_interval(); // renormalization
-
- ++M.symbol_count[data];
- if (--M.symbols_until_update == 0) M.update(true); // periodic model update
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::decode(Adaptive_Data_Model & M)
- {
- #ifdef _DEBUG
- if (mode != 2) AC_Error("decoder not initialized");
- #endif
-
- unsigned n, s, x, y = length;
-
- if (M.decoder_table) { // use table look-up for faster decoding
-
- unsigned dv = value / (length >>= DM__LengthShift);
- unsigned t = dv >> M.table_shift;
-
- s = M.decoder_table[t]; // initial decision based on table look-up
- n = M.decoder_table[t+1] + 1;
-
- while (n > s + 1) { // finish with bisection search
- unsigned m = (s + n) >> 1;
- if (M.distribution[m] > dv) n = m; else s = m;
- }
- // compute products
- x = M.distribution[s] * length;
- if (s != M.last_symbol) {
- y = M.distribution[s+1] * length;
- }
- }
-
- else { // decode using only multiplications
-
- x = s = 0;
- length >>= DM__LengthShift;
- unsigned m = (n = M.data_symbols) >> 1;
- // decode via bisection search
- do {
- unsigned z = length * M.distribution[m];
- if (z > value) {
- n = m;
- y = z; // value is smaller
- }
- else {
- s = m;
- x = z; // value is larger or equal
- }
- } while ((m = (s + n) >> 1) != s);
- }
-
- value -= x; // update interval
- length = y - x;
-
- if (length < AC__MinLength) renorm_dec_interval(); // renormalization
-
- ++M.symbol_count[s];
- if (--M.symbols_until_update == 0) M.update(false); // periodic model update
-
- return s;
- }
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Other Arithmetic_Codec implementations - - - - - - - - - - - - - - - -
-
- Arithmetic_Codec::Arithmetic_Codec(void)
- {
- mode = buffer_size = 0;
- new_buffer = code_buffer = 0;
- }
-
- Arithmetic_Codec::Arithmetic_Codec(unsigned max_code_bytes,
- unsigned char * user_buffer)
- {
- mode = buffer_size = 0;
- new_buffer = code_buffer = 0;
- set_buffer(max_code_bytes, user_buffer);
- }
-
- Arithmetic_Codec::~Arithmetic_Codec(void)
- {
- delete [] new_buffer;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::set_buffer(unsigned max_code_bytes,
- unsigned char * user_buffer)
- {
- // test for reasonable sizes
- if (!max_code_bytes)// || (max_code_bytes > 0x10000000U)) // updated by K. Mammou
- {
- AC_Error("invalid codec buffer size");
- }
- if (mode != 0) AC_Error("cannot set buffer while encoding or decoding");
-
- if (user_buffer != 0) { // user provides memory buffer
- buffer_size = max_code_bytes;
- code_buffer = user_buffer; // set buffer for compressed data
- delete [] new_buffer; // free anything previously assigned
- new_buffer = 0;
- return;
- }
-
- if (max_code_bytes <= buffer_size) return; // enough available
-
- buffer_size = max_code_bytes; // assign new memory
- delete [] new_buffer; // free anything previously assigned
- if ((new_buffer = new unsigned char[buffer_size+16]) == 0) // 16 extra bytes
- AC_Error("cannot assign memory for compressed data buffer");
- code_buffer = new_buffer; // set buffer for compressed data
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::start_encoder(void)
- {
- if (mode != 0) AC_Error("cannot start encoder");
- if (buffer_size == 0) AC_Error("no code buffer set");
-
- mode = 1;
- base = 0; // initialize encoder variables: interval and pointer
- length = AC__MaxLength;
- ac_pointer = code_buffer; // pointer to next data byte
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::start_decoder(void)
- {
- if (mode != 0) AC_Error("cannot start decoder");
- if (buffer_size == 0) AC_Error("no code buffer set");
-
- // initialize decoder: interval, pointer, initial code value
- mode = 2;
- length = AC__MaxLength;
- ac_pointer = code_buffer + 3;
- value = (unsigned(code_buffer[0]) << 24)|(unsigned(code_buffer[1]) << 16) |
- (unsigned(code_buffer[2]) << 8)| unsigned(code_buffer[3]);
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::read_from_file(FILE * code_file)
- {
- unsigned shift = 0, code_bytes = 0;
- int file_byte;
- // read variable-length header with number of code bytes
- do {
- if ((file_byte = getc(code_file)) == EOF)
- AC_Error("cannot read code from file");
- code_bytes |= unsigned(file_byte & 0x7F) << shift;
- shift += 7;
- } while (file_byte & 0x80);
- // read compressed data
- if (code_bytes > buffer_size) AC_Error("code buffer overflow");
- if (fread(code_buffer, 1, code_bytes, code_file) != code_bytes)
- AC_Error("cannot read code from file");
-
- start_decoder(); // initialize decoder
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::stop_encoder(void)
- {
- if (mode != 1) AC_Error("invalid to stop encoder");
- mode = 0;
-
- unsigned init_base = base; // done encoding: set final data bytes
-
- if (length > 2 * AC__MinLength) {
- base += AC__MinLength; // base offset
- length = AC__MinLength >> 1; // set new length for 1 more byte
- }
- else {
- base += AC__MinLength >> 1; // base offset
- length = AC__MinLength >> 9; // set new length for 2 more bytes
- }
-
- if (init_base > base) propagate_carry(); // overflow = carry
-
- renorm_enc_interval(); // renormalization = output last bytes
-
- unsigned code_bytes = unsigned(ac_pointer - code_buffer);
- if (code_bytes > buffer_size) AC_Error("code buffer overflow");
-
- return code_bytes; // number of bytes used
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- unsigned Arithmetic_Codec::write_to_file(FILE * code_file)
- {
- unsigned header_bytes = 0, code_bytes = stop_encoder(), nb = code_bytes;
-
- // write variable-length header with number of code bytes
- do {
- int file_byte = int(nb & 0x7FU);
- if ((nb >>= 7) > 0) file_byte |= 0x80;
- if (putc(file_byte, code_file) == EOF)
- AC_Error("cannot write compressed data to file");
- header_bytes++;
- } while (nb);
- // write compressed data
- if (fwrite(code_buffer, 1, code_bytes, code_file) != code_bytes)
- AC_Error("cannot write compressed data to file");
-
- return code_bytes + header_bytes; // bytes used
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Arithmetic_Codec::stop_decoder(void)
- {
- if (mode != 2) AC_Error("invalid to stop decoder");
- mode = 0;
- }
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - Static bit model implementation - - - - - - - - - - - - - - - - - - - - -
-
- Static_Bit_Model::Static_Bit_Model(void)
- {
- bit_0_prob = 1U << (BM__LengthShift - 1); // p0 = 0.5
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Static_Bit_Model::set_probability_0(double p0)
- {
- if ((p0 < 0.0001)||(p0 > 0.9999)) AC_Error("invalid bit probability");
- bit_0_prob = unsigned(p0 * (1 << BM__LengthShift));
- }
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - Adaptive bit model implementation - - - - - - - - - - - - - - - - - - - -
-
- Adaptive_Bit_Model::Adaptive_Bit_Model(void)
- {
- reset();
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Adaptive_Bit_Model::reset(void)
- {
- // initialization to equiprobable model
- bit_0_count = 1;
- bit_count = 2;
- bit_0_prob = 1U << (BM__LengthShift - 1);
- update_cycle = bits_until_update = 4; // start with frequent updates
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Adaptive_Bit_Model::update(void)
- {
- // halve counts when a threshold is reached
-
- if ((bit_count += update_cycle) > BM__MaxCount) {
- bit_count = (bit_count + 1) >> 1;
- bit_0_count = (bit_0_count + 1) >> 1;
- if (bit_0_count == bit_count) ++bit_count;
- }
- // compute scaled bit 0 probability
- unsigned scale = 0x80000000U / bit_count;
- bit_0_prob = (bit_0_count * scale) >> (31 - BM__LengthShift);
-
- // set frequency of model updates
- update_cycle = (5 * update_cycle) >> 2;
- if (update_cycle > 64) update_cycle = 64;
- bits_until_update = update_cycle;
- }
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Static data model implementation - - - - - - - - - - - - - - - - - - -
-
- Static_Data_Model::Static_Data_Model(void)
- {
- data_symbols = 0;
- distribution = 0;
- }
-
- Static_Data_Model::~Static_Data_Model(void)
- {
- delete [] distribution;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Static_Data_Model::set_distribution(unsigned number_of_symbols,
- const double probability[])
- {
- if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11)))
- AC_Error("invalid number of data symbols");
-
- if (data_symbols != number_of_symbols) { // assign memory for data model
- data_symbols = number_of_symbols;
- last_symbol = data_symbols - 1;
- delete [] distribution;
- // define size of table for fast decoding
- if (data_symbols > 16) {
- unsigned table_bits = 3;
- while (data_symbols > (1U << (table_bits + 2))) ++table_bits;
- table_size = 1 << table_bits;
- table_shift = DM__LengthShift - table_bits;
- distribution = new unsigned[data_symbols+table_size+2];
- decoder_table = distribution + data_symbols;
- }
- else { // small alphabet: no table needed
- decoder_table = 0;
- table_size = table_shift = 0;
- distribution = new unsigned[data_symbols];
- }
- if (distribution == 0) AC_Error("cannot assign model memory");
- }
- // compute cumulative distribution, decoder table
- unsigned s = 0;
- double sum = 0.0, p = 1.0 / double(data_symbols);
-
- for (unsigned k = 0; k < data_symbols; k++) {
- if (probability) p = probability[k];
- if ((p < 0.0001) || (p > 0.9999)) AC_Error("invalid symbol probability");
- distribution[k] = unsigned(sum * (1 << DM__LengthShift));
- sum += p;
- if (table_size == 0) continue;
- unsigned w = distribution[k] >> table_shift;
- while (s < w) decoder_table[++s] = k - 1;
- }
-
- if (table_size != 0) {
- decoder_table[0] = 0;
- while (s <= table_size) decoder_table[++s] = data_symbols - 1;
- }
-
- if ((sum < 0.9999) || (sum > 1.0001)) AC_Error("invalid probabilities");
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Adaptive data model implementation - - - - - - - - - - - - - - - - - -
-
- Adaptive_Data_Model::Adaptive_Data_Model(void)
- {
- data_symbols = 0;
- distribution = 0;
- }
-
- Adaptive_Data_Model::Adaptive_Data_Model(unsigned number_of_symbols)
- {
- data_symbols = 0;
- distribution = 0;
- set_alphabet(number_of_symbols);
- }
-
- Adaptive_Data_Model::~Adaptive_Data_Model(void)
- {
- delete [] distribution;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Adaptive_Data_Model::set_alphabet(unsigned number_of_symbols)
- {
- if ((number_of_symbols < 2) || (number_of_symbols > (1 << 11)))
- AC_Error("invalid number of data symbols");
-
- if (data_symbols != number_of_symbols) { // assign memory for data model
- data_symbols = number_of_symbols;
- last_symbol = data_symbols - 1;
- delete [] distribution;
- // define size of table for fast decoding
- if (data_symbols > 16) {
- unsigned table_bits = 3;
- while (data_symbols > (1U << (table_bits + 2))) ++table_bits;
- table_size = 1 << table_bits;
- table_shift = DM__LengthShift - table_bits;
- distribution = new unsigned[2*data_symbols+table_size+2];
- decoder_table = distribution + 2 * data_symbols;
- }
- else { // small alphabet: no table needed
- decoder_table = 0;
- table_size = table_shift = 0;
- distribution = new unsigned[2*data_symbols];
- }
- symbol_count = distribution + data_symbols;
- if (distribution == 0) AC_Error("cannot assign model memory");
- }
-
- reset(); // initialize model
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Adaptive_Data_Model::update(bool from_encoder)
- {
- // halve counts when a threshold is reached
-
- if ((total_count += update_cycle) > DM__MaxCount) {
- total_count = 0;
- for (unsigned n = 0; n < data_symbols; n++)
- total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1);
- }
- assert(total_count > 0);
- // compute cumulative distribution, decoder table
- unsigned k, sum = 0, s = 0;
- unsigned scale = 0x80000000U / total_count;
-
- if (from_encoder || (table_size == 0))
- for (k = 0; k < data_symbols; k++) {
- distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
- sum += symbol_count[k];
- }
- else {
- assert(decoder_table);
- for (k = 0; k < data_symbols; k++) {
- distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
- sum += symbol_count[k];
- unsigned w = distribution[k] >> table_shift;
- while (s < w) decoder_table[++s] = k - 1;
- }
- decoder_table[0] = 0;
- while (s <= table_size) decoder_table[++s] = data_symbols - 1;
- }
- // set frequency of model updates
- update_cycle = (5 * update_cycle) >> 2;
- unsigned max_cycle = (data_symbols + 6) << 3;
- if (update_cycle > max_cycle) update_cycle = max_cycle;
- symbols_until_update = update_cycle;
- }
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- void Adaptive_Data_Model::reset(void)
- {
- if (data_symbols == 0) return;
-
- // restore probability estimates to uniform distribution
- total_count = 0;
- update_cycle = data_symbols;
- for (unsigned k = 0; k < data_symbols; k++) symbol_count[k] = 1;
- update(false);
- symbols_until_update = update_cycle = (data_symbols + 6) >> 1;
- }
-}
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.h
deleted file mode 100644
index d3cf6d14a..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcArithmeticCodec.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
-Copyright (c) 2004 Amir Said (said@ieee.org) & William A. Pearlman (pearlw@ecse.rpi.edu)
-All rights reserved.
-
-Redistribution and use 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.
-
-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 HOLDER 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.
-*/
-
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// **************************** -
-// ARITHMETIC CODING EXAMPLES -
-// **************************** -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// Fast arithmetic coding implementation -
-// -> 32-bit variables, 32-bit product, periodic updates, table decoding -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// Version 1.00 - April 25, 2004 -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// WARNING -
-// ========= -
-// -
-// The only purpose of this program is to demonstrate the basic principles -
-// of arithmetic coding. It is provided as is, without any express or -
-// implied warranty, without even the warranty of fitness for any particular -
-// purpose, or that the implementations are correct. -
-// -
-// Permission to copy and redistribute this code is hereby granted, provided -
-// that this warning and copyright notices are not removed or altered. -
-// -
-// Copyright (c) 2004 by Amir Said (said@ieee.org) & -
-// William A. Pearlman (pearlw@ecse.rpi.edu) -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-// -
-// A description of the arithmetic coding method used here is available in -
-// -
-// Lossless Compression Handbook, ed. K. Sayood -
-// Chapter 5: Arithmetic Coding (A. Said), pp. 101-152, Academic Press, 2003 -
-// -
-// A. Said, Introduction to Arithetic Coding Theory and Practice -
-// HP Labs report HPL-2004-76 - http://www.hpl.hp.com/techreports/ -
-// -
-// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-// - - Definitions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-#ifndef O3DGC_ARITHMETIC_CODEC
-#define O3DGC_ARITHMETIC_CODEC
-
-#include <stdio.h>
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Class definitions - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- class Static_Bit_Model // static model for binary data
- {
- public:
-
- Static_Bit_Model(void);
-
- void set_probability_0(double); // set probability of symbol '0'
-
- private: // . . . . . . . . . . . . . . . . . . . . . .
- unsigned bit_0_prob;
- friend class Arithmetic_Codec;
- };
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- class Static_Data_Model // static model for general data
- {
- public:
-
- Static_Data_Model(void);
- ~Static_Data_Model(void);
-
- unsigned model_symbols(void) { return data_symbols; }
-
- void set_distribution(unsigned number_of_symbols,
- const double probability[] = 0); // 0 means uniform
-
- private: // . . . . . . . . . . . . . . . . . . . . . .
- unsigned * distribution, * decoder_table;
- unsigned data_symbols, last_symbol, table_size, table_shift;
- friend class Arithmetic_Codec;
- };
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- class Adaptive_Bit_Model // adaptive model for binary data
- {
- public:
-
- Adaptive_Bit_Model(void);
-
- void reset(void); // reset to equiprobable model
-
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void update(void);
- unsigned update_cycle, bits_until_update;
- unsigned bit_0_prob, bit_0_count, bit_count;
- friend class Arithmetic_Codec;
- };
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- class Adaptive_Data_Model // adaptive model for binary data
- {
- public:
-
- Adaptive_Data_Model(void);
- Adaptive_Data_Model(unsigned number_of_symbols);
- ~Adaptive_Data_Model(void);
-
- unsigned model_symbols(void) { return data_symbols; }
-
- void reset(void); // reset to equiprobable model
- void set_alphabet(unsigned number_of_symbols);
-
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void update(bool);
- unsigned * distribution, * symbol_count, * decoder_table;
- unsigned total_count, update_cycle, symbols_until_update;
- unsigned data_symbols, last_symbol, table_size, table_shift;
- friend class Arithmetic_Codec;
- };
-
-
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // - - Encoder and decoder class - - - - - - - - - - - - - - - - - - - - - - -
-
- // Class with both the arithmetic encoder and decoder. All compressed data is
- // saved to a memory buffer
-
- class Arithmetic_Codec
- {
- public:
-
- Arithmetic_Codec(void);
- ~Arithmetic_Codec(void);
- Arithmetic_Codec(unsigned max_code_bytes,
- unsigned char * user_buffer = 0); // 0 = assign new
-
- unsigned char * buffer(void) { return code_buffer; }
-
- void set_buffer(unsigned max_code_bytes,
- unsigned char * user_buffer = 0); // 0 = assign new
-
- void start_encoder(void);
- void start_decoder(void);
- void read_from_file(FILE * code_file); // read code data, start decoder
-
- unsigned stop_encoder(void); // returns number of bytes used
- unsigned write_to_file(FILE * code_file); // stop encoder, write code data
- void stop_decoder(void);
-
- void put_bit(unsigned bit);
- unsigned get_bit(void);
-
- void put_bits(unsigned data, unsigned number_of_bits);
- unsigned get_bits(unsigned number_of_bits);
-
- void encode(unsigned bit,
- Static_Bit_Model &);
- unsigned decode(Static_Bit_Model &);
-
- void encode(unsigned data,
- Static_Data_Model &);
- unsigned decode(Static_Data_Model &);
-
- void encode(unsigned bit,
- Adaptive_Bit_Model &);
- unsigned decode(Adaptive_Bit_Model &);
-
- void encode(unsigned data,
- Adaptive_Data_Model &);
- unsigned decode(Adaptive_Data_Model &);
-
-// This section was added by K. Mammou
- void ExpGolombEncode(unsigned int symbol,
- int k,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1)
- {
- while(1)
- {
- if (symbol >= (unsigned int)(1<<k))
- {
- encode(1, bModel1);
- symbol = symbol - (1<<k);
- k++;
- }
- else
- {
- encode(0, bModel1); // now terminated zero of unary part
- while (k--) // next binary part
- {
- encode((signed short)((symbol>>k)&1), bModel0);
- }
- break;
- }
- }
- }
-
-
- unsigned ExpGolombDecode(int k,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1)
- {
- unsigned int l;
- int symbol = 0;
- int binary_symbol = 0;
- do
- {
- l=decode(bModel1);
- if (l==1)
- {
- symbol += (1<<k);
- k++;
- }
- }
- while (l!=0);
- while (k--) //next binary part
- if (decode(bModel0)==1)
- {
- binary_symbol |= (1<<k);
- }
- return (unsigned int) (symbol+binary_symbol);
- }
-//----------------------------------------------------------
-
- private: // . . . . . . . . . . . . . . . . . . . . . .
- void propagate_carry(void);
- void renorm_enc_interval(void);
- void renorm_dec_interval(void);
- unsigned char * code_buffer, * new_buffer, * ac_pointer;
- unsigned base, value, length; // arithmetic coding state
- unsigned buffer_size, mode; // mode: 0 = undef, 1 = encoder, 2 = decoder
- };
- inline long DecodeIntACEGC(Arithmetic_Codec & acd,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long exp_k,
- const unsigned long M)
- {
- unsigned long uiValue = acd.decode(mModelValues);
- if (uiValue == M)
- {
- uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
- }
- return UIntToInt(uiValue);
- }
- inline unsigned long DecodeUIntACEGC(Arithmetic_Codec & acd,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long exp_k,
- const unsigned long M)
- {
- unsigned long uiValue = acd.decode(mModelValues);
- if (uiValue == M)
- {
- uiValue += acd.ExpGolombDecode(exp_k, bModel0, bModel1);
- }
- return uiValue;
- }
-
- inline void EncodeIntACEGC(long predResidual,
- Arithmetic_Codec & ace,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long M)
- {
- unsigned long uiValue = IntToUInt(predResidual);
- if (uiValue < M)
- {
- ace.encode(uiValue, mModelValues);
- }
- else
- {
- ace.encode(M, mModelValues);
- ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
- }
- }
- inline void EncodeUIntACEGC(long predResidual,
- Arithmetic_Codec & ace,
- Adaptive_Data_Model & mModelValues,
- Static_Bit_Model & bModel0,
- Adaptive_Bit_Model & bModel1,
- const unsigned long M)
- {
- unsigned long uiValue = (unsigned long) predResidual;
- if (uiValue < M)
- {
- ace.encode(uiValue, mModelValues);
- }
- else
- {
- ace.encode(M, mModelValues);
- ace.ExpGolombEncode(uiValue-M, 0, bModel0, bModel1);
- }
- }
-
-}
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-#endif
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcBinaryStream.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcBinaryStream.h
deleted file mode 100644
index b7b7678b7..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcBinaryStream.h
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_BINARY_STREAM_H
-#define O3DGC_BINARY_STREAM_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcVector.h"
-
-namespace o3dgc
-{
- const unsigned long O3DGC_BINARY_STREAM_DEFAULT_SIZE = 4096;
- const unsigned long O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0 = 7;
- const unsigned long O3DGC_BINARY_STREAM_MAX_SYMBOL0 = (1 << O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0) - 1;
- const unsigned long O3DGC_BINARY_STREAM_BITS_PER_SYMBOL1 = 6;
- const unsigned long O3DGC_BINARY_STREAM_MAX_SYMBOL1 = (1 << O3DGC_BINARY_STREAM_BITS_PER_SYMBOL1) - 1;
- const unsigned long O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32 = (32+O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0-1) /
- O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0;
-
- //!
- class BinaryStream
- {
- public:
- //! Constructor.
- BinaryStream(unsigned long size = O3DGC_BINARY_STREAM_DEFAULT_SIZE)
- {
- m_endianness = SystemEndianness();
- m_stream.Allocate(size);
- };
- //! Destructor.
- ~BinaryStream(void){};
-
- void WriteFloat32(float value, O3DGCStreamType streamType)
- {
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- WriteFloat32ASCII(value);
- }
- else
- {
- WriteFloat32Bin(value);
- }
- }
- void WriteUInt32(unsigned long position, unsigned long value, O3DGCStreamType streamType)
- {
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- WriteUInt32ASCII(position, value);
- }
- else
- {
- WriteUInt32Bin(position, value);
- }
- }
- void WriteUInt32(unsigned long value, O3DGCStreamType streamType)
- {
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- WriteUInt32ASCII(value);
- }
- else
- {
- WriteUInt32Bin(value);
- }
- }
- void WriteUChar(unsigned int position, unsigned char value, O3DGCStreamType streamType)
- {
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- WriteUInt32ASCII(position, value);
- }
- else
- {
- WriteUInt32Bin(position, value);
- }
- }
- void WriteUChar(unsigned char value, O3DGCStreamType streamType)
- {
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- WriteUCharASCII(value);
- }
- else
- {
- WriteUChar8Bin(value);
- }
- }
- float ReadFloat32(unsigned long & position, O3DGCStreamType streamType) const
- {
- float value;
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- value = ReadFloat32ASCII(position);
- }
- else
- {
- value = ReadFloat32Bin(position);
- }
- return value;
- }
- unsigned long ReadUInt32(unsigned long & position, O3DGCStreamType streamType) const
- {
- unsigned long value;
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- value = ReadUInt32ASCII(position);
- }
- else
- {
- value = ReadUInt32Bin(position);
- }
- return value;
- }
- unsigned char ReadUChar(unsigned long & position, O3DGCStreamType streamType) const
- {
- unsigned char value;
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- value = ReadUCharASCII(position);
- }
- else
- {
- value = ReadUChar8Bin(position);
- }
- return value;
- }
-
- void WriteFloat32Bin(unsigned long position, float value)
- {
- assert(position < m_stream.GetSize() - 4);
- unsigned char * ptr = (unsigned char *) (&value);
- if (m_endianness == O3DGC_BIG_ENDIAN)
- {
- m_stream[position++] = ptr[3];
- m_stream[position++] = ptr[2];
- m_stream[position++] = ptr[1];
- m_stream[position ] = ptr[0];
- }
- else
- {
- m_stream[position++] = ptr[0];
- m_stream[position++] = ptr[1];
- m_stream[position++] = ptr[2];
- m_stream[position ] = ptr[3];
- }
- }
- void WriteFloat32Bin(float value)
- {
- unsigned char * ptr = (unsigned char *) (&value);
- if (m_endianness == O3DGC_BIG_ENDIAN)
- {
- m_stream.PushBack(ptr[3]);
- m_stream.PushBack(ptr[2]);
- m_stream.PushBack(ptr[1]);
- m_stream.PushBack(ptr[0]);
- }
- else
- {
- m_stream.PushBack(ptr[0]);
- m_stream.PushBack(ptr[1]);
- m_stream.PushBack(ptr[2]);
- m_stream.PushBack(ptr[3]);
- }
- }
- void WriteUInt32Bin(unsigned long position, unsigned long value)
- {
- assert(position < m_stream.GetSize() - 4);
- unsigned char * ptr = (unsigned char *) (&value);
- if (m_endianness == O3DGC_BIG_ENDIAN)
- {
- m_stream[position++] = ptr[3];
- m_stream[position++] = ptr[2];
- m_stream[position++] = ptr[1];
- m_stream[position ] = ptr[0];
- }
- else
- {
- m_stream[position++] = ptr[0];
- m_stream[position++] = ptr[1];
- m_stream[position++] = ptr[2];
- m_stream[position ] = ptr[3];
- }
- }
- void WriteUInt32Bin(unsigned long value)
- {
- unsigned char * ptr = (unsigned char *) (&value);
- if (m_endianness == O3DGC_BIG_ENDIAN)
- {
- m_stream.PushBack(ptr[3]);
- m_stream.PushBack(ptr[2]);
- m_stream.PushBack(ptr[1]);
- m_stream.PushBack(ptr[0]);
- }
- else
- {
- m_stream.PushBack(ptr[0]);
- m_stream.PushBack(ptr[1]);
- m_stream.PushBack(ptr[2]);
- m_stream.PushBack(ptr[3]);
- }
- }
- void WriteUChar8Bin(unsigned int position, unsigned char value)
- {
- m_stream[position] = value;
- }
- void WriteUChar8Bin(unsigned char value)
- {
- m_stream.PushBack(value);
- }
- float ReadFloat32Bin(unsigned long & position) const
- {
- unsigned long value = ReadUInt32Bin(position);
- float fvalue;
- memcpy(&fvalue, &value, 4);
- return fvalue;
- }
- unsigned long ReadUInt32Bin(unsigned long & position) const
- {
- assert(position < m_stream.GetSize() - 4);
- unsigned long value = 0;
- if (m_endianness == O3DGC_BIG_ENDIAN)
- {
- value += (m_stream[position++]<<24);
- value += (m_stream[position++]<<16);
- value += (m_stream[position++]<<8);
- value += (m_stream[position++]);
- }
- else
- {
- value += (m_stream[position++]);
- value += (m_stream[position++]<<8);
- value += (m_stream[position++]<<16);
- value += (m_stream[position++]<<24);
- }
- return value;
- }
- unsigned char ReadUChar8Bin(unsigned long & position) const
- {
- return m_stream[position++];
- }
-
- void WriteFloat32ASCII(float value)
- {
- unsigned long uiValue;
- memcpy(&uiValue, &value, 4);
- WriteUInt32ASCII(uiValue);
- }
- void WriteUInt32ASCII(unsigned long position, unsigned long value)
- {
- assert(position < m_stream.GetSize() - O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32);
- unsigned long value0 = value;
- for(unsigned long i = 0; i < O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32; ++i)
- {
- m_stream[position++] = (value0 & O3DGC_BINARY_STREAM_MAX_SYMBOL0);
- value0 >>= O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0;
- }
- }
- void WriteUInt32ASCII(unsigned long value)
- {
- for(unsigned long i = 0; i < O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32; ++i)
- {
- m_stream.PushBack(value & O3DGC_BINARY_STREAM_MAX_SYMBOL0);
- value >>= O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0;
- }
- }
- void WriteIntASCII(long value)
- {
- WriteUIntASCII(IntToUInt(value));
- }
- void WriteUIntASCII(unsigned long value)
- {
- if (value >= O3DGC_BINARY_STREAM_MAX_SYMBOL0)
- {
- m_stream.PushBack(O3DGC_BINARY_STREAM_MAX_SYMBOL0);
- value -= O3DGC_BINARY_STREAM_MAX_SYMBOL0;
- unsigned char a, b;
- do
- {
- a = ((value & O3DGC_BINARY_STREAM_MAX_SYMBOL1) << 1);
- b = ( (value >>= O3DGC_BINARY_STREAM_BITS_PER_SYMBOL1) > 0);
- a += b;
- m_stream.PushBack(a);
- } while (b);
- }
- else
- {
- m_stream.PushBack((unsigned char) value);
- }
- }
- void WriteUCharASCII(unsigned char value)
- {
- assert(value <= O3DGC_BINARY_STREAM_MAX_SYMBOL0);
- m_stream.PushBack(value);
- }
- float ReadFloat32ASCII(unsigned long & position) const
- {
- unsigned long value = ReadUInt32ASCII(position);
- float fvalue;
- memcpy(&fvalue, &value, 4);
- return fvalue;
- }
- unsigned long ReadUInt32ASCII(unsigned long & position) const
- {
- assert(position < m_stream.GetSize() - O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32);
- unsigned long value = 0;
- unsigned long shift = 0;
- for(unsigned long i = 0; i < O3DGC_BINARY_STREAM_NUM_SYMBOLS_UINT32; ++i)
- {
- value += (m_stream[position++] << shift);
- shift += O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0;
- }
- return value;
- }
- long ReadIntASCII(unsigned long & position) const
- {
- return UIntToInt(ReadUIntASCII(position));
- }
- unsigned long ReadUIntASCII(unsigned long & position) const
- {
- unsigned long value = m_stream[position++];
- if (value == O3DGC_BINARY_STREAM_MAX_SYMBOL0)
- {
- long x;
- unsigned long i = 0;
- do
- {
- x = m_stream[position++];
- value += ( (x>>1) << i);
- i += O3DGC_BINARY_STREAM_BITS_PER_SYMBOL1;
- } while (x & 1);
- }
- return value;
- }
- unsigned char ReadUCharASCII(unsigned long & position) const
- {
- return m_stream[position++];
- }
- O3DGCErrorCode Save(const char * const fileName)
- {
- FILE * fout = fopen(fileName, "wb");
- if (!fout)
- {
- return O3DGC_ERROR_CREATE_FILE;
- }
- fwrite(m_stream.GetBuffer(), 1, m_stream.GetSize(), fout);
- fclose(fout);
- return O3DGC_OK;
- }
- O3DGCErrorCode Load(const char * const fileName)
- {
- FILE * fin = fopen(fileName, "rb");
- if (!fin)
- {
- return O3DGC_ERROR_OPEN_FILE;
- }
- fseek(fin, 0, SEEK_END);
- unsigned long size = ftell(fin);
- m_stream.Allocate(size);
- rewind(fin);
- unsigned int nread = (unsigned int) fread((void *) m_stream.GetBuffer(), 1, size, fin);
- m_stream.SetSize(size);
- if (nread != size)
- {
- return O3DGC_ERROR_READ_FILE;
- }
- fclose(fin);
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadFromBuffer(unsigned char * buffer, unsigned long bufferSize)
- {
- m_stream.Allocate(bufferSize);
- memcpy(m_stream.GetBuffer(), buffer, bufferSize);
- m_stream.SetSize(bufferSize);
- return O3DGC_OK;
- }
- unsigned long GetSize() const
- {
- return m_stream.GetSize();
- }
- const unsigned char * GetBuffer(unsigned long position) const
- {
- return m_stream.GetBuffer() + position;
- }
- unsigned char * GetBuffer(unsigned long position)
- {
- return (m_stream.GetBuffer() + position);
- }
- unsigned char * GetBuffer()
- {
- return m_stream.GetBuffer();
- }
- void GetBuffer(unsigned long position, unsigned char * & buffer) const
- {
- buffer = (unsigned char *) (m_stream.GetBuffer() + position); // fix me: ugly!
- }
- void SetSize(unsigned long size)
- {
- m_stream.SetSize(size);
- };
- void Allocate(unsigned long size)
- {
- m_stream.Allocate(size);
- }
-
- private:
- Vector<unsigned char> m_stream;
- O3DGCEndianness m_endianness;
- };
-
-}
-#endif // O3DGC_BINARY_STREAM_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcCommon.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcCommon.h
deleted file mode 100644
index ff6bf7558..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcCommon.h
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_COMMON_H
-#define O3DGC_COMMON_H
-
-#ifndef _CRT_SECURE_NO_WARNINGS
-#define _CRT_SECURE_NO_WARNINGS
-#endif
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <math.h>
-
-namespace o3dgc
-{
- typedef float Real;
- const double O3DGC_MAX_DOUBLE = 1.79769e+308;
- const long O3DGC_MIN_LONG = -2147483647;
- const long O3DGC_MAX_LONG = 2147483647;
- const long O3DGC_MAX_UCHAR8 = 255;
- const long O3DGC_MAX_TFAN_SIZE = 256;
- const unsigned long O3DGC_MAX_ULONG = 4294967295;
-
- const unsigned long O3DGC_SC3DMC_START_CODE = 0x00001F1;
- const unsigned long O3DGC_DV_START_CODE = 0x00001F2;
- const unsigned long O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES = 256;
- const unsigned long O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES = 256;
- const unsigned long O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES = 32;
-
- const unsigned long O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS = 2;
- const unsigned long O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS = 257;
-
- enum O3DGCEndianness
- {
- O3DGC_BIG_ENDIAN = 0,
- O3DGC_LITTLE_ENDIAN = 1
- };
- enum O3DGCErrorCode
- {
- O3DGC_OK,
- O3DGC_ERROR_BUFFER_FULL,
- O3DGC_ERROR_CREATE_FILE,
- O3DGC_ERROR_OPEN_FILE,
- O3DGC_ERROR_READ_FILE,
- O3DGC_ERROR_CORRUPTED_STREAM,
- O3DGC_ERROR_NON_SUPPORTED_FEATURE
- };
- enum O3DGCSC3DMCBinarization
- {
- O3DGC_SC3DMC_BINARIZATION_FL = 0, // Fixed Length (not supported)
- O3DGC_SC3DMC_BINARIZATION_BP = 1, // BPC (not supported)
- O3DGC_SC3DMC_BINARIZATION_FC = 2, // 4 bits Coding (not supported)
- O3DGC_SC3DMC_BINARIZATION_AC = 3, // Arithmetic Coding (not supported)
- O3DGC_SC3DMC_BINARIZATION_AC_EGC = 4, // Arithmetic Coding & EGCk
- O3DGC_SC3DMC_BINARIZATION_ASCII = 5 // Arithmetic Coding & EGCk
- };
- enum O3DGCStreamType
- {
- O3DGC_STREAM_TYPE_UNKOWN = 0,
- O3DGC_STREAM_TYPE_ASCII = 1,
- O3DGC_STREAM_TYPE_BINARY = 2
- };
- enum O3DGCSC3DMCQuantizationMode
- {
- O3DGC_SC3DMC_DIAG_BB = 0, // supported
- O3DGC_SC3DMC_MAX_ALL_DIMS = 1, // supported
- O3DGC_SC3DMC_MAX_SEP_DIM = 2 // supported
- };
- enum O3DGCSC3DMCPredictionMode
- {
- O3DGC_SC3DMC_NO_PREDICTION = 0, // supported
- O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION = 1, // supported
- O3DGC_SC3DMC_XOR_PREDICTION = 2, // not supported
- O3DGC_SC3DMC_ADAPTIVE_DIFFERENTIAL_PREDICTION = 3, // not supported
- O3DGC_SC3DMC_CIRCULAR_DIFFERENTIAL_PREDICTION = 4, // not supported
- O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION = 5, // supported
- O3DGC_SC3DMC_SURF_NORMALS_PREDICTION = 6 // supported
- };
- enum O3DGCSC3DMCEncodingMode
- {
- O3DGC_SC3DMC_ENCODE_MODE_QBCR = 0, // not supported
- O3DGC_SC3DMC_ENCODE_MODE_SVA = 1, // not supported
- O3DGC_SC3DMC_ENCODE_MODE_TFAN = 2, // supported
- };
- enum O3DGCDVEncodingMode
- {
- O3DGC_DYNAMIC_VECTOR_ENCODE_MODE_LIFT = 0
- };
- enum O3DGCIFSFloatAttributeType
- {
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_UNKOWN = 0,
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_POSITION = 1,
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_NORMAL = 2,
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_COLOR = 3,
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_TEXCOORD = 4,
- O3DGC_IFS_FLOAT_ATTRIBUTE_TYPE_WEIGHT = 5
-
- };
- enum O3DGCIFSIntAttributeType
- {
- O3DGC_IFS_INT_ATTRIBUTE_TYPE_UNKOWN = 0,
- O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX = 1,
- O3DGC_IFS_INT_ATTRIBUTE_TYPE_JOINT_ID = 2,
- O3DGC_IFS_INT_ATTRIBUTE_TYPE_INDEX_BUFFER_ID = 3
- };
-
- template<class T>
- inline const T absolute(const T& a)
- {
- return (a < (T)(0)) ? -a : a;
- }
- template<class T>
- inline const T min(const T& a, const T& b)
- {
- return (b < a) ? b : a;
- }
- template<class T>
- inline const T max(const T& a, const T& b)
- {
- return (b > a) ? b : a;
- }
- template<class T>
- inline void swap(T& a, T& b)
- {
- T tmp = a;
- a = b;
- b = tmp;
- }
- inline double log2( double n )
- {
- return log(n) / log(2.0);
- }
-
- inline O3DGCEndianness SystemEndianness()
- {
- unsigned long num = 1;
- return ( *((char *)(&num)) == 1 )? O3DGC_LITTLE_ENDIAN : O3DGC_BIG_ENDIAN ;
- }
- class SC3DMCStats
- {
- public:
- SC3DMCStats(void)
- {
- memset(this, 0, sizeof(SC3DMCStats));
- };
- ~SC3DMCStats(void){};
-
- double m_timeCoord;
- double m_timeNormal;
- double m_timeCoordIndex;
- double m_timeFloatAttribute[O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- double m_timeIntAttribute [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES ];
- double m_timeReorder;
-
- unsigned long m_streamSizeCoord;
- unsigned long m_streamSizeNormal;
- unsigned long m_streamSizeCoordIndex;
- unsigned long m_streamSizeFloatAttribute[O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- unsigned long m_streamSizeIntAttribute [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES ];
-
- };
- typedef struct
- {
- long m_a;
- long m_b;
- long m_c;
- } SC3DMCTriplet;
-
- typedef struct
- {
- SC3DMCTriplet m_id;
- long m_pred[O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES];
- } SC3DMCPredictor;
-
- inline bool operator< (const SC3DMCTriplet& lhs, const SC3DMCTriplet& rhs)
- {
- if (lhs.m_c != rhs.m_c)
- {
- return (lhs.m_c < rhs.m_c);
- }
- else if (lhs.m_b != rhs.m_b)
- {
- return (lhs.m_b < rhs.m_b);
- }
- return (lhs.m_a < rhs.m_a);
- }
- inline bool operator== (const SC3DMCTriplet& lhs, const SC3DMCTriplet& rhs)
- {
- return (lhs.m_c == rhs.m_c && lhs.m_b == rhs.m_b && lhs.m_a == rhs.m_a);
- }
-
-
- // fix me: optimize this function (e.g., binary search)
- inline unsigned long Insert(SC3DMCTriplet e, unsigned long & nPred, SC3DMCPredictor * const list)
- {
- unsigned long pos = 0xFFFFFFFF;
- bool foundOrInserted = false;
- for (unsigned long j = 0; j < nPred; ++j)
- {
- if (e == list[j].m_id)
- {
- foundOrInserted = true;
- break;
- }
- else if (e < list[j].m_id)
- {
- if (nPred < O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS)
- {
- ++nPred;
- }
- for (unsigned long h = nPred-1; h > j; --h)
- {
- list[h] = list[h-1];
- }
- list[j].m_id = e;
- pos = j;
- foundOrInserted = true;
- break;
- }
- }
- if (!foundOrInserted && nPred < O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS)
- {
- pos = nPred;
- list[nPred++].m_id = e;
- }
- return pos;
- }
- template <class T>
- inline void SphereToCube(const T x, const T y, const T z,
- T & a, T & b, char & index)
- {
- T ax = absolute(x);
- T ay = absolute(y);
- T az = absolute(z);
- if (az >= ax && az >= ay)
- {
- if (z >= (T)(0))
- {
- index = 0;
- a = x;
- b = y;
- }
- else
- {
- index = 1;
- a = -x;
- b = -y;
- }
- }
- else if (ay >= ax && ay >= az)
- {
- if (y >= (T)(0))
- {
- index = 2;
- a = z;
- b = x;
- }
- else
- {
- index = 3;
- a = -z;
- b = -x;
- }
- }
- else if (ax >= ay && ax >= az)
- {
- if (x >= (T)(0))
- {
- index = 4;
- a = y;
- b = z;
- }
- else
- {
- index = 5;
- a = -y;
- b = -z;
- }
- }
- }
- inline void CubeToSphere(const Real a, const Real b, const char index,
- Real & x, Real & y, Real & z)
- {
- switch( index )
- {
- case 0:
- x = a;
- y = b;
- z = (Real) sqrt(max(0.0, 1.0 - x*x-y*y));
- break;
- case 1:
- x = -a;
- y = -b;
- z = -(Real) sqrt(max(0.0, 1.0 - x*x-y*y));
- break;
- case 2:
- z = a;
- x = b;
- y = (Real) sqrt(max(0.0, 1.0 - x*x-z*z));
- break;
- case 3:
- z = -a;
- x = -b;
- y = -(Real) sqrt(max(0.0, 1.0 - x*x-z*z));
- break;
- case 4:
- y = a;
- z = b;
- x = (Real) sqrt(max(0.0, 1.0 - y*y-z*z));
- break;
- case 5:
- y = -a;
- z = -b;
- x = -(Real) sqrt(max(0.0, 1.0 - y*y-z*z));
- break;
- }
- }
- inline unsigned long IntToUInt(long value)
- {
- return (value < 0)?(unsigned long) (-1 - (2 * value)):(unsigned long) (2 * value);
- }
- inline long UIntToInt(unsigned long uiValue)
- {
- return (uiValue & 1)?-((long) ((uiValue+1) >> 1)):((long) (uiValue >> 1));
- }
- inline void ComputeVectorMinMax(const Real * const tab,
- unsigned long size,
- unsigned long dim,
- unsigned long stride,
- Real * minTab,
- Real * maxTab,
- O3DGCSC3DMCQuantizationMode quantMode)
- {
- if (size == 0 || dim == 0)
- {
- return;
- }
- unsigned long p = 0;
- for(unsigned long d = 0; d < dim; ++d)
- {
- maxTab[d] = minTab[d] = tab[p++];
- }
- p = stride;
- for(unsigned long i = 1; i < size; ++i)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- if (maxTab[d] < tab[p+d]) maxTab[d] = tab[p+d];
- if (minTab[d] > tab[p+d]) minTab[d] = tab[p+d];
- }
- p += stride;
- }
-
- if (quantMode == O3DGC_SC3DMC_DIAG_BB)
- {
- Real diag = Real( 0.0 );
- Real r;
- for(unsigned long d = 0; d < dim; ++d)
- {
- r = (maxTab[d] - minTab[d]);
- diag += r*r;
- }
- diag = static_cast<Real>(sqrt(diag));
- for(unsigned long d = 0; d < dim; ++d)
- {
- maxTab[d] = minTab[d] + diag;
- }
- }
- else if (quantMode == O3DGC_SC3DMC_MAX_ALL_DIMS)
- {
- Real maxr = (maxTab[0] - minTab[0]);
- Real r;
- for(unsigned long d = 1; d < dim; ++d)
- {
- r = (maxTab[d] - minTab[d]);
- if ( r > maxr)
- {
- maxr = r;
- }
- }
- for(unsigned long d = 0; d < dim; ++d)
- {
- maxTab[d] = minTab[d] + maxr;
- }
- }
- }
-}
-#endif // O3DGC_COMMON_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDVEncodeParams.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDVEncodeParams.h
deleted file mode 100644
index 6f639f678..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDVEncodeParams.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_DV_ENCODE_PARAMS_H
-#define O3DGC_DV_ENCODE_PARAMS_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- class DVEncodeParams
- {
- public:
- //! Constructor.
- DVEncodeParams(void)
- {
- m_quantBits = 10;
- m_streamTypeMode = O3DGC_STREAM_TYPE_ASCII;
- m_encodeMode = O3DGC_DYNAMIC_VECTOR_ENCODE_MODE_LIFT;
- };
- //! Destructor.
- ~DVEncodeParams(void) {};
-
- unsigned long GetQuantBits() const { return m_quantBits;}
- O3DGCStreamType GetStreamType() const { return m_streamTypeMode;}
- O3DGCDVEncodingMode GetEncodeMode() const { return m_encodeMode;}
-
- void SetQuantBits (unsigned long quantBits ) { m_quantBits = quantBits;}
-
- void SetStreamType(O3DGCStreamType streamTypeMode) { m_streamTypeMode = streamTypeMode;}
- void SetEncodeMode(O3DGCDVEncodingMode encodeMode ) { m_encodeMode = encodeMode ;}
-
-
- private:
- unsigned long m_quantBits;
- O3DGCStreamType m_streamTypeMode;
- O3DGCDVEncodingMode m_encodeMode;
- };
-}
-#endif // O3DGC_DV_ENCODE_PARAMS_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVector.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVector.h
deleted file mode 100644
index aa7fb3142..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVector.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_DYNAMIC_VECTOR_SET_H
-#define O3DGC_DYNAMIC_VECTOR_SET_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- class DynamicVector
- {
- public:
- //! Constructor.
- DynamicVector(void)
- {
- m_num = 0;
- m_dim = 0;
- m_stride = 0;
- m_max = 0;
- m_min = 0;
- m_vectors = 0;
- };
- //! Destructor.
- ~DynamicVector(void) {};
-
- unsigned long GetNVector() const { return m_num;}
- unsigned long GetDimVector() const { return m_dim;}
- unsigned long GetStride() const { return m_stride;}
- const Real * GetMin() const { return m_min;}
- const Real * GetMax() const { return m_max;}
- const Real * GetVectors() const { return m_vectors;}
- Real * GetVectors() { return m_vectors;}
- Real GetMin(unsigned long j) const { return m_min[j];}
- Real GetMax(unsigned long j) const { return m_max[j];}
-
- void SetNVector (unsigned long num ) { m_num = num ;}
- void SetDimVector (unsigned long dim ) { m_dim = dim ;}
- void SetStride (unsigned long stride ) { m_stride = stride ;}
- void SetMin (Real * const min ) { m_min = min ;}
- void SetMax (Real * const max ) { m_max = max ;}
- void SetMin (unsigned long j, Real min) { m_min[j] = min ;}
- void SetMax (unsigned long j, Real max) { m_max[j] = max ;}
- void SetVectors (Real * const vectors) { m_vectors = vectors ;}
-
- void ComputeMinMax(O3DGCSC3DMCQuantizationMode quantMode)
- {
- assert( m_max && m_min && m_vectors && m_stride && m_dim && m_num);
- ComputeVectorMinMax(m_vectors, m_num , m_dim, m_stride, m_min , m_max , quantMode);
- }
-
- private:
- unsigned long m_num;
- unsigned long m_dim;
- unsigned long m_stride;
- Real * m_max;
- Real * m_min;
- Real * m_vectors;
- };
-
-}
-#endif // O3DGC_DYNAMIC_VECTOR_SET_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp
deleted file mode 100644
index b92452eb6..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-#include "o3dgcDynamicVectorDecoder.h"
-#include "o3dgcArithmeticCodec.h"
-
-
-//#define DEBUG_VERBOSE
-
-namespace o3dgc
-{
-#ifdef DEBUG_VERBOSE
- FILE * g_fileDebugDVCDec = NULL;
-#endif //DEBUG_VERBOSE
-
- O3DGCErrorCode IUpdate(long * const data, const long size)
- {
- assert(size > 1);
- const long size1 = size - 1;
- long p = 2;
- data[0] -= data[1] >> 1;
- while(p < size1)
- {
- data[p] -= (data[p-1] + data[p+1] + 2) >> 2;
- p += 2;
- }
- if ( p == size1)
- {
- data[p] -= data[p-1]>>1;
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode IPredict(long * const data, const long size)
- {
- assert(size > 1);
- const long size1 = size - 1;
- long p = 1;
- while(p < size1)
- {
- data[p] += (data[p-1] + data[p+1] + 1) >> 1;
- p += 2;
- }
- if ( p == size1)
- {
- data[p] += data[p-1];
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode Merge(long * const data, const long size)
- {
- assert(size > 1);
- const long h = (size >> 1) + (size & 1);
- long a = h-1;
- long b = h;
- while (a > 0)
- {
- for (long i = a; i < b; i += 2)
- {
- swap(data[i], data[i+1]);
- }
- --a;
- ++b;
- }
- return O3DGC_OK;
- }
- inline O3DGCErrorCode ITransform(long * const data, const unsigned long size)
- {
- unsigned long n = size;
- unsigned long even = 0;
- unsigned long k = 0;
- even += ((n&1) << k++);
- while(n > 1)
- {
- n = (n >> 1) + (n & 1);
- even += ((n&1) << k++);
- }
- for(long i = k-2; i >= 0; --i)
- {
- n = (n << 1) - ((even>>i) & 1);
- Merge (data, n);
- IUpdate (data, n);
- IPredict(data, n);
- }
- return O3DGC_OK;
- }
- DynamicVectorDecoder::DynamicVectorDecoder(void)
- {
- m_streamSize = 0;
- m_maxNumVectors = 0;
- m_numVectors = 0;
- m_dimVectors = 0;
- m_quantVectors = 0;
- m_iterator = 0;
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- }
- DynamicVectorDecoder::~DynamicVectorDecoder()
- {
- delete [] m_quantVectors;
- }
- O3DGCErrorCode DynamicVectorDecoder::DecodeHeader(DynamicVector & dynamicVector,
- const BinaryStream & bstream)
- {
- unsigned long iterator0 = m_iterator;
- unsigned long start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_BINARY);
- if (start_code != O3DGC_DV_START_CODE)
- {
- m_iterator = iterator0;
- start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_ASCII);
- if (start_code != O3DGC_DV_START_CODE)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- else
- {
- m_streamType = O3DGC_STREAM_TYPE_ASCII;
- }
- }
- else
- {
- m_streamType = O3DGC_STREAM_TYPE_BINARY;
- }
- m_streamSize = bstream.ReadUInt32(m_iterator, m_streamType);
- m_params.SetEncodeMode( (O3DGCDVEncodingMode) bstream.ReadUChar(m_iterator, m_streamType));
- dynamicVector.SetNVector ( bstream.ReadUInt32(m_iterator, m_streamType) );
-
- if (dynamicVector.GetNVector() > 0)
- {
- dynamicVector.SetDimVector( bstream.ReadUInt32(m_iterator, m_streamType) );
- m_params.SetQuantBits(bstream.ReadUChar(m_iterator, m_streamType));
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode DynamicVectorDecoder::DecodePlayload(DynamicVector & dynamicVector,
- const BinaryStream & bstream)
- {
- O3DGCErrorCode ret = O3DGC_OK;
-#ifdef DEBUG_VERBOSE
- g_fileDebugDVCDec = fopen("dv_dec.txt", "w");
-#endif //DEBUG_VERBOSE
- unsigned long start = m_iterator;
- unsigned long streamSize = bstream.ReadUInt32(m_iterator, m_streamType); // bitsream size
-
- const unsigned long dim = dynamicVector.GetDimVector();
- const unsigned long num = dynamicVector.GetNVector();
- const unsigned long size = dim * num;
- for(unsigned long j=0 ; j < dynamicVector.GetDimVector() ; ++j)
- {
- dynamicVector.SetMin(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- dynamicVector.SetMax(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- }
- Arithmetic_Codec acd;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- unsigned char * buffer = 0;
- streamSize -= (m_iterator - start);
- unsigned int exp_k = 0;
- unsigned int M = 0;
- if (m_streamType == O3DGC_STREAM_TYPE_BINARY)
- {
- bstream.GetBuffer(m_iterator, buffer);
- m_iterator += streamSize;
- acd.set_buffer(streamSize, buffer);
- acd.start_decoder();
- exp_k = acd.ExpGolombDecode(0, bModel0, bModel1);
- M = acd.ExpGolombDecode(0, bModel0, bModel1);
- }
- Adaptive_Data_Model mModelValues(M+2);
-
- if (m_maxNumVectors < size)
- {
- delete [] m_quantVectors;
- m_maxNumVectors = size;
- m_quantVectors = new long [size];
- }
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- m_quantVectors[d * num + v] = bstream.ReadIntASCII(m_iterator);
- }
- }
- }
- else
- {
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- m_quantVectors[d * num + v] = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- }
- }
- #ifdef DEBUG_VERBOSE
- printf("IntArray (%i, %i)\n", num, dim);
- fprintf(g_fileDebugDVCDec, "IntArray (%i, %i)\n", num, dim);
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- printf("%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
- fprintf(g_fileDebugDVCDec, "%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
- }
- }
- fflush(g_fileDebugDVCDec);
- #endif //DEBUG_VERBOSE
- for(unsigned long d = 0; d < dim; ++d)
- {
- ITransform(m_quantVectors + d * num, num);
- }
- IQuantize(dynamicVector.GetVectors(),
- num,
- dim,
- dynamicVector.GetStride(),
- dynamicVector.GetMin(),
- dynamicVector.GetMax(),
- m_params.GetQuantBits());
-
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugDVCDec);
-#endif //DEBUG_VERBOSE
- return ret;
- }
- O3DGCErrorCode DynamicVectorDecoder::IQuantize(Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits)
- {
- const unsigned long size = numFloatArray * dimFloatArray;
- Real r;
- if (m_maxNumVectors < size)
- {
- delete [] m_quantVectors;
- m_maxNumVectors = size;
- m_quantVectors = new long [m_maxNumVectors];
- }
- Real idelta;
- for(unsigned long d = 0; d < dimFloatArray; ++d)
- {
- r = maxFloatArray[d] - minFloatArray[d];
- if (r > 0.0f)
- {
- idelta = (float)(r) / ((1 << nQBits) - 1);
- }
- else
- {
- idelta = 1.0f;
- }
- for(unsigned long v = 0; v < numFloatArray; ++v)
- {
- floatArray[v * stride + d] = m_quantVectors[v + d * numFloatArray] * idelta + minFloatArray[d];
- }
- }
- return O3DGC_OK;
- }
-}
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.h
deleted file mode 100644
index 6e21b4fa3..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorDecoder.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_DYNAMIC_VECTOR_DECODER_H
-#define O3DGC_DYNAMIC_VECTOR_DECODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcDVEncodeParams.h"
-#include "o3dgcDynamicVector.h"
-
-namespace o3dgc
-{
- //!
- class DynamicVectorDecoder
- {
- public:
- //! Constructor.
- DynamicVectorDecoder(void);
- //! Destructor.
- ~DynamicVectorDecoder(void);
- //!
- //!
- O3DGCErrorCode DecodeHeader(DynamicVector & dynamicVector,
- const BinaryStream & bstream);
- //!
- O3DGCErrorCode DecodePlayload(DynamicVector & dynamicVector,
- const BinaryStream & bstream);
-
- O3DGCStreamType GetStreamType() const { return m_streamType; }
- void SetStreamType(O3DGCStreamType streamType) { m_streamType = streamType; }
- unsigned long GetIterator() const { return m_iterator;}
- O3DGCErrorCode SetIterator(unsigned long iterator) { m_iterator = iterator; return O3DGC_OK; }
-
- private:
- O3DGCErrorCode IQuantize(Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits);
-
- unsigned long m_streamSize;
- unsigned long m_maxNumVectors;
- unsigned long m_numVectors;
- unsigned long m_dimVectors;
- unsigned long m_iterator;
- long * m_quantVectors;
- DVEncodeParams m_params;
- O3DGCStreamType m_streamType;
- };
-}
-#endif // O3DGC_DYNAMIC_VECTOR_DECODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
deleted file mode 100644
index 00ae75e35..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-#include "o3dgcDVEncodeParams.h"
-#include "o3dgcDynamicVectorEncoder.h"
-#include "o3dgcArithmeticCodec.h"
-#include "o3dgcBinaryStream.h"
-
-//#define DEBUG_VERBOSE
-
-namespace o3dgc
-{
-#ifdef DEBUG_VERBOSE
- FILE * g_fileDebugDVEnc = NULL;
-#endif //DEBUG_VERBOSE
-
- inline O3DGCErrorCode Update(long * const data, const long size)
- {
- assert(size > 1);
- const long size1 = size - 1;
- long p = 2;
- data[0] += data[1] >> 1;
- while(p < size1)
- {
- data[p] += (data[p-1] + data[p+1] + 2) >> 2;
- p += 2;
- }
- if ( p == size1)
- {
- data[p] += data[p-1]>>1;
- }
- return O3DGC_OK;
- }
- inline O3DGCErrorCode Predict(long * const data, const long size)
- {
- assert(size > 1);
- const long size1 = size - 1;
- long p = 1;
- while(p < size1)
- {
- data[p] -= (data[p-1] + data[p+1] + 1) >> 1;
- p += 2;
- }
- if ( p == size1)
- {
- data[p] -= data[p-1];
- }
- return O3DGC_OK;
- }
- inline O3DGCErrorCode Split(long * const data, const long size)
- {
- assert(size > 1);
- long a = 1;
- long b = size-1;
- while (a < b)
- {
- for (long i = a; i < b; i += 2)
- {
- swap(data[i], data[i+1]);
- }
- ++a;
- --b;
- }
- return O3DGC_OK;
- }
- inline O3DGCErrorCode Transform(long * const data, const unsigned long size)
- {
- unsigned long n = size;
- while(n > 1)
- {
- Predict(data, n);
- Update (data, n);
- Split(data, n);
- n = (n >> 1) + (n & 1);
- }
- return O3DGC_OK;
- }
- DynamicVectorEncoder::DynamicVectorEncoder(void)
- {
- m_maxNumVectors = 0;
- m_numVectors = 0;
- m_dimVectors = 0;
- m_quantVectors = 0;
- m_sizeBufferAC = 0;
- m_bufferAC = 0;
- m_posSize = 0;
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- }
- DynamicVectorEncoder::~DynamicVectorEncoder()
- {
- delete [] m_quantVectors;
- delete [] m_bufferAC;
- }
- O3DGCErrorCode DynamicVectorEncoder::Encode(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream)
- {
- assert(params.GetQuantBits() > 0);
- assert(dynamicVector.GetNVector() > 0);
- assert(dynamicVector.GetDimVector() > 0);
- assert(dynamicVector.GetStride() >= dynamicVector.GetDimVector());
- assert(dynamicVector.GetVectors() && dynamicVector.GetMin() && dynamicVector.GetMax());
- assert(m_streamType != O3DGC_STREAM_TYPE_UNKOWN);
- // Encode header
- unsigned long start = bstream.GetSize();
- EncodeHeader(params, dynamicVector, bstream);
- // Encode payload
- EncodePayload(params, dynamicVector, bstream);
- bstream.WriteUInt32(m_posSize, bstream.GetSize() - start, m_streamType);
- return O3DGC_OK;
-
- }
- O3DGCErrorCode DynamicVectorEncoder::EncodeHeader(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream)
- {
- m_streamType = params.GetStreamType();
- bstream.WriteUInt32(O3DGC_DV_START_CODE, m_streamType);
- m_posSize = bstream.GetSize();
- bstream.WriteUInt32(0, m_streamType); // to be filled later
- bstream.WriteUChar((unsigned char) params.GetEncodeMode(), m_streamType);
- bstream.WriteUInt32(dynamicVector.GetNVector() , m_streamType);
- if (dynamicVector.GetNVector() > 0)
- {
- bstream.WriteUInt32(dynamicVector.GetDimVector(), m_streamType);
- bstream.WriteUChar ((unsigned char) params.GetQuantBits(), m_streamType);
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode DynamicVectorEncoder::EncodeAC(unsigned long num,
- unsigned long dim,
- unsigned long M,
- unsigned long & encodedBytes)
- {
- Arithmetic_Codec ace;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- Adaptive_Data_Model mModelValues(M+2);
- const unsigned int NMAX = num * dim * 8 + 100;
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- ace.ExpGolombEncode(0, 0, bModel0, bModel1);
- ace.ExpGolombEncode(M, 0, bModel0, bModel1);
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- EncodeIntACEGC(m_quantVectors[d * num + v], ace, mModelValues, bModel0, bModel1, M);
- }
- }
- encodedBytes = ace.stop_encoder();
- return O3DGC_OK;
- }
-
- O3DGCErrorCode DynamicVectorEncoder::EncodePayload(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream)
- {
-#ifdef DEBUG_VERBOSE
- g_fileDebugDVEnc = fopen("dv_enc.txt", "w");
-#endif //DEBUG_VERBOSE
- unsigned long start = bstream.GetSize();
- const unsigned long dim = dynamicVector.GetDimVector();
- const unsigned long num = dynamicVector.GetNVector();
-
- bstream.WriteUInt32(0, m_streamType);
-
- for(unsigned long j=0 ; j<dynamicVector.GetDimVector() ; ++j)
- {
- bstream.WriteFloat32((float) dynamicVector.GetMin(j), m_streamType);
- bstream.WriteFloat32((float) dynamicVector.GetMax(j), m_streamType);
- }
- Quantize(dynamicVector.GetVectors(),
- num,
- dim,
- dynamicVector.GetStride(),
- dynamicVector.GetMin(),
- dynamicVector.GetMax(),
- params.GetQuantBits());
- for(unsigned long d = 0; d < dim; ++d)
- {
- Transform(m_quantVectors + d * num, num);
- }
- #ifdef DEBUG_VERBOSE
- printf("IntArray (%i, %i)\n", num, dim);
- fprintf(g_fileDebugDVEnc, "IntArray (%i, %i)\n", num, dim);
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- printf("%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
- fprintf(g_fileDebugDVEnc, "%i\t %i \t %i\n", d * num + v, m_quantVectors[d * num + v], IntToUInt(m_quantVectors[d * num + v]));
- }
- }
- #endif //DEBUG_VERBOSE
-
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- for(unsigned long v = 0; v < num; ++v)
- {
- for(unsigned long d = 0; d < dim; ++d)
- {
- bstream.WriteIntASCII(m_quantVectors[d * num + v]);
- }
- }
- }
- else
- {
- unsigned long encodedBytes = 0;
- unsigned long bestEncodedBytes = O3DGC_MAX_ULONG;
- unsigned long M = 1;
- unsigned long bestM = 1;
- while (M < 1024)
- {
- EncodeAC(num, dim, M, encodedBytes);
- if (encodedBytes > bestEncodedBytes)
- {
- break;
- }
- bestM = M;
- bestEncodedBytes = encodedBytes;
- M *= 2;
- }
- EncodeAC(num, dim, bestM, encodedBytes);
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32(start, bstream.GetSize() - start, m_streamType);
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugDVEnc);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- O3DGCErrorCode DynamicVectorEncoder::Quantize(const Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits)
- {
- const unsigned long size = numFloatArray * dimFloatArray;
- Real r;
- if (m_maxNumVectors < size)
- {
- delete [] m_quantVectors;
- m_maxNumVectors = size;
- m_quantVectors = new long [m_maxNumVectors];
- }
- Real delta;
- for(unsigned long d = 0; d < dimFloatArray; ++d)
- {
- r = maxFloatArray[d] - minFloatArray[d];
- if (r > 0.0f)
- {
- delta = (float)((1 << nQBits) - 1) / r;
- }
- else
- {
- delta = 1.0f;
- }
- for(unsigned long v = 0; v < numFloatArray; ++v)
- {
- m_quantVectors[v + d * numFloatArray] = (long)((floatArray[v * stride + d]-minFloatArray[d]) * delta + 0.5f);
- }
- }
- return O3DGC_OK;
- }
-}
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.h
deleted file mode 100644
index de42a020f..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcDynamicVectorEncoder.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_DYNAMIC_VECTOR_ENCODER_H
-#define O3DGC_DYNAMIC_VECTOR_ENCODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcDynamicVector.h"
-
-namespace o3dgc
-{
- //!
- class DynamicVectorEncoder
- {
- public:
- //! Constructor.
- DynamicVectorEncoder(void);
- //! Destructor.
- ~DynamicVectorEncoder(void);
- //!
- O3DGCErrorCode Encode(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream);
- O3DGCStreamType GetStreamType() const { return m_streamType; }
- void SetStreamType(O3DGCStreamType streamType) { m_streamType = streamType; }
-
- private:
- O3DGCErrorCode EncodeHeader(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream);
- O3DGCErrorCode EncodePayload(const DVEncodeParams & params,
- const DynamicVector & dynamicVector,
- BinaryStream & bstream);
- O3DGCErrorCode Quantize(const Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits);
- O3DGCErrorCode EncodeAC(unsigned long num,
- unsigned long dim,
- unsigned long M,
- unsigned long & encodedBytes);
-
- unsigned long m_posSize;
- unsigned long m_sizeBufferAC;
- unsigned long m_maxNumVectors;
- unsigned long m_numVectors;
- unsigned long m_dimVectors;
- unsigned char * m_bufferAC;
- long * m_quantVectors;
- O3DGCStreamType m_streamType;
- };
-}
-#endif // O3DGC_DYNAMIC_VECTOR_ENCODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcFIFO.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcFIFO.h
deleted file mode 100644
index 4a5555f2a..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcFIFO.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_FIFO_H
-#define O3DGC_FIFO_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- //!
- template < typename T > class FIFO
- {
- public:
- //! Constructor.
- FIFO()
- {
- m_buffer = 0;
- m_allocated = 0;
- m_size = 0;
- m_start = 0;
- m_end = 0;
- };
- //! Destructor.
- ~FIFO(void)
- {
- delete [] m_buffer;
- };
- O3DGCErrorCode Allocate(unsigned long size)
- {
- assert(size > 0);
- if (size > m_allocated)
- {
- delete [] m_buffer;
- m_allocated = size;
- m_buffer = new T [m_allocated];
- }
- Clear();
- return O3DGC_OK;
- }
- const T & PopFirst()
- {
- assert(m_size > 0);
- --m_size;
- unsigned long current = m_start++;
- if (m_start == m_allocated)
- {
- m_end = 0;
- }
- return m_buffer[current];
- };
- void PushBack(const T & value)
- {
- assert( m_size < m_allocated);
- m_buffer[m_end] = value;
- ++m_size;
- ++m_end;
- if (m_end == m_allocated)
- {
- m_end = 0;
- }
- }
- unsigned long GetSize() const { return m_size;};
- unsigned long GetAllocatedSize() const { return m_allocated;};
- void Clear() { m_start = m_end = m_size = 0;};
-
- private:
- T * m_buffer;
- unsigned long m_allocated;
- unsigned long m_size;
- unsigned long m_start;
- unsigned long m_end;
- };
-}
-#endif // O3DGC_FIFO_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.h
deleted file mode 100644
index adb8cb001..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_INDEXED_FACE_SET_H
-#define O3DGC_INDEXED_FACE_SET_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- template<class T>
- class IndexedFaceSet
- {
- public:
- //! Constructor.
- IndexedFaceSet(void)
- {
- memset(this, 0, sizeof(IndexedFaceSet));
- m_ccw = true;
- m_solid = true;
- m_convex = true;
- m_isTriangularMesh = true;
- m_creaseAngle = 30;
- };
- //! Destructor.
- ~IndexedFaceSet(void) {};
-
- unsigned long GetNCoordIndex() const { return m_nCoordIndex ;}
- // only coordIndex is supported
- unsigned long GetNCoord() const { return m_nCoord ;}
- unsigned long GetNNormal() const { return m_nNormal ;}
- unsigned long GetNFloatAttribute(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_nFloatAttribute[a];
- }
- unsigned long GetNIntAttribute(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_nIntAttribute[a];
- }
- unsigned long GetNumFloatAttributes() const { return m_numFloatAttributes;}
- unsigned long GetNumIntAttributes() const { return m_numIntAttributes ;}
- const Real * GetCoordMin () const { return m_coordMin;}
- const Real * GetCoordMax () const { return m_coordMax;}
- const Real * GetNormalMin () const { return m_normalMin;}
- const Real * GetNormalMax () const { return m_normalMax;}
- Real GetCoordMin (int j) const { return m_coordMin[j] ;}
- Real GetCoordMax (int j) const { return m_coordMax[j] ;}
- Real GetNormalMin (int j) const { return m_normalMin[j] ;}
- Real GetNormalMax (int j) const { return m_normalMax[j] ;}
-
- O3DGCIFSFloatAttributeType GetFloatAttributeType(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_typeFloatAttribute[a];
- }
- O3DGCIFSIntAttributeType GetIntAttributeType(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_typeIntAttribute[a];
- }
- unsigned long GetFloatAttributeDim(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_dimFloatAttribute[a];
- }
- unsigned long GetIntAttributeDim(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_dimIntAttribute[a];
- }
- const Real * GetFloatAttributeMin(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return &(m_minFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES]);
- }
- const Real * GetFloatAttributeMax(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return &(m_maxFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES]);
- }
- Real GetFloatAttributeMin(unsigned long a, unsigned long dim) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- assert(dim < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- return m_minFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES + dim];
- }
- Real GetFloatAttributeMax(unsigned long a, unsigned long dim) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- assert(dim < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- return m_maxFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES + dim];
- }
- Real GetCreaseAngle() const { return m_creaseAngle ;}
- bool GetCCW() const { return m_ccw ;}
- bool GetSolid() const { return m_solid ;}
- bool GetConvex() const { return m_convex ;}
- bool GetIsTriangularMesh() const { return m_isTriangularMesh;}
- const unsigned long * GetIndexBufferID() const { return m_indexBufferID ;}
- const T * GetCoordIndex() const { return m_coordIndex;}
- T * GetCoordIndex() { return m_coordIndex;}
- Real * GetCoord() const { return m_coord ;}
- Real * GetNormal() const { return m_normal ;}
- Real * GetFloatAttribute(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_floatAttribute[a];
- }
- long * GetIntAttribute(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_intAttribute[a] ;
- }
- // only coordIndex is supported
- void SetNNormalIndex(unsigned long) {}
- void SetNTexCoordIndex(unsigned long) {}
- void SetNFloatAttributeIndex(int, unsigned long) {}
- void SetNIntAttributeIndex (int, unsigned long) {}
- // per triangle attributes not supported
- void SetNormalPerVertex(bool) {}
- void SetColorPerVertex(bool) {}
- void SetFloatAttributePerVertex(int, bool){}
- void SetIntAttributePerVertex (int, bool){}
- void SetNCoordIndex (unsigned long nCoordIndex) { m_nCoordIndex = nCoordIndex;}
- void SetNCoord (unsigned long nCoord) { m_nCoord = nCoord ;}
- void SetNNormal (unsigned long nNormal) { m_nNormal = nNormal ;}
- void SetNumFloatAttributes(unsigned long numFloatAttributes)
- {
- assert(numFloatAttributes < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_numFloatAttributes = numFloatAttributes;
- }
- void SetNumIntAttributes (unsigned long numIntAttributes)
- {
- assert(numIntAttributes < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_numIntAttributes = numIntAttributes;
- }
- void SetCreaseAngle (Real creaseAngle) { m_creaseAngle = creaseAngle ;}
- void SetCCW (bool ccw) { m_ccw = ccw ;}
- void SetSolid (bool solid) { m_solid = solid ;}
- void SetConvex (bool convex) { m_convex = convex ;}
- void SetIsTriangularMesh (bool isTriangularMesh) { m_isTriangularMesh = isTriangularMesh;}
- void SetCoordMin (int j, Real min) { m_coordMin[j] = min;}
- void SetCoordMax (int j, Real max) { m_coordMax[j] = max;}
- void SetNormalMin (int j, Real min) { m_normalMin[j] = min;}
- void SetNormalMax (int j, Real max) { m_normalMax[j] = max;}
- void SetNFloatAttribute(unsigned long a, unsigned long nFloatAttribute)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_nFloatAttribute[a] = nFloatAttribute;
- }
- void SetNIntAttribute(unsigned long a, unsigned long nIntAttribute)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_nIntAttribute[a] = nIntAttribute;
- }
- void SetFloatAttributeDim(unsigned long a, unsigned long d)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_dimFloatAttribute[a] = d;
- }
- void SetIntAttributeDim(unsigned long a, unsigned long d)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_dimIntAttribute[a] = d;
- }
- void SetFloatAttributeType(unsigned long a, O3DGCIFSFloatAttributeType t)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_typeFloatAttribute[a] = t;
- }
- void SetIntAttributeType(unsigned long a, O3DGCIFSIntAttributeType t)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_typeIntAttribute[a] = t;
- }
- void SetFloatAttributeMin(unsigned long a, unsigned long dim, Real min)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- assert(dim < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- m_minFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES + dim] = min;
- }
- void SetFloatAttributeMax(unsigned long a, unsigned long dim, Real max)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- assert(dim < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- m_maxFloatAttribute[a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES + dim] = max;
- }
- void SetIndexBufferID (unsigned long * const indexBufferID) { m_indexBufferID = indexBufferID;}
- void SetCoordIndex (T * const coordIndex) { m_coordIndex = coordIndex;}
- void SetCoord (Real * const coord ) { m_coord = coord ;}
- void SetNormal (Real * const normal ) { m_normal = normal ;}
- void SetFloatAttribute (unsigned long a, Real * const floatAttribute)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_floatAttribute[a] = floatAttribute;
- }
- void SetIntAttribute (unsigned long a, long * const intAttribute)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_intAttribute[a] = intAttribute ;
- }
- void ComputeMinMax(O3DGCSC3DMCQuantizationMode quantMode);
-
- private:
- // triangles list
- unsigned long m_nCoordIndex;
- T * m_coordIndex;
- unsigned long * m_indexBufferID;
- // coord, normals, texcoord and color
- unsigned long m_nCoord;
- unsigned long m_nNormal;
- Real m_coordMin [3];
- Real m_coordMax [3];
- Real m_normalMin [3];
- Real m_normalMax [3];
- Real * m_coord;
- Real * m_normal;
- // other attributes
- unsigned long m_numFloatAttributes;
- unsigned long m_numIntAttributes;
- O3DGCIFSFloatAttributeType m_typeFloatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- O3DGCIFSIntAttributeType m_typeIntAttribute [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES ];
- unsigned long m_nFloatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- unsigned long m_nIntAttribute [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES ];
- unsigned long m_dimFloatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- unsigned long m_dimIntAttribute [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES ];
- Real m_minFloatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES];
- Real m_maxFloatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES];
- Real * m_floatAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- long * m_intAttribute [O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- // mesh info
- Real m_creaseAngle;
- bool m_ccw;
- bool m_solid;
- bool m_convex;
- bool m_isTriangularMesh;
- };
-}
-#include "o3dgcIndexedFaceSet.inl" // template implementation
-#endif // O3DGC_INDEXED_FACE_SET_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.inl
deleted file mode 100644
index ddac26d76..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcIndexedFaceSet.inl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_INDEXED_FACE_SET_INL
-#define O3DGC_INDEXED_FACE_SET_INL
-
-#include <math.h>
-namespace o3dgc
-{
- template <class T>
- void IndexedFaceSet<T>::ComputeMinMax(O3DGCSC3DMCQuantizationMode quantMode)
- {
- ComputeVectorMinMax(m_coord , m_nCoord , 3, 3, m_coordMin , m_coordMax , quantMode);
- ComputeVectorMinMax(m_normal , m_nNormal , 3, 3, m_normalMin , m_normalMax , quantMode);
- unsigned long numFloatAttributes = GetNumFloatAttributes();
- for(unsigned long a = 0; a < numFloatAttributes; ++a)
- {
- ComputeVectorMinMax(m_floatAttribute[a],
- m_nFloatAttribute[a],
- m_dimFloatAttribute[a],
- m_dimFloatAttribute[a], // stride
- m_minFloatAttribute + (a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES),
- m_maxFloatAttribute + (a * O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES), quantMode);
- }
- }
-}
-#endif // O3DGC_INDEXED_FACE_SET_INL
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.h
deleted file mode 100644
index f3f1617c4..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_SC3DMC_DECODER_H
-#define O3DGC_SC3DMC_DECODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcIndexedFaceSet.h"
-#include "o3dgcSC3DMCEncodeParams.h"
-#include "o3dgcTriangleListDecoder.h"
-
-namespace o3dgc
-{
- //!
- template <class T>
- class SC3DMCDecoder
- {
- public:
- //! Constructor.
- SC3DMCDecoder(void)
- {
- m_iterator = 0;
- m_streamSize = 0;
- m_quantFloatArray = 0;
- m_quantFloatArraySize = 0;
- m_normals = 0;
- m_normalsSize = 0;
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- };
- //! Destructor.
- ~SC3DMCDecoder(void)
- {
- delete [] m_normals;
- delete [] m_quantFloatArray;
- }
- //!
- O3DGCErrorCode DecodeHeader(IndexedFaceSet<T> & ifs,
- const BinaryStream & bstream);
- //!
- O3DGCErrorCode DecodePayload(IndexedFaceSet<T> & ifs,
- const BinaryStream & bstream);
- const SC3DMCStats & GetStats() const { return m_stats;}
- unsigned long GetIterator() const { return m_iterator;}
- O3DGCErrorCode SetIterator(unsigned long iterator) { m_iterator = iterator; return O3DGC_OK; }
-
-
- private:
- O3DGCErrorCode DecodeFloatArray(Real * const floatArray,
- unsigned long numfloatArraySize,
- unsigned long dimfloatArraySize,
- unsigned long stride,
- const Real * const minfloatArray,
- const Real * const maxfloatArray,
- unsigned long nQBits,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode & predMode,
- const BinaryStream & bstream);
- O3DGCErrorCode IQuantizeFloatArray(Real * const floatArray,
- unsigned long numfloatArraySize,
- unsigned long dimfloatArraySize,
- unsigned long stride,
- const Real * const minfloatArray,
- const Real * const maxfloatArray,
- unsigned long nQBits);
- O3DGCErrorCode DecodeIntArray(long * const intArray,
- unsigned long numIntArraySize,
- unsigned long dimIntArraySize,
- unsigned long stride,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode & predMode,
- const BinaryStream & bstream);
- O3DGCErrorCode ProcessNormals(const IndexedFaceSet<T> & ifs);
-
- unsigned long m_iterator;
- unsigned long m_streamSize;
- SC3DMCEncodeParams m_params;
- TriangleListDecoder<T> m_triangleListDecoder;
- long * m_quantFloatArray;
- unsigned long m_quantFloatArraySize;
- Vector<char> m_orientation;
- Real * m_normals;
- unsigned long m_normalsSize;
- SC3DMCStats m_stats;
- O3DGCStreamType m_streamType;
- };
-}
-#include "o3dgcSC3DMCDecoder.inl" // template implementation
-#endif // O3DGC_SC3DMC_DECODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.inl
deleted file mode 100644
index aa6f24b73..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCDecoder.inl
+++ /dev/null
@@ -1,850 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_SC3DMC_DECODER_INL
-#define O3DGC_SC3DMC_DECODER_INL
-
-#include "o3dgcArithmeticCodec.h"
-#include "o3dgcTimer.h"
-
-//#define DEBUG_VERBOSE
-
-namespace o3dgc
-{
-#ifdef DEBUG_VERBOSE
- FILE * g_fileDebugSC3DMCDec = NULL;
-#endif //DEBUG_VERBOSE
-
- template<class T>
- O3DGCErrorCode SC3DMCDecoder<T>::DecodeHeader(IndexedFaceSet<T> & ifs,
- const BinaryStream & bstream)
- {
- unsigned long iterator0 = m_iterator;
- unsigned long start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_BINARY);
- if (start_code != O3DGC_SC3DMC_START_CODE)
- {
- m_iterator = iterator0;
- start_code = bstream.ReadUInt32(m_iterator, O3DGC_STREAM_TYPE_ASCII);
- if (start_code != O3DGC_SC3DMC_START_CODE)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- else
- {
- m_streamType = O3DGC_STREAM_TYPE_ASCII;
- }
- }
- else
- {
- m_streamType = O3DGC_STREAM_TYPE_BINARY;
- }
-
- m_streamSize = bstream.ReadUInt32(m_iterator, m_streamType);
- m_params.SetEncodeMode( (O3DGCSC3DMCEncodingMode) bstream.ReadUChar(m_iterator, m_streamType));
-
- ifs.SetCreaseAngle((Real) bstream.ReadFloat32(m_iterator, m_streamType));
-
- unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType);
-
- ifs.SetCCW ((mask & 1) == 1);
- ifs.SetSolid ((mask & 2) == 1);
- ifs.SetConvex ((mask & 4) == 1);
- ifs.SetIsTriangularMesh((mask & 8) == 1);
- //bool markerBit0 = (mask & 16 ) == 1;
- //bool markerBit1 = (mask & 32 ) == 1;
- //bool markerBit2 = (mask & 64 ) == 1;
- //bool markerBit3 = (mask & 128) == 1;
-
- ifs.SetNCoord (bstream.ReadUInt32(m_iterator, m_streamType));
- ifs.SetNNormal (bstream.ReadUInt32(m_iterator, m_streamType));
-
-
- ifs.SetNumFloatAttributes(bstream.ReadUInt32(m_iterator, m_streamType));
- ifs.SetNumIntAttributes (bstream.ReadUInt32(m_iterator, m_streamType));
-
- if (ifs.GetNCoord() > 0)
- {
- ifs.SetNCoordIndex(bstream.ReadUInt32(m_iterator, m_streamType));
- for(int j=0 ; j<3 ; ++j)
- {
- ifs.SetCoordMin(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- ifs.SetCoordMax(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- }
- m_params.SetCoordQuantBits( bstream.ReadUChar(m_iterator, m_streamType) );
- }
- if (ifs.GetNNormal() > 0)
- {
- ifs.SetNNormalIndex(bstream.ReadUInt32(m_iterator, m_streamType));
- for(int j=0 ; j<3 ; ++j)
- {
- ifs.SetNormalMin(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- ifs.SetNormalMax(j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- }
- ifs.SetNormalPerVertex(bstream.ReadUChar(m_iterator, m_streamType) == 1);
- m_params.SetNormalQuantBits(bstream.ReadUChar(m_iterator, m_streamType));
- }
-
- for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a)
- {
- ifs.SetNFloatAttribute(a, bstream.ReadUInt32(m_iterator, m_streamType));
- if (ifs.GetNFloatAttribute(a) > 0)
- {
- ifs.SetNFloatAttributeIndex(a, bstream.ReadUInt32(m_iterator, m_streamType));
- unsigned char d = bstream.ReadUChar(m_iterator, m_streamType);
- ifs.SetFloatAttributeDim(a, d);
- for(unsigned char j = 0 ; j < d ; ++j)
- {
- ifs.SetFloatAttributeMin(a, j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- ifs.SetFloatAttributeMax(a, j, (Real) bstream.ReadFloat32(m_iterator, m_streamType));
- }
- ifs.SetFloatAttributePerVertex(a, bstream.ReadUChar(m_iterator, m_streamType) == 1);
- ifs.SetFloatAttributeType(a, (O3DGCIFSFloatAttributeType) bstream.ReadUChar(m_iterator, m_streamType));
- m_params.SetFloatAttributeQuantBits(a, bstream.ReadUChar(m_iterator, m_streamType));
- }
- }
- for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a)
- {
- ifs.SetNIntAttribute(a, bstream.ReadUInt32(m_iterator, m_streamType));
- if (ifs.GetNIntAttribute(a) > 0)
- {
- ifs.SetNIntAttributeIndex(a, bstream.ReadUInt32(m_iterator, m_streamType));
- ifs.SetIntAttributeDim(a, bstream.ReadUChar(m_iterator, m_streamType));
- ifs.SetIntAttributePerVertex(a, bstream.ReadUChar(m_iterator, m_streamType) == 1);
- ifs.SetIntAttributeType(a, (O3DGCIFSIntAttributeType) bstream.ReadUChar(m_iterator, m_streamType));
- }
- }
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode SC3DMCDecoder<T>::DecodePayload(IndexedFaceSet<T> & ifs,
- const BinaryStream & bstream)
- {
- O3DGCErrorCode ret = O3DGC_OK;
-#ifdef DEBUG_VERBOSE
- g_fileDebugSC3DMCDec = fopen("tfans_dec_main.txt", "w");
-#endif //DEBUG_VERBOSE
-
- m_triangleListDecoder.SetStreamType(m_streamType);
- m_stats.m_streamSizeCoordIndex = m_iterator;
- Timer timer;
- timer.Tic();
- m_triangleListDecoder.Decode(ifs.GetCoordIndex(), ifs.GetNCoordIndex(), ifs.GetNCoord(), bstream, m_iterator);
- timer.Toc();
- m_stats.m_timeCoordIndex = timer.GetElapsedTime();
- m_stats.m_streamSizeCoordIndex = m_iterator - m_stats.m_streamSizeCoordIndex;
-
- // decode coord
- m_stats.m_streamSizeCoord = m_iterator;
- timer.Tic();
- if (ifs.GetNCoord() > 0)
- {
- ret = DecodeFloatArray(ifs.GetCoord(), ifs.GetNCoord(), 3, 3, ifs.GetCoordMin(), ifs.GetCoordMax(),
- m_params.GetCoordQuantBits(), ifs, m_params.GetCoordPredMode(), bstream);
- }
- if (ret != O3DGC_OK)
- {
- return ret;
- }
- timer.Toc();
- m_stats.m_timeCoord = timer.GetElapsedTime();
- m_stats.m_streamSizeCoord = m_iterator - m_stats.m_streamSizeCoord;
-
- // decode Normal
- m_stats.m_streamSizeNormal = m_iterator;
- timer.Tic();
- if (ifs.GetNNormal() > 0)
- {
- DecodeFloatArray(ifs.GetNormal(), ifs.GetNNormal(), 3, 3, ifs.GetNormalMin(), ifs.GetNormalMax(),
- m_params.GetNormalQuantBits(), ifs, m_params.GetNormalPredMode(), bstream);
- }
- if (ret != O3DGC_OK)
- {
- return ret;
- }
- timer.Toc();
- m_stats.m_timeNormal = timer.GetElapsedTime();
- m_stats.m_streamSizeNormal = m_iterator - m_stats.m_streamSizeNormal;
-
- // decode FloatAttributes
- for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a)
- {
- m_stats.m_streamSizeFloatAttribute[a] = m_iterator;
- timer.Tic();
- DecodeFloatArray(ifs.GetFloatAttribute(a), ifs.GetNFloatAttribute(a), ifs.GetFloatAttributeDim(a), ifs.GetFloatAttributeDim(a),
- ifs.GetFloatAttributeMin(a), ifs.GetFloatAttributeMax(a),
- m_params.GetFloatAttributeQuantBits(a), ifs, m_params.GetFloatAttributePredMode(a), bstream);
- timer.Toc();
- m_stats.m_timeFloatAttribute[a] = timer.GetElapsedTime();
- m_stats.m_streamSizeFloatAttribute[a] = m_iterator - m_stats.m_streamSizeFloatAttribute[a];
- }
- if (ret != O3DGC_OK)
- {
- return ret;
- }
-
- // decode IntAttributes
- for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a)
- {
- m_stats.m_streamSizeIntAttribute[a] = m_iterator;
- timer.Tic();
- DecodeIntArray(ifs.GetIntAttribute(a), ifs.GetNIntAttribute(a), ifs.GetIntAttributeDim(a), ifs.GetIntAttributeDim(a),
- ifs, m_params.GetIntAttributePredMode(a), bstream);
- timer.Toc();
- m_stats.m_timeIntAttribute[a] = timer.GetElapsedTime();
- m_stats.m_streamSizeIntAttribute[a] = m_iterator - m_stats.m_streamSizeIntAttribute[a];
- }
- if (ret != O3DGC_OK)
- {
- return ret;
- }
-
- timer.Tic();
- m_triangleListDecoder.Reorder();
- timer.Toc();
- m_stats.m_timeReorder = timer.GetElapsedTime();
-
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugSC3DMCDec);
-#endif //DEBUG_VERBOSE
- return ret;
- }
- template<class T>
- O3DGCErrorCode SC3DMCDecoder<T>::DecodeIntArray(long * const intArray,
- unsigned long numIntArray,
- unsigned long dimIntArray,
- unsigned long stride,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode & predMode,
- const BinaryStream & bstream)
- {
- assert(dimIntArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- long predResidual;
- SC3DMCPredictor m_neighbors [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS];
- Arithmetic_Codec acd;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1);
- unsigned long nPred;
-
- const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle();
- const T * const triangles = ifs.GetCoordIndex();
- const long nvert = (long) numIntArray;
- unsigned char * buffer = 0;
- unsigned long start = m_iterator;
- unsigned long streamSize = bstream.ReadUInt32(m_iterator, m_streamType); // bitsream size
- unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType);
- O3DGCSC3DMCBinarization binarization = (O3DGCSC3DMCBinarization)((mask >> 4) & 7);
- predMode = (O3DGCSC3DMCPredictionMode)(mask & 7);
- streamSize -= (m_iterator - start);
- unsigned long iteratorPred = m_iterator + streamSize;
- unsigned int exp_k = 0;
- unsigned int M = 0;
- if (m_streamType != O3DGC_STREAM_TYPE_ASCII)
- {
- if (binarization != O3DGC_SC3DMC_BINARIZATION_AC_EGC)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- bstream.GetBuffer(m_iterator, buffer);
- m_iterator += streamSize;
- acd.set_buffer(streamSize, buffer);
- acd.start_decoder();
- exp_k = acd.ExpGolombDecode(0, bModel0, bModel1);
- M = acd.ExpGolombDecode(0, bModel0, bModel1);
- }
- else
- {
- if (binarization != O3DGC_SC3DMC_BINARIZATION_ASCII)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- bstream.ReadUInt32(iteratorPred, m_streamType); // predictors bitsream size
- }
- Adaptive_Data_Model mModelValues(M+2);
-
-#ifdef DEBUG_VERBOSE
- printf("IntArray (%i, %i)\n", numIntArray, dimIntArray);
- fprintf(g_fileDebugSC3DMCDec, "IntArray (%i, %i)\n", numIntArray, dimIntArray);
-#endif //DEBUG_VERBOSE
-
- for (long v=0; v < nvert; ++v)
- {
- nPred = 0;
- if ( v2T.GetNumNeighbors(v) > 0 &&
- predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- if (ta < 0)
- {
- break;
- }
- for(long k = 0; k < 3; ++k)
- {
- long w = triangles[ta*3 + k];
- if ( w < v )
- {
- SC3DMCTriplet id = {-1, -1, w};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- m_neighbors[p].m_pred[i] = intArray[w*stride+i];
- }
- }
- }
- }
- }
- }
- if (nPred > 1)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t vm %i\n", v);
- fprintf(g_fileDebugSC3DMCDec, "\t\t vm %i\n", v);
- for (unsigned long p = 0; p < nPred; ++p)
- {
- printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- fprintf(g_fileDebugSC3DMCDec, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- for (unsigned long i = 0; i < dimIntArray; ++i)
- {
- printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- fprintf(g_fileDebugSC3DMCDec, "\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- }
- }
-#endif //DEBUG_VERBOSE
- unsigned long bestPred;
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bestPred = bstream.ReadUCharASCII(iteratorPred);
- }
- else
- {
- bestPred = acd.decode(mModelPreds);
- }
-#ifdef DEBUG_VERBOSE1
- printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
- fprintf(g_fileDebugSC3DMCDec, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
-#endif //DEBUG_VERBOSE
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- intArray[v*stride+i] = predResidual + m_neighbors[bestPred].m_pred[i];
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i \t [%i]\n", v*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i \t [%i]\n", v*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
-#endif //DEBUG_VERBOSE
- }
- }
- else if (v > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- intArray[v*stride+i] = predResidual + intArray[(v-1)*stride+i];
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", v*dimIntArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimIntArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- else
- {
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadUIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeUIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- intArray[v*stride+i] = predResidual;
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", v*dimIntArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimIntArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- }
- m_iterator = iteratorPred;
-#ifdef DEBUG_VERBOSE
- fflush(g_fileDebugSC3DMCDec);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode SC3DMCDecoder<T>::ProcessNormals(const IndexedFaceSet<T> & ifs)
- {
- const long nvert = (long) ifs.GetNNormal();
- const unsigned long normalSize = ifs.GetNNormal() * 2;
- if (m_normalsSize < normalSize)
- {
- delete [] m_normals;
- m_normalsSize = normalSize;
- m_normals = new Real [normalSize];
- }
- const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle();
- const T * const triangles = ifs.GetCoordIndex();
- Vec3<long> p1, p2, p3, n0, nt;
- long na0 = 0, nb0 = 0;
- Real rna0, rnb0, norm0;
- char ni0 = 0, ni1 = 0;
- long a, b, c;
- for (long v=0; v < nvert; ++v)
- {
- n0.X() = 0;
- n0.Y() = 0;
- n0.Z() = 0;
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- if (ta == -1)
- {
- break;
- }
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 1];
- c = triangles[ta*3 + 2];
- p1.X() = m_quantFloatArray[3*a];
- p1.Y() = m_quantFloatArray[3*a+1];
- p1.Z() = m_quantFloatArray[3*a+2];
- p2.X() = m_quantFloatArray[3*b];
- p2.Y() = m_quantFloatArray[3*b+1];
- p2.Z() = m_quantFloatArray[3*b+2];
- p3.X() = m_quantFloatArray[3*c];
- p3.Y() = m_quantFloatArray[3*c+1];
- p3.Z() = m_quantFloatArray[3*c+2];
- nt = (p2-p1)^(p3-p1);
- n0 += nt;
- }
- norm0 = (Real) n0.GetNorm();
- if (norm0 == 0.0)
- {
- norm0 = 1.0;
- }
- SphereToCube(n0.X(), n0.Y(), n0.Z(), na0, nb0, ni0);
-
-
- rna0 = na0 / norm0;
- rnb0 = nb0 / norm0;
- ni1 = ni0 + m_orientation[v];
- m_orientation[v] = ni1;
- if ( (ni1 >> 1) != (ni0 >> 1) )
- {
- rna0 = Real(0.0);
- rnb0 = Real(0.0);
- }
- m_normals[2*v] = rna0;
- m_normals[2*v+1] = rnb0;
-
-#ifdef DEBUG_VERBOSE1
- printf("n0 \t %i \t %i \t %i \t %i (%f, %f)\n", v, n0.X(), n0.Y(), n0.Z(), rna0, rnb0);
- fprintf(g_fileDebugSC3DMCDec, "n0 \t %i \t %i \t %i \t %i (%f, %f)\n", v, n0.X(), n0.Y(), n0.Z(), rna0, rnb0);
-#endif //DEBUG_VERBOSE
-
- }
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode SC3DMCDecoder<T>::DecodeFloatArray(Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode & predMode,
- const BinaryStream & bstream)
- {
- assert(dimFloatArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- long predResidual;
- SC3DMCPredictor m_neighbors [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS];
- Arithmetic_Codec acd;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1);
- unsigned long nPred;
-
- const AdjacencyInfo & v2T = m_triangleListDecoder.GetVertexToTriangle();
- const T * const triangles = ifs.GetCoordIndex();
- const long nvert = (long) numFloatArray;
- const unsigned long size = numFloatArray * dimFloatArray;
- unsigned char * buffer = 0;
- unsigned long start = m_iterator;
- unsigned long streamSize = bstream.ReadUInt32(m_iterator, m_streamType); // bitsream size
- unsigned char mask = bstream.ReadUChar(m_iterator, m_streamType);
- O3DGCSC3DMCBinarization binarization = (O3DGCSC3DMCBinarization)((mask >> 4) & 7);
- predMode = (O3DGCSC3DMCPredictionMode)(mask & 7);
- streamSize -= (m_iterator - start);
- unsigned long iteratorPred = m_iterator + streamSize;
- unsigned int exp_k = 0;
- unsigned int M = 0;
- if (m_streamType != O3DGC_STREAM_TYPE_ASCII)
- {
- if (binarization != O3DGC_SC3DMC_BINARIZATION_AC_EGC)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- bstream.GetBuffer(m_iterator, buffer);
- m_iterator += streamSize;
- acd.set_buffer(streamSize, buffer);
- acd.start_decoder();
- exp_k = acd.ExpGolombDecode(0, bModel0, bModel1);
- M = acd.ExpGolombDecode(0, bModel0, bModel1);
- }
- else
- {
- if (binarization != O3DGC_SC3DMC_BINARIZATION_ASCII)
- {
- return O3DGC_ERROR_CORRUPTED_STREAM;
- }
- bstream.ReadUInt32(iteratorPred, m_streamType); // predictors bitsream size
- }
- Adaptive_Data_Model mModelValues(M+2);
-
-
- if (predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION)
- {
- m_orientation.Allocate(size);
- m_orientation.Clear();
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- for(unsigned long i = 0; i < numFloatArray; ++i)
- {
- m_orientation.PushBack((unsigned char) bstream.ReadIntASCII(m_iterator));
- }
- }
- else
- {
- Adaptive_Data_Model dModel(12);
- for(unsigned long i = 0; i < numFloatArray; ++i)
- {
- m_orientation.PushBack((unsigned char) UIntToInt(acd.decode(dModel)));
- }
- }
- ProcessNormals(ifs);
- dimFloatArray = 2;
- }
-#ifdef DEBUG_VERBOSE
- printf("FloatArray (%i, %i)\n", numFloatArray, dimFloatArray);
- fprintf(g_fileDebugSC3DMCDec, "FloatArray (%i, %i)\n", numFloatArray, dimFloatArray);
-#endif //DEBUG_VERBOSE
-
- if (m_quantFloatArraySize < size)
- {
- delete [] m_quantFloatArray;
- m_quantFloatArraySize = size;
- m_quantFloatArray = new long [size];
- }
- for (long v=0; v < nvert; ++v)
- {
- nPred = 0;
- if ( v2T.GetNumNeighbors(v) > 0 &&
- predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- if (ta < 0)
- {
- break;
- }
- if (predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION)
- {
- long a,b;
- if ((long) triangles[ta*3] == v)
- {
- a = triangles[ta*3 + 1];
- b = triangles[ta*3 + 2];
- }
- else if ((long)triangles[ta*3 + 1] == v)
- {
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 2];
- }
- else
- {
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 1];
- }
- if ( a < v && b < v)
- {
- int u0 = v2T.Begin(a);
- int u1 = v2T.End(a);
- for (long u = u0; u < u1; u++)
- {
- long tb = v2T.GetNeighbor(u);
- if (tb < 0)
- {
- break;
- }
- long c = -1;
- bool foundB = false;
- for(long k = 0; k < 3; ++k)
- {
- long x = triangles[tb*3 + k];
- if (x == b)
- {
- foundB = true;
- }
- if (x < v && x != a && x != b)
- {
- c = x;
- }
- }
- if (c != -1 && foundB)
- {
- SC3DMCTriplet id = {min(a, b), max(a, b), -c-1};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- m_neighbors[p].m_pred[i] = m_quantFloatArray[a*stride+i] +
- m_quantFloatArray[b*stride+i] -
- m_quantFloatArray[c*stride+i];
- }
- }
- }
- }
- }
- }
- if ( predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION ||
- predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION ||
- predMode == O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION )
- {
- for(long k = 0; k < 3; ++k)
- {
- long w = triangles[ta*3 + k];
- if ( w < v )
- {
- SC3DMCTriplet id = {-1, -1, w};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- m_neighbors[p].m_pred[i] = m_quantFloatArray[w*stride+i];
- }
- }
- }
- }
- }
- }
- }
- if (nPred > 1)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t vm %i\n", v);
- fprintf(g_fileDebugSC3DMCDec, "\t\t vm %i\n", v);
- for (unsigned long p = 0; p < nPred; ++p)
- {
- printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- fprintf(g_fileDebugSC3DMCDec, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- for (unsigned long i = 0; i < dimFloatArray; ++i)
- {
- printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- fprintf(g_fileDebugSC3DMCDec, "\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- }
- }
-#endif //DEBUG_VERBOSE
- unsigned long bestPred;
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bestPred = bstream.ReadUCharASCII(iteratorPred);
- }
- else
- {
- bestPred = acd.decode(mModelPreds);
- }
-#ifdef DEBUG_VERBOSE1
- printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
- fprintf(g_fileDebugSC3DMCDec, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
-#endif //DEBUG_VERBOSE
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- m_quantFloatArray[v*stride+i] = predResidual + m_neighbors[bestPred].m_pred[i];
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i \t [%i]\n", v*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i \t [%i]\n", v*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
-#endif //DEBUG_VERBOSE
- }
- }
- else if (v > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- m_quantFloatArray[v*stride+i] = predResidual + m_quantFloatArray[(v-1)*stride+i];
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", v*dimFloatArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimFloatArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- else
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- predResidual = bstream.ReadUIntASCII(m_iterator);
- }
- else
- {
- predResidual = DecodeUIntACEGC(acd, mModelValues, bModel0, bModel1, exp_k, M);
- }
- m_quantFloatArray[v*stride+i] = predResidual;
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", v*dimFloatArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCDec, "%i \t %i\n", v*dimFloatArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- }
- m_iterator = iteratorPred;
- if (predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION)
- {
- const Real minNormal[2] = {(Real)(-2),(Real)(-2)};
- const Real maxNormal[2] = {(Real)(2),(Real)(2)};
- Real na1, nb1;
- Real na0, nb0;
- char ni1;
- IQuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minNormal, maxNormal, nQBits+1);
- for (long v=0; v < nvert; ++v)
- {
- na0 = m_normals[2*v];
- nb0 = m_normals[2*v+1];
- na1 = floatArray[stride*v] + na0;
- nb1 = floatArray[stride*v+1] + nb0;
- ni1 = m_orientation[v];
-
- CubeToSphere(na1, nb1, ni1,
- floatArray[stride*v],
- floatArray[stride*v+1],
- floatArray[stride*v+2]);
-
-#ifdef DEBUG_VERBOSE1
- printf("normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n",
- v,
- floatArray[stride*v],
- floatArray[stride*v+1],
- floatArray[stride*v+2],
- ni1, na1, nb1,
- na0, nb0);
- fprintf(g_fileDebugSC3DMCDec, "normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n",
- v,
- floatArray[stride*v],
- floatArray[stride*v+1],
- floatArray[stride*v+2],
- ni1, na1, nb1,
- na0, nb0);
-#endif //DEBUG_VERBOSE
- }
- }
- else
- {
- IQuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minFloatArray, maxFloatArray, nQBits);
- }
-#ifdef DEBUG_VERBOSE
- fflush(g_fileDebugSC3DMCDec);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode SC3DMCDecoder<T>::IQuantizeFloatArray(Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits)
- {
-
- Real idelta[O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES];
- Real r;
- for(unsigned long d = 0; d < dimFloatArray; d++)
- {
- r = maxFloatArray[d] - minFloatArray[d];
- if (r > 0.0f)
- {
- idelta[d] = r/(float)((1 << nQBits) - 1);
- }
- else
- {
- idelta[d] = 1.0f;
- }
- }
- for(unsigned long v = 0; v < numFloatArray; ++v)
- {
- for(unsigned long d = 0; d < dimFloatArray; ++d)
- {
-// floatArray[v * stride + d] = m_quantFloatArray[v * stride + d];
- floatArray[v * stride + d] = m_quantFloatArray[v * stride + d] * idelta[d] + minFloatArray[d];
- }
- }
- return O3DGC_OK;
- }
-}
-#endif // O3DGC_SC3DMC_DECODER_INL
-
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h
deleted file mode 100644
index 5f3db969c..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncodeParams.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_SC3DMC_ENCODE_PARAMS_H
-#define O3DGC_SC3DMC_ENCODE_PARAMS_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- class SC3DMCEncodeParams
- {
- public:
- //! Constructor.
- SC3DMCEncodeParams(void)
- {
- memset(this, 0, sizeof(SC3DMCEncodeParams));
- m_encodeMode = O3DGC_SC3DMC_ENCODE_MODE_TFAN;
- m_streamTypeMode = O3DGC_STREAM_TYPE_ASCII;
- m_coordQuantBits = 14;
- m_normalQuantBits = 8;
- m_coordPredMode = O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION;
- m_normalPredMode = O3DGC_SC3DMC_SURF_NORMALS_PREDICTION;
- for(unsigned long a = 0; a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES; ++a)
- {
- m_floatAttributePredMode[a] = O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION;
- }
- for(unsigned long a = 0; a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES; ++a)
- {
- m_intAttributePredMode[a] = O3DGC_SC3DMC_NO_PREDICTION;
- }
- };
- //! Destructor.
- ~SC3DMCEncodeParams(void) {};
-
- O3DGCStreamType GetStreamType() const { return m_streamTypeMode;}
- O3DGCSC3DMCEncodingMode GetEncodeMode() const { return m_encodeMode;}
-
- unsigned long GetNumFloatAttributes() const { return m_numFloatAttributes;}
- unsigned long GetNumIntAttributes() const { return m_numIntAttributes;}
- unsigned long GetCoordQuantBits() const { return m_coordQuantBits;}
- unsigned long GetNormalQuantBits() const { return m_normalQuantBits;}
- unsigned long GetFloatAttributeQuantBits(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_floatAttributeQuantBits[a];
- }
- O3DGCSC3DMCPredictionMode GetCoordPredMode() const { return m_coordPredMode; }
- O3DGCSC3DMCPredictionMode GetNormalPredMode() const { return m_normalPredMode; }
- O3DGCSC3DMCPredictionMode GetFloatAttributePredMode(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_floatAttributePredMode[a];
- }
- O3DGCSC3DMCPredictionMode GetIntAttributePredMode(unsigned long a) const
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_intAttributePredMode[a];
- }
- O3DGCSC3DMCPredictionMode & GetCoordPredMode() { return m_coordPredMode; }
- O3DGCSC3DMCPredictionMode & GetNormalPredMode() { return m_normalPredMode; }
- O3DGCSC3DMCPredictionMode & GetFloatAttributePredMode(unsigned long a)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- return m_floatAttributePredMode[a];
- }
- O3DGCSC3DMCPredictionMode & GetIntAttributePredMode(unsigned long a)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- return m_intAttributePredMode[a];
- }
- void SetStreamType(O3DGCStreamType streamTypeMode) { m_streamTypeMode = streamTypeMode;}
- void SetEncodeMode(O3DGCSC3DMCEncodingMode encodeMode) { m_encodeMode = encodeMode;}
- void SetNumFloatAttributes(unsigned long numFloatAttributes)
- {
- assert(numFloatAttributes < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_numFloatAttributes = numFloatAttributes;
- }
- void SetNumIntAttributes (unsigned long numIntAttributes)
- {
- assert(numIntAttributes < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_numIntAttributes = numIntAttributes;
- }
- void SetCoordQuantBits (unsigned int coordQuantBits ) { m_coordQuantBits = coordQuantBits ; }
- void SetNormalQuantBits (unsigned int normalQuantBits ) { m_normalQuantBits = normalQuantBits ; }
- void SetFloatAttributeQuantBits(unsigned long a, unsigned long q)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_floatAttributeQuantBits[a] = q;
- }
- void SetCoordPredMode (O3DGCSC3DMCPredictionMode coordPredMode ) { m_coordPredMode = coordPredMode ; }
- void SetNormalPredMode (O3DGCSC3DMCPredictionMode normalPredMode ) { m_normalPredMode = normalPredMode ; }
- void SetFloatAttributePredMode(unsigned long a, O3DGCSC3DMCPredictionMode p)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES);
- m_floatAttributePredMode[a] = p;
- }
- void SetIntAttributePredMode(unsigned long a, O3DGCSC3DMCPredictionMode p)
- {
- assert(a < O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES);
- m_intAttributePredMode[a] = p;
- }
- private:
- unsigned long m_numFloatAttributes;
- unsigned long m_numIntAttributes;
- unsigned long m_coordQuantBits;
- unsigned long m_normalQuantBits;
- unsigned long m_floatAttributeQuantBits[O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
-
- O3DGCSC3DMCPredictionMode m_coordPredMode;
- O3DGCSC3DMCPredictionMode m_normalPredMode;
- O3DGCSC3DMCPredictionMode m_floatAttributePredMode[O3DGC_SC3DMC_MAX_NUM_FLOAT_ATTRIBUTES];
- O3DGCSC3DMCPredictionMode m_intAttributePredMode [O3DGC_SC3DMC_MAX_NUM_INT_ATTRIBUTES];
- O3DGCStreamType m_streamTypeMode;
- O3DGCSC3DMCEncodingMode m_encodeMode;
- };
-}
-#endif // O3DGC_SC3DMC_ENCODE_PARAMS_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.h
deleted file mode 100644
index 9c4e95026..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_SC3DMC_ENCODER_H
-#define O3DGC_SC3DMC_ENCODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcIndexedFaceSet.h"
-#include "o3dgcSC3DMCEncodeParams.h"
-#include "o3dgcTriangleListEncoder.h"
-
-namespace o3dgc
-{
- //!
- template<class T>
- class SC3DMCEncoder
- {
- public:
- //! Constructor.
- SC3DMCEncoder(void)
- {
- m_posSize = 0;
- m_quantFloatArray = 0;
- m_quantFloatArraySize = 0;
- m_sizeBufferAC = 0;
- m_bufferAC = 0;
- m_normals = 0;
- m_normalsSize = 0;
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- };
- //! Destructor.
- ~SC3DMCEncoder(void)
- {
- delete [] m_normals;
- delete [] m_quantFloatArray;
- delete [] m_bufferAC;
- }
- //!
- O3DGCErrorCode Encode(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream);
- const SC3DMCStats & GetStats() const { return m_stats;}
-
- private:
- O3DGCErrorCode EncodeHeader(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream);
- O3DGCErrorCode EncodePayload(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream);
- O3DGCErrorCode EncodeFloatArray(const Real * const floatArray,
- unsigned long numfloatArray,
- unsigned long dimfloatArray,
- unsigned long stride,
- const Real * const minfloatArray,
- const Real * const maxfloatArray,
- unsigned long nQBits,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode predMode,
- BinaryStream & bstream);
- O3DGCErrorCode QuantizeFloatArray(const Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minfloatArray,
- const Real * const maxfloatArray,
- unsigned long nQBits);
- O3DGCErrorCode EncodeIntArray(const long * const intArray,
- unsigned long numIntArray,
- unsigned long dimIntArray,
- unsigned long stride,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode predMode,
- BinaryStream & bstream);
- O3DGCErrorCode ProcessNormals(const IndexedFaceSet<T> & ifs);
- TriangleListEncoder<T> m_triangleListEncoder;
- long * m_quantFloatArray;
- unsigned long m_posSize;
- unsigned long m_quantFloatArraySize;
- unsigned char * m_bufferAC;
- unsigned long m_sizeBufferAC;
- SC3DMCPredictor m_neighbors [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS];
- unsigned long m_freqSymbols[O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS];
- unsigned long m_freqPreds [O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS];
- Vector<long> m_predictors;
- Real * m_normals;
- unsigned long m_normalsSize;
- SC3DMCStats m_stats;
- O3DGCStreamType m_streamType;
- };
-}
-#include "o3dgcSC3DMCEncoder.inl" // template implementation
-#endif // O3DGC_SC3DMC_ENCODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.inl
deleted file mode 100644
index 2d30b05a2..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcSC3DMCEncoder.inl
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_SC3DMC_ENCODER_INL
-#define O3DGC_SC3DMC_ENCODER_INL
-
-
-#include "o3dgcArithmeticCodec.h"
-#include "o3dgcTimer.h"
-#include "o3dgcVector.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcCommon.h"
-
-//#define DEBUG_VERBOSE
-
-namespace o3dgc
-{
-#ifdef DEBUG_VERBOSE
- FILE * g_fileDebugSC3DMCEnc = NULL;
-#endif //DEBUG_VERBOSE
-
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::Encode(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream)
- {
- // Encode header
- unsigned long start = bstream.GetSize();
- EncodeHeader(params, ifs, bstream);
- // Encode payload
- EncodePayload(params, ifs, bstream);
- bstream.WriteUInt32(m_posSize, bstream.GetSize() - start, m_streamType);
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::EncodeHeader(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream)
- {
- m_streamType = params.GetStreamType();
- bstream.WriteUInt32(O3DGC_SC3DMC_START_CODE, m_streamType);
- m_posSize = bstream.GetSize();
- bstream.WriteUInt32(0, m_streamType); // to be filled later
-
- bstream.WriteUChar(O3DGC_SC3DMC_ENCODE_MODE_TFAN, m_streamType);
- bstream.WriteFloat32((float)ifs.GetCreaseAngle(), m_streamType);
-
- unsigned char mask = 0;
- bool markerBit0 = false;
- bool markerBit1 = false;
- bool markerBit2 = false;
- bool markerBit3 = false;
-
- mask += (ifs.GetCCW() );
- mask += (ifs.GetSolid() << 1);
- mask += (ifs.GetConvex() << 2);
- mask += (ifs.GetIsTriangularMesh() << 3);
- mask += (markerBit0 << 4);
- mask += (markerBit1 << 5);
- mask += (markerBit2 << 6);
- mask += (markerBit3 << 7);
-
- bstream.WriteUChar(mask, m_streamType);
-
- bstream.WriteUInt32(ifs.GetNCoord(), m_streamType);
- bstream.WriteUInt32(ifs.GetNNormal(), m_streamType);
- bstream.WriteUInt32(ifs.GetNumFloatAttributes(), m_streamType);
- bstream.WriteUInt32(ifs.GetNumIntAttributes(), m_streamType);
-
- if (ifs.GetNCoord() > 0)
- {
- bstream.WriteUInt32(ifs.GetNCoordIndex(), m_streamType);
- for(int j=0 ; j<3 ; ++j)
- {
- bstream.WriteFloat32((float) ifs.GetCoordMin(j), m_streamType);
- bstream.WriteFloat32((float) ifs.GetCoordMax(j), m_streamType);
- }
- bstream.WriteUChar((unsigned char) params.GetCoordQuantBits(), m_streamType);
- }
- if (ifs.GetNNormal() > 0)
- {
- bstream.WriteUInt32(0, m_streamType);
- for(int j=0 ; j<3 ; ++j)
- {
- bstream.WriteFloat32((float) ifs.GetNormalMin(j), m_streamType);
- bstream.WriteFloat32((float) ifs.GetNormalMax(j), m_streamType);
- }
- bstream.WriteUChar(true, m_streamType); //(unsigned char) ifs.GetNormalPerVertex()
- bstream.WriteUChar((unsigned char) params.GetNormalQuantBits(), m_streamType);
- }
- for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a)
- {
- bstream.WriteUInt32(ifs.GetNFloatAttribute(a), m_streamType);
- if (ifs.GetNFloatAttribute(a) > 0)
- {
- assert(ifs.GetFloatAttributeDim(a) < (unsigned long) O3DGC_MAX_UCHAR8);
- bstream.WriteUInt32(0, m_streamType);
- unsigned char d = (unsigned char) ifs.GetFloatAttributeDim(a);
- bstream.WriteUChar(d, m_streamType);
- for(unsigned char j = 0 ; j < d ; ++j)
- {
- bstream.WriteFloat32((float) ifs.GetFloatAttributeMin(a, j), m_streamType);
- bstream.WriteFloat32((float) ifs.GetFloatAttributeMax(a, j), m_streamType);
- }
- bstream.WriteUChar(true, m_streamType); //(unsigned char) ifs.GetFloatAttributePerVertex(a)
- bstream.WriteUChar((unsigned char) ifs.GetFloatAttributeType(a), m_streamType);
- bstream.WriteUChar((unsigned char) params.GetFloatAttributeQuantBits(a), m_streamType);
- }
- }
- for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a)
- {
- bstream.WriteUInt32(ifs.GetNIntAttribute(a), m_streamType);
- if (ifs.GetNIntAttribute(a) > 0)
- {
- assert(ifs.GetFloatAttributeDim(a) < (unsigned long) O3DGC_MAX_UCHAR8);
- bstream.WriteUInt32(0, m_streamType);
- bstream.WriteUChar((unsigned char) ifs.GetIntAttributeDim(a), m_streamType);
- bstream.WriteUChar(true, m_streamType); // (unsigned char) ifs.GetIntAttributePerVertex(a)
- bstream.WriteUChar((unsigned char) ifs.GetIntAttributeType(a), m_streamType);
- }
- }
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::QuantizeFloatArray(const Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits)
- {
- const unsigned long size = numFloatArray * dimFloatArray;
- Real delta[O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES];
- Real r;
- for(unsigned long d = 0; d < dimFloatArray; d++)
- {
- r = maxFloatArray[d] - minFloatArray[d];
- if (r > 0.0f)
- {
- delta[d] = (float)((1 << nQBits) - 1) / r;
- }
- else
- {
- delta[d] = 1.0f;
- }
- }
- if (m_quantFloatArraySize < size)
- {
- delete [] m_quantFloatArray;
- m_quantFloatArraySize = size;
- m_quantFloatArray = new long [size];
- }
- for(unsigned long v = 0; v < numFloatArray; ++v)
- {
- for(unsigned long d = 0; d < dimFloatArray; ++d)
- {
- m_quantFloatArray[v * stride + d] = (long)((floatArray[v * stride + d]-minFloatArray[d]) * delta[d] + 0.5f);
- }
- }
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::EncodeFloatArray(const Real * const floatArray,
- unsigned long numFloatArray,
- unsigned long dimFloatArray,
- unsigned long stride,
- const Real * const minFloatArray,
- const Real * const maxFloatArray,
- unsigned long nQBits,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode predMode,
- BinaryStream & bstream)
- {
- assert(dimFloatArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- long predResidual, v, uPredResidual;
- unsigned long nPred;
- Arithmetic_Codec ace;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
-
- const AdjacencyInfo & v2T = m_triangleListEncoder.GetVertexToTriangle();
- const long * const vmap = m_triangleListEncoder.GetVMap();
- const long * const invVMap = m_triangleListEncoder.GetInvVMap();
- const T * const triangles = ifs.GetCoordIndex();
- const long nvert = (long) numFloatArray;
- unsigned long start = bstream.GetSize();
- unsigned char mask = predMode & 7;
- const unsigned long M = O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS - 1;
- unsigned long nSymbols = O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS;
- unsigned long nPredictors = O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS;
-
-
- Adaptive_Data_Model mModelValues(M+2);
- Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1);
-
- memset(m_freqSymbols, 0, sizeof(unsigned long) * O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS);
- memset(m_freqPreds , 0, sizeof(unsigned long) * O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS);
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- mask += (O3DGC_SC3DMC_BINARIZATION_ASCII & 7)<<4;
- m_predictors.Allocate(nvert);
- m_predictors.Clear();
- }
- else
- {
- mask += (O3DGC_SC3DMC_BINARIZATION_AC_EGC & 7)<<4;
- const unsigned int NMAX = numFloatArray * dimFloatArray * 8 + 100;
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- ace.ExpGolombEncode(0, 0, bModel0, bModel1);
- ace.ExpGolombEncode(M, 0, bModel0, bModel1);
- }
- bstream.WriteUInt32(0, m_streamType);
- bstream.WriteUChar(mask, m_streamType);
-
-#ifdef DEBUG_VERBOSE
- printf("FloatArray (%i, %i)\n", numFloatArray, dimFloatArray);
- fprintf(g_fileDebugSC3DMCEnc, "FloatArray (%i, %i)\n", numFloatArray, dimFloatArray);
-#endif //DEBUG_VERBOSE
-
- if (predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION)
- {
- const Real minFloatArray[2] = {(Real)(-2.0),(Real)(-2.0)};
- const Real maxFloatArray[2] = {(Real)(2.0),(Real)(2.0)};
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- for(unsigned long i = 0; i < numFloatArray; ++i)
- {
- bstream.WriteIntASCII(m_predictors[i]);
- }
- }
- else
- {
- Adaptive_Data_Model dModel(12);
- for(unsigned long i = 0; i < numFloatArray; ++i)
- {
- ace.encode(IntToUInt(m_predictors[i]), dModel);
- }
- }
- QuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minFloatArray, maxFloatArray, nQBits+1);
- }
- else
- {
- QuantizeFloatArray(floatArray, numFloatArray, dimFloatArray, stride, minFloatArray, maxFloatArray, nQBits);
- }
-
- for (long vm=0; vm < nvert; ++vm)
- {
- nPred = 0;
- v = invVMap[vm];
- assert( v >= 0 && v < nvert);
- if ( v2T.GetNumNeighbors(v) > 0 &&
- predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- if ( predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION )
- {
- long a,b;
- if ((long) triangles[ta*3] == v)
- {
- a = triangles[ta*3 + 1];
- b = triangles[ta*3 + 2];
- }
- else if ((long) triangles[ta*3 + 1] == v)
- {
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 2];
- }
- else
- {
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 1];
- }
- if ( vmap[a] < vm && vmap[b] < vm)
- {
- int u0 = v2T.Begin(a);
- int u1 = v2T.End(a);
- for (long u = u0; u < u1; u++)
- {
- long tb = v2T.GetNeighbor(u);
- long c = -1;
- bool foundB = false;
- for(long k = 0; k < 3; ++k)
- {
- long x = triangles[tb*3 + k];
- if (x == b)
- {
- foundB = true;
- }
- if (vmap[x] < vm && x != a && x != b)
- {
- c = x;
- }
- }
- if (c != -1 && foundB)
- {
- SC3DMCTriplet id = {min(vmap[a], vmap[b]), max(vmap[a], vmap[b]), -vmap[c]-1};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- m_neighbors[p].m_pred[i] = m_quantFloatArray[a*stride+i] +
- m_quantFloatArray[b*stride+i] -
- m_quantFloatArray[c*stride+i];
- }
- }
- }
- }
- }
- }
- if ( predMode == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION ||
- predMode == O3DGC_SC3DMC_PARALLELOGRAM_PREDICTION ||
- predMode == O3DGC_SC3DMC_DIFFERENTIAL_PREDICTION )
- {
- for(long k = 0; k < 3; ++k)
- {
- long w = triangles[ta*3 + k];
- if ( vmap[w] < vm )
- {
- SC3DMCTriplet id = {-1, -1, vmap[w]};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- m_neighbors[p].m_pred[i] = m_quantFloatArray[w*stride+i];
- }
- }
- }
- }
- }
- }
- }
- if (nPred > 1)
- {
- // find best predictor
- unsigned long bestPred = 0xFFFFFFFF;
- double bestCost = O3DGC_MAX_DOUBLE;
- double cost;
-#ifdef DEBUG_VERBOSE1
- printf("\t\t vm %i\n", vm);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t vm %i\n", vm);
-#endif //DEBUG_VERBOSE
-
- for (unsigned long p = 0; p < nPred; ++p)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
-#endif //DEBUG_VERBOSE
- cost = -log2((m_freqPreds[p]+1.0) / nPredictors );
- for (unsigned long i = 0; i < dimFloatArray; ++i)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t\t %i\n", m_neighbors[p].m_pred[i]);
-#endif //DEBUG_VERBOSE
-
- predResidual = (long) IntToUInt(m_quantFloatArray[v*stride+i] - m_neighbors[p].m_pred[i]);
- if (predResidual < (long) M)
- {
- cost += -log2((m_freqSymbols[predResidual]+1.0) / nSymbols );
- }
- else
- {
- cost += -log2((m_freqSymbols[M] + 1.0) / nSymbols ) + log2((double) (predResidual-M));
- }
- }
- if (cost < bestCost)
- {
- bestCost = cost;
- bestPred = p;
- }
- }
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- m_predictors.PushBack((unsigned char) bestPred);
- }
- else
- {
- ace.encode(bestPred, mModelPreds);
- }
-#ifdef DEBUG_VERBOSE1
- printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
- fprintf(g_fileDebugSC3DMCEnc, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
-#endif //DEBUG_VERBOSE
- // use best predictor
- for (unsigned long i = 0; i < dimFloatArray; ++i)
- {
- predResidual = m_quantFloatArray[v*stride+i] - m_neighbors[bestPred].m_pred[i];
- uPredResidual = IntToUInt(predResidual);
- ++m_freqSymbols[(uPredResidual < (long) M)? uPredResidual : M];
-
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i \t [%i]\n", vm*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i \t [%i]\n", vm*dimFloatArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
-#endif //DEBUG_VERBOSE
-
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteIntASCII(predResidual);
- }
- else
- {
- EncodeIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
- }
- ++m_freqPreds[bestPred];
- nSymbols += dimFloatArray;
- ++nPredictors;
- }
- else if ( vm > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- long prev = invVMap[vm-1];
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- predResidual = m_quantFloatArray[v*stride+i] - m_quantFloatArray[prev*stride+i];
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteIntASCII(predResidual);
- }
- else
- {
- EncodeIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", vm*dimFloatArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i\n", vm*dimFloatArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- else
- {
- for (unsigned long i = 0; i < dimFloatArray; i++)
- {
- predResidual = m_quantFloatArray[v*stride+i];
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteUIntASCII(predResidual);
- }
- else
- {
- EncodeUIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", vm*dimFloatArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i\n", vm*dimFloatArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- }
- if (m_streamType != O3DGC_STREAM_TYPE_ASCII)
- {
- unsigned long encodedBytes = ace.stop_encoder();
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32(start, bstream.GetSize() - start, m_streamType);
-
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- unsigned long start = bstream.GetSize();
- bstream.WriteUInt32ASCII(0);
- const unsigned long size = m_predictors.GetSize();
- for(unsigned long i = 0; i < size; ++i)
- {
- bstream.WriteUCharASCII((unsigned char) m_predictors[i]);
- }
- bstream.WriteUInt32ASCII(start, bstream.GetSize() - start);
- }
-#ifdef DEBUG_VERBOSE
- fflush(g_fileDebugSC3DMCEnc);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
-
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::EncodeIntArray(const long * const intArray,
- unsigned long numIntArray,
- unsigned long dimIntArray,
- unsigned long stride,
- const IndexedFaceSet<T> & ifs,
- O3DGCSC3DMCPredictionMode predMode,
- BinaryStream & bstream)
- {
- assert(dimIntArray < O3DGC_SC3DMC_MAX_DIM_ATTRIBUTES);
- long predResidual, v, uPredResidual;
- unsigned long nPred;
- Arithmetic_Codec ace;
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
-
- const AdjacencyInfo & v2T = m_triangleListEncoder.GetVertexToTriangle();
- const long * const vmap = m_triangleListEncoder.GetVMap();
- const long * const invVMap = m_triangleListEncoder.GetInvVMap();
- const T * const triangles = ifs.GetCoordIndex();
- const long nvert = (long) numIntArray;
- unsigned long start = bstream.GetSize();
- unsigned char mask = predMode & 7;
- const unsigned long M = O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS - 1;
- unsigned long nSymbols = O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS;
- unsigned long nPredictors = O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS;
-
-
- Adaptive_Data_Model mModelValues(M+2);
- Adaptive_Data_Model mModelPreds(O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS+1);
-
- memset(m_freqSymbols, 0, sizeof(unsigned long) * O3DGC_SC3DMC_MAX_PREDICTION_SYMBOLS);
- memset(m_freqPreds , 0, sizeof(unsigned long) * O3DGC_SC3DMC_MAX_PREDICTION_NEIGHBORS);
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- mask += (O3DGC_SC3DMC_BINARIZATION_ASCII & 7)<<4;
- m_predictors.Allocate(nvert);
- m_predictors.Clear();
- }
- else
- {
- mask += (O3DGC_SC3DMC_BINARIZATION_AC_EGC & 7)<<4;
- const unsigned int NMAX = numIntArray * dimIntArray * 8 + 100;
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- ace.ExpGolombEncode(0, 0, bModel0, bModel1);
- ace.ExpGolombEncode(M, 0, bModel0, bModel1);
- }
- bstream.WriteUInt32(0, m_streamType);
- bstream.WriteUChar(mask, m_streamType);
-
-#ifdef DEBUG_VERBOSE
- printf("IntArray (%i, %i)\n", numIntArray, dimIntArray);
- fprintf(g_fileDebugSC3DMCEnc, "IntArray (%i, %i)\n", numIntArray, dimIntArray);
-#endif //DEBUG_VERBOSE
-
- for (long vm=0; vm < nvert; ++vm)
- {
- nPred = 0;
- v = invVMap[vm];
- assert( v >= 0 && v < nvert);
- if ( v2T.GetNumNeighbors(v) > 0 &&
- predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- for(long k = 0; k < 3; ++k)
- {
- long w = triangles[ta*3 + k];
- if ( vmap[w] < vm )
- {
- SC3DMCTriplet id = {-1, -1, vmap[w]};
- unsigned long p = Insert(id, nPred, m_neighbors);
- if (p != 0xFFFFFFFF)
- {
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- m_neighbors[p].m_pred[i] = intArray[w*stride+i];
- }
- }
- }
- }
- }
- }
- if (nPred > 1)
- {
- // find best predictor
- unsigned long bestPred = 0xFFFFFFFF;
- double bestCost = O3DGC_MAX_DOUBLE;
- double cost;
-#ifdef DEBUG_VERBOSE1
- printf("\t\t vm %i\n", vm);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t vm %i\n", vm);
-#endif //DEBUG_VERBOSE
-
- for (unsigned long p = 0; p < nPred; ++p)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t pred a = %i b = %i c = %i \n", m_neighbors[p].m_id.m_a, m_neighbors[p].m_id.m_b, m_neighbors[p].m_id.m_c);
-#endif //DEBUG_VERBOSE
- cost = -log2((m_freqPreds[p]+1.0) / nPredictors );
- for (unsigned long i = 0; i < dimIntArray; ++i)
- {
-#ifdef DEBUG_VERBOSE1
- printf("\t\t\t %i\n", m_neighbors[p].m_pred[i]);
- fprintf(g_fileDebugSC3DMCEnc, "\t\t\t %i\n", m_neighbors[p].m_pred[i]);
-#endif //DEBUG_VERBOSE
-
- predResidual = (long) IntToUInt(intArray[v*stride+i] - m_neighbors[p].m_pred[i]);
- if (predResidual < (long) M)
- {
- cost += -log2((m_freqSymbols[predResidual]+1.0) / nSymbols );
- }
- else
- {
- cost += -log2((m_freqSymbols[M] + 1.0) / nSymbols ) + log2((double) (predResidual-M));
- }
- }
- if (cost < bestCost)
- {
- bestCost = cost;
- bestPred = p;
- }
- }
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- m_predictors.PushBack((unsigned char) bestPred);
- }
- else
- {
- ace.encode(bestPred, mModelPreds);
- }
-#ifdef DEBUG_VERBOSE1
- printf("best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
- fprintf(g_fileDebugSC3DMCEnc, "best (%i, %i, %i) \t pos %i\n", m_neighbors[bestPred].m_id.m_a, m_neighbors[bestPred].m_id.m_b, m_neighbors[bestPred].m_id.m_c, bestPred);
-#endif //DEBUG_VERBOSE
- // use best predictor
- for (unsigned long i = 0; i < dimIntArray; ++i)
- {
- predResidual = intArray[v*stride+i] - m_neighbors[bestPred].m_pred[i];
- uPredResidual = IntToUInt(predResidual);
- ++m_freqSymbols[(uPredResidual < (long) M)? uPredResidual : M];
-
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i \t [%i]\n", vm*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i \t [%i]\n", vm*dimIntArray+i, predResidual, m_neighbors[bestPred].m_pred[i]);
-#endif //DEBUG_VERBOSE
-
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteIntASCII(predResidual);
- }
- else
- {
- EncodeIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
- }
- ++m_freqPreds[bestPred];
- nSymbols += dimIntArray;
- ++nPredictors;
- }
- else if ( vm > 0 && predMode != O3DGC_SC3DMC_NO_PREDICTION)
- {
- long prev = invVMap[vm-1];
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- predResidual = intArray[v*stride+i] - intArray[prev*stride+i];
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteIntASCII(predResidual);
- }
- else
- {
- EncodeIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", vm*dimIntArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i\n", vm*dimIntArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- else
- {
- for (unsigned long i = 0; i < dimIntArray; i++)
- {
- predResidual = intArray[v*stride+i];
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- bstream.WriteUIntASCII(predResidual);
- }
- else
- {
- EncodeUIntACEGC(predResidual, ace, mModelValues, bModel0, bModel1, M);
- }
-#ifdef DEBUG_VERBOSE
- printf("%i \t %i\n", vm*dimIntArray+i, predResidual);
- fprintf(g_fileDebugSC3DMCEnc, "%i \t %i\n", vm*dimIntArray+i, predResidual);
-#endif //DEBUG_VERBOSE
- }
- }
- }
- if (m_streamType != O3DGC_STREAM_TYPE_ASCII)
- {
- unsigned long encodedBytes = ace.stop_encoder();
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32(start, bstream.GetSize() - start, m_streamType);
-
- if (m_streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- unsigned long start = bstream.GetSize();
- bstream.WriteUInt32ASCII(0);
- const unsigned long size = m_predictors.GetSize();
- for(unsigned long i = 0; i < size; ++i)
- {
- bstream.WriteUCharASCII((unsigned char) m_predictors[i]);
- }
- bstream.WriteUInt32ASCII(start, bstream.GetSize() - start);
- }
-#ifdef DEBUG_VERBOSE
- fflush(g_fileDebugSC3DMCEnc);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::ProcessNormals(const IndexedFaceSet<T> & ifs)
- {
- const long nvert = (long) ifs.GetNNormal();
- const unsigned long normalSize = ifs.GetNNormal() * 2;
- if (m_normalsSize < normalSize)
- {
- delete [] m_normals;
- m_normalsSize = normalSize;
- m_normals = new Real [normalSize];
- }
- const AdjacencyInfo & v2T = m_triangleListEncoder.GetVertexToTriangle();
- const long * const invVMap = m_triangleListEncoder.GetInvVMap();
- const T * const triangles = ifs.GetCoordIndex();
- const Real * const originalNormals = ifs.GetNormal();
- Vec3<long> p1, p2, p3, n0, nt;
- Vec3<Real> n1;
- long na0 = 0, nb0 = 0;
- Real rna0, rnb0, na1 = 0, nb1 = 0, norm0, norm1;
- char ni0 = 0, ni1 = 0;
- long a, b, c, v;
- m_predictors.Clear();
- for (long i=0; i < nvert; ++i)
- {
- v = invVMap[i];
- n0.X() = 0;
- n0.Y() = 0;
- n0.Z() = 0;
- int u0 = v2T.Begin(v);
- int u1 = v2T.End(v);
- for (long u = u0; u < u1; u++)
- {
- long ta = v2T.GetNeighbor(u);
- a = triangles[ta*3 + 0];
- b = triangles[ta*3 + 1];
- c = triangles[ta*3 + 2];
- p1.X() = m_quantFloatArray[3*a];
- p1.Y() = m_quantFloatArray[3*a+1];
- p1.Z() = m_quantFloatArray[3*a+2];
- p2.X() = m_quantFloatArray[3*b];
- p2.Y() = m_quantFloatArray[3*b+1];
- p2.Z() = m_quantFloatArray[3*b+2];
- p3.X() = m_quantFloatArray[3*c];
- p3.Y() = m_quantFloatArray[3*c+1];
- p3.Z() = m_quantFloatArray[3*c+2];
- nt = (p2-p1)^(p3-p1);
- n0 += nt;
- }
- norm0 = (Real) n0.GetNorm();
- if (norm0 == 0.0)
- {
- norm0 = 1.0;
- }
- SphereToCube(n0.X(), n0.Y(), n0.Z(), na0, nb0, ni0);
- rna0 = na0 / norm0;
- rnb0 = nb0 / norm0;
-
- n1.X() = originalNormals[3*v];
- n1.Y() = originalNormals[3*v+1];
- n1.Z() = originalNormals[3*v+2];
- norm1 = (Real) n1.GetNorm();
- if (norm1 != 0.0)
- {
- n1.X() /= norm1;
- n1.Y() /= norm1;
- n1.Z() /= norm1;
- }
- SphereToCube(n1.X(), n1.Y(), n1.Z(), na1, nb1, ni1);
- m_predictors.PushBack(ni1 - ni0);
- if ( (ni1 >> 1) != (ni0 >> 1) )
- {
- rna0 = (Real)0.0;
- rnb0 = (Real)0.0;
- }
- m_normals[2*v] = na1 - rna0;
- m_normals[2*v+1] = nb1 - rnb0;
-
-#ifdef DEBUG_VERBOSE1
- printf("n0 \t %i \t %i \t %i \t %i (%f, %f)\n", i, n0.X(), n0.Y(), n0.Z(), rna0, rnb0);
- fprintf(g_fileDebugSC3DMCEnc,"n0 \t %i \t %i \t %i \t %i (%f, %f)\n", i, n0.X(), n0.Y(), n0.Z(), rna0, rnb0);
-#endif //DEBUG_VERBOSE
-
-#ifdef DEBUG_VERBOSE1
- printf("normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n", i, n1.X(), n1.Y(), n1.Z(), ni1, na1, nb1, rna0, rnb0);
- fprintf(g_fileDebugSC3DMCEnc, "normal \t %i \t %f \t %f \t %f \t (%i, %f, %f) \t (%f, %f)\n", i, n1.X(), n1.Y(), n1.Z(), ni1, na1, nb1, rna0, rnb0);
-#endif //DEBUG_VERBOSE
-
- }
- return O3DGC_OK;
- }
-
- template <class T>
- O3DGCErrorCode SC3DMCEncoder<T>::EncodePayload(const SC3DMCEncodeParams & params,
- const IndexedFaceSet<T> & ifs,
- BinaryStream & bstream)
- {
-#ifdef DEBUG_VERBOSE
- g_fileDebugSC3DMCEnc = fopen("tfans_enc_main.txt", "w");
-#endif //DEBUG_VERBOSE
-
- // encode triangle list
- m_triangleListEncoder.SetStreamType(params.GetStreamType());
- m_stats.m_streamSizeCoordIndex = bstream.GetSize();
- Timer timer;
- timer.Tic();
- m_triangleListEncoder.Encode(ifs.GetCoordIndex(), ifs.GetIndexBufferID(), ifs.GetNCoordIndex(), ifs.GetNCoord(), bstream);
- timer.Toc();
- m_stats.m_timeCoordIndex = timer.GetElapsedTime();
- m_stats.m_streamSizeCoordIndex = bstream.GetSize() - m_stats.m_streamSizeCoordIndex;
-
- // encode coord
- m_stats.m_streamSizeCoord = bstream.GetSize();
- timer.Tic();
- if (ifs.GetNCoord() > 0)
- {
- EncodeFloatArray(ifs.GetCoord(), ifs.GetNCoord(), 3, 3, ifs.GetCoordMin(), ifs.GetCoordMax(),
- params.GetCoordQuantBits(), ifs, params.GetCoordPredMode(), bstream);
- }
- timer.Toc();
- m_stats.m_timeCoord = timer.GetElapsedTime();
- m_stats.m_streamSizeCoord = bstream.GetSize() - m_stats.m_streamSizeCoord;
-
-
- // encode Normal
- m_stats.m_streamSizeNormal = bstream.GetSize();
- timer.Tic();
- if (ifs.GetNNormal() > 0)
- {
- if (params.GetNormalPredMode() == O3DGC_SC3DMC_SURF_NORMALS_PREDICTION)
- {
- ProcessNormals(ifs);
- EncodeFloatArray(m_normals, ifs.GetNNormal(), 2, 2, ifs.GetNormalMin(), ifs.GetNormalMax(),
- params.GetNormalQuantBits(), ifs, params.GetNormalPredMode(), bstream);
- }
- else
- {
- EncodeFloatArray(ifs.GetNormal(), ifs.GetNNormal(), 3, 3, ifs.GetNormalMin(), ifs.GetNormalMax(),
- params.GetNormalQuantBits(), ifs, params.GetNormalPredMode(), bstream);
- }
- }
- timer.Toc();
- m_stats.m_timeNormal = timer.GetElapsedTime();
- m_stats.m_streamSizeNormal = bstream.GetSize() - m_stats.m_streamSizeNormal;
-
-
- // encode FloatAttribute
- for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a)
- {
- m_stats.m_streamSizeFloatAttribute[a] = bstream.GetSize();
- timer.Tic();
- EncodeFloatArray(ifs.GetFloatAttribute(a), ifs.GetNFloatAttribute(a),
- ifs.GetFloatAttributeDim(a), ifs.GetFloatAttributeDim(a),
- ifs.GetFloatAttributeMin(a), ifs.GetFloatAttributeMax(a),
- params.GetFloatAttributeQuantBits(a), ifs,
- params.GetFloatAttributePredMode(a), bstream);
- timer.Toc();
- m_stats.m_timeFloatAttribute[a] = timer.GetElapsedTime();
- m_stats.m_streamSizeFloatAttribute[a] = bstream.GetSize() - m_stats.m_streamSizeFloatAttribute[a];
- }
-
- // encode IntAttribute
- for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a)
- {
- m_stats.m_streamSizeIntAttribute[a] = bstream.GetSize();
- timer.Tic();
- EncodeIntArray(ifs.GetIntAttribute(a), ifs.GetNIntAttribute(a), ifs.GetIntAttributeDim(a),
- ifs.GetIntAttributeDim(a), ifs, params.GetIntAttributePredMode(a), bstream);
- timer.Toc();
- m_stats.m_timeIntAttribute[a] = timer.GetElapsedTime();
- m_stats.m_streamSizeIntAttribute[a] = bstream.GetSize() - m_stats.m_streamSizeIntAttribute[a];
- }
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugSC3DMCEnc);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
-}
-#endif // O3DGC_SC3DMC_ENCODER_INL
-
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTimer.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTimer.h
deleted file mode 100644
index 00fe5b653..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTimer.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_TIMER_H
-#define O3DGC_TIMER_H
-
-#include "o3dgcCommon.h"
-
-#ifdef _WIN32
-/* Thank you, Microsoft, for file WinDef.h with min/max redefinition. */
-#define NOMINMAX
-#include <windows.h>
-#elif __MACH__
-#include <mach/clock.h>
-#include <mach/mach.h>
-#else
-#include <time.h>
-#include <sys/time.h>
-#endif
-
-
-
-namespace o3dgc
-{
-#ifdef _WIN32
- class Timer
- {
- public:
- Timer(void)
- {
- m_start.QuadPart = 0;
- m_stop.QuadPart = 0;
- QueryPerformanceFrequency( &m_freq ) ;
- };
- ~Timer(void){};
- void Tic()
- {
- QueryPerformanceCounter(&m_start) ;
- }
- void Toc()
- {
- QueryPerformanceCounter(&m_stop);
- }
- double GetElapsedTime() // in ms
- {
- LARGE_INTEGER delta;
- delta.QuadPart = m_stop.QuadPart - m_start.QuadPart;
- return (1000.0 * delta.QuadPart) / (double)m_freq.QuadPart;
- }
- private:
- LARGE_INTEGER m_start;
- LARGE_INTEGER m_stop;
- LARGE_INTEGER m_freq;
-
- };
-#elif __MACH__
- class Timer
- {
- public:
- Timer(void)
- {
- memset(this, 0, sizeof(Timer));
- host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, & m_cclock);
- };
- ~Timer(void)
- {
- mach_port_deallocate(mach_task_self(), m_cclock);
- };
- void Tic()
- {
- clock_get_time( m_cclock, &m_start);
- }
- void Toc()
- {
- clock_get_time( m_cclock, &m_stop);
- }
- double GetElapsedTime() // in ms
- {
- return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec));
- }
- private:
- clock_serv_t m_cclock;
- mach_timespec_t m_start;
- mach_timespec_t m_stop;
- };
-#else
- class Timer
- {
- public:
- Timer(void)
- {
- memset(this, 0, sizeof(Timer));
- };
- ~Timer(void){};
- void Tic()
- {
- clock_gettime(CLOCK_REALTIME, &m_start);
- }
- void Toc()
- {
- clock_gettime(CLOCK_REALTIME, &m_stop);
- }
- double GetElapsedTime() // in ms
- {
- return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec));
- }
- private:
- struct timespec m_start;
- struct timespec m_stop;
- };
-#endif
-
-}
-#endif // O3DGC_TIMER_H
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTools.cpp b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTools.cpp
deleted file mode 100644
index 52b552304..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTools.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.cpp b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.cpp
deleted file mode 100644
index 078ed16e6..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#include "o3dgcTriangleFans.h"
-#include "o3dgcArithmeticCodec.h"
-
-//#define DEBUG_VERBOSE
-
-namespace o3dgc
-{
-#ifdef DEBUG_VERBOSE
- FILE* g_fileDebugTF = NULL;
-#endif //DEBUG_VERBOSE
-
- O3DGCErrorCode SaveUIntData(const Vector<long> & data,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- bstream.WriteUInt32ASCII(0);
- const unsigned long size = data.GetSize();
- bstream.WriteUInt32ASCII(size);
- for(unsigned long i = 0; i < size; ++i)
- {
- bstream.WriteUIntASCII(data[i]);
- }
- bstream.WriteUInt32ASCII(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
- O3DGCErrorCode SaveIntData(const Vector<long> & data,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- bstream.WriteUInt32ASCII(0);
- const unsigned long size = data.GetSize();
- bstream.WriteUInt32ASCII(size);
- for(unsigned long i = 0; i < size; ++i)
- {
- bstream.WriteIntASCII(data[i]);
- }
- bstream.WriteUInt32ASCII(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
- O3DGCErrorCode SaveBinData(const Vector<long> & data,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- bstream.WriteUInt32ASCII(0);
- const unsigned long size = data.GetSize();
- long symbol;
- bstream.WriteUInt32ASCII(size);
- for(unsigned long i = 0; i < size; )
- {
- symbol = 0;
- for(unsigned long h = 0; h < O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0 && i < size; ++h)
- {
- symbol += (data[i] << h);
- ++i;
- }
- bstream.WriteUCharASCII((unsigned char) symbol);
- }
- bstream.WriteUInt32ASCII(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
- O3DGCErrorCode CompressedTriangleFans::SaveUIntAC(const Vector<long> & data,
- const unsigned long M,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- const unsigned int NMAX = data.GetSize() * 8 + 100;
- const unsigned long size = data.GetSize();
- long minValue = O3DGC_MAX_LONG;
- bstream.WriteUInt32Bin(0);
- bstream.WriteUInt32Bin(size);
- if (size > 0)
- {
- #ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i, start %i\n", size, start);
- fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start);
- #endif //DEBUG_VERBOSE
-
- for(unsigned long i = 0; i < size; ++i)
- {
- if (minValue > data[i])
- {
- minValue = data[i];
- }
- #ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
- #endif //DEBUG_VERBOSE
- }
- bstream.WriteUInt32Bin(minValue);
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- Arithmetic_Codec ace;
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- Adaptive_Data_Model mModelValues(M+1);
- for(unsigned long i = 0; i < size; ++i)
- {
- ace.encode(data[i]-minValue, mModelValues);
- }
- unsigned long encodedBytes = ace.stop_encoder();
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32Bin(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
- O3DGCErrorCode CompressedTriangleFans::SaveBinAC(const Vector<long> & data,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- const unsigned int NMAX = data.GetSize() * 8 + 100;
- const unsigned long size = data.GetSize();
- bstream.WriteUInt32Bin(0);
- bstream.WriteUInt32Bin(size);
- if (size > 0)
- {
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- Arithmetic_Codec ace;
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- Adaptive_Bit_Model bModel;
- #ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i, start %i\n", size, start);
- fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start);
- #endif //DEBUG_VERBOSE
- for(unsigned long i = 0; i < size; ++i)
- {
- ace.encode(data[i], bModel);
- #ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
- #endif //DEBUG_VERBOSE
- }
- unsigned long encodedBytes = ace.stop_encoder();
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32Bin(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
-
- O3DGCErrorCode CompressedTriangleFans::SaveIntACEGC(const Vector<long> & data,
- const unsigned long M,
- BinaryStream & bstream)
- {
- unsigned long start = bstream.GetSize();
- const unsigned int NMAX = data.GetSize() * 8 + 100;
- const unsigned long size = data.GetSize();
- long minValue = 0;
- bstream.WriteUInt32Bin(0);
- bstream.WriteUInt32Bin(size);
- if (size > 0)
- {
-#ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i, start %i\n", size, start);
- fprintf(g_fileDebugTF, "-----------\nsize %i, start %i\n", size, start);
-#endif //DEBUG_VERBOSE
- for(unsigned long i = 0; i < size; ++i)
- {
- if (minValue > data[i])
- {
- minValue = data[i];
- }
-#ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
-#endif //DEBUG_VERBOSE
- }
- bstream.WriteUInt32Bin(minValue + O3DGC_MAX_LONG);
- if ( m_sizeBufferAC < NMAX )
- {
- delete [] m_bufferAC;
- m_sizeBufferAC = NMAX;
- m_bufferAC = new unsigned char [m_sizeBufferAC];
- }
- Arithmetic_Codec ace;
- ace.set_buffer(NMAX, m_bufferAC);
- ace.start_encoder();
- Adaptive_Data_Model mModelValues(M+2);
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- unsigned long value;
- for(unsigned long i = 0; i < size; ++i)
- {
- value = data[i]-minValue;
- if (value < M)
- {
- ace.encode(value, mModelValues);
- }
- else
- {
- ace.encode(M, mModelValues);
- ace.ExpGolombEncode(value-M, 0, bModel0, bModel1);
- }
- }
- unsigned long encodedBytes = ace.stop_encoder();
- for(unsigned long i = 0; i < encodedBytes; ++i)
- {
- bstream.WriteUChar8Bin(m_bufferAC[i]);
- }
- }
- bstream.WriteUInt32Bin(start, bstream.GetSize() - start);
- return O3DGC_OK;
- }
- O3DGCErrorCode CompressedTriangleFans::Save(BinaryStream & bstream, bool encodeTrianglesOrder, O3DGCStreamType streamType)
- {
-#ifdef DEBUG_VERBOSE
- g_fileDebugTF = fopen("SaveIntACEGC_new.txt", "w");
-#endif //DEBUG_VERBOSE
-
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- SaveUIntData(m_numTFANs , bstream);
- SaveUIntData(m_degrees , bstream);
- SaveUIntData(m_configs , bstream);
- SaveBinData (m_operations, bstream);
- SaveIntData (m_indices , bstream);
- if (encodeTrianglesOrder)
- {
- SaveUIntData(m_trianglesOrder, bstream);
- }
- }
- else
- {
- SaveIntACEGC(m_numTFANs , 4 , bstream);
- SaveIntACEGC(m_degrees , 16, bstream);
- SaveUIntAC (m_configs , 10, bstream);
- SaveBinAC (m_operations, bstream);
- SaveIntACEGC(m_indices , 8 , bstream);
- if (encodeTrianglesOrder)
- {
- SaveIntACEGC(m_trianglesOrder , 16, bstream);
- }
- }
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugTF);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadUIntData(Vector<long> & data,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- bstream.ReadUInt32ASCII(iterator);
- const unsigned long size = bstream.ReadUInt32ASCII(iterator);
- data.Allocate(size);
- data.Clear();
- for(unsigned long i = 0; i < size; ++i)
- {
- data.PushBack(bstream.ReadUIntASCII(iterator));
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadIntData(Vector<long> & data,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- bstream.ReadUInt32ASCII(iterator);
- const unsigned long size = bstream.ReadUInt32ASCII(iterator);
- data.Allocate(size);
- data.Clear();
- for(unsigned long i = 0; i < size; ++i)
- {
- data.PushBack(bstream.ReadIntASCII(iterator));
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadBinData(Vector<long> & data,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- bstream.ReadUInt32ASCII(iterator);
- const unsigned long size = bstream.ReadUInt32ASCII(iterator);
- long symbol;
- data.Allocate(size * O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0);
- data.Clear();
- for(unsigned long i = 0; i < size;)
- {
- symbol = bstream.ReadUCharASCII(iterator);
- for(unsigned long h = 0; h < O3DGC_BINARY_STREAM_BITS_PER_SYMBOL0; ++h)
- {
- data.PushBack(symbol & 1);
- symbol >>= 1;
- ++i;
- }
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadUIntAC(Vector<long> & data,
- const unsigned long M,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 12;
- unsigned long size = bstream.ReadUInt32Bin(iterator);
- if (size == 0)
- {
- return O3DGC_OK;
- }
- long minValue = bstream.ReadUInt32Bin(iterator);
- unsigned char * buffer = 0;
- bstream.GetBuffer(iterator, buffer);
- iterator += sizeSize;
- data.Allocate(size);
- Arithmetic_Codec acd;
- acd.set_buffer(sizeSize, buffer);
- acd.start_decoder();
- Adaptive_Data_Model mModelValues(M+1);
-#ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i\n", size);
- fprintf(g_fileDebugTF, "size %i\n", size);
-#endif //DEBUG_VERBOSE
- for(unsigned long i = 0; i < size; ++i)
- {
- data.PushBack(acd.decode(mModelValues)+minValue);
-#ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
-#endif //DEBUG_VERBOSE
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadIntACEGC(Vector<long> & data,
- const unsigned long M,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 12;
- unsigned long size = bstream.ReadUInt32Bin(iterator);
- if (size == 0)
- {
- return O3DGC_OK;
- }
- long minValue = bstream.ReadUInt32Bin(iterator) - O3DGC_MAX_LONG;
- unsigned char * buffer = 0;
- bstream.GetBuffer(iterator, buffer);
- iterator += sizeSize;
- data.Allocate(size);
- Arithmetic_Codec acd;
- acd.set_buffer(sizeSize, buffer);
- acd.start_decoder();
- Adaptive_Data_Model mModelValues(M+2);
- Static_Bit_Model bModel0;
- Adaptive_Bit_Model bModel1;
- unsigned long value;
-
-#ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i\n", size);
- fprintf(g_fileDebugTF, "size %i\n", size);
-#endif //DEBUG_VERBOSE
- for(unsigned long i = 0; i < size; ++i)
- {
- value = acd.decode(mModelValues);
- if ( value == M)
- {
- value += acd.ExpGolombDecode(0, bModel0, bModel1);
- }
- data.PushBack(value + minValue);
-#ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
-#endif //DEBUG_VERBOSE
- }
-#ifdef DEBUG_VERBOSE
- fflush(g_fileDebugTF);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
- O3DGCErrorCode LoadBinAC(Vector<long> & data,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- unsigned long sizeSize = bstream.ReadUInt32Bin(iterator) - 8;
- unsigned long size = bstream.ReadUInt32Bin(iterator);
- if (size == 0)
- {
- return O3DGC_OK;
- }
- unsigned char * buffer = 0;
- bstream.GetBuffer(iterator, buffer);
- iterator += sizeSize;
- data.Allocate(size);
- Arithmetic_Codec acd;
- acd.set_buffer(sizeSize, buffer);
- acd.start_decoder();
- Adaptive_Bit_Model bModel;
-#ifdef DEBUG_VERBOSE
- printf("-----------\nsize %i\n", size);
- fprintf(g_fileDebugTF, "size %i\n", size);
-#endif //DEBUG_VERBOSE
- for(unsigned long i = 0; i < size; ++i)
- {
- data.PushBack(acd.decode(bModel));
-#ifdef DEBUG_VERBOSE
- printf("%i\t%i\n", i, data[i]);
- fprintf(g_fileDebugTF, "%i\t%i\n", i, data[i]);
-#endif //DEBUG_VERBOSE
- }
- return O3DGC_OK;
- }
- O3DGCErrorCode CompressedTriangleFans::Load(const BinaryStream & bstream,
- unsigned long & iterator,
- bool decodeTrianglesOrder,
- O3DGCStreamType streamType)
- {
-#ifdef DEBUG_VERBOSE
- g_fileDebugTF = fopen("Load_new.txt", "w");
-#endif //DEBUG_VERBOSE
- if (streamType == O3DGC_STREAM_TYPE_ASCII)
- {
- LoadUIntData(m_numTFANs , bstream, iterator);
- LoadUIntData(m_degrees , bstream, iterator);
- LoadUIntData(m_configs , bstream, iterator);
- LoadBinData (m_operations, bstream, iterator);
- LoadIntData (m_indices , bstream, iterator);
- if (decodeTrianglesOrder)
- {
- LoadUIntData(m_trianglesOrder , bstream, iterator);
- }
- }
- else
- {
- LoadIntACEGC(m_numTFANs , 4 , bstream, iterator);
- LoadIntACEGC(m_degrees , 16, bstream, iterator);
- LoadUIntAC (m_configs , 10, bstream, iterator);
- LoadBinAC (m_operations, bstream, iterator);
- LoadIntACEGC(m_indices , 8 , bstream, iterator);
- if (decodeTrianglesOrder)
- {
- LoadIntACEGC(m_trianglesOrder , 16, bstream, iterator);
- }
- }
-
-#ifdef DEBUG_VERBOSE
- fclose(g_fileDebugTF);
-#endif //DEBUG_VERBOSE
- return O3DGC_OK;
- }
-}
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.h
deleted file mode 100644
index 861836428..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleFans.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_TRIANGLE_FANS_H
-#define O3DGC_TRIANGLE_FANS_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcVector.h"
-#include "o3dgcBinaryStream.h"
-
-
-namespace o3dgc
-{
- const long O3DGC_TFANS_MIN_SIZE_ALLOCATED_VERTICES_BUFFER = 128;
- const long O3DGC_TFANS_MIN_SIZE_TFAN_SIZE_BUFFER = 8;
-
- class CompressedTriangleFans
- {
- public:
- //! Constructor.
- CompressedTriangleFans(void)
- {
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- m_bufferAC = 0;
- m_sizeBufferAC = 0;
- };
- //! Destructor.
- ~CompressedTriangleFans(void)
- {
- delete [] m_bufferAC;
- };
- O3DGCStreamType GetStreamType() const { return m_streamType; }
- void SetStreamType(O3DGCStreamType streamType) { m_streamType = streamType; }
-
- O3DGCErrorCode Allocate(long numVertices, long numTriangles)
- {
- assert(numVertices > 0);
- m_numTFANs.Allocate(numVertices);
- m_degrees.Allocate(2*numVertices);
- m_configs.Allocate(2*numVertices);
- m_operations.Allocate(2*numVertices);
- m_indices.Allocate(2*numVertices);
- m_trianglesOrder.Allocate(numTriangles);
- Clear();
- return O3DGC_OK;
- }
- O3DGCErrorCode PushNumTFans(long numTFans)
- {
- m_numTFANs.PushBack(numTFans);
- return O3DGC_OK;
- }
- long ReadNumTFans(unsigned long & iterator) const
- {
- assert(iterator < m_numTFANs.GetSize());
- return m_numTFANs[iterator++];
- }
- O3DGCErrorCode PushDegree(long degree)
- {
- m_degrees.PushBack(degree);
- return O3DGC_OK;
- }
- long ReadDegree(unsigned long & iterator) const
- {
- assert(iterator < m_degrees.GetSize());
- return m_degrees[iterator++];
- }
- O3DGCErrorCode PushConfig(long config)
- {
- m_configs.PushBack(config);
- return O3DGC_OK;
- }
- long ReadConfig(unsigned long & iterator) const
- {
- assert(iterator < m_configs.GetSize());
- return m_configs[iterator++];
- }
- O3DGCErrorCode PushOperation(long op)
- {
- m_operations.PushBack(op);
- return O3DGC_OK;
- }
- long ReadOperation(unsigned long & iterator) const
- {
- assert(iterator < m_operations.GetSize());
- return m_operations[iterator++];
- }
- O3DGCErrorCode PushIndex(long index)
- {
- m_indices.PushBack(index);
- return O3DGC_OK;
- }
- long ReadIndex(unsigned long & iterator) const
- {
- assert(iterator < m_indices.GetSize());
- return m_indices[iterator++];
- }
- O3DGCErrorCode PushTriangleIndex(long index)
- {
- m_trianglesOrder.PushBack(IntToUInt(index));
- return O3DGC_OK;
- }
- long ReadTriangleIndex(unsigned long & iterator) const
- {
- assert(iterator < m_trianglesOrder.GetSize());
- return UIntToInt(m_trianglesOrder[iterator++]);
- }
- O3DGCErrorCode Clear()
- {
- m_numTFANs.Clear();
- m_degrees.Clear();
- m_configs.Clear();
- m_operations.Clear();
- m_indices.Clear();
- return O3DGC_OK;
- }
- O3DGCErrorCode Save(BinaryStream & bstream,
- bool encodeTrianglesOrder,
- O3DGCStreamType streamType);
- O3DGCErrorCode Load(const BinaryStream & bstream,
- unsigned long & iterator,
- bool decodeTrianglesOrder,
- O3DGCStreamType streamType);
-
- private:
- O3DGCErrorCode SaveBinAC(const Vector<long> & data,
- BinaryStream & bstream);
- O3DGCErrorCode SaveUIntAC(const Vector<long> & data,
- const unsigned long M,
- BinaryStream & bstream);
- O3DGCErrorCode SaveIntACEGC(const Vector<long> & data,
- const unsigned long M,
- BinaryStream & bstream);
-
- Vector<long> m_numTFANs;
- Vector<long> m_degrees;
- Vector<long> m_configs;
- Vector<long> m_operations;
- Vector<long> m_indices;
- Vector<long> m_trianglesOrder;
- unsigned char * m_bufferAC;
- unsigned long m_sizeBufferAC;
- O3DGCStreamType m_streamType;
- };
-
- //!
- class TriangleFans
- {
- public:
- //! Constructor.
- TriangleFans(long sizeTFAN = O3DGC_TFANS_MIN_SIZE_TFAN_SIZE_BUFFER,
- long verticesSize = O3DGC_TFANS_MIN_SIZE_ALLOCATED_VERTICES_BUFFER)
- {
- assert(sizeTFAN > 0);
- assert(verticesSize > 0);
- m_numTFANs = 0;
- m_numVertices = 0;
- m_verticesAllocatedSize = verticesSize;
- m_sizeTFANAllocatedSize = sizeTFAN;
- m_sizeTFAN = new long [m_sizeTFANAllocatedSize];
- m_vertices = new long [m_verticesAllocatedSize];
- };
- //! Destructor.
- ~TriangleFans(void)
- {
- delete [] m_vertices;
- delete [] m_sizeTFAN;
- };
-
- O3DGCErrorCode Allocate(long sizeTFAN, long verticesSize)
- {
- assert(sizeTFAN > 0);
- assert(verticesSize > 0);
- m_numTFANs = 0;
- m_numVertices = 0;
- if (m_verticesAllocatedSize < verticesSize)
- {
- delete [] m_vertices;
- m_verticesAllocatedSize = verticesSize;
- m_vertices = new long [m_verticesAllocatedSize];
- }
- if (m_sizeTFANAllocatedSize < sizeTFAN)
- {
- delete [] m_sizeTFAN;
- m_sizeTFANAllocatedSize = sizeTFAN;
- m_sizeTFAN = new long [m_sizeTFANAllocatedSize];
- }
- return O3DGC_OK;
- };
- O3DGCErrorCode Clear()
- {
- m_numTFANs = 0;
- m_numVertices = 0;
- return O3DGC_OK;
- }
- O3DGCErrorCode AddVertex(long vertex)
- {
- assert(m_numTFANs >= 0);
- assert(m_numTFANs < m_sizeTFANAllocatedSize);
- assert(m_numVertices >= 0);
- ++m_numVertices;
- if (m_numVertices == m_verticesAllocatedSize)
- {
- m_verticesAllocatedSize *= 2;
- long * tmp = m_vertices;
- m_vertices = new long [m_verticesAllocatedSize];
- memcpy(m_vertices, tmp, sizeof(long) * m_numVertices);
- delete [] tmp;
- }
- m_vertices[m_numVertices-1] = vertex;
- ++m_sizeTFAN[m_numTFANs-1];
- return O3DGC_OK;
- }
- O3DGCErrorCode AddTFAN()
- {
- assert(m_numTFANs >= 0);
- ++m_numTFANs;
- if (m_numTFANs == m_sizeTFANAllocatedSize)
- {
- m_sizeTFANAllocatedSize *= 2;
- long * tmp = m_sizeTFAN;
- m_sizeTFAN = new long [m_sizeTFANAllocatedSize];
- memcpy(m_sizeTFAN, tmp, sizeof(long) * m_numTFANs);
- delete [] tmp;
- }
- m_sizeTFAN[m_numTFANs-1] = (m_numTFANs > 1) ? m_sizeTFAN[m_numTFANs-2] : 0;
- return O3DGC_OK;
- }
- long Begin(long tfan) const
- {
- assert(tfan < m_numTFANs);
- assert(tfan >= 0);
- return (tfan>0)?m_sizeTFAN[tfan-1]:0;
- }
- long End(long tfan) const
- {
- assert(tfan < m_numTFANs);
- assert(tfan >= 0);
- return m_sizeTFAN[tfan];
- }
- long GetVertex(long vertex) const
- {
- assert(vertex < m_numVertices);
- assert(vertex >= 0);
- return m_vertices[vertex];
- }
- long GetTFANSize(long tfan) const
- {
- return End(tfan) - Begin(tfan);
- }
- long GetNumTFANs() const
- {
- return m_numTFANs;
- }
- long GetNumVertices() const
- {
- return m_numVertices;
- }
-
- private:
- long m_verticesAllocatedSize;
- long m_sizeTFANAllocatedSize;
- long m_numTFANs;
- long m_numVertices;
- long * m_vertices;
- long * m_sizeTFAN;
-
- };
-}
-#endif // O3DGC_TRIANGLE_FANS_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.h
deleted file mode 100644
index 65df526d1..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_TRIANGLE_LIST_DECODER_H
-#define O3DGC_TRIANGLE_LIST_DECODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcTriangleFans.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcAdjacencyInfo.h"
-
-namespace o3dgc
-{
-
- //!
- template <class T>
- class TriangleListDecoder
- {
- public:
- //! Constructor.
- TriangleListDecoder(void)
- {
- m_vertexCount = 0;
- m_triangleCount = 0;
- m_numTriangles = 0;
- m_numVertices = 0;
- m_triangles = 0;
- m_numConqueredTriangles = 0;
- m_numVisitedVertices = 0;
- m_visitedVertices = 0;
- m_visitedVerticesValence = 0;
- m_maxNumVertices = 0;
- m_maxNumTriangles = 0;
- m_itNumTFans = 0;
- m_itDegree = 0;
- m_itConfig = 0;
- m_itOperation = 0;
- m_itIndex = 0;
- m_tempTriangles = 0;
- m_tempTrianglesSize = 0;
- m_decodeTrianglesOrder = false;
- m_decodeVerticesOrder = false;
- };
- //! Destructor.
- ~TriangleListDecoder(void)
- {
- delete [] m_tempTriangles;
- };
-
- O3DGCStreamType GetStreamType() const { return m_streamType; }
- bool GetReorderTriangles() const { return m_decodeTrianglesOrder; }
- bool GetReorderVertices() const { return m_decodeVerticesOrder; }
- void SetStreamType(O3DGCStreamType streamType) { m_streamType = streamType; }
- const AdjacencyInfo & GetVertexToTriangle() const { return m_vertexToTriangle;}
- O3DGCErrorCode Decode(T * const triangles,
- const long numTriangles,
- const long numVertices,
- const BinaryStream & bstream,
- unsigned long & iterator)
- {
- unsigned char compressionMask = bstream.ReadUChar(iterator, m_streamType);
- m_decodeTrianglesOrder = ( (compressionMask&2) != 0);
- m_decodeVerticesOrder = ( (compressionMask&1) != 0);
- if (m_decodeVerticesOrder) // vertices reordering not supported
- {
- return O3DGC_ERROR_NON_SUPPORTED_FEATURE;
- }
- unsigned long maxSizeV2T = bstream.ReadUInt32(iterator, m_streamType);
- Init(triangles, numTriangles, numVertices, maxSizeV2T);
- m_ctfans.Load(bstream, iterator, m_decodeTrianglesOrder, m_streamType);
- Decompress();
- return O3DGC_OK;
- }
- O3DGCErrorCode Reorder();
-
- private:
- O3DGCErrorCode Init(T * const triangles,
- const long numTriangles,
- const long numVertices,
- const long maxSizeV2T);
- O3DGCErrorCode Decompress();
- O3DGCErrorCode CompueLocalConnectivityInfo(const long focusVertex);
- O3DGCErrorCode DecompressTFAN(const long focusVertex);
-
- unsigned long m_itNumTFans;
- unsigned long m_itDegree;
- unsigned long m_itConfig;
- unsigned long m_itOperation;
- unsigned long m_itIndex;
- long m_maxNumVertices;
- long m_maxNumTriangles;
- long m_numTriangles;
- long m_numVertices;
- long m_tempTrianglesSize;
- T * m_triangles;
- T * m_tempTriangles;
- long m_vertexCount;
- long m_triangleCount;
- long m_numConqueredTriangles;
- long m_numVisitedVertices;
- long * m_visitedVertices;
- long * m_visitedVerticesValence;
- AdjacencyInfo m_vertexToTriangle;
- CompressedTriangleFans m_ctfans;
- TriangleFans m_tfans;
- O3DGCStreamType m_streamType;
- bool m_decodeTrianglesOrder;
- bool m_decodeVerticesOrder;
- };
-}
-#include "o3dgcTriangleListDecoder.inl" // template implementation
-#endif // O3DGC_TRIANGLE_LIST_DECODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
deleted file mode 100644
index dd3af4aa7..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListDecoder.inl
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_TRIANGLE_LIST_DECODER_INL
-#define O3DGC_TRIANGLE_LIST_DECODER_INL
-
-namespace o3dgc
-{
- template<class T>
- O3DGCErrorCode TriangleListDecoder<T>::Init(T * const triangles,
- const long numTriangles,
- const long numVertices,
- const long maxSizeV2T)
- {
- assert(numVertices > 0);
- assert(numTriangles > 0);
- m_numTriangles = numTriangles;
- m_numVertices = numVertices;
- m_triangles = triangles;
- m_vertexCount = 0;
- m_triangleCount = 0;
- m_itNumTFans = 0;
- m_itDegree = 0;
- m_itConfig = 0;
- m_itOperation = 0;
- m_itIndex = 0;
- if (m_numVertices > m_maxNumVertices)
- {
- m_maxNumVertices = m_numVertices;
- delete [] m_visitedVerticesValence;
- delete [] m_visitedVertices;
- m_visitedVerticesValence = new long [m_numVertices];
- m_visitedVertices = new long [m_numVertices];
- }
-
- if (m_decodeTrianglesOrder && m_tempTrianglesSize < m_numTriangles)
- {
- delete [] m_tempTriangles;
- m_tempTrianglesSize = m_numTriangles;
- m_tempTriangles = new T [3*m_tempTrianglesSize];
- }
-
- m_ctfans.SetStreamType(m_streamType);
- m_ctfans.Allocate(m_numVertices, m_numTriangles);
- m_tfans.Allocate(2 * m_numVertices, 8 * m_numVertices);
-
- // compute vertex-to-triangle adjacency information
- m_vertexToTriangle.AllocateNumNeighborsArray(numVertices);
- long * numNeighbors = m_vertexToTriangle.GetNumNeighborsBuffer();
- for(long i = 0; i < numVertices; ++i)
- {
- numNeighbors[i] = maxSizeV2T;
- }
- m_vertexToTriangle.AllocateNeighborsArray();
- m_vertexToTriangle.ClearNeighborsArray();
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode TriangleListDecoder<T>::Decompress()
- {
- for(long focusVertex = 0; focusVertex < m_numVertices; ++focusVertex)
- {
- if (focusVertex == m_vertexCount)
- {
- m_vertexCount++; // insert focusVertex
- }
- CompueLocalConnectivityInfo(focusVertex);
- DecompressTFAN(focusVertex);
- }
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode TriangleListDecoder<T>::Reorder()
- {
- if (m_decodeTrianglesOrder)
- {
- unsigned long itTriangleIndex = 0;
- long prevTriangleIndex = 0;
- long t;
- memcpy(m_tempTriangles, m_triangles, m_numTriangles * 3 * sizeof(T));
- for(long i = 0; i < m_numTriangles; ++i)
- {
- t = m_ctfans.ReadTriangleIndex(itTriangleIndex) + prevTriangleIndex;
- assert( t >= 0 && t < m_numTriangles);
- memcpy(m_triangles + 3 * t, m_tempTriangles + 3 * i, sizeof(T) * 3);
- prevTriangleIndex = t + 1;
- }
- }
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode TriangleListDecoder<T>::CompueLocalConnectivityInfo(const long focusVertex)
- {
- long t = 0;
- long p, v;
- m_numConqueredTriangles = 0;
- m_numVisitedVertices = 0;
- for(long i = m_vertexToTriangle.Begin(focusVertex); (t >= 0) && (i < m_vertexToTriangle.End(focusVertex)); ++i)
- {
- t = m_vertexToTriangle.GetNeighbor(i);
- if ( t >= 0)
- {
- ++m_numConqueredTriangles;
- p = 3*t;
- // extract visited vertices
- for(long k = 0; k < 3; ++k)
- {
- v = m_triangles[p+k];
- if (v > focusVertex) // vertices are insertices by increasing traversal order
- {
- bool foundOrInserted = false;
- for (long j = 0; j < m_numVisitedVertices; ++j)
- {
- if (v == m_visitedVertices[j])
- {
- m_visitedVerticesValence[j]++;
- foundOrInserted = true;
- break;
- }
- else if (v < m_visitedVertices[j])
- {
- ++m_numVisitedVertices;
- for (long h = m_numVisitedVertices-1; h > j; --h)
- {
- m_visitedVertices[h] = m_visitedVertices[h-1];
- m_visitedVerticesValence[h] = m_visitedVerticesValence[h-1];
- }
- m_visitedVertices[j] = v;
- m_visitedVerticesValence[j] = 1;
- foundOrInserted = true;
- break;
- }
- }
- if (!foundOrInserted)
- {
- m_visitedVertices[m_numVisitedVertices] = v;
- m_visitedVerticesValence[m_numVisitedVertices] = 1;
- m_numVisitedVertices++;
- }
- }
- }
- }
- }
- // re-order visited vertices by taking into account their valence (i.e., # of conquered triangles incident to each vertex)
- // in order to avoid config. 9
- if (m_numVisitedVertices > 2)
- {
- long y;
- for(long x = 1; x < m_numVisitedVertices; ++x)
- {
-
- if (m_visitedVerticesValence[x] == 1)
- {
- y = x;
- while( (y > 0) && (m_visitedVerticesValence[y] < m_visitedVerticesValence[y-1]) )
- {
- swap(m_visitedVerticesValence[y], m_visitedVerticesValence[y-1]);
- swap(m_visitedVertices[y], m_visitedVertices[y-1]);
- --y;
- }
- }
- }
- }
- return O3DGC_OK;
- }
- template<class T>
- O3DGCErrorCode TriangleListDecoder<T>::DecompressTFAN(const long focusVertex)
- {
- long ntfans;
- long degree, config;
- long op;
- long index;
- long k0, k1;
- long b, c, t;
-
- ntfans = m_ctfans.ReadNumTFans(m_itNumTFans);
- if (ntfans > 0)
- {
- for(long f = 0; f != ntfans; f++)
- {
- m_tfans.AddTFAN();
- degree = m_ctfans.ReadDegree(m_itDegree) +2 - m_numConqueredTriangles;
- config = m_ctfans.ReadConfig(m_itConfig);
- k0 = m_tfans.GetNumVertices();
- m_tfans.AddVertex(focusVertex);
- switch(config)
- {
- case 0:// ops: 1000001 vertices: -1 -2
- m_tfans.AddVertex(m_visitedVertices[0]);
- for(long u = 1; u < degree-1; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- m_tfans.AddVertex(m_visitedVertices[1]);
- break;
- case 1: // ops: 1xxxxxx1 vertices: -1 x x x x x -2
- m_tfans.AddVertex(m_visitedVertices[0]);
- for(long u = 1; u < degree-1; u++)
- {
- op = m_ctfans.ReadOperation(m_itOperation);
- if (op == 1)
- {
- index = m_ctfans.ReadIndex(m_itIndex);
- if ( index < 0)
- {
- m_tfans.AddVertex(m_visitedVertices[-index-1]);
- }
- else
- {
- m_tfans.AddVertex(index + focusVertex);
- }
- }
- else
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- }
- m_tfans.AddVertex(m_visitedVertices[1]);
- break;
- case 2: // ops: 00000001 vertices: -1
- for(long u = 0; u < degree-1; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- m_tfans.AddVertex(m_visitedVertices[0]);
- break;
- case 3: // ops: 00000001 vertices: -2
- for(long u=0; u < degree-1; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- m_tfans.AddVertex(m_visitedVertices[1]);
- break;
- case 4: // ops: 10000000 vertices: -1
- m_tfans.AddVertex(m_visitedVertices[0]);
- for(long u = 1; u < degree; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- break;
- case 5: // ops: 10000000 vertices: -2
- m_tfans.AddVertex(m_visitedVertices[1]);
- for(long u = 1; u < degree; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- break;
- case 6:// ops: 00000000 vertices:
- for(long u = 0; u < degree; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- break;
- case 7: // ops: 1000001 vertices: -2 -1
- m_tfans.AddVertex(m_visitedVertices[1]);
- for(long u = 1; u < degree-1; u++)
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- m_tfans.AddVertex(m_visitedVertices[0]);
- break;
- case 8: // ops: 1xxxxxx1 vertices: -2 x x x x x -1
- m_tfans.AddVertex(m_visitedVertices[1]);
- for(long u = 1; u < degree-1; u++)
- {
- op = m_ctfans.ReadOperation(m_itOperation);
- if (op == 1)
- {
- index = m_ctfans.ReadIndex(m_itIndex);
- if ( index < 0)
- {
- m_tfans.AddVertex(m_visitedVertices[-index-1]);
- }
- else
- {
- m_tfans.AddVertex(index + focusVertex);
- }
- }
- else
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- }
- m_tfans.AddVertex(m_visitedVertices[0]);
- break;
- case 9: // general case
- for(long u = 0; u < degree; u++)
- {
- op = m_ctfans.ReadOperation(m_itOperation);
- if (op == 1)
- {
- index = m_ctfans.ReadIndex(m_itIndex);
- if ( index < 0)
- {
- m_tfans.AddVertex(m_visitedVertices[-index-1]);
- }
- else
- {
- m_tfans.AddVertex(index + focusVertex);
- }
- }
- else
- {
- m_visitedVertices[m_numVisitedVertices++] = m_vertexCount;
- m_tfans.AddVertex(m_vertexCount++);
- }
- }
- break;
-
- }
- //logger.write_2_log("\t degree=%i \t cas = %i\n", degree, cas);
- k1 = m_tfans.GetNumVertices();
- b = m_tfans.GetVertex(k0+1);
- for (long k = k0+2; k < k1; k++)
- {
- c = m_tfans.GetVertex(k);
- t = m_triangleCount*3;
-
- m_triangles[t++] = (T) focusVertex;
- m_triangles[t++] = (T) b;
- m_triangles[t ] = (T) c;
-
- m_vertexToTriangle.AddNeighbor(focusVertex, m_triangleCount);
- m_vertexToTriangle.AddNeighbor(b , m_triangleCount);
- m_vertexToTriangle.AddNeighbor(c , m_triangleCount);
- b=c;
- m_triangleCount++;
- }
- }
- }
- return O3DGC_OK;
- }
-}
-#endif //O3DGC_TRIANGLE_LIST_DECODER_INL
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.h
deleted file mode 100644
index c09172273..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-
-#pragma once
-#ifndef O3DGC_TRIANGLE_LIST_ENCODER_H
-#define O3DGC_TRIANGLE_LIST_ENCODER_H
-
-#include "o3dgcCommon.h"
-#include "o3dgcAdjacencyInfo.h"
-#include "o3dgcBinaryStream.h"
-#include "o3dgcFIFO.h"
-#include "o3dgcTriangleFans.h"
-
-namespace o3dgc
-{
- //!
- template <class T>
- class TriangleListEncoder
- {
- public:
- //! Constructor.
- TriangleListEncoder(void);
- //! Destructor.
- ~TriangleListEncoder(void);
- //!
- O3DGCErrorCode Encode(const T * const triangles,
- const unsigned long * const indexBufferIDs,
- const long numTriangles,
- const long numVertices,
- BinaryStream & bstream);
- O3DGCStreamType GetStreamType() const { return m_streamType; }
- void SetStreamType(O3DGCStreamType streamType) { m_streamType = streamType; }
- const long * GetInvVMap() const { return m_invVMap;}
- const long * GetInvTMap() const { return m_invTMap;}
- const long * GetVMap() const { return m_vmap;}
- const long * GetTMap() const { return m_tmap;}
- const AdjacencyInfo & GetVertexToTriangle() const { return m_vertexToTriangle;}
-
- private:
- O3DGCErrorCode Init(const T * const triangles,
- long numTriangles,
- long numVertices);
- O3DGCErrorCode CompueLocalConnectivityInfo(const long focusVertex);
- O3DGCErrorCode ProcessVertex( long focusVertex);
- O3DGCErrorCode ComputeTFANDecomposition(const long focusVertex);
- O3DGCErrorCode CompressTFAN(const long focusVertex);
-
- long m_vertexCount;
- long m_triangleCount;
- long m_maxNumVertices;
- long m_maxNumTriangles;
- long m_numNonConqueredTriangles;
- long m_numConqueredTriangles;
- long m_numVisitedVertices;
- long m_numTriangles;
- long m_numVertices;
- long m_maxSizeVertexToTriangle;
- T const * m_triangles;
- long * m_vtags;
- long * m_ttags;
- long * m_vmap;
- long * m_invVMap;
- long * m_tmap;
- long * m_invTMap;
- long * m_count;
- long * m_nonConqueredTriangles;
- long * m_nonConqueredEdges;
- long * m_visitedVertices;
- long * m_visitedVerticesValence;
- FIFO<long> m_vfifo;
- AdjacencyInfo m_vertexToTriangle;
- AdjacencyInfo m_triangleToTriangle;
- AdjacencyInfo m_triangleToTriangleInv;
- TriangleFans m_tfans;
- CompressedTriangleFans m_ctfans;
- O3DGCStreamType m_streamType;
- };
-}
-#include "o3dgcTriangleListEncoder.inl" // template implementation
-#endif // O3DGC_TRIANGLE_LIST_ENCODER_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.inl
deleted file mode 100644
index 017dd86bf..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcTriangleListEncoder.inl
+++ /dev/null
@@ -1,719 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_TRIANGLE_LIST_ENCODER_INL
-#define O3DGC_TRIANGLE_LIST_ENCODER_INL
-
-namespace o3dgc
-{
- // extract opposite edge
- template <class T>
- inline void CompueOppositeEdge(const long focusVertex,
- const T * triangle,
- long & a, long & b)
- {
- if ((long) triangle[0] == focusVertex)
- {
- a = triangle[1];
- b = triangle[2];
- }
- else if ((long) triangle[1] == focusVertex)
- {
- a = triangle[2];
- b = triangle[0];
- }
- else
- {
- a = triangle[0];
- b = triangle[1];
- }
- }
- inline bool IsCase0(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 1000001 vertices: -1 -2
- if ((numIndices != 2) || (degree < 2)) {
- return false;
- }
- if ((indices[0] != -1) ||(indices[1] != -2) ||
- (ops[0] != 1) ||(ops[degree-1] != 1) ) return false;
- for (long u = 1; u < degree-1; u++) {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase1(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 1xxxxxx1 indices: -1 x x x x x -2
- if ((degree < 2) || (numIndices < 1))
- {
- return false;
- }
- if ((indices[0] != -1) ||(indices[numIndices-1] != -2) ||
- (ops[0] != 1) ||(ops[degree-1] != 1) ) return false;
- return true;
- }
- inline bool IsCase2(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 00000001 indices: -1
- if ((degree < 2) || (numIndices!= 1))
- {
- return false;
- }
- if ((indices[0] != -1) || (ops[degree-1] != 1) ) return false;
- for (long u = 0; u < degree-1; u++) {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase3(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 00000001 indices: -2
- if ((degree < 2) || (numIndices!= 1))
- {
- return false;
- }
- if ((indices[0] != -2) || (ops[degree-1] != 1) ) return false;
- for (long u = 0; u < degree-1; u++) {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase4(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 10000000 indices: -1
- if ((degree < 2) || (numIndices!= 1))
- {
- return false;
- }
- if ((indices[0] != -1) || (ops[0] != 1) ) return false;
- for (long u = 1; u < degree; u++)
- {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase5(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 10000000 indices: -2
- if ((degree < 2) || (numIndices!= 1))
- {
- return false;
- }
- if ((indices[0] != -2) || (ops[0] != 1) ) return false;
- for (long u = 1; u < degree; u++) {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase6(long degree, long numIndices, const long * const ops, const long * const /*indices*/)
- {
- // ops: 0000000 indices:
- if (numIndices!= 0)
- {
- return false;
- }
- for (long u = 0; u < degree; u++)
- {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase7(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 1000001 indices: -2 -1
- if ((numIndices!= 2) || (degree < 2))
- {
- return false;
- }
- if ((indices[0] != -2) ||(indices[1] != -1) ||
- (ops[0] != 1) ||(ops[degree-1] != 1) ) return false;
- for (long u = 1; u < degree-1; u++)
- {
- if (ops[u] != 0) return false;
- }
- return true;
- }
- inline bool IsCase8(long degree, long numIndices, const long * const ops, const long * const indices)
- {
- // ops: 1xxxxxx1 indices: -1 x x x x x -2
- if ((degree < 2) || (numIndices < 1))
- {
- return false;
- }
- if ((indices[0] != -2) ||(indices[numIndices-1] != -1) ||
- (ops[0] != 1) ||(ops[degree-1] != 1) ) return false;
- return true;
- }
- template <class T>
- TriangleListEncoder<T>::TriangleListEncoder(void)
- {
- m_vtags = 0;
- m_ttags = 0;
- m_tmap = 0;
- m_vmap = 0;
- m_count = 0;
- m_invVMap = 0;
- m_invTMap = 0;
- m_nonConqueredTriangles = 0;
- m_nonConqueredEdges = 0;
- m_visitedVertices = 0;
- m_visitedVerticesValence = 0;
- m_vertexCount = 0;
- m_triangleCount = 0;
- m_maxNumVertices = 0;
- m_maxNumTriangles = 0;
- m_numTriangles = 0;
- m_numVertices = 0;
- m_triangles = 0;
- m_maxSizeVertexToTriangle = 0;
- m_streamType = O3DGC_STREAM_TYPE_UNKOWN;
- }
- template <class T>
- TriangleListEncoder<T>::~TriangleListEncoder()
- {
- delete [] m_vtags;
- delete [] m_vmap;
- delete [] m_invVMap;
- delete [] m_invTMap;
- delete [] m_visitedVerticesValence;
- delete [] m_visitedVertices;
- delete [] m_ttags;
- delete [] m_tmap;
- delete [] m_count;
- delete [] m_nonConqueredTriangles;
- delete [] m_nonConqueredEdges;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::Init(const T * const triangles,
- long numTriangles,
- long numVertices)
- {
- assert(numVertices > 0);
- assert(numTriangles > 0);
-
- m_numTriangles = numTriangles;
- m_numVertices = numVertices;
- m_triangles = triangles;
- m_vertexCount = 0;
- m_triangleCount = 0;
-
- if (m_numVertices > m_maxNumVertices)
- {
- delete [] m_vtags;
- delete [] m_vmap;
- delete [] m_invVMap;
- delete [] m_visitedVerticesValence;
- delete [] m_visitedVertices;
- m_maxNumVertices = m_numVertices;
- m_vtags = new long [m_numVertices];
- m_vmap = new long [m_numVertices];
- m_invVMap = new long [m_numVertices];
- m_visitedVerticesValence = new long [m_numVertices];
- m_visitedVertices = new long [m_numVertices];
- }
-
- if (m_numTriangles > m_maxNumTriangles)
- {
- delete [] m_ttags;
- delete [] m_tmap;
- delete [] m_invTMap;
- delete [] m_nonConqueredTriangles;
- delete [] m_nonConqueredEdges;
- delete [] m_count;
- m_maxNumTriangles = m_numTriangles;
- m_ttags = new long [m_numTriangles];
- m_tmap = new long [m_numTriangles];
- m_invTMap = new long [m_numTriangles];
- m_count = new long [m_numTriangles+1];
- m_nonConqueredTriangles = new long [m_numTriangles];
- m_nonConqueredEdges = new long [2*m_numTriangles];
- }
-
- memset(m_vtags , 0x00, sizeof(long) * m_numVertices );
- memset(m_vmap , 0xFF, sizeof(long) * m_numVertices );
- memset(m_invVMap, 0xFF, sizeof(long) * m_numVertices );
- memset(m_ttags , 0x00, sizeof(long) * m_numTriangles);
- memset(m_tmap , 0xFF, sizeof(long) * m_numTriangles);
- memset(m_invTMap, 0xFF, sizeof(long) * m_numTriangles);
- memset(m_count , 0x00, sizeof(long) * (m_numTriangles+1));
-
- m_vfifo.Allocate(m_numVertices);
- m_ctfans.SetStreamType(m_streamType);
- m_ctfans.Allocate(m_numVertices, m_numTriangles);
-
- // compute vertex-to-triangle adjacency information
- m_vertexToTriangle.AllocateNumNeighborsArray(numVertices);
- m_vertexToTriangle.ClearNumNeighborsArray();
- long * numNeighbors = m_vertexToTriangle.GetNumNeighborsBuffer();
- for(long i = 0, t = 0; i < m_numTriangles; ++i, t+=3)
- {
- ++numNeighbors[ triangles[t ] ];
- ++numNeighbors[ triangles[t+1] ];
- ++numNeighbors[ triangles[t+2] ];
- }
- m_maxSizeVertexToTriangle = 0;
- for(long i = 0; i < numVertices; ++i)
- {
- if (m_maxSizeVertexToTriangle < numNeighbors[i])
- {
- m_maxSizeVertexToTriangle = numNeighbors[i];
- }
- }
- m_vertexToTriangle.AllocateNeighborsArray();
- m_vertexToTriangle.ClearNeighborsArray();
- for(long i = 0, t = 0; i < m_numTriangles; ++i, t+=3)
- {
- m_vertexToTriangle.AddNeighbor(triangles[t ], i);
- m_vertexToTriangle.AddNeighbor(triangles[t+1], i);
- m_vertexToTriangle.AddNeighbor(triangles[t+2], i);
- }
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::Encode(const T * const triangles,
- const unsigned long * const indexBufferIDs,
- const long numTriangles,
- const long numVertices,
- BinaryStream & bstream)
- {
- assert(numVertices > 0);
- assert(numTriangles > 0);
-
- Init(triangles, numTriangles, numVertices);
- unsigned char mask = 0;
- bool encodeTrianglesOrder = (indexBufferIDs != 0);
-
-
- if (encodeTrianglesOrder)
- {
- long numBufferIDs = 0;
- for (long t = 0; t < numTriangles; t++)
- {
- if (numBufferIDs <= (long) indexBufferIDs[t])
- {
- ++numBufferIDs;
- assert(numBufferIDs <= numTriangles);
- }
- ++m_count[indexBufferIDs[t]+1];
- }
- for (long i = 2; i <= numBufferIDs; i++)
- {
- m_count[i] += m_count[i-1];
- }
- mask += 2; // preserved triangles order
- }
- bstream.WriteUChar(mask, m_streamType);
- bstream.WriteUInt32(m_maxSizeVertexToTriangle, m_streamType);
-
- long v0;
- for (long v = 0; v < m_numVertices; v++)
- {
- if (!m_vtags[v])
- {
- m_vfifo.PushBack(v);
- m_vtags[v] = 1;
- m_vmap[v] = m_vertexCount++;
- m_invVMap[m_vmap[v]] = v;
- while (m_vfifo.GetSize() > 0 )
- {
- v0 = m_vfifo.PopFirst();
- ProcessVertex(v0);
- }
- }
- }
- if (encodeTrianglesOrder)
- {
- long t, prev = 0;
- long pred;
- for (long i = 0; i < numTriangles; ++i)
- {
- t = m_invTMap[i];
- m_tmap[t] = m_count[ indexBufferIDs[t] ]++;
- pred = m_tmap[t] - prev;
- m_ctfans.PushTriangleIndex(pred);
- prev = m_tmap[t] + 1;
- }
- for (long t = 0; t < numTriangles; ++t)
- {
- m_invTMap[m_tmap[t]] = t;
- }
- }
- m_ctfans.Save(bstream, encodeTrianglesOrder, m_streamType);
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::CompueLocalConnectivityInfo(const long focusVertex)
- {
- long t, v, p;
- m_numNonConqueredTriangles = 0;
- m_numConqueredTriangles = 0;
- m_numVisitedVertices = 0;
- for(long i = m_vertexToTriangle.Begin(focusVertex); i < m_vertexToTriangle.End(focusVertex); ++i)
- {
- t = m_vertexToTriangle.GetNeighbor(i);
-
- if ( m_ttags[t] == 0) // non-processed triangle
- {
- m_nonConqueredTriangles[m_numNonConqueredTriangles] = t;
- CompueOppositeEdge( focusVertex,
- m_triangles + (3*t),
- m_nonConqueredEdges[m_numNonConqueredTriangles*2],
- m_nonConqueredEdges[m_numNonConqueredTriangles*2+1]);
- ++m_numNonConqueredTriangles;
- }
- else // triangle already processed
- {
- m_numConqueredTriangles++;
- p = 3*t;
- // extract visited vertices
- for(long k = 0; k < 3; ++k)
- {
- v = m_triangles[p+k];
- if (m_vmap[v] > m_vmap[focusVertex]) // vertices are insertices by increasing traversal order
- {
- bool foundOrInserted = false;
- for (long j = 0; j < m_numVisitedVertices; ++j)
- {
-
- if (m_vmap[v] == m_visitedVertices[j])
- {
- m_visitedVerticesValence[j]++;
- foundOrInserted = true;
- break;
- }
- else if (m_vmap[v] < m_visitedVertices[j])
- {
- ++m_numVisitedVertices;
- for (long h = m_numVisitedVertices-1; h > j; --h)
- {
- m_visitedVertices[h] = m_visitedVertices[h-1];
- m_visitedVerticesValence[h] = m_visitedVerticesValence[h-1];
- }
- m_visitedVertices[j] = m_vmap[v];
- m_visitedVerticesValence[j] = 1;
- foundOrInserted = true;
- break;
- }
- }
- if (!foundOrInserted)
- {
- m_visitedVertices[m_numVisitedVertices] = m_vmap[v];
- m_visitedVerticesValence[m_numVisitedVertices] = 1;
- m_numVisitedVertices++;
- }
- }
- }
- }
- }
- // re-order visited vertices by taking into account their valence (i.e., # of conquered triangles incident to each vertex)
- // in order to avoid config. 9
- if (m_numVisitedVertices > 2)
- {
- long y;
- for(long x = 1; x < m_numVisitedVertices; ++x)
- {
-
- if (m_visitedVerticesValence[x] == 1)
- {
- y = x;
- while( (y > 0) && (m_visitedVerticesValence[y] < m_visitedVerticesValence[y-1]) )
- {
- swap(m_visitedVerticesValence[y], m_visitedVerticesValence[y-1]);
- swap(m_visitedVertices[y], m_visitedVertices[y-1]);
- --y;
- }
- }
- }
- }
- if (m_numNonConqueredTriangles > 0)
- {
- // compute triangle-to-triangle adjacency information
- m_triangleToTriangle.AllocateNumNeighborsArray(m_numNonConqueredTriangles);
- m_triangleToTriangle.ClearNumNeighborsArray();
- m_triangleToTriangleInv.AllocateNumNeighborsArray(m_numNonConqueredTriangles);
- m_triangleToTriangleInv.ClearNumNeighborsArray();
- long * const numNeighbors = m_triangleToTriangle.GetNumNeighborsBuffer();
- long * const invNumNeighbors = m_triangleToTriangleInv.GetNumNeighborsBuffer();
- for(long i = 0; i < m_numNonConqueredTriangles; ++i)
- {
- for(long j = i+1; j < m_numNonConqueredTriangles; ++j)
- {
- if (m_nonConqueredEdges[2*i+1] == m_nonConqueredEdges[2*j]) // edge i is connected to edge j
- {
- ++numNeighbors[i];
- ++invNumNeighbors[j];
- }
- if (m_nonConqueredEdges[2*i] == m_nonConqueredEdges[2*j+1]) // edge i is connected to edge j
- {
- ++numNeighbors[j];
- ++invNumNeighbors[i];
- }
- }
- }
- m_triangleToTriangle.AllocateNeighborsArray();
- m_triangleToTriangle.ClearNeighborsArray();
- m_triangleToTriangleInv.AllocateNeighborsArray();
- m_triangleToTriangleInv.ClearNeighborsArray();
- for(long i = 0; i < m_numNonConqueredTriangles; ++i)
- {
- for(long j = 1; j < m_numNonConqueredTriangles; ++j)
- {
- if (m_nonConqueredEdges[2*i+1] == m_nonConqueredEdges[2*j]) // edge i is connected to edge j
- {
- m_triangleToTriangle.AddNeighbor(i, j);
- m_triangleToTriangleInv.AddNeighbor(j, i);
- }
- if (m_nonConqueredEdges[2*i] == m_nonConqueredEdges[2*j+1]) // edge i is connected to edge j
- {
- m_triangleToTriangle.AddNeighbor(j, i);
- m_triangleToTriangleInv.AddNeighbor(i, j);
- }
- }
- }
- }
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::ComputeTFANDecomposition(const long focusVertex)
- {
- long processedTriangles = 0;
- long minNumInputEdges;
- long numInputEdges;
- long indexSeedTriangle;
- long seedTriangle;
- long currentIndex;
- long currentTriangle;
- long i0, i1, index;
-
- m_tfans.Clear();
- while (processedTriangles != m_numNonConqueredTriangles)
- {
- // find non processed triangle with lowest number of inputs
- minNumInputEdges = m_numTriangles;
- indexSeedTriangle = -1;
- for(long i = 0; i < m_numNonConqueredTriangles; ++i)
- {
- numInputEdges = m_triangleToTriangleInv.GetNumNeighbors(i);
- if ( !m_ttags[m_nonConqueredTriangles[i]] &&
- numInputEdges < minNumInputEdges )
- {
- minNumInputEdges = numInputEdges;
- indexSeedTriangle = i;
- if (minNumInputEdges == 0) // found boundary triangle
- {
- break;
- }
- }
- }
- assert(indexSeedTriangle >= 0);
- seedTriangle = m_nonConqueredTriangles[indexSeedTriangle];
- m_tfans.AddTFAN();
- m_tfans.AddVertex( focusVertex );
- m_tfans.AddVertex( m_nonConqueredEdges[indexSeedTriangle*2] );
- m_tfans.AddVertex( m_nonConqueredEdges[indexSeedTriangle*2 + 1] );
- m_ttags[ seedTriangle ] = 1; // mark triangle as processed
- m_tmap[seedTriangle] = m_triangleCount++;
- m_invTMap[m_tmap[seedTriangle]] = seedTriangle;
- ++processedTriangles;
- currentIndex = indexSeedTriangle;
- currentTriangle = seedTriangle;
- do
- {
- // find next triangle
- i0 = m_triangleToTriangle.Begin(currentIndex);
- i1 = m_triangleToTriangle.End(currentIndex);
- currentIndex = -1;
- for(long i = i0; i < i1; ++i)
- {
- index = m_triangleToTriangle.GetNeighbor(i);
- currentTriangle = m_nonConqueredTriangles[index];
- if ( !m_ttags[currentTriangle] )
- {
- currentIndex = index;
- m_tfans.AddVertex( m_nonConqueredEdges[currentIndex*2+1] );
- m_ttags[currentTriangle] = 1; // mark triangle as processed
- m_tmap [currentTriangle] = m_triangleCount++;
- m_invTMap[m_tmap [currentTriangle]] = currentTriangle;
- ++processedTriangles;
- break;
- }
- }
- } while (currentIndex != -1);
- }
-
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::CompressTFAN(const long focusVertex)
- {
- m_ctfans.PushNumTFans(m_tfans.GetNumTFANs());
-
- const long ntfans = m_tfans.GetNumTFANs();
- long degree;
- long k0, k1;
- long v0;
- long ops[O3DGC_MAX_TFAN_SIZE];
- long indices[O3DGC_MAX_TFAN_SIZE];
-
- long numOps;
- long numIndices;
- long pos;
- long found;
-
- if (m_tfans.GetNumTFANs() > 0)
- {
- for(long f = 0; f != ntfans; f++)
- {
- degree = m_tfans.GetTFANSize(f) - 1;
- m_ctfans.PushDegree(degree-2+ m_numConqueredTriangles);
- numOps = 0;
- numIndices = 0;
- k0 = 1 + m_tfans.Begin(f);
- k1 = m_tfans.End(f);
- for(long k = k0; k < k1; k++)
- {
- v0 = m_tfans.GetVertex(k);
- if (m_vtags[v0] == 0)
- {
- ops[numOps++] = 0;
- m_vtags[v0] = 1;
- m_vmap[v0] = m_vertexCount++;
- m_invVMap[m_vmap[v0]] = v0;
- m_vfifo.PushBack(v0);
- m_visitedVertices[m_numVisitedVertices++] = m_vmap[v0];
- }
- else
- {
- ops[numOps++] = 1;
- pos = 0;
- found = 0;
- for(long u=0; u < m_numVisitedVertices; ++u)
- {
- pos++;
- if (m_visitedVertices[u] == m_vmap[v0])
- {
- found = 1;
- break;
- }
- }
- if (found == 1)
- {
- indices[numIndices++] = -pos;
- }
- else
- {
- indices[numIndices++] = m_vmap[v0] - m_vmap[focusVertex];
- }
- }
- }
- //-----------------------------------------------
- if (IsCase0(degree, numIndices, ops, indices))
- {
- // ops: 1000001 vertices: -1 -2
- m_ctfans.PushConfig(0);
- }
- else if (IsCase1(degree, numIndices, ops, indices))
- {
- // ops: 1xxxxxx1 vertices: -1 x x x x x -2
- long u = 1;
- for(u = 1; u < degree-1; u++)
- {
- m_ctfans.PushOperation(ops[u]);
- }
- for(u =1; u < numIndices-1; u++)
- {
- m_ctfans.PushIndex(indices[u]);
- }
- m_ctfans.PushConfig(1);
- }
- else if (IsCase2(degree, numIndices, ops, indices))
- {
- // ops: 00000001 vertices: -1
- m_ctfans.PushConfig(2);
- }
- else if (IsCase3(degree, numIndices, ops, indices))
- {
- // ops: 00000001 vertices: -2
- m_ctfans.PushConfig(3);
- }
- else if (IsCase4(degree, numIndices, ops, indices))
- {
- // ops: 10000000 vertices: -1
- m_ctfans.PushConfig(4);
- }
- else if (IsCase5(degree, numIndices, ops, indices))
- {
- // ops: 10000000 vertices: -2
- m_ctfans.PushConfig(5);
- }
- else if (IsCase6(degree, numIndices, ops, indices))
- {
- // ops: 00000000 vertices:
- m_ctfans.PushConfig(6);
- }
- else if (IsCase7(degree, numIndices, ops, indices))
- {
- // ops: 1000001 vertices: -1 -2
- m_ctfans.PushConfig(7);
- }
- else if (IsCase8(degree, numIndices, ops, indices))
- {
- // ops: 1xxxxxx1 vertices: -2 x x x x x -1
- long u = 1;
- for(u =1; u < degree-1; u++)
- {
- m_ctfans.PushOperation(ops[u]);
- }
- for(u =1; u < numIndices-1; u++)
- {
- m_ctfans.PushIndex(indices[u]);
- }
- m_ctfans.PushConfig(8);
- }
- else
- {
- long u = 0;
- for(u =0; u < degree; u++)
- {
- m_ctfans.PushOperation(ops[u]);
- }
- for(u =0; u < numIndices; u++)
- {
- m_ctfans.PushIndex(indices[u]);
- }
- m_ctfans.PushConfig(9);
- }
- }
- }
- return O3DGC_OK;
- }
- template <class T>
- O3DGCErrorCode TriangleListEncoder<T>::ProcessVertex(const long focusVertex)
- {
- CompueLocalConnectivityInfo(focusVertex);
- ComputeTFANDecomposition(focusVertex);
- CompressTFAN(focusVertex);
- return O3DGC_OK;
- }
-}
-#endif //O3DGC_TRIANGLE_LIST_ENCODER_INL
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.h b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.h
deleted file mode 100644
index 08d3ed564..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_VECTOR_H
-#define O3DGC_VECTOR_H
-
-#include "o3dgcCommon.h"
-
-namespace o3dgc
-{
- const unsigned long O3DGC_DEFAULT_VECTOR_SIZE = 32;
-
- //!
- template < typename T > class Vector
- {
- public:
- //! Constructor.
- Vector()
- {
- m_allocated = 0;
- m_size = 0;
- m_buffer = 0;
- };
- //! Destructor.
- ~Vector(void)
- {
- delete [] m_buffer;
- };
- T & operator[](unsigned long i)
- {
- return m_buffer[i];
- }
- const T & operator[](unsigned long i) const
- {
- return m_buffer[i];
- }
- void Allocate(unsigned long size)
- {
- if (size > m_allocated)
- {
- m_allocated = size;
- T * tmp = new T [m_allocated];
- if (m_size > 0)
- {
- memcpy(tmp, m_buffer, m_size * sizeof(T) );
- delete [] m_buffer;
- }
- m_buffer = tmp;
- }
- };
- void PushBack(const T & value)
- {
- if (m_size == m_allocated)
- {
- m_allocated *= 2;
- if (m_allocated < O3DGC_DEFAULT_VECTOR_SIZE)
- {
- m_allocated = O3DGC_DEFAULT_VECTOR_SIZE;
- }
- T * tmp = new T [m_allocated];
- if (m_size > 0)
- {
- memcpy(tmp, m_buffer, m_size * sizeof(T) );
- delete [] m_buffer;
- }
- m_buffer = tmp;
- }
- assert(m_size < m_allocated);
- m_buffer[m_size++] = value;
- }
- const T * GetBuffer() const { return m_buffer;};
- T * GetBuffer() { return m_buffer;};
- unsigned long GetSize() const { return m_size;};
- void SetSize(unsigned long size)
- {
- assert(size <= m_allocated);
- m_size = size;
- };
- unsigned long GetAllocatedSize() const { return m_allocated;};
- void Clear(){ m_size = 0;};
-
- private:
- T * m_buffer;
- unsigned long m_allocated;
- unsigned long m_size;
- };
-
-
-
-
- //! Vector dim 3.
- template < typename T > class Vec3
- {
- public:
- T & operator[](unsigned long i) { return m_data[i];}
- const T & operator[](unsigned long i) const { return m_data[i];}
- T & X();
- T & Y();
- T & Z();
- const T & X() const;
- const T & Y() const;
- const T & Z() const;
- double GetNorm() const;
- void operator= (const Vec3 & rhs);
- void operator+=(const Vec3 & rhs);
- void operator-=(const Vec3 & rhs);
- void operator-=(T a);
- void operator+=(T a);
- void operator/=(T a);
- void operator*=(T a);
- Vec3 operator^ (const Vec3 & rhs) const;
- T operator* (const Vec3 & rhs) const;
- Vec3 operator+ (const Vec3 & rhs) const;
- Vec3 operator- (const Vec3 & rhs) const;
- Vec3 operator- () const;
- Vec3 operator* (T rhs) const;
- Vec3 operator/ (T rhs) const;
- Vec3();
- Vec3(T a);
- Vec3(T x, T y, T z);
- Vec3(const Vec3 & rhs);
- ~Vec3(void);
-
- private:
- T m_data[3];
- };
- //! Vector dim 2.
- template < typename T > class Vec2
- {
- public:
- T & operator[](unsigned long i) { return m_data[i];}
- const T & operator[](unsigned long i) const { return m_data[i];}
- T & X();
- T & Y();
- const T & X() const;
- const T & Y() const;
- double GetNorm() const;
- void operator= (const Vec2 & rhs);
- void operator+=(const Vec2 & rhs);
- void operator-=(const Vec2 & rhs);
- void operator-=(T a);
- void operator+=(T a);
- void operator/=(T a);
- void operator*=(T a);
- T operator^ (const Vec2 & rhs) const;
- T operator* (const Vec2 & rhs) const;
- Vec2 operator+ (const Vec2 & rhs) const;
- Vec2 operator- (const Vec2 & rhs) const;
- Vec2 operator- () const;
- Vec2 operator* (T rhs) const;
- Vec2 operator/ (T rhs) const;
- Vec2();
- Vec2(T a);
- Vec2(T x, T y);
- Vec2(const Vec2 & rhs);
- ~Vec2(void);
-
- private:
- T m_data[2];
- };
-}
-#include "o3dgcVector.inl" // template implementation
-#endif // O3DGC_VECTOR_H
-
diff --git a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.inl b/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.inl
deleted file mode 100644
index 5549b00ce..000000000
--- a/src/3rdparty/assimp/contrib/Open3DGC/o3dgcVector.inl
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
-Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-
-#pragma once
-#ifndef O3DGC_VECTOR_INL
-#define O3DGC_VECTOR_INL
-namespace o3dgc
-{
- template <typename T>
- inline Vec3<T> operator*(T lhs, const Vec3<T> & rhs)
- {
- return Vec3<T>(lhs * rhs.X(), lhs * rhs.Y(), lhs * rhs.Z());
- }
- template <typename T>
- inline T & Vec3<T>::X()
- {
- return m_data[0];
- }
- template <typename T>
- inline T & Vec3<T>::Y()
- {
- return m_data[1];
- }
- template <typename T>
- inline T & Vec3<T>::Z()
- {
- return m_data[2];
- }
- template <typename T>
- inline const T & Vec3<T>::X() const
- {
- return m_data[0];
- }
- template <typename T>
- inline const T & Vec3<T>::Y() const
- {
- return m_data[1];
- }
- template <typename T>
- inline const T & Vec3<T>::Z() const
- {
- return m_data[2];
- }
- template <typename T>
- inline double Vec3<T>::GetNorm() const
- {
- double a = (double) (m_data[0]);
- double b = (double) (m_data[1]);
- double c = (double) (m_data[2]);
- return sqrt(a*a+b*b+c*c);
- }
- template <typename T>
- inline void Vec3<T>::operator= (const Vec3 & rhs)
- {
- this->m_data[0] = rhs.m_data[0];
- this->m_data[1] = rhs.m_data[1];
- this->m_data[2] = rhs.m_data[2];
- }
- template <typename T>
- inline void Vec3<T>::operator+=(const Vec3 & rhs)
- {
- this->m_data[0] += rhs.m_data[0];
- this->m_data[1] += rhs.m_data[1];
- this->m_data[2] += rhs.m_data[2];
- }
- template <typename T>
- inline void Vec3<T>::operator-=(const Vec3 & rhs)
- {
- this->m_data[0] -= rhs.m_data[0];
- this->m_data[1] -= rhs.m_data[1];
- this->m_data[2] -= rhs.m_data[2];
- }
- template <typename T>
- inline void Vec3<T>::operator-=(T a)
- {
- this->m_data[0] -= a;
- this->m_data[1] -= a;
- this->m_data[2] -= a;
- }
- template <typename T>
- inline void Vec3<T>::operator+=(T a)
- {
- this->m_data[0] += a;
- this->m_data[1] += a;
- this->m_data[2] += a;
- }
- template <typename T>
- inline void Vec3<T>::operator/=(T a)
- {
- this->m_data[0] /= a;
- this->m_data[1] /= a;
- this->m_data[2] /= a;
- }
- template <typename T>
- inline void Vec3<T>::operator*=(T a)
- {
- this->m_data[0] *= a;
- this->m_data[1] *= a;
- this->m_data[2] *= a;
- }
- template <typename T>
- inline Vec3<T> Vec3<T>::operator^ (const Vec3<T> & rhs) const
- {
- return Vec3<T>(m_data[1] * rhs.m_data[2] - m_data[2] * rhs.m_data[1],
- m_data[2] * rhs.m_data[0] - m_data[0] * rhs.m_data[2],
- m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0]);
- }
- template <typename T>
- inline T Vec3<T>::operator*(const Vec3<T> & rhs) const
- {
- return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1] + m_data[2] * rhs.m_data[2]);
- }
- template <typename T>
- inline Vec3<T> Vec3<T>::operator+(const Vec3<T> & rhs) const
- {
- return Vec3<T>(m_data[0] + rhs.m_data[0],m_data[1] + rhs.m_data[1],m_data[2] + rhs.m_data[2]);
- }
- template <typename T>
- inline Vec3<T> Vec3<T>::operator-(const Vec3<T> & rhs) const
- {
- return Vec3<T>(m_data[0] - rhs.m_data[0],m_data[1] - rhs.m_data[1],m_data[2] - rhs.m_data[2]);
- }
- template <typename T>
- inline Vec3<T> Vec3<T>::operator-() const
- {
- return Vec3<T>(-m_data[0],-m_data[1],-m_data[2]);
- }
-
- template <typename T>
- inline Vec3<T> Vec3<T>::operator*(T rhs) const
- {
- return Vec3<T>(rhs * this->m_data[0], rhs * this->m_data[1], rhs * this->m_data[2]);
- }
- template <typename T>
- inline Vec3<T> Vec3<T>::operator/ (T rhs) const
- {
- return Vec3<T>(m_data[0] / rhs, m_data[1] / rhs, m_data[2] / rhs);
- }
- template <typename T>
- inline Vec3<T>::Vec3(T a)
- {
- m_data[0] = m_data[1] = m_data[2] = a;
- }
- template <typename T>
- inline Vec3<T>::Vec3(T x, T y, T z)
- {
- m_data[0] = x;
- m_data[1] = y;
- m_data[2] = z;
- }
- template <typename T>
- inline Vec3<T>::Vec3(const Vec3 & rhs)
- {
- m_data[0] = rhs.m_data[0];
- m_data[1] = rhs.m_data[1];
- m_data[2] = rhs.m_data[2];
- }
- template <typename T>
- inline Vec3<T>::~Vec3(void){};
-
- template <typename T>
- inline Vec3<T>::Vec3() {}
-
- template <typename T>
- inline Vec2<T> operator*(T lhs, const Vec2<T> & rhs)
- {
- return Vec2<T>(lhs * rhs.X(), lhs * rhs.Y());
- }
- template <typename T>
- inline T & Vec2<T>::X()
- {
- return m_data[0];
- }
- template <typename T>
- inline T & Vec2<T>::Y()
- {
- return m_data[1];
- }
- template <typename T>
- inline const T & Vec2<T>::X() const
- {
- return m_data[0];
- }
- template <typename T>
- inline const T & Vec2<T>::Y() const
- {
- return m_data[1];
- }
- template <typename T>
- inline double Vec2<T>::GetNorm() const
- {
- double a = (double) (m_data[0]);
- double b = (double) (m_data[1]);
- return sqrt(a*a+b*b);
- }
- template <typename T>
- inline void Vec2<T>::operator= (const Vec2 & rhs)
- {
- this->m_data[0] = rhs.m_data[0];
- this->m_data[1] = rhs.m_data[1];
- }
- template <typename T>
- inline void Vec2<T>::operator+=(const Vec2 & rhs)
- {
- this->m_data[0] += rhs.m_data[0];
- this->m_data[1] += rhs.m_data[1];
- }
- template <typename T>
- inline void Vec2<T>::operator-=(const Vec2 & rhs)
- {
- this->m_data[0] -= rhs.m_data[0];
- this->m_data[1] -= rhs.m_data[1];
- }
- template <typename T>
- inline void Vec2<T>::operator-=(T a)
- {
- this->m_data[0] -= a;
- this->m_data[1] -= a;
- }
- template <typename T>
- inline void Vec2<T>::operator+=(T a)
- {
- this->m_data[0] += a;
- this->m_data[1] += a;
- }
- template <typename T>
- inline void Vec2<T>::operator/=(T a)
- {
- this->m_data[0] /= a;
- this->m_data[1] /= a;
- }
- template <typename T>
- inline void Vec2<T>::operator*=(T a)
- {
- this->m_data[0] *= a;
- this->m_data[1] *= a;
- }
- template <typename T>
- inline T Vec2<T>::operator^ (const Vec2<T> & rhs) const
- {
- return m_data[0] * rhs.m_data[1] - m_data[1] * rhs.m_data[0];
- }
- template <typename T>
- inline T Vec2<T>::operator*(const Vec2<T> & rhs) const
- {
- return (m_data[0] * rhs.m_data[0] + m_data[1] * rhs.m_data[1]);
- }
- template <typename T>
- inline Vec2<T> Vec2<T>::operator+(const Vec2<T> & rhs) const
- {
- return Vec2<T>(m_data[0] + rhs.m_data[0],m_data[1] + rhs.m_data[1]);
- }
- template <typename T>
- inline Vec2<T> Vec2<T>::operator-(const Vec2<T> & rhs) const
- {
- return Vec2<T>(m_data[0] - rhs.m_data[0],m_data[1] - rhs.m_data[1]);
- }
- template <typename T>
- inline Vec2<T> Vec2<T>::operator-() const
- {
- return Vec2<T>(-m_data[0],-m_data[1]) ;
- }
-
- template <typename T>
- inline Vec2<T> Vec2<T>::operator*(T rhs) const
- {
- return Vec2<T>(rhs * this->m_data[0], rhs * this->m_data[1]);
- }
- template <typename T>
- inline Vec2<T> Vec2<T>::operator/ (T rhs) const
- {
- return Vec2<T>(m_data[0] / rhs, m_data[1] / rhs);
- }
- template <typename T>
- inline Vec2<T>::Vec2(T a)
- {
- m_data[0] = m_data[1] = a;
- }
- template <typename T>
- inline Vec2<T>::Vec2(T x, T y)
- {
- m_data[0] = x;
- m_data[1] = y;
- }
- template <typename T>
- inline Vec2<T>::Vec2(const Vec2 & rhs)
- {
- m_data[0] = rhs.m_data[0];
- m_data[1] = rhs.m_data[1];
- }
- template <typename T>
- inline Vec2<T>::~Vec2(void){};
-
- template <typename T>
- inline Vec2<T>::Vec2() {}
-}
-#endif //O3DGC_VECTOR_INL
-
diff --git a/src/3rdparty/assimp/contrib/clipper/License.txt b/src/3rdparty/assimp/contrib/clipper/License.txt
deleted file mode 100644
index 8e2278cef..000000000
--- a/src/3rdparty/assimp/contrib/clipper/License.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-The Clipper code library, the "Software" (that includes Delphi, C++ & C#
-source code, accompanying samples and documentation), has been released
-under the following license, terms and conditions:
-
-Boost Software License - Version 1.0 - August 17th, 2003
-http://www.boost.org/LICENSE_1_0.txt
-
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-
diff --git a/src/3rdparty/assimp/contrib/clipper/clipper.cpp b/src/3rdparty/assimp/contrib/clipper/clipper.cpp
deleted file mode 100644
index 074f22b21..000000000
--- a/src/3rdparty/assimp/contrib/clipper/clipper.cpp
+++ /dev/null
@@ -1,3451 +0,0 @@
-/*******************************************************************************
-* *
-* Author : Angus Johnson *
-* Version : 4.8.8 *
-* Date : 30 August 2012 *
-* Website : http://www.angusj.com *
-* Copyright : Angus Johnson 2010-2012 *
-* *
-* License: *
-* Use, modification & distribution is subject to Boost Software License Ver 1. *
-* http://www.boost.org/LICENSE_1_0.txt *
-* *
-* Attributions: *
-* The code in this library is an extension of Bala Vatti's clipping algorithm: *
-* "A generic solution to polygon clipping" *
-* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
-* http://portal.acm.org/citation.cfm?id=129906 *
-* *
-* Computer graphics and geometric modeling: implementation and algorithms *
-* By Max K. Agoston *
-* Springer; 1 edition (January 4, 2005) *
-* http://books.google.com/books?q=vatti+clipping+agoston *
-* *
-* See also: *
-* "Polygon Offsetting by Computing Winding Numbers" *
-* Paper no. DETC2005-85513 pp. 565-575 *
-* ASME 2005 International Design Engineering Technical Conferences *
-* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
-* September 24-28, 2005 , Long Beach, California, USA *
-* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
-* *
-*******************************************************************************/
-
-/*******************************************************************************
-* *
-* This is a translation of the Delphi Clipper library and the naming style *
-* used has retained a Delphi flavour. *
-* *
-*******************************************************************************/
-
-#include "clipper.hpp"
-#include <cmath>
-#include <vector>
-#include <algorithm>
-#include <stdexcept>
-#include <cassert>
-#include <cstring>
-#include <cstdlib>
-#include <ostream>
-
-namespace ClipperLib {
-
-static long64 const loRange = 0x3FFFFFFF;
-static long64 const hiRange = 0x3FFFFFFFFFFFFFFFLL;
-static double const pi = 3.141592653589793238;
-enum Direction { dRightToLeft, dLeftToRight };
-
-#define HORIZONTAL (-1.0E+40)
-#define TOLERANCE (1.0e-20)
-#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
-#define NEAR_EQUAL(a, b) NEAR_ZERO((a) - (b))
-
-inline long64 Abs(long64 val)
-{
- return val < 0 ? -val : val;
-}
-//------------------------------------------------------------------------------
-
-//------------------------------------------------------------------------------
-// Int128 class (enables safe math on signed 64bit integers)
-// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1
-// Int128 val2((long64)9223372036854775807);
-// Int128 val3 = val1 * val2;
-// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37)
-//------------------------------------------------------------------------------
-
-class Int128
-{
- public:
-
- Int128(long64 _lo = 0)
- {
- 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)
- {
- 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
- {
- if (hi != val.hi)
- return hi > val.hi;
- else
- return lo > val.lo;
- }
-
- bool operator < (const Int128 &val) const
- {
- 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;
- lo += rhs.lo;
- if (ulong64(lo) < ulong64(rhs.lo)) hi++;
- return *this;
- }
-
- Int128 operator + (const Int128 &rhs) const
- {
- Int128 result(*this);
- result+= rhs;
- return result;
- }
-
- Int128& operator -= (const Int128 &rhs)
- {
- Int128 tmp(rhs);
- Negate(tmp);
- *this += tmp;
- 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;
- return result;
- }
-
- 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);
-
- Int128 tmp(*this);
- if (tmp.hi < 0) Negate(tmp);
- ulong64 int1Hi = ulong64(tmp.lo) >> 32;
- ulong64 int1Lo = ulong64(tmp.lo & 0xFFFFFFFF);
-
- tmp = rhs;
- if (tmp.hi < 0) Negate(tmp);
- ulong64 int2Hi = ulong64(tmp.lo) >> 32;
- ulong64 int2Lo = ulong64(tmp.lo & 0xFFFFFFFF);
-
- //nb: see comments in clipper.pas
- ulong64 a = int1Hi * int2Hi;
- ulong64 b = int1Lo * int2Lo;
- ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;
-
- tmp.hi = long64(a + (c >> 32));
- tmp.lo = long64(c << 32);
- tmp.lo += long64(b);
- if (ulong64(tmp.lo) < b) tmp.hi++;
- if (negate) Negate(tmp);
- return tmp;
- }
-
- Int128 operator/ (const Int128 &rhs) const
- {
- if (rhs.lo == 0 && rhs.hi == 0)
- throw "Int128 operator/: divide by zero";
- bool negate = (rhs.hi < 0) != (hi < 0);
- Int128 result(*this), denom(rhs);
- if (result.hi < 0) Negate(result);
- if (denom.hi < 0) Negate(denom);
- if (denom > result) return Int128(0); //result is only a fraction of 1
- Negate(denom);
-
- Int128 p(0);
- for (int i = 0; i < 128; ++i)
- {
- p.hi = p.hi << 1;
- if (p.lo < 0) p.hi++;
- p.lo = long64(p.lo) << 1;
- if (result.hi < 0) p.lo++;
- result.hi = result.hi << 1;
- if (result.lo < 0) result.hi++;
- result.lo = long64(result.lo) << 1;
- Int128 p2(p);
- p += denom;
- if (p.hi < 0) p = p2;
- else result.lo++;
- }
- if (negate) Negate(result);
- return result;
- }
-
- double AsDouble() const
- {
- const double shift64 = 18446744073709551616.0; //2^64
- const double bit64 = 9223372036854775808.0;
- if (hi < 0)
- {
- Int128 tmp(*this);
- Negate(tmp);
- if (tmp.lo < 0)
- return (double)tmp.lo - bit64 - tmp.hi * shift64;
- else
- return -(double)tmp.lo - tmp.hi * shift64;
- }
- else if (lo < 0)
- return -(double)lo + bit64 + hi * shift64;
- else
- return (double)lo + (double)hi * shift64;
- }
-
- //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;
- //}
-
-private:
- long64 hi;
- long64 lo;
-
- static void Negate(Int128 &val)
- {
- if (val.lo == 0) {
- if (val.hi != 0) val.hi = -val.hi;;
- }
- 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);
- // }
- // }
- //}
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-bool FullRangeNeeded(const Polygon &pts)
-{
- bool result = false;
- for (Polygon::size_type i = 0; i < pts.size(); ++i)
- {
- if (Abs(pts[i].X) > hiRange || Abs(pts[i].Y) > hiRange)
- throw "Coordinate exceeds range bounds.";
- else if (Abs(pts[i].X) > loRange || Abs(pts[i].Y) > loRange)
- result = true;
- }
- return result;
-}
-//------------------------------------------------------------------------------
-
-bool Orientation(const Polygon &poly)
-{
- int highI = (int)poly.size() -1;
- if (highI < 2) return false;
-
- int j = 0, jplus, jminus;
- for (int i = 0; i <= highI; ++i)
- {
- if (poly[i].Y < poly[j].Y) continue;
- if ((poly[i].Y > poly[j].Y || poly[i].X < poly[j].X)) j = i;
- };
- if (j == highI) jplus = 0;
- else jplus = j +1;
- if (j == 0) jminus = highI;
- else jminus = j -1;
-
- IntPoint vec1, vec2;
- //get cross product of vectors of the edges adjacent to highest point ...
- vec1.X = poly[j].X - poly[jminus].X;
- vec1.Y = poly[j].Y - poly[jminus].Y;
- vec2.X = poly[jplus].X - poly[j].X;
- vec2.Y = poly[jplus].Y - poly[j].Y;
-
- 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;
- }
- 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 );
-}
-//------------------------------------------------------------------------------
-
-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)
- {
- if (op->pt.Y >= opBottom->pt.Y)
- {
- if (op->pt.Y > opBottom->pt.Y || op->pt.X < opBottom->pt.X)
- opBottom = op;
- }
- op = op->next;
- }
- outRec->bottomPt = opBottom;
- opBottom->idx = outRec->idx;
-
- 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)
- return Int128(ip1.X) * Int128(ip2.Y) - Int128(ip2.X) * Int128(ip1.Y) >= 0;
- else
- return (ip1.X * ip2.Y - ip2.X * ip1.Y) >= 0;
-}
-//------------------------------------------------------------------------------
-
-double Area(const Polygon &poly)
-{
- int highI = (int)poly.size() -1;
- if (highI < 2) return 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)
- a += Int128(poly[i].X) * Int128(poly[i+1].Y) -
- Int128(poly[i+1].X) * Int128(poly[i].Y);
- return a.AsDouble() / 2;
- }
- else
- {
- double a;
- a = (double)poly[highI].X * poly[0].Y - (double)poly[0].X * poly[highI].Y;
- for (int i = 0; i < highI; ++i)
- a += (double)poly[i].X * poly[i+1].Y - (double)poly[i+1].X * poly[i].Y;
- return a/2;
- }
-}
-//------------------------------------------------------------------------------
-
-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;
- do
- {
- if (PointsEqual(pp2->pt, pt)) return true;
- pp2 = pp2->next;
- }
- while (pp2 != pp);
- return false;
-}
-//------------------------------------------------------------------------------
-
-bool PointInPolygon(const IntPoint &pt, OutPt *pp, bool UseFullInt64Range)
-{
- OutPt *pp2 = pp;
- bool result = false;
- if (UseFullInt64Range) {
- do
- {
- if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) ||
- ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) &&
- Int128(pt.X - pp2->pt.X) < (Int128(pp2->prev->pt.X - pp2->pt.X) *
- Int128(pt.Y - pp2->pt.Y)) / Int128(pp2->prev->pt.Y - pp2->pt.Y))
- result = !result;
- pp2 = pp2->next;
- }
- while (pp2 != pp);
- }
- else
- {
- do
- {
- if ((((pp2->pt.Y <= pt.Y) && (pt.Y < pp2->prev->pt.Y)) ||
- ((pp2->prev->pt.Y <= pt.Y) && (pt.Y < pp2->pt.Y))) &&
- (pt.X < (pp2->prev->pt.X - pp2->pt.X) * (pt.Y - pp2->pt.Y) /
- (pp2->prev->pt.Y - pp2->pt.Y) + pp2->pt.X )) result = !result;
- pp2 = pp2->next;
- }
- while (pp2 != pp);
- }
- return result;
-}
-//------------------------------------------------------------------------------
-
-bool SlopesEqual(TEdge &e1, TEdge &e2, bool 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) ==
- (e1.xtop - e1.xbot)*(e2.ytop - e2.ybot);
-}
-//------------------------------------------------------------------------------
-
-bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
- const IntPoint pt3, bool 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);
-}
-//------------------------------------------------------------------------------
-
-bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
- const IntPoint pt3, const IntPoint pt4, bool 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);
-}
-//------------------------------------------------------------------------------
-
-double GetDx(const IntPoint pt1, const IntPoint pt2)
-{
- 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);
-}
-//---------------------------------------------------------------------------
-
-void SwapSides(TEdge &edge1, TEdge &edge2)
-{
- EdgeSide side = edge1.side;
- edge1.side = edge2.side;
- edge2.side = side;
-}
-//------------------------------------------------------------------------------
-
-void SwapPolyIndexes(TEdge &edge1, TEdge &edge2)
-{
- int outIdx = edge1.outIdx;
- edge1.outIdx = edge2.outIdx;
- edge2.outIdx = outIdx;
-}
-//------------------------------------------------------------------------------
-
-inline long64 Round(double val)
-{
- return (val < 0) ?
- static_cast<long64>(val - 0.5) : static_cast<long64>(val + 0.5);
-}
-//------------------------------------------------------------------------------
-
-long64 TopX(TEdge &edge, const long64 currentY)
-{
- return ( currentY == edge.ytop ) ?
- edge.xtop : edge.xbot + Round(edge.dx *(currentY - edge.ybot));
-}
-//------------------------------------------------------------------------------
-
-long64 TopX(const IntPoint pt1, const IntPoint pt2, const long64 currentY)
-{
- //preconditions: pt1.Y <> pt2.Y and pt1.Y > pt2.Y
- if (currentY >= pt1.Y) return pt1.X;
- else if (currentY == pt2.Y) return pt2.X;
- else if (pt1.X == pt2.X) return pt1.X;
- else
- {
- double q = (double)(pt1.X-pt2.X)/(double)(pt1.Y-pt2.Y);
- return Round(pt1.X + (currentY - pt1.Y) *q);
- }
-}
-//------------------------------------------------------------------------------
-
-bool IntersectPoint(TEdge &edge1, TEdge &edge2,
- IntPoint &ip, bool UseFullInt64Range)
-{
- double b1, b2;
- if (SlopesEqual(edge1, edge2, UseFullInt64Range)) return false;
- else if (NEAR_ZERO(edge1.dx))
- {
- ip.X = edge1.xbot;
- if (NEAR_EQUAL(edge2.dx, HORIZONTAL))
- {
- ip.Y = edge2.ybot;
- } else
- {
- b2 = edge2.ybot - (edge2.xbot/edge2.dx);
- ip.Y = Round(ip.X/edge2.dx + b2);
- }
- }
- else if (NEAR_ZERO(edge2.dx))
- {
- ip.X = edge2.xbot;
- if (NEAR_EQUAL(edge1.dx, HORIZONTAL))
- {
- ip.Y = edge1.ybot;
- } else
- {
- b1 = edge1.ybot - (edge1.xbot/edge1.dx);
- ip.Y = Round(ip.X/edge1.dx + b1);
- }
- } else
- {
- b1 = edge1.xbot - edge1.ybot * edge1.dx;
- b2 = edge2.xbot - edge2.ybot * edge2.dx;
- b2 = (b2-b1)/(edge1.dx - edge2.dx);
- ip.Y = Round(b2);
- ip.X = Round(edge1.dx * b2 + b1);
- }
-
- return
- //can be *so close* to the top of one edge that the rounded Y equals one ytop ...
- (ip.Y == edge1.ytop && ip.Y >= edge2.ytop && edge1.tmpX > edge2.tmpX) ||
- (ip.Y == edge2.ytop && ip.Y >= edge1.ytop && edge1.tmpX > edge2.tmpX) ||
- (ip.Y > edge1.ytop && ip.Y > edge2.ytop);
-}
-//------------------------------------------------------------------------------
-
-void ReversePolyPtLinks(OutPt &pp)
-{
- OutPt *pp1, *pp2;
- pp1 = &pp;
- do {
- pp2 = pp1->next;
- pp1->next = pp1->prev;
- pp1->prev = pp2;
- pp1 = pp2;
- } while( pp1 != &pp );
-}
-//------------------------------------------------------------------------------
-
-void DisposeOutPts(OutPt*& pp)
-{
- if (pp == 0) return;
- pp->prev->next = 0;
- while( pp )
- {
- OutPt *tmpPp = pp;
- pp = pp->next;
- delete tmpPp ;
- }
-}
-//------------------------------------------------------------------------------
-
-void InitEdge(TEdge *e, TEdge *eNext,
- TEdge *ePrev, const IntPoint &pt, PolyType polyType)
-{
- std::memset( e, 0, sizeof( TEdge ));
-
- e->next = eNext;
- e->prev = ePrev;
- e->xcurr = pt.X;
- e->ycurr = pt.Y;
- if (e->ycurr >= e->next->ycurr)
- {
- e->xbot = e->xcurr;
- e->ybot = e->ycurr;
- e->xtop = e->next->xcurr;
- e->ytop = e->next->ycurr;
- e->windDelta = 1;
- } else
- {
- e->xtop = e->xcurr;
- e->ytop = e->ycurr;
- e->xbot = e->next->xcurr;
- e->ybot = e->next->ycurr;
- e->windDelta = -1;
- }
- SetDx(*e);
- e->polyType = polyType;
- e->outIdx = -1;
-}
-//------------------------------------------------------------------------------
-
-inline void SwapX(TEdge &e)
-{
- //swap horizontal edges' top and bottom x's so they follow the natural
- //progression of the bounds - ie so their xbots will align with the
- //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
- e.xcurr = e.xtop;
- e.xtop = e.xbot;
- e.xbot = e.xcurr;
-}
-//------------------------------------------------------------------------------
-
-void SwapPoints(IntPoint &pt1, IntPoint &pt2)
-{
- IntPoint tmp = pt1;
- pt1 = pt2;
- pt2 = tmp;
-}
-//------------------------------------------------------------------------------
-
-bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
- IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
-{
- //precondition: segments are colinear.
- if ( pt1a.Y == pt1b.Y || Abs((pt1a.X - pt1b.X)/(pt1a.Y - pt1b.Y)) > 1 )
- {
- if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b);
- if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b);
- if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a;
- if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b;
- return pt1.X < pt2.X;
- } else
- {
- if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b);
- if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b);
- if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a;
- if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b;
- return pt1.Y > pt2.Y;
- }
-}
-//------------------------------------------------------------------------------
-
-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;
- while (p != pp)
- {
- 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;
- }
- 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;
-}
-//------------------------------------------------------------------------------
-
-bool FindSegment(OutPt* &pp, IntPoint &pt1, IntPoint &pt2)
-{
- //outPt1 & outPt2 => the overlap segment (if the function returns true)
- if (!pp) return false;
- OutPt* pp2 = pp;
- IntPoint pt1a = pt1, pt2a = pt2;
- do
- {
- if (SlopesEqual(pt1a, pt2a, pp->pt, pp->prev->pt, true) &&
- SlopesEqual(pt1a, pt2a, pp->pt, true) &&
- GetOverlapSegment(pt1a, pt2a, pp->pt, pp->prev->pt, pt1, pt2))
- return true;
- pp = pp->next;
- }
- while (pp != pp2);
- return false;
-}
-//------------------------------------------------------------------------------
-
-bool Pt3IsBetweenPt1AndPt2(const IntPoint pt1,
- const IntPoint pt2, const IntPoint pt3)
-{
- if (PointsEqual(pt1, pt3) || PointsEqual(pt2, pt3)) return true;
- else if (pt1.X != pt2.X) return (pt1.X < pt3.X) == (pt3.X < pt2.X);
- else return (pt1.Y < pt3.Y) == (pt3.Y < pt2.Y);
-}
-//------------------------------------------------------------------------------
-
-OutPt* InsertPolyPtBetween(OutPt* p1, OutPt* p2, const IntPoint pt)
-{
- if (p1 == p2) throw "JoinError";
- OutPt* result = new OutPt;
- result->pt = pt;
- if (p2 == p1->next)
- {
- p1->next = result;
- p2->prev = result;
- result->next = p2;
- result->prev = p1;
- } else
- {
- p2->next = result;
- p1->prev = result;
- result->next = p1;
- result->prev = p2;
- }
- return result;
-}
-
-//------------------------------------------------------------------------------
-// ClipperBase class methods ...
-//------------------------------------------------------------------------------
-
-ClipperBase::ClipperBase() //constructor
-{
- m_MinimaList = 0;
- m_CurrentLM = 0;
- m_UseFullRange = true;
-}
-//------------------------------------------------------------------------------
-
-ClipperBase::~ClipperBase() //destructor
-{
- Clear();
-}
-//------------------------------------------------------------------------------
-
-bool ClipperBase::AddPolygon( const Polygon &pg, PolyType polyType)
-{
- int len = (int)pg.size();
- if (len < 3) return false;
- Polygon p(len);
- p[0] = pg[0];
- int j = 0;
-
- long64 maxVal;
- if (m_UseFullRange) maxVal = hiRange; else maxVal = loRange;
-
- for (int i = 0; i < len; ++i)
- {
- if (Abs(pg[i].X) > maxVal || Abs(pg[i].Y) > maxVal)
- {
- if (Abs(pg[i].X) > hiRange || Abs(pg[i].Y) > hiRange)
- throw "Coordinate exceeds range bounds";
- maxVal = hiRange;
- m_UseFullRange = true;
- }
-
- if (i == 0 || PointsEqual(p[j], pg[i])) continue;
- else if (j > 0 && SlopesEqual(p[j-1], p[j], pg[i], m_UseFullRange))
- {
- if (PointsEqual(p[j-1], pg[i])) j--;
- } else j++;
- p[j] = pg[i];
- }
- if (j < 2) return false;
-
- len = j+1;
- while (len > 2)
- {
- //nb: test for point equality before testing slopes ...
- if (PointsEqual(p[j], p[0])) j--;
- else if (PointsEqual(p[0], p[1]) ||
- SlopesEqual(p[j], p[0], p[1], m_UseFullRange))
- p[0] = p[j--];
- else if (SlopesEqual(p[j-1], p[j], p[0], m_UseFullRange)) j--;
- else if (SlopesEqual(p[0], p[1], p[2], m_UseFullRange))
- {
- for (int i = 2; i <= j; ++i) p[i-1] = p[i];
- j--;
- }
- else break;
- len--;
- }
- if (len < 3) return false;
-
- //create a new edge array ...
- TEdge *edges = new TEdge [len];
- m_edges.push_back(edges);
-
- //convert vertices to a double-linked-list of edges and initialize ...
- edges[0].xcurr = p[0].X;
- edges[0].ycurr = p[0].Y;
- InitEdge(&edges[len-1], &edges[0], &edges[len-2], p[len-1], polyType);
- for (int i = len-2; i > 0; --i)
- InitEdge(&edges[i], &edges[i+1], &edges[i-1], p[i], polyType);
- InitEdge(&edges[0], &edges[1], &edges[len-1], p[0], polyType);
-
- //reset xcurr & ycurr and find 'eHighest' (given the Y axis coordinates
- //increase downward so the 'highest' edge will have the smallest ytop) ...
- TEdge *e = &edges[0];
- TEdge *eHighest = e;
- do
- {
- e->xcurr = e->xbot;
- e->ycurr = e->ybot;
- if (e->ytop < eHighest->ytop) eHighest = e;
- e = e->next;
- }
- while ( e != &edges[0]);
-
- //make sure eHighest is positioned so the following loop works safely ...
- if (eHighest->windDelta > 0) eHighest = eHighest->next;
- if (NEAR_EQUAL(eHighest->dx, HORIZONTAL)) eHighest = eHighest->next;
-
- //finally insert each local minima ...
- e = eHighest;
- do {
- e = AddBoundsToLML(e);
- }
- while( e != eHighest );
- return true;
-}
-//------------------------------------------------------------------------------
-
-void ClipperBase::InsertLocalMinima(LocalMinima *newLm)
-{
- if( ! m_MinimaList )
- {
- m_MinimaList = newLm;
- }
- else if( newLm->Y >= m_MinimaList->Y )
- {
- newLm->next = m_MinimaList;
- m_MinimaList = newLm;
- } else
- {
- LocalMinima* tmpLm = m_MinimaList;
- while( tmpLm->next && ( newLm->Y < tmpLm->next->Y ) )
- tmpLm = tmpLm->next;
- newLm->next = tmpLm->next;
- tmpLm->next = newLm;
- }
-}
-//------------------------------------------------------------------------------
-
-TEdge* ClipperBase::AddBoundsToLML(TEdge *e)
-{
- //Starting at the top of one bound we progress to the bottom where there's
- //a local minima. We then go to the top of the next bound. These two bounds
- //form the left and right (or right and left) bounds of the local minima.
- e->nextInLML = 0;
- e = e->next;
- for (;;)
- {
- if (NEAR_EQUAL(e->dx, HORIZONTAL))
- {
- //nb: proceed through horizontals when approaching from their right,
- // but break on horizontal minima if approaching from their left.
- // This ensures 'local minima' are always on the left of horizontals.
- if (e->next->ytop < e->ytop && e->next->xbot > e->prev->xbot) break;
- if (e->xtop != e->prev->xbot) SwapX(*e);
- e->nextInLML = e->prev;
- }
- else if (e->ycurr == e->prev->ycurr) break;
- else e->nextInLML = e->prev;
- e = e->next;
- }
-
- //e and e.prev are now at a local minima ...
- LocalMinima* newLm = new LocalMinima;
- newLm->next = 0;
- newLm->Y = e->prev->ybot;
-
- if ( NEAR_EQUAL(e->dx, HORIZONTAL) ) //horizontal edges never start a left bound
- {
- if (e->xbot != e->prev->xbot) SwapX(*e);
- newLm->leftBound = e->prev;
- newLm->rightBound = e;
- } else if (e->dx < e->prev->dx)
- {
- newLm->leftBound = e->prev;
- newLm->rightBound = e;
- } else
- {
- newLm->leftBound = e;
- newLm->rightBound = e->prev;
- }
- newLm->leftBound->side = esLeft;
- newLm->rightBound->side = esRight;
- InsertLocalMinima( newLm );
-
- for (;;)
- {
- if ( e->next->ytop == e->ytop && !NEAR_EQUAL(e->next->dx, HORIZONTAL) ) break;
- e->nextInLML = e->next;
- e = e->next;
- if ( NEAR_EQUAL(e->dx, HORIZONTAL) && e->xbot != e->prev->xtop) SwapX(*e);
- }
- return e->next;
-}
-//------------------------------------------------------------------------------
-
-bool ClipperBase::AddPolygons(const Polygons &ppg, PolyType polyType)
-{
- bool result = false;
- for (Polygons::size_type i = 0; i < ppg.size(); ++i)
- if (AddPolygon(ppg[i], polyType)) result = true;
- return result;
-}
-//------------------------------------------------------------------------------
-
-void ClipperBase::Clear()
-{
- DisposeLocalMinimaList();
- for (EdgeList::size_type i = 0; i < m_edges.size(); ++i) delete [] m_edges[i];
- m_edges.clear();
- m_UseFullRange = false;
-}
-//------------------------------------------------------------------------------
-
-void ClipperBase::Reset()
-{
- m_CurrentLM = m_MinimaList;
- if( !m_CurrentLM ) return; //ie nothing to process
-
- //reset all edges ...
- LocalMinima* lm = m_MinimaList;
- while( lm )
- {
- TEdge* e = lm->leftBound;
- while( e )
- {
- e->xcurr = e->xbot;
- e->ycurr = e->ybot;
- e->side = esLeft;
- e->outIdx = -1;
- e = e->nextInLML;
- }
- e = lm->rightBound;
- while( e )
- {
- e->xcurr = e->xbot;
- e->ycurr = e->ybot;
- e->side = esRight;
- e->outIdx = -1;
- e = e->nextInLML;
- }
- lm = lm->next;
- }
-}
-//------------------------------------------------------------------------------
-
-void ClipperBase::DisposeLocalMinimaList()
-{
- while( m_MinimaList )
- {
- LocalMinima* tmpLm = m_MinimaList->next;
- delete m_MinimaList;
- m_MinimaList = tmpLm;
- }
- m_CurrentLM = 0;
-}
-//------------------------------------------------------------------------------
-
-void ClipperBase::PopLocalMinima()
-{
- if( ! m_CurrentLM ) return;
- m_CurrentLM = m_CurrentLM->next;
-}
-//------------------------------------------------------------------------------
-
-IntRect ClipperBase::GetBounds()
-{
- IntRect result;
- LocalMinima* lm = m_MinimaList;
- if (!lm)
- {
- result.left = result.top = result.right = result.bottom = 0;
- return result;
- }
- result.left = lm->leftBound->xbot;
- result.top = lm->leftBound->ybot;
- result.right = lm->leftBound->xbot;
- result.bottom = lm->leftBound->ybot;
- while (lm)
- {
- if (lm->leftBound->ybot > result.bottom)
- result.bottom = lm->leftBound->ybot;
- TEdge* e = lm->leftBound;
- for (;;) {
- TEdge* bottomE = e;
- while (e->nextInLML)
- {
- if (e->xbot < result.left) result.left = e->xbot;
- if (e->xbot > result.right) result.right = e->xbot;
- e = e->nextInLML;
- }
- if (e->xbot < result.left) result.left = e->xbot;
- if (e->xbot > result.right) result.right = e->xbot;
- if (e->xtop < result.left) result.left = e->xtop;
- if (e->xtop > result.right) result.right = e->xtop;
- if (e->ytop < result.top) result.top = e->ytop;
-
- if (bottomE == lm->leftBound) e = lm->rightBound;
- else break;
- }
- lm = lm->next;
- }
- return result;
-}
-
-
-//------------------------------------------------------------------------------
-// TClipper methods ...
-//------------------------------------------------------------------------------
-
-Clipper::Clipper() : ClipperBase() //constructor
-{
- m_Scanbeam = 0;
- m_ActiveEdges = 0;
- m_SortedEdges = 0;
- m_IntersectNodes = 0;
- m_ExecuteLocked = false;
- m_UseFullRange = false;
- m_ReverseOutput = false;
-}
-//------------------------------------------------------------------------------
-
-Clipper::~Clipper() //destructor
-{
- Clear();
- DisposeScanbeamList();
-}
-//------------------------------------------------------------------------------
-
-void Clipper::Clear()
-{
- if (m_edges.size() == 0) return; //avoids problems with ClipperBase destructor
- DisposeAllPolyPts();
- ClipperBase::Clear();
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeScanbeamList()
-{
- while ( m_Scanbeam ) {
- Scanbeam* sb2 = m_Scanbeam->next;
- delete m_Scanbeam;
- m_Scanbeam = sb2;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::Reset()
-{
- ClipperBase::Reset();
- m_Scanbeam = 0;
- m_ActiveEdges = 0;
- m_SortedEdges = 0;
- DisposeAllPolyPts();
- LocalMinima* lm = m_MinimaList;
- while (lm)
- {
- InsertScanbeam(lm->Y);
- InsertScanbeam(lm->leftBound->ytop);
- lm = lm->next;
- }
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::Execute(ClipType clipType, Polygons &solution,
- PolyFillType subjFillType, PolyFillType clipFillType)
-{
- if( m_ExecuteLocked ) return false;
- m_ExecuteLocked = true;
- solution.resize(0);
- m_SubjFillType = subjFillType;
- m_ClipFillType = clipFillType;
- m_ClipType = clipType;
- bool succeeded = ExecuteInternal(false);
- if (succeeded) BuildResult(solution);
- m_ExecuteLocked = false;
- return succeeded;
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::Execute(ClipType clipType, ExPolygons &solution,
- PolyFillType subjFillType, PolyFillType clipFillType)
-{
- if( m_ExecuteLocked ) return false;
- m_ExecuteLocked = true;
- solution.resize(0);
- m_SubjFillType = subjFillType;
- m_ClipFillType = clipFillType;
- m_ClipType = clipType;
- bool succeeded = ExecuteInternal(true);
- if (succeeded) BuildResultEx(solution);
- m_ExecuteLocked = false;
- return succeeded;
-}
-//------------------------------------------------------------------------------
-
-bool PolySort(OutRec *or1, OutRec *or2)
-{
- if (or1 == or2) return false;
- if (!or1->pts || !or2->pts)
- {
- if (or1->pts != or2->pts)
- {
- return or1->pts ? true : false;
- }
- else return false;
- }
- int i1, i2;
- if (or1->isHole)
- i1 = or1->FirstLeft->idx; else
- i1 = or1->idx;
- if (or2->isHole)
- i2 = or2->FirstLeft->idx; else
- i2 = or2->idx;
- int result = i1 - i2;
- if (result == 0 && (or1->isHole != or2->isHole))
- {
- return or1->isHole ? false : true;
- }
- else return result < 0;
-}
-//------------------------------------------------------------------------------
-
-OutRec* FindAppendLinkEnd(OutRec *outRec)
-{
- while (outRec->AppendLink) outRec = outRec->AppendLink;
- return outRec;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::FixHoleLinkage(OutRec *outRec)
-{
- OutRec *tmp;
- if (outRec->bottomPt)
- tmp = m_PolyOuts[outRec->bottomPt->idx]->FirstLeft;
- else
- tmp = outRec->FirstLeft;
- if (outRec == tmp) throw clipperException("HoleLinkage error");
-
- if (tmp)
- {
- if (tmp->AppendLink) tmp = FindAppendLinkEnd(tmp);
- if (tmp == outRec) tmp = 0;
- else if (tmp->isHole)
- {
- FixHoleLinkage(tmp);
- tmp = tmp->FirstLeft;
- }
- }
- outRec->FirstLeft = tmp;
- if (!tmp) outRec->isHole = false;
- outRec->AppendLink = 0;
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::ExecuteInternal(bool fixHoleLinkages)
-{
- bool succeeded;
- try {
- Reset();
- if (!m_CurrentLM ) return true;
- long64 botY = PopScanbeam();
- do {
- InsertLocalMinimaIntoAEL(botY);
- ClearHorzJoins();
- ProcessHorizontals();
- long64 topY = PopScanbeam();
- succeeded = ProcessIntersections(botY, topY);
- if (!succeeded) break;
- ProcessEdgesAtTopOfScanbeam(topY);
- botY = topY;
- } while( m_Scanbeam );
- }
- catch(...) {
- succeeded = false;
- }
-
- if (succeeded)
- {
- //tidy up output polygons and fix orientations where necessary ...
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- {
- OutRec *outRec = m_PolyOuts[i];
- if (!outRec->pts) continue;
- 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);
- }
-
- JoinCommonEdges(fixHoleLinkages);
- if (fixHoleLinkages)
- std::sort(m_PolyOuts.begin(), m_PolyOuts.end(), PolySort);
- }
-
- ClearJoins();
- ClearHorzJoins();
- return succeeded;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::InsertScanbeam(const long64 Y)
-{
- if( !m_Scanbeam )
- {
- m_Scanbeam = new Scanbeam;
- m_Scanbeam->next = 0;
- m_Scanbeam->Y = Y;
- }
- else if( Y > m_Scanbeam->Y )
- {
- Scanbeam* newSb = new Scanbeam;
- newSb->Y = Y;
- newSb->next = m_Scanbeam;
- m_Scanbeam = newSb;
- } else
- {
- Scanbeam* sb2 = m_Scanbeam;
- while( sb2->next && ( Y <= sb2->next->Y ) ) sb2 = sb2->next;
- if( Y == sb2->Y ) return; //ie ignores duplicates
- Scanbeam* newSb = new Scanbeam;
- newSb->Y = Y;
- newSb->next = sb2->next;
- sb2->next = newSb;
- }
-}
-//------------------------------------------------------------------------------
-
-long64 Clipper::PopScanbeam()
-{
- long64 Y = m_Scanbeam->Y;
- Scanbeam* sb2 = m_Scanbeam;
- m_Scanbeam = m_Scanbeam->next;
- delete sb2;
- return Y;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeAllPolyPts(){
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- DisposeOutRec(i);
- m_PolyOuts.clear();
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeOutRec(PolyOutList::size_type index)
-{
- OutRec *outRec = m_PolyOuts[index];
- if (outRec->pts) DisposeOutPts(outRec->pts);
- delete outRec;
- m_PolyOuts[index] = 0;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::SetWindingCount(TEdge &edge)
-{
- TEdge *e = edge.prevInAEL;
- //find the edge of the same polytype that immediately preceeds 'edge' in AEL
- while ( e && e->polyType != edge.polyType ) e = e->prevInAEL;
- if ( !e )
- {
- edge.windCnt = edge.windDelta;
- edge.windCnt2 = 0;
- e = m_ActiveEdges; //ie get ready to calc windCnt2
- } else if ( IsEvenOddFillType(edge) )
- {
- //EvenOdd filling ...
- edge.windCnt = 1;
- edge.windCnt2 = e->windCnt2;
- e = e->nextInAEL; //ie get ready to calc windCnt2
- } else
- {
- //nonZero, Positive or Negative filling ...
- if ( e->windCnt * e->windDelta < 0 )
- {
- if (Abs(e->windCnt) > 1)
- {
- if (e->windDelta * edge.windDelta < 0) edge.windCnt = e->windCnt;
- else edge.windCnt = e->windCnt + edge.windDelta;
- } else
- edge.windCnt = e->windCnt + e->windDelta + edge.windDelta;
- } else
- {
- if ( Abs(e->windCnt) > 1 && e->windDelta * edge.windDelta < 0)
- edge.windCnt = e->windCnt;
- else if ( e->windCnt + edge.windDelta == 0 )
- edge.windCnt = e->windCnt;
- else edge.windCnt = e->windCnt + edge.windDelta;
- }
- edge.windCnt2 = e->windCnt2;
- e = e->nextInAEL; //ie get ready to calc windCnt2
- }
-
- //update windCnt2 ...
- if ( IsEvenOddAltFillType(edge) )
- {
- //EvenOdd filling ...
- while ( e != &edge )
- {
- edge.windCnt2 = (edge.windCnt2 == 0) ? 1 : 0;
- e = e->nextInAEL;
- }
- } else
- {
- //nonZero, Positive or Negative filling ...
- while ( e != &edge )
- {
- edge.windCnt2 += e->windDelta;
- e = e->nextInAEL;
- }
- }
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::IsEvenOddFillType(const TEdge& edge) const
-{
- if (edge.polyType == ptSubject)
- return m_SubjFillType == pftEvenOdd; else
- return m_ClipFillType == pftEvenOdd;
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
-{
- if (edge.polyType == ptSubject)
- return m_ClipFillType == pftEvenOdd; else
- return m_SubjFillType == pftEvenOdd;
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::IsContributing(const TEdge& edge) const
-{
- PolyFillType pft, pft2;
- if (edge.polyType == ptSubject)
- {
- pft = m_SubjFillType;
- pft2 = m_ClipFillType;
- } else
- {
- pft = m_ClipFillType;
- pft2 = m_SubjFillType;
- }
-
- switch(pft)
- {
- case pftEvenOdd:
- case pftNonZero:
- if (Abs(edge.windCnt) != 1) return false;
- break;
- case pftPositive:
- if (edge.windCnt != 1) return false;
- break;
- default: //pftNegative
- if (edge.windCnt != -1) return false;
- }
-
- switch(m_ClipType)
- {
- case ctIntersection:
- switch(pft2)
- {
- case pftEvenOdd:
- case pftNonZero:
- return (edge.windCnt2 != 0);
- case pftPositive:
- return (edge.windCnt2 > 0);
- default:
- return (edge.windCnt2 < 0);
- }
- case ctUnion:
- switch(pft2)
- {
- case pftEvenOdd:
- case pftNonZero:
- return (edge.windCnt2 == 0);
- case pftPositive:
- return (edge.windCnt2 <= 0);
- default:
- return (edge.windCnt2 >= 0);
- }
- case ctDifference:
- if (edge.polyType == ptSubject)
- switch(pft2)
- {
- case pftEvenOdd:
- case pftNonZero:
- return (edge.windCnt2 == 0);
- case pftPositive:
- return (edge.windCnt2 <= 0);
- default:
- return (edge.windCnt2 >= 0);
- }
- else
- switch(pft2)
- {
- case pftEvenOdd:
- case pftNonZero:
- return (edge.windCnt2 != 0);
- case pftPositive:
- return (edge.windCnt2 > 0);
- default:
- return (edge.windCnt2 < 0);
- }
- default:
- return true;
- }
-}
-//------------------------------------------------------------------------------
-
-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, 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, 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, pt );
- if( e1->outIdx == e2->outIdx )
- {
- e1->outIdx = -1;
- e2->outIdx = -1;
- }
- else if (e1->outIdx < e2->outIdx)
- AppendPolygon(e1, e2);
- else
- AppendPolygon(e2, e1);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::AddEdgeToSEL(TEdge *edge)
-{
- //SEL pointers in PEdge are reused to build a list of horizontal edges.
- //However, we don't need to worry about order with horizontal edge processing.
- if( !m_SortedEdges )
- {
- m_SortedEdges = edge;
- edge->prevInSEL = 0;
- edge->nextInSEL = 0;
- }
- else
- {
- edge->nextInSEL = m_SortedEdges;
- edge->prevInSEL = 0;
- m_SortedEdges->prevInSEL = edge;
- m_SortedEdges = edge;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::CopyAELToSEL()
-{
- TEdge* e = m_ActiveEdges;
- m_SortedEdges = e;
- if (!m_ActiveEdges) return;
- m_SortedEdges->prevInSEL = 0;
- e = e->nextInAEL;
- while ( e )
- {
- e->prevInSEL = e->prevInAEL;
- e->prevInSEL->nextInSEL = e;
- e->nextInSEL = 0;
- e = e->nextInAEL;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx, int e2OutIdx)
-{
- JoinRec* jr = new JoinRec;
- if (e1OutIdx >= 0)
- jr->poly1Idx = e1OutIdx; else
- jr->poly1Idx = e1->outIdx;
- jr->pt1a = IntPoint(e1->xcurr, e1->ycurr);
- jr->pt1b = IntPoint(e1->xtop, e1->ytop);
- if (e2OutIdx >= 0)
- jr->poly2Idx = e2OutIdx; else
- jr->poly2Idx = e2->outIdx;
- jr->pt2a = IntPoint(e2->xcurr, e2->ycurr);
- jr->pt2b = IntPoint(e2->xtop, e2->ytop);
- m_Joins.push_back(jr);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ClearJoins()
-{
- for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
- delete m_Joins[i];
- m_Joins.resize(0);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::AddHorzJoin(TEdge *e, int idx)
-{
- HorzJoinRec* hj = new HorzJoinRec;
- hj->edge = e;
- hj->savedIdx = idx;
- m_HorizJoins.push_back(hj);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ClearHorzJoins()
-{
- for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); i++)
- delete m_HorizJoins[i];
- m_HorizJoins.resize(0);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::InsertLocalMinimaIntoAEL( const long64 botY)
-{
- while( m_CurrentLM && ( m_CurrentLM->Y == botY ) )
- {
- TEdge* lb = m_CurrentLM->leftBound;
- TEdge* rb = m_CurrentLM->rightBound;
-
- InsertEdgeIntoAEL( lb );
- InsertScanbeam( lb->ytop );
- InsertEdgeIntoAEL( rb );
-
- if (IsEvenOddFillType(*lb))
- {
- lb->windDelta = 1;
- rb->windDelta = 1;
- }
- else
- {
- rb->windDelta = -lb->windDelta;
- }
- SetWindingCount( *lb );
- rb->windCnt = lb->windCnt;
- rb->windCnt2 = lb->windCnt2;
-
- if( NEAR_EQUAL(rb->dx, HORIZONTAL) )
- {
- //nb: only rightbounds can have a horizontal bottom edge
- AddEdgeToSEL( rb );
- InsertScanbeam( rb->nextInLML->ytop );
- }
- else
- InsertScanbeam( rb->ytop );
-
- if( IsContributing(*lb) )
- AddLocalMinPoly( lb, rb, IntPoint(lb->xcurr, m_CurrentLM->Y) );
-
- //if any output polygons share an edge, they'll need joining later ...
- if (rb->outIdx >= 0)
- {
- if (NEAR_EQUAL(rb->dx, HORIZONTAL))
- {
- for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i)
- {
- IntPoint pt, pt2; //returned by GetOverlapSegment() but unused here.
- HorzJoinRec* hj = m_HorizJoins[i];
- //if horizontals rb and hj.edge overlap, flag for joining later ...
- if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot),
- IntPoint(hj->edge->xtop, hj->edge->ytop),
- IntPoint(rb->xbot, rb->ybot),
- IntPoint(rb->xtop, rb->ytop), pt, pt2))
- AddJoin(hj->edge, rb, hj->savedIdx);
- }
- }
- }
-
- if( lb->nextInAEL != rb )
- {
- if (rb->outIdx >= 0 && rb->prevInAEL->outIdx >= 0 &&
- SlopesEqual(*rb->prevInAEL, *rb, m_UseFullRange))
- AddJoin(rb, rb->prevInAEL);
-
- TEdge* e = lb->nextInAEL;
- IntPoint pt = IntPoint(lb->xcurr, lb->ycurr);
- while( e != rb )
- {
- if(!e) throw clipperException("InsertLocalMinimaIntoAEL: missing rightbound!");
- //nb: For calculating winding counts etc, IntersectEdges() assumes
- //that param1 will be to the right of param2 ABOVE the intersection ...
- IntersectEdges( rb , e , pt , ipNone); //order important here
- e = e->nextInAEL;
- }
- }
- PopLocalMinima();
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DeleteFromAEL(TEdge *e)
-{
- TEdge* AelPrev = e->prevInAEL;
- TEdge* AelNext = e->nextInAEL;
- if( !AelPrev && !AelNext && (e != m_ActiveEdges) ) return; //already deleted
- if( AelPrev ) AelPrev->nextInAEL = AelNext;
- else m_ActiveEdges = AelNext;
- if( AelNext ) AelNext->prevInAEL = AelPrev;
- e->nextInAEL = 0;
- e->prevInAEL = 0;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DeleteFromSEL(TEdge *e)
-{
- TEdge* SelPrev = e->prevInSEL;
- TEdge* SelNext = e->nextInSEL;
- if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted
- if( SelPrev ) SelPrev->nextInSEL = SelNext;
- else m_SortedEdges = SelNext;
- if( SelNext ) SelNext->prevInSEL = SelPrev;
- e->nextInSEL = 0;
- e->prevInSEL = 0;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::IntersectEdges(TEdge *e1, TEdge *e2,
- const IntPoint &pt, IntersectProtects protects)
-{
- //e1 will be to the left of e2 BELOW the intersection. Therefore e1 is before
- //e2 in AEL except when e1 is being inserted at the intersection point ...
- bool e1stops = !(ipLeft & protects) && !e1->nextInLML &&
- e1->xtop == pt.X && e1->ytop == pt.Y;
- bool e2stops = !(ipRight & protects) && !e2->nextInLML &&
- e2->xtop == pt.X && e2->ytop == pt.Y;
- bool e1Contributing = ( e1->outIdx >= 0 );
- bool e2contributing = ( e2->outIdx >= 0 );
-
- //update winding counts...
- //assumes that e1 will be to the right of e2 ABOVE the intersection
- if ( e1->polyType == e2->polyType )
- {
- if ( IsEvenOddFillType( *e1) )
- {
- int oldE1WindCnt = e1->windCnt;
- e1->windCnt = e2->windCnt;
- e2->windCnt = oldE1WindCnt;
- } else
- {
- if (e1->windCnt + e2->windDelta == 0 ) e1->windCnt = -e1->windCnt;
- else e1->windCnt += e2->windDelta;
- if ( e2->windCnt - e1->windDelta == 0 ) e2->windCnt = -e2->windCnt;
- else e2->windCnt -= e1->windDelta;
- }
- } else
- {
- if (!IsEvenOddFillType(*e2)) e1->windCnt2 += e2->windDelta;
- else e1->windCnt2 = ( e1->windCnt2 == 0 ) ? 1 : 0;
- if (!IsEvenOddFillType(*e1)) e2->windCnt2 -= e1->windDelta;
- else e2->windCnt2 = ( e2->windCnt2 == 0 ) ? 1 : 0;
- }
-
- PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
- if (e1->polyType == ptSubject)
- {
- e1FillType = m_SubjFillType;
- e1FillType2 = m_ClipFillType;
- } else
- {
- e1FillType = m_ClipFillType;
- e1FillType2 = m_SubjFillType;
- }
- if (e2->polyType == ptSubject)
- {
- e2FillType = m_SubjFillType;
- e2FillType2 = m_ClipFillType;
- } else
- {
- e2FillType = m_ClipFillType;
- e2FillType2 = m_SubjFillType;
- }
-
- long64 e1Wc, e2Wc;
- switch (e1FillType)
- {
- case pftPositive: e1Wc = e1->windCnt; break;
- case pftNegative: e1Wc = -e1->windCnt; break;
- default: e1Wc = Abs(e1->windCnt);
- }
- switch(e2FillType)
- {
- case pftPositive: e2Wc = e2->windCnt; break;
- case pftNegative: e2Wc = -e2->windCnt; break;
- default: e2Wc = Abs(e2->windCnt);
- }
-
- if ( e1Contributing && e2contributing )
- {
- if ( e1stops || e2stops ||
- (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
- (e1->polyType != e2->polyType && m_ClipType != ctXor) )
- AddLocalMaxPoly(e1, e2, pt);
- else
- DoBothEdges( e1, e2, pt );
- }
- else if ( e1Contributing )
- {
- if ((e2Wc == 0 || e2Wc == 1) &&
- (m_ClipType != ctIntersection ||
- e2->polyType == ptSubject || (e2->windCnt2 != 0)))
- DoEdge1(e1, e2, pt);
- }
- else if ( e2contributing )
- {
- if ((e1Wc == 0 || e1Wc == 1) &&
- (m_ClipType != ctIntersection ||
- e1->polyType == ptSubject || (e1->windCnt2 != 0)))
- DoEdge2(e1, e2, pt);
- }
- else if ( (e1Wc == 0 || e1Wc == 1) &&
- (e2Wc == 0 || e2Wc == 1) && !e1stops && !e2stops )
- {
- //neither edge is currently contributing ...
-
- long64 e1Wc2, e2Wc2;
- switch (e1FillType2)
- {
- case pftPositive: e1Wc2 = e1->windCnt2; break;
- case pftNegative : e1Wc2 = -e1->windCnt2; break;
- default: e1Wc2 = Abs(e1->windCnt2);
- }
- switch (e2FillType2)
- {
- case pftPositive: e2Wc2 = e2->windCnt2; break;
- case pftNegative: e2Wc2 = -e2->windCnt2; break;
- default: e2Wc2 = Abs(e2->windCnt2);
- }
-
- if (e1->polyType != e2->polyType)
- AddLocalMinPoly(e1, e2, pt);
- else if (e1Wc == 1 && e2Wc == 1)
- switch( m_ClipType ) {
- case ctIntersection:
- if (e1Wc2 > 0 && e2Wc2 > 0)
- AddLocalMinPoly(e1, e2, pt);
- break;
- case ctUnion:
- if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
- AddLocalMinPoly(e1, e2, pt);
- break;
- case ctDifference:
- if (((e1->polyType == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
- ((e1->polyType == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
- AddLocalMinPoly(e1, e2, pt);
- break;
- case ctXor:
- AddLocalMinPoly(e1, e2, pt);
- }
- else
- SwapSides( *e1, *e2 );
- }
-
- if( (e1stops != e2stops) &&
- ( (e1stops && (e1->outIdx >= 0)) || (e2stops && (e2->outIdx >= 0)) ) )
- {
- SwapSides( *e1, *e2 );
- SwapPolyIndexes( *e1, *e2 );
- }
-
- //finally, delete any non-contributing maxima edges ...
- if( e1stops ) DeleteFromAEL( e1 );
- if( e2stops ) DeleteFromAEL( e2 );
-}
-//------------------------------------------------------------------------------
-
-void Clipper::SetHoleState(TEdge *e, OutRec *outRec)
-{
- bool isHole = false;
- TEdge *e2 = e->prevInAEL;
- while (e2)
- {
- if (e2->outIdx >= 0)
- {
- isHole = !isHole;
- if (! outRec->FirstLeft)
- outRec->FirstLeft = m_PolyOuts[e2->outIdx];
- }
- e2 = e2->prevInAEL;
- }
- if (isHole) outRec->isHole = true;
-}
-//------------------------------------------------------------------------------
-
-OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
-{
- //work out which polygon fragment has the correct hole state ...
- OutPt *outPt1 = outRec1->bottomPt;
- OutPt *outPt2 = outRec2->bottomPt;
- if (outPt1->pt.Y > outPt2->pt.Y) return outRec1;
- 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 (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
- {
- outRec1 = outRec1->FirstLeft;
- if (outRec1 == outRec2) return true;
- } while (outRec1);
- return false;
-}
-//------------------------------------------------------------------------------
-
-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;
- 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;
- OutPt* p2_lft = outRec2->pts;
- OutPt* p2_rt = p2_lft->prev;
-
- EdgeSide side;
- //join e2 poly onto e1 poly and delete pointers to e2 ...
- if( e1->side == esLeft )
- {
- if( e2->side == esLeft )
- {
- //z y x a b c
- ReversePolyPtLinks(*p2_lft);
- p2_lft->next = p1_lft;
- p1_lft->prev = p2_lft;
- p1_rt->next = p2_rt;
- p2_rt->prev = p1_rt;
- outRec1->pts = p2_rt;
- } else
- {
- //x y z a b c
- p2_rt->next = p1_lft;
- p1_lft->prev = p2_rt;
- p2_lft->prev = p1_rt;
- p1_rt->next = p2_lft;
- outRec1->pts = p2_lft;
- }
- side = esLeft;
- } else
- {
- if( e2->side == esRight )
- {
- //a b c z y x
- ReversePolyPtLinks( *p2_lft );
- p1_rt->next = p2_rt;
- p2_rt->prev = p1_rt;
- p2_lft->next = p1_lft;
- p1_lft->prev = p2_lft;
- } else
- {
- //a b c x y z
- p1_rt->next = p2_lft;
- p2_lft->prev = p1_rt;
- p1_lft->prev = p2_rt;
- p2_rt->next = p1_lft;
- }
- side = esRight;
- }
-
- if (holeStateRec == outRec2)
- {
- outRec1->bottomPt = outRec2->bottomPt;
- outRec1->bottomPt->idx = outRec1->idx;
- if (outRec2->FirstLeft != outRec1)
- outRec1->FirstLeft = outRec2->FirstLeft;
- outRec1->isHole = outRec2->isHole;
- }
- outRec2->pts = 0;
- outRec2->bottomPt = 0;
- outRec2->AppendLink = outRec1;
- int OKIdx = e1->outIdx;
- int ObsoleteIdx = e2->outIdx;
-
- e1->outIdx = -1; //nb: safe because we only get here via AddLocalMaxPoly
- e2->outIdx = -1;
-
- TEdge* e = m_ActiveEdges;
- while( e )
- {
- if( e->outIdx == ObsoleteIdx )
- {
- e->outIdx = OKIdx;
- e->side = side;
- break;
- }
- e = e->nextInAEL;
- }
-
- for (JoinList::size_type i = 0; i < m_Joins.size(); ++i)
- {
- if (m_Joins[i]->poly1Idx == ObsoleteIdx) m_Joins[i]->poly1Idx = OKIdx;
- if (m_Joins[i]->poly2Idx == ObsoleteIdx) m_Joins[i]->poly2Idx = OKIdx;
- }
-
- for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i)
- {
- if (m_HorizJoins[i]->savedIdx == ObsoleteIdx)
- m_HorizJoins[i]->savedIdx = OKIdx;
- }
-
-}
-//------------------------------------------------------------------------------
-
-OutRec* Clipper::CreateOutRec()
-{
- OutRec* result = new OutRec;
- result->isHole = false;
- result->FirstLeft = 0;
- result->AppendLink = 0;
- result->pts = 0;
- result->bottomPt = 0;
- result->sides = esNeither;
- result->bottomFlag = 0;
-
- return result;
-}
-//------------------------------------------------------------------------------
-
-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 )
- {
- OutRec *outRec = CreateOutRec();
- m_PolyOuts.push_back(outRec);
- outRec->idx = (int)m_PolyOuts.size()-1;
- e->outIdx = outRec->idx;
- OutPt* op = new OutPt;
- outRec->pts = op;
- outRec->bottomPt = op;
- op->pt = pt;
- op->idx = outRec->idx;
- op->next = op;
- op->prev = op;
- SetHoleState(e, outRec);
- } else
- {
- OutRec *outRec = m_PolyOuts[e->outIdx];
- 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;
- op2->next = op;
- op2->prev = op->prev;
- op2->prev->next = op2;
- op->prev = op2;
- if (ToFront) outRec->pts = op2;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ProcessHorizontals()
-{
- TEdge* horzEdge = m_SortedEdges;
- while( horzEdge )
- {
- DeleteFromSEL( horzEdge );
- ProcessHorizontal( horzEdge );
- horzEdge = m_SortedEdges;
- }
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::IsTopHorz(const long64 XPos)
-{
- TEdge* e = m_SortedEdges;
- while( e )
- {
- if( ( XPos >= std::min(e->xcurr, e->xtop) ) &&
- ( XPos <= std::max(e->xcurr, e->xtop) ) ) return false;
- e = e->nextInSEL;
- }
- return true;
-}
-//------------------------------------------------------------------------------
-
-bool IsMinima(TEdge *e)
-{
- return e && (e->prev->nextInLML != e) && (e->next->nextInLML != e);
-}
-//------------------------------------------------------------------------------
-
-bool IsMaxima(TEdge *e, const long64 Y)
-{
- return e && e->ytop == Y && !e->nextInLML;
-}
-//------------------------------------------------------------------------------
-
-bool IsIntermediate(TEdge *e, const long64 Y)
-{
- return e->ytop == Y && e->nextInLML;
-}
-//------------------------------------------------------------------------------
-
-TEdge *GetMaximaPair(TEdge *e)
-{
- if( !IsMaxima(e->next, e->ytop) || e->next->xtop != e->xtop )
- return e->prev; else
- return e->next;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::SwapPositionsInAEL(TEdge *edge1, TEdge *edge2)
-{
- if( !edge1->nextInAEL && !edge1->prevInAEL ) return;
- if( !edge2->nextInAEL && !edge2->prevInAEL ) return;
-
- if( edge1->nextInAEL == edge2 )
- {
- TEdge* next = edge2->nextInAEL;
- if( next ) next->prevInAEL = edge1;
- TEdge* prev = edge1->prevInAEL;
- if( prev ) prev->nextInAEL = edge2;
- edge2->prevInAEL = prev;
- edge2->nextInAEL = edge1;
- edge1->prevInAEL = edge2;
- edge1->nextInAEL = next;
- }
- else if( edge2->nextInAEL == edge1 )
- {
- TEdge* next = edge1->nextInAEL;
- if( next ) next->prevInAEL = edge2;
- TEdge* prev = edge2->prevInAEL;
- if( prev ) prev->nextInAEL = edge1;
- edge1->prevInAEL = prev;
- edge1->nextInAEL = edge2;
- edge2->prevInAEL = edge1;
- edge2->nextInAEL = next;
- }
- else
- {
- TEdge* next = edge1->nextInAEL;
- TEdge* prev = edge1->prevInAEL;
- edge1->nextInAEL = edge2->nextInAEL;
- if( edge1->nextInAEL ) edge1->nextInAEL->prevInAEL = edge1;
- edge1->prevInAEL = edge2->prevInAEL;
- if( edge1->prevInAEL ) edge1->prevInAEL->nextInAEL = edge1;
- edge2->nextInAEL = next;
- if( edge2->nextInAEL ) edge2->nextInAEL->prevInAEL = edge2;
- edge2->prevInAEL = prev;
- if( edge2->prevInAEL ) edge2->prevInAEL->nextInAEL = edge2;
- }
-
- if( !edge1->prevInAEL ) m_ActiveEdges = edge1;
- else if( !edge2->prevInAEL ) m_ActiveEdges = edge2;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::SwapPositionsInSEL(TEdge *edge1, TEdge *edge2)
-{
- if( !( edge1->nextInSEL ) && !( edge1->prevInSEL ) ) return;
- if( !( edge2->nextInSEL ) && !( edge2->prevInSEL ) ) return;
-
- if( edge1->nextInSEL == edge2 )
- {
- TEdge* next = edge2->nextInSEL;
- if( next ) next->prevInSEL = edge1;
- TEdge* prev = edge1->prevInSEL;
- if( prev ) prev->nextInSEL = edge2;
- edge2->prevInSEL = prev;
- edge2->nextInSEL = edge1;
- edge1->prevInSEL = edge2;
- edge1->nextInSEL = next;
- }
- else if( edge2->nextInSEL == edge1 )
- {
- TEdge* next = edge1->nextInSEL;
- if( next ) next->prevInSEL = edge2;
- TEdge* prev = edge2->prevInSEL;
- if( prev ) prev->nextInSEL = edge1;
- edge1->prevInSEL = prev;
- edge1->nextInSEL = edge2;
- edge2->prevInSEL = edge1;
- edge2->nextInSEL = next;
- }
- else
- {
- TEdge* next = edge1->nextInSEL;
- TEdge* prev = edge1->prevInSEL;
- edge1->nextInSEL = edge2->nextInSEL;
- if( edge1->nextInSEL ) edge1->nextInSEL->prevInSEL = edge1;
- edge1->prevInSEL = edge2->prevInSEL;
- if( edge1->prevInSEL ) edge1->prevInSEL->nextInSEL = edge1;
- edge2->nextInSEL = next;
- if( edge2->nextInSEL ) edge2->nextInSEL->prevInSEL = edge2;
- edge2->prevInSEL = prev;
- if( edge2->prevInSEL ) edge2->prevInSEL->nextInSEL = edge2;
- }
-
- if( !edge1->prevInSEL ) m_SortedEdges = edge1;
- else if( !edge2->prevInSEL ) m_SortedEdges = edge2;
-}
-//------------------------------------------------------------------------------
-
-TEdge* GetNextInAEL(TEdge *e, Direction dir)
-{
- return dir == dLeftToRight ? e->nextInAEL : e->prevInAEL;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ProcessHorizontal(TEdge *horzEdge)
-{
- Direction dir;
- long64 horzLeft, horzRight;
-
- if( horzEdge->xcurr < horzEdge->xtop )
- {
- horzLeft = horzEdge->xcurr;
- horzRight = horzEdge->xtop;
- dir = dLeftToRight;
- } else
- {
- horzLeft = horzEdge->xtop;
- horzRight = horzEdge->xcurr;
- dir = dRightToLeft;
- }
-
- TEdge* eMaxPair;
- if( horzEdge->nextInLML ) eMaxPair = 0;
- else eMaxPair = GetMaximaPair(horzEdge);
-
- TEdge* e = GetNextInAEL( horzEdge , dir );
- while( e )
- {
- TEdge* eNext = GetNextInAEL( e, dir );
-
- if (eMaxPair ||
- ((dir == dLeftToRight) && (e->xcurr <= horzRight)) ||
- ((dir == dRightToLeft) && (e->xcurr >= horzLeft)))
- {
- //ok, so far it looks like we're still in range of the horizontal edge
- if ( e->xcurr == horzEdge->xtop && !eMaxPair )
- {
- assert(horzEdge->nextInLML);
- if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange))
- {
- //if output polygons share an edge, they'll need joining later ...
- if (horzEdge->outIdx >= 0 && e->outIdx >= 0)
- AddJoin(horzEdge->nextInLML, e, horzEdge->outIdx);
- break; //we've reached the end of the horizontal line
- }
- else if (e->dx < horzEdge->nextInLML->dx)
- //we really have got to the end of the intermediate horz edge so quit.
- //nb: More -ve slopes follow more +ve slopes ABOVE the horizontal.
- break;
- }
-
- if( e == eMaxPair )
- {
- //horzEdge is evidently a maxima horizontal and we've arrived at its end.
- if (dir == dLeftToRight)
- IntersectEdges(horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr), ipNone);
- else
- IntersectEdges(e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr), ipNone);
- if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error");
- return;
- }
- else if( NEAR_EQUAL(e->dx, HORIZONTAL) && !IsMinima(e) && !(e->xcurr > e->xtop) )
- {
- //An overlapping horizontal edge. Overlapping horizontal edges are
- //processed as if layered with the current horizontal edge (horizEdge)
- //being infinitesimally lower that the next (e). Therfore, we
- //intersect with e only if e.xcurr is within the bounds of horzEdge ...
- if( dir == dLeftToRight )
- IntersectEdges( horzEdge , e, IntPoint(e->xcurr, horzEdge->ycurr),
- (IsTopHorz( e->xcurr ))? ipLeft : ipBoth );
- else
- IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr),
- (IsTopHorz( e->xcurr ))? ipRight : ipBoth );
- }
- else if( dir == dLeftToRight )
- {
- IntersectEdges( horzEdge, e, IntPoint(e->xcurr, horzEdge->ycurr),
- (IsTopHorz( e->xcurr ))? ipLeft : ipBoth );
- }
- else
- {
- IntersectEdges( e, horzEdge, IntPoint(e->xcurr, horzEdge->ycurr),
- (IsTopHorz( e->xcurr ))? ipRight : ipBoth );
- }
- SwapPositionsInAEL( horzEdge, e );
- }
- else if( (dir == dLeftToRight && e->xcurr > horzRight && m_SortedEdges) ||
- (dir == dRightToLeft && e->xcurr < horzLeft && m_SortedEdges) ) break;
- e = eNext;
- } //end while
-
- if( horzEdge->nextInLML )
- {
- if( horzEdge->outIdx >= 0 )
- AddOutPt( horzEdge, IntPoint(horzEdge->xtop, horzEdge->ytop));
- UpdateEdgeIntoAEL( horzEdge );
- }
- else
- {
- if ( horzEdge->outIdx >= 0 )
- IntersectEdges( horzEdge, eMaxPair,
- IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth);
- assert(eMaxPair);
- if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error");
- DeleteFromAEL(eMaxPair);
- DeleteFromAEL(horzEdge);
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::UpdateEdgeIntoAEL(TEdge *&e)
-{
- if( !e->nextInLML ) throw
- clipperException("UpdateEdgeIntoAEL: invalid call");
- TEdge* AelPrev = e->prevInAEL;
- TEdge* AelNext = e->nextInAEL;
- e->nextInLML->outIdx = e->outIdx;
- if( AelPrev ) AelPrev->nextInAEL = e->nextInLML;
- else m_ActiveEdges = e->nextInLML;
- if( AelNext ) AelNext->prevInAEL = e->nextInLML;
- e->nextInLML->side = e->side;
- e->nextInLML->windDelta = e->windDelta;
- e->nextInLML->windCnt = e->windCnt;
- e->nextInLML->windCnt2 = e->windCnt2;
- e = e->nextInLML;
- e->prevInAEL = AelPrev;
- e->nextInAEL = AelNext;
- if( !NEAR_EQUAL(e->dx, HORIZONTAL) ) InsertScanbeam( e->ytop );
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::ProcessIntersections(const long64 botY, const long64 topY)
-{
- if( !m_ActiveEdges ) return true;
- try {
- BuildIntersectList(botY, topY);
- if ( !m_IntersectNodes) return true;
- if ( FixupIntersections() ) ProcessIntersectList();
- else return false;
- }
- catch(...) {
- m_SortedEdges = 0;
- DisposeIntersectNodes();
- throw clipperException("ProcessIntersections error");
- }
- return true;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DisposeIntersectNodes()
-{
- while ( m_IntersectNodes )
- {
- IntersectNode* iNode = m_IntersectNodes->next;
- delete m_IntersectNodes;
- m_IntersectNodes = iNode;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::BuildIntersectList(const long64 botY, const long64 topY)
-{
- if ( !m_ActiveEdges ) return;
-
- //prepare for sorting ...
- TEdge* e = m_ActiveEdges;
- e->tmpX = TopX( *e, topY );
- m_SortedEdges = e;
- m_SortedEdges->prevInSEL = 0;
- e = e->nextInAEL;
- while( e )
- {
- e->prevInSEL = e->prevInAEL;
- e->prevInSEL->nextInSEL = e;
- e->nextInSEL = 0;
- e->tmpX = TopX( *e, topY );
- e = e->nextInAEL;
- }
-
- //bubblesort ...
- bool isModified = true;
- while( isModified && m_SortedEdges )
- {
- isModified = false;
- e = m_SortedEdges;
- while( e->nextInSEL )
- {
- TEdge *eNext = e->nextInSEL;
- IntPoint pt;
- if(e->tmpX > eNext->tmpX &&
- IntersectPoint(*e, *eNext, pt, m_UseFullRange))
- {
- if (pt.Y > botY)
- {
- pt.Y = botY;
- pt.X = TopX(*e, pt.Y);
- }
- AddIntersectNode( e, eNext, pt );
- SwapPositionsInSEL(e, eNext);
- isModified = true;
- }
- else
- e = eNext;
- }
- if( e->prevInSEL ) e->prevInSEL->nextInSEL = 0;
- else break;
- }
- m_SortedEdges = 0;
-}
-//------------------------------------------------------------------------------
-
-bool ProcessParam1BeforeParam2(IntersectNode &node1, IntersectNode &node2)
-{
- bool result;
- if (node1.pt.Y == node2.pt.Y)
- {
- if (node1.edge1 == node2.edge1 || node1.edge2 == node2.edge1)
- {
- result = node2.pt.X > node1.pt.X;
- return node2.edge1->dx > 0 ? !result : result;
- }
- else if (node1.edge1 == node2.edge2 || node1.edge2 == node2.edge2)
- {
- result = node2.pt.X > node1.pt.X;
- return node2.edge2->dx > 0 ? !result : result;
- }
- else return node2.pt.X > node1.pt.X;
- }
- else return node1.pt.Y > node2.pt.Y;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::AddIntersectNode(TEdge *e1, TEdge *e2, const IntPoint &pt)
-{
- IntersectNode* newNode = new IntersectNode;
- newNode->edge1 = e1;
- newNode->edge2 = e2;
- newNode->pt = pt;
- newNode->next = 0;
- if( !m_IntersectNodes ) m_IntersectNodes = newNode;
- else if( ProcessParam1BeforeParam2(*newNode, *m_IntersectNodes) )
- {
- newNode->next = m_IntersectNodes;
- m_IntersectNodes = newNode;
- }
- else
- {
- IntersectNode* iNode = m_IntersectNodes;
- while( iNode->next && ProcessParam1BeforeParam2(*iNode->next, *newNode) )
- iNode = iNode->next;
- newNode->next = iNode->next;
- iNode->next = newNode;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ProcessIntersectList()
-{
- while( m_IntersectNodes )
- {
- IntersectNode* iNode = m_IntersectNodes->next;
- {
- IntersectEdges( m_IntersectNodes->edge1 ,
- m_IntersectNodes->edge2 , m_IntersectNodes->pt, ipBoth );
- SwapPositionsInAEL( m_IntersectNodes->edge1 , m_IntersectNodes->edge2 );
- }
- delete m_IntersectNodes;
- m_IntersectNodes = iNode;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::DoMaxima(TEdge *e, long64 topY)
-{
- TEdge* eMaxPair = GetMaximaPair(e);
- long64 X = e->xtop;
- TEdge* eNext = e->nextInAEL;
- while( eNext != eMaxPair )
- {
- if (!eNext) throw clipperException("DoMaxima error");
- IntersectEdges( e, eNext, IntPoint(X, topY), ipBoth );
- eNext = eNext->nextInAEL;
- }
- if( e->outIdx < 0 && eMaxPair->outIdx < 0 )
- {
- DeleteFromAEL( e );
- DeleteFromAEL( eMaxPair );
- }
- else if( e->outIdx >= 0 && eMaxPair->outIdx >= 0 )
- {
- IntersectEdges( e, eMaxPair, IntPoint(X, topY), ipNone );
- }
- else throw clipperException("DoMaxima error");
-}
-//------------------------------------------------------------------------------
-
-void Clipper::ProcessEdgesAtTopOfScanbeam(const long64 topY)
-{
- TEdge* e = m_ActiveEdges;
- while( e )
- {
- //1. process maxima, treating them as if they're 'bent' horizontal edges,
- // but exclude maxima with horizontal edges. nb: e can't be a horizontal.
- if( IsMaxima(e, topY) && !NEAR_EQUAL(GetMaximaPair(e)->dx, HORIZONTAL) )
- {
- //'e' might be removed from AEL, as may any following edges so ...
- TEdge* ePrior = e->prevInAEL;
- DoMaxima(e, topY);
- if( !ePrior ) e = m_ActiveEdges;
- else e = ePrior->nextInAEL;
- }
- else
- {
- //2. promote horizontal edges, otherwise update xcurr and ycurr ...
- if( IsIntermediate(e, topY) && NEAR_EQUAL(e->nextInLML->dx, HORIZONTAL) )
- {
- if (e->outIdx >= 0)
- {
- AddOutPt(e, IntPoint(e->xtop, e->ytop));
-
- for (HorzJoinList::size_type i = 0; i < m_HorizJoins.size(); ++i)
- {
- IntPoint pt, pt2;
- HorzJoinRec* hj = m_HorizJoins[i];
- if (GetOverlapSegment(IntPoint(hj->edge->xbot, hj->edge->ybot),
- IntPoint(hj->edge->xtop, hj->edge->ytop),
- IntPoint(e->nextInLML->xbot, e->nextInLML->ybot),
- IntPoint(e->nextInLML->xtop, e->nextInLML->ytop), pt, pt2))
- AddJoin(hj->edge, e->nextInLML, hj->savedIdx, e->outIdx);
- }
-
- AddHorzJoin(e->nextInLML, e->outIdx);
- }
- UpdateEdgeIntoAEL(e);
- AddEdgeToSEL(e);
- } else
- {
- //this just simplifies horizontal processing ...
- e->xcurr = TopX( *e, topY );
- e->ycurr = topY;
- }
- e = e->nextInAEL;
- }
- }
-
- //3. Process horizontals at the top of the scanbeam ...
- ProcessHorizontals();
-
- //4. Promote intermediate vertices ...
- e = m_ActiveEdges;
- while( e )
- {
- if( IsIntermediate( e, topY ) )
- {
- if( e->outIdx >= 0 ) AddOutPt(e, IntPoint(e->xtop,e->ytop));
- UpdateEdgeIntoAEL(e);
-
- //if output polygons share an edge, they'll need joining later ...
- if (e->outIdx >= 0 && e->prevInAEL && e->prevInAEL->outIdx >= 0 &&
- e->prevInAEL->xcurr == e->xbot && e->prevInAEL->ycurr == e->ybot &&
- SlopesEqual(IntPoint(e->xbot,e->ybot), IntPoint(e->xtop, e->ytop),
- IntPoint(e->xbot,e->ybot),
- IntPoint(e->prevInAEL->xtop, e->prevInAEL->ytop), m_UseFullRange))
- {
- 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->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, IntPoint(e->xbot, e->ybot));
- AddJoin(e, e->nextInAEL);
- }
- }
- e = e->nextInAEL;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::FixupOutPolygon(OutRec &outRec)
-{
- //FixupOutPolygon() - removes duplicate points and simplifies consecutive
- //parallel edges by removing the middle vertex.
- OutPt *lastOK = 0;
- outRec.pts = outRec.bottomPt;
- OutPt *pp = outRec.bottomPt;
-
- for (;;)
- {
- if (pp->prev == pp || pp->prev == pp->next )
- {
- DisposeOutPts(pp);
- outRec.pts = 0;
- outRec.bottomPt = 0;
- return;
- }
- //test for duplicate points and for same slope (cross-product) ...
- if ( PointsEqual(pp->pt, pp->next->pt) ||
- SlopesEqual(pp->prev->pt, pp->pt, pp->next->pt, m_UseFullRange) )
- {
- lastOK = 0;
- OutPt *tmp = pp;
- if (pp == outRec.bottomPt)
- outRec.bottomPt = 0; //flags need for updating
- pp->prev->next = pp->next;
- pp->next->prev = pp->prev;
- pp = pp->prev;
- delete tmp;
- }
- else if (pp == lastOK) break;
- else
- {
- if (!lastOK) lastOK = pp;
- pp = pp->next;
- }
- }
- if (!outRec.bottomPt) {
- outRec.bottomPt = GetBottomPt(pp);
- outRec.bottomPt->idx = outRec.idx;
- outRec.pts = outRec.bottomPt;
- }
-}
-//------------------------------------------------------------------------------
-
-void Clipper::BuildResult(Polygons &polys)
-{
- int k = 0;
- polys.resize(m_PolyOuts.size());
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- {
- if (m_PolyOuts[i]->pts)
- {
- Polygon* pg = &polys[k];
- pg->clear();
- OutPt* p = m_PolyOuts[i]->pts;
- do
- {
- pg->push_back(p->pt);
- p = p->next;
- } while (p != m_PolyOuts[i]->pts);
- //make sure each polygon has at least 3 vertices ...
- if (pg->size() < 3) pg->clear(); else k++;
- }
- }
- polys.resize(k);
-}
-//------------------------------------------------------------------------------
-
-void Clipper::BuildResultEx(ExPolygons &polys)
-{
- PolyOutList::size_type i = 0;
- int k = 0;
- polys.resize(0);
- polys.reserve(m_PolyOuts.size());
- while (i < m_PolyOuts.size() && m_PolyOuts[i]->pts)
- {
- ExPolygon epg;
- OutPt* p = m_PolyOuts[i]->pts;
- do {
- epg.outer.push_back(p->pt);
- p = p->next;
- } while (p != m_PolyOuts[i]->pts);
- i++;
- //make sure polygons have at least 3 vertices ...
- if (epg.outer.size() < 3) continue;
- while (i < m_PolyOuts.size()
- && m_PolyOuts[i]->pts && m_PolyOuts[i]->isHole)
- {
- Polygon pg;
- p = m_PolyOuts[i]->pts;
- do {
- pg.push_back(p->pt);
- p = p->next;
- } while (p != m_PolyOuts[i]->pts);
- epg.holes.push_back(pg);
- i++;
- }
- polys.push_back(epg);
- k++;
- }
- polys.resize(k);
-}
-//------------------------------------------------------------------------------
-
-void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
-{
- TEdge *e1 = int1.edge1;
- TEdge *e2 = int1.edge2;
- IntPoint p = int1.pt;
-
- int1.edge1 = int2.edge1;
- int1.edge2 = int2.edge2;
- int1.pt = int2.pt;
-
- int2.edge1 = e1;
- int2.edge2 = e2;
- int2.pt = p;
-}
-//------------------------------------------------------------------------------
-
-bool Clipper::FixupIntersections()
-{
- if ( !m_IntersectNodes->next ) return true;
-
- CopyAELToSEL();
- IntersectNode *int1 = m_IntersectNodes;
- IntersectNode *int2 = m_IntersectNodes->next;
- while (int2)
- {
- TEdge *e1 = int1->edge1;
- TEdge *e2;
- if (e1->prevInSEL == int1->edge2) e2 = e1->prevInSEL;
- else if (e1->nextInSEL == int1->edge2) e2 = e1->nextInSEL;
- else
- {
- //The current intersection is out of order, so try and swap it with
- //a subsequent intersection ...
- while (int2)
- {
- if (int2->edge1->nextInSEL == int2->edge2 ||
- int2->edge1->prevInSEL == int2->edge2) break;
- else int2 = int2->next;
- }
- if ( !int2 ) return false; //oops!!!
-
- //found an intersect node that can be swapped ...
- SwapIntersectNodes(*int1, *int2);
- e1 = int1->edge1;
- e2 = int1->edge2;
- }
- SwapPositionsInSEL(e1, e2);
- int1 = int1->next;
- int2 = int1->next;
- }
-
- m_SortedEdges = 0;
-
- //finally, check the last intersection too ...
- return (int1->edge1->prevInSEL == int1->edge2 ||
- int1->edge1->nextInSEL == int1->edge2);
-}
-//------------------------------------------------------------------------------
-
-bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
-{
- return e2.xcurr == e1.xcurr ? e2.dx > e1.dx : e2.xcurr < e1.xcurr;
-}
-//------------------------------------------------------------------------------
-
-void Clipper::InsertEdgeIntoAEL(TEdge *edge)
-{
- edge->prevInAEL = 0;
- edge->nextInAEL = 0;
- if( !m_ActiveEdges )
- {
- m_ActiveEdges = edge;
- }
- else if( E2InsertsBeforeE1(*m_ActiveEdges, *edge) )
- {
- edge->nextInAEL = m_ActiveEdges;
- m_ActiveEdges->prevInAEL = edge;
- m_ActiveEdges = edge;
- } else
- {
- TEdge* e = m_ActiveEdges;
- while( e->nextInAEL && !E2InsertsBeforeE1(*e->nextInAEL , *edge) )
- e = e->nextInAEL;
- edge->nextInAEL = e->nextInAEL;
- if( e->nextInAEL ) e->nextInAEL->prevInAEL = edge;
- edge->prevInAEL = e;
- e->nextInAEL = edge;
- }
-}
-//----------------------------------------------------------------------
-
-void Clipper::DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt)
-{
- AddOutPt(edge1, pt);
- SwapSides(*edge1, *edge2);
- SwapPolyIndexes(*edge1, *edge2);
-}
-//----------------------------------------------------------------------
-
-void Clipper::DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt)
-{
- AddOutPt(edge2, pt);
- SwapSides(*edge1, *edge2);
- SwapPolyIndexes(*edge1, *edge2);
-}
-//----------------------------------------------------------------------
-
-void Clipper::DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt)
-{
- AddOutPt(edge1, pt);
- AddOutPt(edge2, pt);
- SwapSides( *edge1 , *edge2 );
- SwapPolyIndexes( *edge1 , *edge2 );
-}
-//----------------------------------------------------------------------
-
-void Clipper::CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2)
-{
- //when a polygon is split into 2 polygons, make sure any holes the original
- //polygon contained link to the correct polygon ...
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- {
- OutRec *orec = m_PolyOuts[i];
- if (orec->isHole && orec->bottomPt && orec->FirstLeft == outRec1 &&
- !PointInPolygon(orec->bottomPt->pt, outRec1->pts, m_UseFullRange))
- orec->FirstLeft = outRec2;
- }
-}
-//----------------------------------------------------------------------
-
-void Clipper::CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2)
-{
- //if a hole is owned by outRec2 then make it owned by outRec1 ...
- for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
- if (m_PolyOuts[i]->isHole && m_PolyOuts[i]->bottomPt &&
- m_PolyOuts[i]->FirstLeft == outRec2)
- m_PolyOuts[i]->FirstLeft = outRec1;
-}
-//----------------------------------------------------------------------
-
-void Clipper::JoinCommonEdges(bool fixHoleLinkages)
-{
- for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
- {
- JoinRec* j = m_Joins[i];
- OutRec *outRec1 = m_PolyOuts[j->poly1Idx];
- OutPt *pp1a = outRec1->pts;
- OutRec *outRec2 = m_PolyOuts[j->poly2Idx];
- OutPt *pp2a = outRec2->pts;
- IntPoint pt1 = j->pt2a, pt2 = j->pt2b;
- IntPoint pt3 = j->pt1a, pt4 = j->pt1b;
- if (!FindSegment(pp1a, pt1, pt2)) continue;
- if (j->poly1Idx == j->poly2Idx)
- {
- //we're searching the same polygon for overlapping segments so
- //segment 2 mustn't be the same as segment 1 ...
- pp2a = pp1a->next;
- if (!FindSegment(pp2a, pt3, pt4) || (pp2a == pp1a)) continue;
- }
- else if (!FindSegment(pp2a, pt3, pt4)) continue;
-
- if (!GetOverlapSegment(pt1, pt2, pt3, pt4, pt1, pt2)) continue;
-
- OutPt *p1, *p2, *p3, *p4;
- OutPt *prev = pp1a->prev;
- //get p1 & p2 polypts - the overlap start & endpoints on poly1
- if (PointsEqual(pp1a->pt, pt1)) p1 = pp1a;
- else if (PointsEqual(prev->pt, pt1)) p1 = prev;
- else p1 = InsertPolyPtBetween(pp1a, prev, pt1);
-
- if (PointsEqual(pp1a->pt, pt2)) p2 = pp1a;
- else if (PointsEqual(prev->pt, pt2)) p2 = prev;
- else if ((p1 == pp1a) || (p1 == prev))
- p2 = InsertPolyPtBetween(pp1a, prev, pt2);
- else if (Pt3IsBetweenPt1AndPt2(pp1a->pt, p1->pt, pt2))
- p2 = InsertPolyPtBetween(pp1a, p1, pt2); else
- p2 = InsertPolyPtBetween(p1, prev, pt2);
-
- //get p3 & p4 polypts - the overlap start & endpoints on poly2
- prev = pp2a->prev;
- if (PointsEqual(pp2a->pt, pt1)) p3 = pp2a;
- else if (PointsEqual(prev->pt, pt1)) p3 = prev;
- else p3 = InsertPolyPtBetween(pp2a, prev, pt1);
-
- if (PointsEqual(pp2a->pt, pt2)) p4 = pp2a;
- else if (PointsEqual(prev->pt, pt2)) p4 = prev;
- else if ((p3 == pp2a) || (p3 == prev))
- p4 = InsertPolyPtBetween(pp2a, prev, pt2);
- else if (Pt3IsBetweenPt1AndPt2(pp2a->pt, p3->pt, pt2))
- p4 = InsertPolyPtBetween(pp2a, p3, pt2); else
- p4 = InsertPolyPtBetween(p3, prev, pt2);
-
- //p1.pt == p3.pt and p2.pt == p4.pt so join p1 to p3 and p2 to p4 ...
- if (p1->next == p2 && p3->prev == p4)
- {
- p1->next = p3;
- p3->prev = p1;
- p2->prev = p4;
- p4->next = p2;
- }
- else if (p1->prev == p2 && p3->next == p4)
- {
- p1->prev = p3;
- p3->next = p1;
- p2->next = p4;
- p4->prev = p2;
- }
- else
- continue; //an orientation is probably wrong
-
- if (j->poly2Idx == j->poly1Idx)
- {
- //instead of joining two polygons, we've just created a new one by
- //splitting one polygon into two.
- 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 = 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 ==
- (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 ==
- (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;
- outRec2->FirstLeft = outRec1->FirstLeft;
- //make sure any contained holes now link to the correct polygon ...
- if (fixHoleLinkages) CheckHoleLinkages1(outRec1, outRec2);
- }
-
- //now fixup any subsequent joins that match this polygon
- for (JoinList::size_type k = i+1; k < m_Joins.size(); k++)
- {
- JoinRec* j2 = m_Joins[k];
- if (j2->poly1Idx == j->poly1Idx && PointIsVertex(j2->pt1a, p2))
- j2->poly1Idx = j->poly2Idx;
- if (j2->poly2Idx == j->poly1Idx && PointIsVertex(j2->pt2a, p2))
- j2->poly2Idx = j->poly2Idx;
- }
-
- //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 ...
-
- //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;
-
- //now fixup any subsequent Joins that match this polygon
- for (JoinList::size_type k = i+1; k < m_Joins.size(); k++)
- {
- JoinRec* j2 = m_Joins[k];
- if (j2->poly1Idx == ObsoleteIdx) j2->poly1Idx = OKIdx;
- if (j2->poly2Idx == ObsoleteIdx) j2->poly2Idx = OKIdx;
- }
- }
- }
-}
-//------------------------------------------------------------------------------
-
-void ReversePolygon(Polygon& p)
-{
- std::reverse(p.begin(), p.end());
-}
-//------------------------------------------------------------------------------
-
-void ReversePolygons(Polygons& p)
-{
- for (Polygons::size_type i = 0; i < p.size(); ++i)
- ReversePolygon(p[i]);
-}
-
-//------------------------------------------------------------------------------
-// OffsetPolygon functions ...
-//------------------------------------------------------------------------------
-
-struct DoublePoint
-{
- double X;
- double Y;
- DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
-};
-//------------------------------------------------------------------------------
-
-Polygon BuildArc(const IntPoint &pt,
- const double a1, const double a2, const double r)
-{
- 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)
- {
- result[i].X = pt.X + Round(std::cos(a)*r);
- result[i].Y = pt.Y + Round(std::sin(a)*r);
- a += da;
- }
- return result;
-}
-//------------------------------------------------------------------------------
-
-DoublePoint GetUnitNormal( const IntPoint &pt1, const IntPoint &pt2)
-{
- if(pt2.X == pt1.X && pt2.Y == pt1.Y)
- return DoublePoint(0, 0);
-
- double dx = (double)(pt2.X - pt1.X);
- double dy = (double)(pt2.Y - pt1.Y);
- double f = 1 *1.0/ std::sqrt( dx*dx + dy*dy );
- dx *= f;
- dy *= f;
- return DoublePoint(dy, -dx);
-}
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-class PolyOffsetBuilder
-{
-private:
- Polygons m_p;
- Polygon* m_curr_poly;
- std::vector<DoublePoint> normals;
- double m_delta, m_RMin, m_R;
- size_t m_i, m_j, m_k;
- static const int buffLength = 128;
- JoinType m_jointype;
-
-public:
-
-PolyOffsetBuilder(const Polygons& in_polys, Polygons& out_polys,
- double delta, JoinType jointype, double MiterLimit)
-{
- //nb precondition - out_polys != ptsin_polys
- if (NEAR_ZERO(delta))
- {
- out_polys = in_polys;
- return;
- }
-
- this->m_p = in_polys;
- this->m_delta = delta;
- this->m_jointype = jointype;
- if (MiterLimit <= 1) MiterLimit = 1;
- m_RMin = 2/(MiterLimit*MiterLimit);
-
- double deltaSq = delta*delta;
- out_polys.clear();
- out_polys.resize(in_polys.size());
- for (m_i = 0; m_i < in_polys.size(); m_i++)
- {
- m_curr_poly = &out_polys[m_i];
- size_t len = in_polys[m_i].size();
- if (len > 1 && m_p[m_i][0].X == m_p[m_i][len - 1].X &&
- m_p[m_i][0].Y == m_p[m_i][len-1].Y) len--;
-
- //when 'shrinking' polygons - to minimize artefacts
- //strip those polygons that have an area < pi * delta^2 ...
- double a1 = Area(in_polys[m_i]);
- if (delta < 0) { if (a1 > 0 && a1 < deltaSq *pi) len = 0; }
- else if (a1 < 0 && -a1 < deltaSq *pi) len = 0; //holes have neg. area
-
- if (len == 0 || (len < 3 && delta <= 0))
- continue;
- else if (len == 1)
- {
- Polygon arc;
- arc = BuildArc(in_polys[m_i][len-1], 0, 2 * pi, delta);
- out_polys[m_i] = arc;
- continue;
- }
-
- //build normals ...
- normals.clear();
- normals.resize(len);
- normals[len-1] = GetUnitNormal(in_polys[m_i][len-1], in_polys[m_i][0]);
- for (m_j = 0; m_j < len -1; ++m_j)
- normals[m_j] = GetUnitNormal(in_polys[m_i][m_j], in_polys[m_i][m_j+1]);
-
- m_k = len -1;
- for (m_j = 0; m_j < len; ++m_j)
- {
- switch (jointype)
- {
- case jtMiter:
- {
- m_R = 1 + (normals[m_j].X*normals[m_k].X +
- normals[m_j].Y*normals[m_k].Y);
- if (m_R >= m_RMin) DoMiter(); else DoSquare(MiterLimit);
- break;
- }
- case jtSquare: DoSquare(); break;
- case jtRound: DoRound(); break;
- }
- m_k = m_j;
- }
- }
-
- //finally, clean up untidy corners using Clipper ...
- Clipper clpr;
- clpr.AddPolygons(out_polys, ptSubject);
- if (delta > 0)
- {
- if (!clpr.Execute(ctUnion, out_polys, pftPositive, pftPositive))
- out_polys.clear();
- }
- else
- {
- IntRect r = clpr.GetBounds();
- Polygon outer(4);
- outer[0] = IntPoint(r.left - 10, r.bottom + 10);
- outer[1] = IntPoint(r.right + 10, r.bottom + 10);
- outer[2] = IntPoint(r.right + 10, r.top - 10);
- outer[3] = IntPoint(r.left - 10, r.top - 10);
-
- clpr.AddPolygon(outer, ptSubject);
- if (clpr.Execute(ctUnion, out_polys, pftNegative, pftNegative))
- {
- out_polys.erase(out_polys.begin());
- ReversePolygons(out_polys);
-
- } else
- out_polys.clear();
- }
-}
-//------------------------------------------------------------------------------
-
-private:
-
-void AddPoint(const IntPoint& pt)
-{
- Polygon::size_type len = m_curr_poly->size();
- if (len == m_curr_poly->capacity())
- m_curr_poly->reserve(len + buffLength);
- m_curr_poly->push_back(pt);
-}
-//------------------------------------------------------------------------------
-
-void DoSquare(double mul = 1.0)
-{
- IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta),
- (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta));
- IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta),
- (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);
- }
- else
- {
- AddPoint(pt1);
- AddPoint(m_p[m_i][m_j]);
- AddPoint(pt2);
- }
-}
-//------------------------------------------------------------------------------
-
-void DoMiter()
-{
- if ((normals[m_k].X * normals[m_j].Y - normals[m_j].X * normals[m_k].Y) * m_delta >= 0)
- {
- double q = m_delta / m_R;
- AddPoint(IntPoint((long64)Round(m_p[m_i][m_j].X +
- (normals[m_k].X + normals[m_j].X) * q),
- (long64)Round(m_p[m_i][m_j].Y + (normals[m_k].Y + normals[m_j].Y) * q)));
- }
- else
- {
- IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X *
- m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta));
- IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X *
- m_delta), (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta));
- AddPoint(pt1);
- AddPoint(m_p[m_i][m_j]);
- AddPoint(pt2);
- }
-}
-//------------------------------------------------------------------------------
-
-void DoRound()
-{
- IntPoint pt1 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_k].X * m_delta),
- (long64)Round(m_p[m_i][m_j].Y + normals[m_k].Y * m_delta));
- IntPoint pt2 = IntPoint((long64)Round(m_p[m_i][m_j].X + normals[m_j].X * m_delta),
- (long64)Round(m_p[m_i][m_j].Y + normals[m_j].Y * m_delta));
- AddPoint(pt1);
- //round off reflex angles (ie > 180 deg) unless almost flat (ie < ~10deg).
- if ((normals[m_k].X*normals[m_j].Y - normals[m_j].X*normals[m_k].Y) * m_delta >= 0)
- {
- if (normals[m_j].X * normals[m_k].X + normals[m_j].Y * normals[m_k].Y < 0.985)
- {
- double a1 = std::atan2(normals[m_k].Y, normals[m_k].X);
- double a2 = std::atan2(normals[m_j].Y, normals[m_j].X);
- if (m_delta > 0 && a2 < a1) a2 += pi *2;
- else if (m_delta < 0 && a2 > a1) a2 -= pi *2;
- Polygon arc = BuildArc(m_p[m_i][m_j], a1, a2, m_delta);
- for (Polygon::size_type m = 0; m < arc.size(); m++)
- AddPoint(arc[m]);
- }
- }
- else
- AddPoint(m_p[m_i][m_j]);
- AddPoint(pt2);
-}
-//--------------------------------------------------------------------------
-
-}; //end PolyOffsetBuilder
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-void OffsetPolygons(const Polygons &in_polys, Polygons &out_polys,
- double delta, JoinType jointype, double MiterLimit)
-{
- if (&out_polys == &in_polys)
- {
- Polygons poly2(in_polys);
- PolyOffsetBuilder(poly2, out_polys, delta, jointype, MiterLimit);
- }
- else PolyOffsetBuilder(in_polys, out_polys, delta, jointype, MiterLimit);
-}
-//------------------------------------------------------------------------------
-
-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";
- return s;
-}
-//------------------------------------------------------------------------------
-
-std::ostream& operator <<(std::ostream &s, Polygon &p)
-{
- for (Polygon::size_type i = 0; i < p.size(); i++)
- s << p[i];
- s << "\n";
- return s;
-}
-//------------------------------------------------------------------------------
-
-std::ostream& operator <<(std::ostream &s, Polygons &p)
-{
- for (Polygons::size_type i = 0; i < p.size(); i++)
- s << p[i];
- s << "\n";
- return s;
-}
-//------------------------------------------------------------------------------
-
-} //ClipperLib namespace
diff --git a/src/3rdparty/assimp/contrib/clipper/clipper.hpp b/src/3rdparty/assimp/contrib/clipper/clipper.hpp
deleted file mode 100644
index 7cdac6c3f..000000000
--- a/src/3rdparty/assimp/contrib/clipper/clipper.hpp
+++ /dev/null
@@ -1,306 +0,0 @@
-/*******************************************************************************
-* *
-* Author : Angus Johnson *
-* Version : 4.8.8 *
-* Date : 30 August 2012 *
-* Website : http://www.angusj.com *
-* Copyright : Angus Johnson 2010-2012 *
-* *
-* License: *
-* Use, modification & distribution is subject to Boost Software License Ver 1. *
-* http://www.boost.org/LICENSE_1_0.txt *
-* *
-* Attributions: *
-* The code in this library is an extension of Bala Vatti's clipping algorithm: *
-* "A generic solution to polygon clipping" *
-* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
-* http://portal.acm.org/citation.cfm?id=129906 *
-* *
-* Computer graphics and geometric modeling: implementation and algorithms *
-* By Max K. Agoston *
-* Springer; 1 edition (January 4, 2005) *
-* http://books.google.com/books?q=vatti+clipping+agoston *
-* *
-* See also: *
-* "Polygon Offsetting by Computing Winding Numbers" *
-* Paper no. DETC2005-85513 pp. 565-575 *
-* ASME 2005 International Design Engineering Technical Conferences *
-* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
-* September 24-28, 2005 , Long Beach, California, USA *
-* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
-* *
-*******************************************************************************/
-
-#ifndef clipper_hpp
-#define clipper_hpp
-
-#include <vector>
-#include <stdexcept>
-#include <cstring>
-#include <cstdlib>
-#include <ostream>
-
-namespace ClipperLib {
-
-enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
-enum PolyType { ptSubject, ptClip };
-//By far the most widely used winding rules for polygon filling are
-//EvenOdd & NonZero (GDI, GDI+, XLib, OpenGL, Cairo, AGG, Quartz, SVG, Gr32)
-//Others rules include Positive, Negative and ABS_GTR_EQ_TWO (only in OpenGL)
-//see http://glprogramming.com/red/chapter11.html
-enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
-
-typedef signed long long long64;
-typedef unsigned long long ulong64;
-
-struct IntPoint {
-public:
- long64 X;
- long64 Y;
- IntPoint(long64 x = 0, long64 y = 0): X(x), Y(y) {};
- friend std::ostream& operator <<(std::ostream &s, IntPoint &p);
-};
-
-typedef std::vector< IntPoint > Polygon;
-typedef std::vector< Polygon > Polygons;
-
-std::ostream& operator <<(std::ostream &s, Polygon &p);
-std::ostream& operator <<(std::ostream &s, Polygons &p);
-
-struct ExPolygon {
- Polygon outer;
- Polygons holes;
-};
-typedef std::vector< ExPolygon > ExPolygons;
-
-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 ReversePolygon(Polygon& p);
-void ReversePolygons(Polygons& p);
-
-//used internally ...
-enum EdgeSide { esNeither = 0, esLeft = 1, esRight = 2, esBoth = 3 };
-enum IntersectProtects { ipNone = 0, ipLeft = 1, ipRight = 2, ipBoth = 3 };
-
-struct TEdge {
- long64 xbot;
- long64 ybot;
- long64 xcurr;
- long64 ycurr;
- long64 xtop;
- long64 ytop;
- double dx;
- long64 tmpX;
- PolyType polyType;
- EdgeSide side;
- int windDelta; //1 or -1 depending on winding direction
- int windCnt;
- int windCnt2; //winding count of the opposite polytype
- int outIdx;
- TEdge *next;
- TEdge *prev;
- TEdge *nextInLML;
- TEdge *nextInAEL;
- TEdge *prevInAEL;
- TEdge *nextInSEL;
- TEdge *prevInSEL;
-};
-
-struct IntersectNode {
- TEdge *edge1;
- TEdge *edge2;
- IntPoint pt;
- IntersectNode *next;
-};
-
-struct LocalMinima {
- long64 Y;
- TEdge *leftBound;
- TEdge *rightBound;
- LocalMinima *next;
-};
-
-struct Scanbeam {
- long64 Y;
- Scanbeam *next;
-};
-
-struct OutPt; //forward declaration
-
-struct OutRec {
- int idx;
- bool isHole;
- OutRec *FirstLeft;
- OutRec *AppendLink;
- OutPt *pts;
- OutPt *bottomPt;
- OutPt *bottomFlag;
- EdgeSide sides;
-};
-
-struct OutPt {
- int idx;
- IntPoint pt;
- OutPt *next;
- OutPt *prev;
-};
-
-struct JoinRec {
- IntPoint pt1a;
- IntPoint pt1b;
- int poly1Idx;
- IntPoint pt2a;
- IntPoint pt2b;
- int poly2Idx;
-};
-
-struct HorzJoinRec {
- TEdge *edge;
- int savedIdx;
-};
-
-struct IntRect { long64 left; long64 top; long64 right; long64 bottom; };
-
-typedef std::vector < OutRec* > PolyOutList;
-typedef std::vector < TEdge* > EdgeList;
-typedef std::vector < JoinRec* > JoinList;
-typedef std::vector < HorzJoinRec* > HorzJoinList;
-
-//ClipperBase is the ancestor to the Clipper class. It should not be
-//instantiated directly. This class simply abstracts the conversion of sets of
-//polygon coordinates into edge objects that are stored in a LocalMinima list.
-class ClipperBase
-{
-public:
- ClipperBase();
- virtual ~ClipperBase();
- bool AddPolygon(const Polygon &pg, PolyType polyType);
- bool AddPolygons( const Polygons &ppg, PolyType polyType);
- virtual void Clear();
- IntRect GetBounds();
-protected:
- void DisposeLocalMinimaList();
- TEdge* AddBoundsToLML(TEdge *e);
- void PopLocalMinima();
- virtual void Reset();
- void InsertLocalMinima(LocalMinima *newLm);
- LocalMinima *m_CurrentLM;
- LocalMinima *m_MinimaList;
- bool m_UseFullRange;
- EdgeList m_edges;
-};
-
-class Clipper : public virtual ClipperBase
-{
-public:
- Clipper();
- ~Clipper();
- bool Execute(ClipType clipType,
- Polygons &solution,
- PolyFillType subjFillType = pftEvenOdd,
- PolyFillType clipFillType = pftEvenOdd);
- bool Execute(ClipType clipType,
- ExPolygons &solution,
- PolyFillType subjFillType = pftEvenOdd,
- PolyFillType clipFillType = pftEvenOdd);
- void Clear();
- bool ReverseSolution() {return m_ReverseOutput;};
- void ReverseSolution(bool value) {m_ReverseOutput = value;};
-protected:
- void Reset();
- virtual bool ExecuteInternal(bool fixHoleLinkages);
-private:
- PolyOutList m_PolyOuts;
- JoinList m_Joins;
- HorzJoinList m_HorizJoins;
- ClipType m_ClipType;
- Scanbeam *m_Scanbeam;
- TEdge *m_ActiveEdges;
- TEdge *m_SortedEdges;
- IntersectNode *m_IntersectNodes;
- bool m_ExecuteLocked;
- PolyFillType m_ClipFillType;
- PolyFillType m_SubjFillType;
- bool m_ReverseOutput;
- void DisposeScanbeamList();
- void SetWindingCount(TEdge& edge);
- bool IsEvenOddFillType(const TEdge& edge) const;
- bool IsEvenOddAltFillType(const TEdge& edge) const;
- void InsertScanbeam(const long64 Y);
- long64 PopScanbeam();
- void InsertLocalMinimaIntoAEL(const long64 botY);
- void InsertEdgeIntoAEL(TEdge *edge);
- void AddEdgeToSEL(TEdge *edge);
- void CopyAELToSEL();
- void DeleteFromSEL(TEdge *e);
- void DeleteFromAEL(TEdge *e);
- void UpdateEdgeIntoAEL(TEdge *&e);
- void SwapPositionsInSEL(TEdge *edge1, TEdge *edge2);
- bool IsContributing(const TEdge& edge) const;
- bool IsTopHorz(const long64 XPos);
- void SwapPositionsInAEL(TEdge *edge1, TEdge *edge2);
- void DoMaxima(TEdge *e, long64 topY);
- void ProcessHorizontals();
- void ProcessHorizontal(TEdge *horzEdge);
- void AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
- void AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &pt);
- void AppendPolygon(TEdge *e1, TEdge *e2);
- void DoEdge1(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
- void DoEdge2(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
- void DoBothEdges(TEdge *edge1, TEdge *edge2, const IntPoint &pt);
- void IntersectEdges(TEdge *e1, TEdge *e2,
- const IntPoint &pt, IntersectProtects protects);
- OutRec* CreateOutRec();
- void AddOutPt(TEdge *e, const IntPoint &pt);
- void DisposeBottomPt(OutRec &outRec);
- void DisposeAllPolyPts();
- 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);
- void ProcessIntersectList();
- void ProcessEdgesAtTopOfScanbeam(const long64 topY);
- void BuildResult(Polygons& polys);
- void BuildResultEx(ExPolygons& polys);
- void SetHoleState(TEdge *e, OutRec *OutRec);
- void DisposeIntersectNodes();
- bool FixupIntersections();
- void FixupOutPolygon(OutRec &outRec);
- bool IsHole(TEdge *e);
- void FixHoleLinkage(OutRec *outRec);
- void CheckHoleLinkages1(OutRec *outRec1, OutRec *outRec2);
- void CheckHoleLinkages2(OutRec *outRec1, OutRec *outRec2);
- void AddJoin(TEdge *e1, TEdge *e2, int e1OutIdx = -1, int e2OutIdx = -1);
- void ClearJoins();
- void AddHorzJoin(TEdge *e, int idx);
- void ClearHorzJoins();
- void JoinCommonEdges(bool fixHoleLinkages);
-};
-
-//------------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-
-class clipperException : public std::exception
-{
- public:
- clipperException(const char* description): m_descr(description) {}
- virtual ~clipperException() throw() {}
- virtual const char* what() const throw() {return m_descr.c_str();}
- private:
- std::string m_descr;
-};
-//------------------------------------------------------------------------------
-
-} //ClipperLib namespace
-
-#endif //clipper_hpp
-
-
diff --git a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h b/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h
deleted file mode 100644
index 63b700dc1..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/CXMLReaderImpl.h
+++ /dev/null
@@ -1,809 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
-
-#ifndef __ICXML_READER_IMPL_H_INCLUDED__
-#define __ICXML_READER_IMPL_H_INCLUDED__
-
-#include "irrXML.h"
-#include "irrString.h"
-#include "irrArray.h"
-
-using namespace Assimp;
-
-#ifdef _DEBUG
-#define IRR_DEBUGPRINT(x) printf((x));
-#else // _DEBUG
-#define IRR_DEBUGPRINT(x)
-#endif // _DEBUG
-
-
-namespace irr
-{
-namespace io
-{
-
-
-//! implementation of the IrrXMLReader
-template<class char_type, class superclass>
-class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
-{
-public:
-
- //! Constructor
- CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
- : TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE),
- SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
- {
- if (!callback)
- return;
-
- storeTargetFormat();
-
- // read whole xml file
-
- readFile(callback);
-
- // clean up
-
- if (deleteCallBack)
- delete callback;
-
- // create list with special characters
-
- createSpecialCharacterList();
-
- // set pointer to text begin
- P = TextBegin;
- }
-
-
- //! Destructor
- virtual ~CXMLReaderImpl()
- {
- delete [] TextData;
- }
-
-
- //! Reads forward to the next xml node.
- //! \return Returns false, if there was no further node.
- virtual bool read()
- {
- // if not end reached, parse the node
- if (P && (unsigned int)(P - TextBegin) < TextSize - 1 && *P != 0)
- {
- parseCurrentNode();
- return true;
- }
-
- _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
- return false;
- }
-
-
- //! Returns the type of the current XML node.
- virtual EXML_NODE getNodeType() const
- {
- return CurrentNodeType;
- }
-
-
- //! Returns attribute count of the current XML node.
- virtual int getAttributeCount() const
- {
- return Attributes.size();
- }
-
-
- //! Returns name of an attribute.
- virtual const char_type* getAttributeName(int idx) const
- {
- if (idx < 0 || idx >= (int)Attributes.size())
- return 0;
-
- return Attributes[idx].Name.c_str();
- }
-
-
- //! Returns the value of an attribute.
- virtual const char_type* getAttributeValue(int idx) const
- {
- if (idx < 0 || idx >= (int)Attributes.size())
- return 0;
-
- return Attributes[idx].Value.c_str();
- }
-
-
- //! Returns the value of an attribute.
- virtual const char_type* getAttributeValue(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return 0;
-
- return attr->Value.c_str();
- }
-
-
- //! Returns the value of an attribute
- virtual const char_type* getAttributeValueSafe(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return EmptyString.c_str();
-
- return attr->Value.c_str();
- }
-
-
-
- //! Returns the value of an attribute as integer.
- int getAttributeValueAsInt(const char_type* name) const
- {
- return (int)getAttributeValueAsFloat(name);
- }
-
-
- //! Returns the value of an attribute as integer.
- int getAttributeValueAsInt(int idx) const
- {
- return (int)getAttributeValueAsFloat(idx);
- }
-
-
- //! Returns the value of an attribute as float.
- float getAttributeValueAsFloat(const char_type* name) const
- {
- const SAttribute* attr = getAttributeByName(name);
- if (!attr)
- return 0;
-
- core::stringc c = attr->Value.c_str();
- return fast_atof(c.c_str());
- }
-
-
- //! Returns the value of an attribute as float.
- float getAttributeValueAsFloat(int idx) const
- {
- const char_type* attrvalue = getAttributeValue(idx);
- if (!attrvalue)
- return 0;
-
- core::stringc c = attrvalue;
- return fast_atof(c.c_str());
- }
-
-
- //! Returns the name of the current node.
- virtual const char_type* getNodeName() const
- {
- return NodeName.c_str();
- }
-
-
- //! Returns data of the current node.
- virtual const char_type* getNodeData() const
- {
- return NodeName.c_str();
- }
-
-
- //! Returns if an element is an empty element, like <foo />
- virtual bool isEmptyElement() const
- {
- return IsEmptyElement;
- }
-
- //! Returns format of the source xml file.
- virtual ETEXT_FORMAT getSourceFormat() const
- {
- return SourceFormat;
- }
-
- //! Returns format of the strings returned by the parser.
- virtual ETEXT_FORMAT getParserFormat() const
- {
- return TargetFormat;
- }
-
-private:
-
- // Reads the current xml node
- void parseCurrentNode()
- {
- char_type* start = P;
-
- // move forward until '<' found
- while(*P != L'<' && *P)
- ++P;
-
- if (!*P)
- return;
-
- if (P - start > 0)
- {
- // we found some text, store it
- if (setText(start, P))
- return;
- }
-
- ++P;
-
- // based on current token, parse and report next element
- switch(*P)
- {
- case L'/':
- parseClosingXMLElement();
- break;
- case L'?':
- ignoreDefinition();
- break;
- case L'!':
- if (!parseCDATA())
- parseComment();
- break;
- default:
- parseOpeningXMLElement();
- break;
- }
- }
-
-
- //! sets the state that text was found. Returns true if set should be set
- bool setText(char_type* start, char_type* end)
- {
- // check if text is more than 2 characters, and if not, check if there is
- // only white space, so that this text won't be reported
- if (end - start < 3)
- {
- char_type* p = start;
- for(; p != end; ++p)
- if (!isWhiteSpace(*p))
- break;
-
- if (p == end)
- return false;
- }
-
- // set current text to the parsed text, and replace xml special characters
- core::string<char_type> s(start, (int)(end - start));
- NodeName = replaceSpecialCharacters(s);
-
- // current XML node type is text
- CurrentNodeType = EXN_TEXT;
-
- return true;
- }
-
-
-
- //! ignores an xml definition like <?xml something />
- void ignoreDefinition()
- {
- CurrentNodeType = EXN_UNKNOWN;
-
- // move until end marked with '>' reached
- while(*P != L'>')
- ++P;
-
- ++P;
- }
-
-
- //! parses a comment
- void parseComment()
- {
- CurrentNodeType = EXN_COMMENT;
- P += 1;
-
- char_type *pCommentBegin = P;
-
- int count = 1;
-
- // move until end of comment reached
- while(count)
- {
- if (*P == L'>')
- --count;
- else
- if (*P == L'<')
- ++count;
-
- ++P;
- }
-
- P -= 3;
- NodeName = core::string<char_type>(pCommentBegin+2, (int)(P - pCommentBegin-2));
- P += 3;
- }
-
-
- //! parses an opening xml element and reads attributes
- void parseOpeningXMLElement()
- {
- CurrentNodeType = EXN_ELEMENT;
- IsEmptyElement = false;
- Attributes.clear();
-
- // find name
- const char_type* startName = P;
-
- // find end of element
- while(*P != L'>' && !isWhiteSpace(*P))
- ++P;
-
- const char_type* endName = P;
-
- // find Attributes
- while(*P != L'>')
- {
- if (isWhiteSpace(*P))
- ++P;
- else
- {
- if (*P != L'/')
- {
- // we've got an attribute
-
- // read the attribute names
- const char_type* attributeNameBegin = P;
-
- while(!isWhiteSpace(*P) && *P != L'=')
- ++P;
-
- const char_type* attributeNameEnd = P;
- ++P;
-
- // read the attribute value
- // check for quotes and single quotes, thx to murphy
- while( (*P != L'\"') && (*P != L'\'') && *P)
- ++P;
-
- if (!*P) // malformatted xml file
- return;
-
- const char_type attributeQuoteChar = *P;
-
- ++P;
- const char_type* attributeValueBegin = P;
-
- while(*P != attributeQuoteChar && *P)
- ++P;
-
- if (!*P) // malformatted xml file
- return;
-
- const char_type* attributeValueEnd = P;
- ++P;
-
- SAttribute attr;
- attr.Name = core::string<char_type>(attributeNameBegin,
- (int)(attributeNameEnd - attributeNameBegin));
-
- core::string<char_type> s(attributeValueBegin,
- (int)(attributeValueEnd - attributeValueBegin));
-
- attr.Value = replaceSpecialCharacters(s);
- Attributes.push_back(attr);
- }
- else
- {
- // tag is closed directly
- ++P;
- IsEmptyElement = true;
- break;
- }
- }
- }
-
- // check if this tag is closing directly
- if (endName > startName && *(endName-1) == L'/')
- {
- // directly closing tag
- IsEmptyElement = true;
- endName--;
- }
-
- NodeName = core::string<char_type>(startName, (int)(endName - startName));
-
- ++P;
- }
-
-
- //! parses an closing xml tag
- void parseClosingXMLElement()
- {
- CurrentNodeType = EXN_ELEMENT_END;
- IsEmptyElement = false;
- Attributes.clear();
-
- ++P;
- const char_type* pBeginClose = P;
-
- while(*P != L'>')
- ++P;
-
- // remove trailing whitespace, if any
- while( isspace( P[-1]))
- --P;
-
- NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
- ++P;
- }
-
- //! parses a possible CDATA section, returns false if begin was not a CDATA section
- bool parseCDATA()
- {
- if (*(P+1) != L'[')
- return false;
-
- CurrentNodeType = EXN_CDATA;
-
- // skip '<![CDATA['
- int count=0;
- while( *P && count<8 )
- {
- ++P;
- ++count;
- }
-
- if (!*P)
- return true;
-
- char_type *cDataBegin = P;
- char_type *cDataEnd = 0;
-
- // find end of CDATA
- while(*P && !cDataEnd)
- {
- if (*P == L'>' &&
- (*(P-1) == L']') &&
- (*(P-2) == L']'))
- {
- cDataEnd = P - 2;
- }
-
- ++P;
- }
-
- if ( cDataEnd )
- NodeName = core::string<char_type>(cDataBegin, (int)(cDataEnd - cDataBegin));
- else
- NodeName = "";
-
- return true;
- }
-
-
- // structure for storing attribute-name pairs
- struct SAttribute
- {
- core::string<char_type> Name;
- core::string<char_type> Value;
- };
-
- // finds a current attribute by name, returns 0 if not found
- const SAttribute* getAttributeByName(const char_type* name) const
- {
- if (!name)
- return 0;
-
- core::string<char_type> n = name;
-
- for (int i=0; i<(int)Attributes.size(); ++i)
- if (Attributes[i].Name == n)
- return &Attributes[i];
-
- return 0;
- }
-
- // replaces xml special characters in a string and creates a new one
- core::string<char_type> replaceSpecialCharacters(
- core::string<char_type>& origstr)
- {
- int pos = origstr.findFirst(L'&');
- int oldPos = 0;
-
- if (pos == -1)
- return origstr;
-
- core::string<char_type> newstr;
-
- while(pos != -1 && pos < origstr.size()-2)
- {
- // check if it is one of the special characters
-
- int specialChar = -1;
- for (int i=0; i<(int)SpecialCharacters.size(); ++i)
- {
- const char_type* p = &origstr.c_str()[pos]+1;
-
- if (equalsn(&SpecialCharacters[i][1], p, SpecialCharacters[i].size()-1))
- {
- specialChar = i;
- break;
- }
- }
-
- if (specialChar != -1)
- {
- newstr.append(origstr.subString(oldPos, pos - oldPos));
- newstr.append(SpecialCharacters[specialChar][0]);
- pos += SpecialCharacters[specialChar].size();
- }
- else
- {
- newstr.append(origstr.subString(oldPos, pos - oldPos + 1));
- pos += 1;
- }
-
- // find next &
- oldPos = pos;
- pos = origstr.findNext(L'&', pos);
- }
-
- if (oldPos < origstr.size()-1)
- newstr.append(origstr.subString(oldPos, origstr.size()-oldPos));
-
- return newstr;
- }
-
-
-
- //! reads the xml file and converts it into the wanted character format.
- bool readFile(IFileReadCallBack* callback)
- {
- int size = callback->getSize();
- size += 4; // We need two terminating 0's at the end.
- // For ASCII we need 1 0's, for UTF-16 2, for UTF-32 4.
-
- char* data8 = new char[size];
-
- if (!callback->read(data8, size-4))
- {
- delete [] data8;
- return false;
- }
-
- // add zeros at end
-
- data8[size-1] = 0;
- data8[size-2] = 0;
- data8[size-3] = 0;
- data8[size-4] = 0;
-
- char16* data16 = reinterpret_cast<char16*>(data8);
- char32* data32 = reinterpret_cast<char32*>(data8);
-
- // now we need to convert the data to the desired target format
- // based on the byte order mark.
-
- const unsigned char UTF8[] = {0xEF, 0xBB, 0xBF}; // 0xEFBBBF;
- const int UTF16_BE = 0xFFFE;
- const int UTF16_LE = 0xFEFF;
- const int UTF32_BE = 0xFFFE0000;
- const int UTF32_LE = 0x0000FEFF;
-
- // check source for all utf versions and convert to target data format
-
- if (size >= 4 && data32[0] == (char32)UTF32_BE)
- {
- // UTF-32, big endian
- SourceFormat = ETF_UTF32_BE;
- convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
- }
- else
- if (size >= 4 && data32[0] == (char32)UTF32_LE)
- {
- // UTF-32, little endian
- SourceFormat = ETF_UTF32_LE;
- convertTextData(data32+1, data8, (size/4)); // data32+1 because we need to skip the header
- }
- else
- if (size >= 2 && data16[0] == UTF16_BE)
- {
- // UTF-16, big endian
- SourceFormat = ETF_UTF16_BE;
- convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
- }
- else
- if (size >= 2 && data16[0] == UTF16_LE)
- {
- // UTF-16, little endian
- SourceFormat = ETF_UTF16_LE;
- convertTextData(data16+1, data8, (size/2)); // data16+1 because we need to skip the header
- }
- else
- if (size >= 3 && data8[0] == UTF8[0] && data8[1] == UTF8[1] && data8[2] == UTF8[2])
- {
- // UTF-8
- SourceFormat = ETF_UTF8;
- convertTextData(data8+3, data8, size); // data8+3 because we need to skip the header
- }
- else
- {
- // ASCII
- SourceFormat = ETF_ASCII;
- convertTextData(data8, data8, size);
- }
-
- return true;
- }
-
-
- //! converts the text file into the desired format.
- //! \param source: begin of the text (without byte order mark)
- //! \param pointerToStore: pointer to text data block which can be
- //! stored or deleted based on the nesessary conversion.
- //! \param sizeWithoutHeader: Text size in characters without header
- template<class src_char_type>
- void convertTextData(src_char_type* source, char* pointerToStore, int sizeWithoutHeader)
- {
- // convert little to big endian if necessary
- if (sizeof(src_char_type) > 1 &&
- isLittleEndian(TargetFormat) != isLittleEndian(SourceFormat))
- convertToLittleEndian(source);
-
- // check if conversion is necessary:
- if (sizeof(src_char_type) == sizeof(char_type))
- {
- // no need to convert
- TextBegin = (char_type*)source;
- TextData = (char_type*)pointerToStore;
- TextSize = sizeWithoutHeader;
- }
- else
- {
- // convert source into target data format.
- // TODO: implement a real conversion. This one just
- // copies bytes. This is a problem when there are
- // unicode symbols using more than one character.
-
- TextData = new char_type[sizeWithoutHeader];
-
- // MSVC debugger complains here about loss of data ...
-
-
- // FIXME - gcc complains about 'shift width larger than width of type'
- // for T == unsigned long. Avoid it by messing around volatile ..
- volatile unsigned int c = 3;
- const src_char_type cc = (src_char_type)((((uint64_t)1u << (sizeof( char_type)<<c)) - 1));
- for (int i=0; i<sizeWithoutHeader; ++i)
- TextData[i] = char_type( source[i] & cc);
-
- TextBegin = TextData;
- TextSize = sizeWithoutHeader;
-
- // delete original data because no longer needed
- delete [] pointerToStore;
- }
- }
-
- //! converts whole text buffer to little endian
- template<class src_char_type>
- void convertToLittleEndian(src_char_type* t)
- {
- if (sizeof(src_char_type) == 4)
- {
- // 32 bit
-
- while(*t)
- {
- *t = ((*t & 0xff000000) >> 24) |
- ((*t & 0x00ff0000) >> 8) |
- ((*t & 0x0000ff00) << 8) |
- ((*t & 0x000000ff) << 24);
- ++t;
- }
- }
- else
- {
- // 16 bit
-
- while(*t)
- {
- *t = (*t >> 8) | (*t << 8);
- ++t;
- }
- }
- }
-
- //! returns if a format is little endian
- inline bool isLittleEndian(ETEXT_FORMAT f)
- {
- return f == ETF_ASCII ||
- f == ETF_UTF8 ||
- f == ETF_UTF16_LE ||
- f == ETF_UTF32_LE;
- }
-
-
- //! returns true if a character is whitespace
- inline bool isWhiteSpace(char_type c)
- {
- return (c==' ' || c=='\t' || c=='\n' || c=='\r');
- }
-
-
- //! generates a list with xml special characters
- void createSpecialCharacterList()
- {
- // list of strings containing special symbols,
- // the first character is the special character,
- // the following is the symbol string without trailing &.
-
- SpecialCharacters.push_back("&amp;");
- SpecialCharacters.push_back("<lt;");
- SpecialCharacters.push_back(">gt;");
- SpecialCharacters.push_back("\"quot;");
- SpecialCharacters.push_back("'apos;");
-
- }
-
-
- //! compares the first n characters of the strings
- bool equalsn(const char_type* str1, const char_type* str2, int len)
- {
- int i;
- for(i=0; str1[i] && str2[i] && i < len; ++i)
- if (str1[i] != str2[i])
- return false;
-
- // if one (or both) of the strings was smaller then they
- // are only equal if they have the same lenght
- return (i == len) || (str1[i] == 0 && str2[i] == 0);
- }
-
-
- //! stores the target text format
- void storeTargetFormat()
- {
- // get target format. We could have done this using template specialization,
- // but VisualStudio 6 don't like it and we want to support it.
-
- switch(sizeof(char_type))
- {
- case 1:
- TargetFormat = ETF_UTF8;
- break;
- case 2:
- TargetFormat = ETF_UTF16_LE;
- break;
- case 4:
- TargetFormat = ETF_UTF32_LE;
- break;
- default:
- TargetFormat = ETF_ASCII; // should never happen.
- }
- }
-
-
- // instance variables:
-
- char_type* TextData; // data block of the text file
- char_type* P; // current point in text to parse
- char_type* TextBegin; // start of text to parse
- unsigned int TextSize; // size of text to parse in characters, not bytes
-
- EXML_NODE CurrentNodeType; // type of the currently parsed node
- ETEXT_FORMAT SourceFormat; // source format of the xml file
- ETEXT_FORMAT TargetFormat; // output format of this parser
-
- core::string<char_type> NodeName; // name of the node currently in
- core::string<char_type> EmptyString; // empty string to be returned by getSafe() methods
-
- bool IsEmptyElement; // is the currently parsed node empty?
-
- core::array< core::string<char_type> > SpecialCharacters; // see createSpecialCharacterList()
-
- core::array<SAttribute> Attributes; // attributes of current element
-
-}; // end CXMLReaderImpl
-
-
-} // end namespace
-} // end namespace
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/irrXML/heapsort.h b/src/3rdparty/assimp/contrib/irrXML/heapsort.h
deleted file mode 100644
index d0db319d0..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/heapsort.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __IRR_HEAPSORT_H_INCLUDED__
-#define __IRR_HEAPSORT_H_INCLUDED__
-
-#include "irrTypes.h"
-
-namespace irr
-{
-namespace core
-{
-
-//! Sinks an element into the heap.
-template<class T>
-inline void heapsink(T*array, s32 element, s32 max)
-{
- while ((element<<1) < max) // there is a left child
- {
- s32 j = (element<<1);
-
- if (j+1 < max && array[j] < array[j+1])
- j = j+1; // take right child
-
- if (array[element] < array[j])
- {
- T t = array[j]; // swap elements
- array[j] = array[element];
- array[element] = t;
- element = j;
- }
- else
- return;
- }
-}
-
-
-//! Sorts an array with size 'size' using heapsort.
-template<class T>
-inline void heapsort(T* array_, s32 size)
-{
- // for heapsink we pretent this is not c++, where
- // arrays start with index 0. So we decrease the array pointer,
- // the maximum always +2 and the element always +1
-
- T* virtualArray = array_ - 1;
- s32 virtualSize = size + 2;
- s32 i;
-
- // build heap
-
- for (i=((size-1)/2); i>=0; --i)
- heapsink(virtualArray, i+1, virtualSize-1);
-
- // sort array
-
- for (i=size-1; i>=0; --i)
- {
- T t = array_[0];
- array_[0] = array_[i];
- array_[i] = t;
- heapsink(virtualArray, 1, i + 1);
- }
-}
-
-} // end namespace core
-} // end namespace irr
-
-
-
-#endif
-
diff --git a/src/3rdparty/assimp/contrib/irrXML/irrArray.h b/src/3rdparty/assimp/contrib/irrXML/irrArray.h
deleted file mode 100644
index 40c822590..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/irrArray.h
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
-
-#ifndef __IRR_ARRAY_H_INCLUDED__
-#define __IRR_ARRAY_H_INCLUDED__
-
-#include "irrTypes.h"
-#include "heapsort.h"
-
-namespace irr
-{
-namespace core
-{
-
-//! Self reallocating template array (like stl vector) with additional features.
-/** Some features are: Heap sorting, binary search methods, easier debugging.
-*/
-template <class T>
-class array
-{
-
-public:
-
- array()
- : data(0), allocated(0), used(0),
- free_when_destroyed(true), is_sorted(true)
- {
- }
-
- //! Constructs a array and allocates an initial chunk of memory.
- //! \param start_count: Amount of elements to allocate.
- array(u32 start_count)
- : data(0), allocated(0), used(0),
- free_when_destroyed(true), is_sorted(true)
- {
- reallocate(start_count);
- }
-
-
- //! Copy constructor
- array(const array<T>& other)
- : data(0)
- {
- *this = other;
- }
-
-
-
- //! Destructor. Frees allocated memory, if set_free_when_destroyed
- //! was not set to false by the user before.
- ~array()
- {
- if (free_when_destroyed)
- delete [] data;
- }
-
-
-
- //! Reallocates the array, make it bigger or smaller.
- //! \param new_size: New size of array.
- void reallocate(u32 new_size)
- {
- T* old_data = data;
-
- data = new T[new_size];
- allocated = new_size;
-
- s32 end = used < new_size ? used : new_size;
- for (s32 i=0; i<end; ++i)
- data[i] = old_data[i];
-
- if (allocated < used)
- used = allocated;
-
- delete [] old_data;
- }
-
- //! Adds an element at back of array. If the array is to small to
- //! add this new element, the array is made bigger.
- //! \param element: Element to add at the back of the array.
- void push_back(const T& element)
- {
- if (used + 1 > allocated)
- {
- // reallocate(used * 2 +1);
- // this doesn't work if the element is in the same array. So
- // we'll copy the element first to be sure we'll get no data
- // corruption
-
- T e;
- e = element; // copy element
- reallocate(used * 2 +1); // increase data block
- data[used++] = e; // push_back
- is_sorted = false;
- return;
- }
-
- data[used++] = element;
- is_sorted = false;
- }
-
-
- //! Adds an element at the front of the array. If the array is to small to
- //! add this new element, the array is made bigger. Please note that this
- //! is slow, because the whole array needs to be copied for this.
- //! \param element: Element to add at the back of the array.
- void push_front(const T& element)
- {
- if (used + 1 > allocated)
- reallocate(used * 2 +1);
-
- for (int i=(int)used; i>0; --i)
- data[i] = data[i-1];
-
- data[0] = element;
- is_sorted = false;
- ++used;
- }
-
-
- //! Insert item into array at specified position. Please use this
- //! only if you know what you are doing (possible performance loss).
- //! The preferred method of adding elements should be push_back().
- //! \param element: Element to be inserted
- //! \param index: Where position to insert the new element.
- void insert(const T& element, u32 index=0)
- {
- _IRR_DEBUG_BREAK_IF(index>used) // access violation
-
- if (used + 1 > allocated)
- reallocate(used * 2 +1);
-
- for (u32 i=used++; i>index; i--)
- data[i] = data[i-1];
-
- data[index] = element;
- is_sorted = false;
- }
-
-
-
-
- //! Clears the array and deletes all allocated memory.
- void clear()
- {
- delete [] data;
- data = 0;
- used = 0;
- allocated = 0;
- is_sorted = true;
- }
-
-
-
- //! Sets pointer to new array, using this as new workspace.
- //! \param newPointer: Pointer to new array of elements.
- //! \param size: Size of the new array.
- void set_pointer(T* newPointer, u32 size)
- {
- delete [] data;
- data = newPointer;
- allocated = size;
- used = size;
- is_sorted = false;
- }
-
-
-
- //! Sets if the array should delete the memory it used.
- //! \param f: If true, the array frees the allocated memory in its
- //! destructor, otherwise not. The default is true.
- void set_free_when_destroyed(bool f)
- {
- free_when_destroyed = f;
- }
-
-
-
- //! Sets the size of the array.
- //! \param usedNow: Amount of elements now used.
- void set_used(u32 usedNow)
- {
- if (allocated < usedNow)
- reallocate(usedNow);
-
- used = usedNow;
- }
-
-
-
- //! Assignement operator
- void operator=(const array<T>& other)
- {
- if (data)
- delete [] data;
-
- //if (allocated < other.allocated)
- if (other.allocated == 0)
- data = 0;
- else
- data = new T[other.allocated];
-
- used = other.used;
- free_when_destroyed = other.free_when_destroyed;
- is_sorted = other.is_sorted;
- allocated = other.allocated;
-
- for (u32 i=0; i<other.used; ++i)
- data[i] = other.data[i];
- }
-
-
- //! Direct access operator
- T& operator [](u32 index)
- {
- _IRR_DEBUG_BREAK_IF(index>=used) // access violation
-
- return data[index];
- }
-
-
-
- //! Direct access operator
- const T& operator [](u32 index) const
- {
- _IRR_DEBUG_BREAK_IF(index>=used) // access violation
-
- return data[index];
- }
-
- //! Gets last frame
- const T& getLast() const
- {
- _IRR_DEBUG_BREAK_IF(!used) // access violation
-
- return data[used-1];
- }
-
- //! Gets last frame
- T& getLast()
- {
- _IRR_DEBUG_BREAK_IF(!used) // access violation
-
- return data[used-1];
- }
-
-
- //! Returns a pointer to the array.
- //! \return Pointer to the array.
- T* pointer()
- {
- return data;
- }
-
-
-
- //! Returns a const pointer to the array.
- //! \return Pointer to the array.
- const T* const_pointer() const
- {
- return data;
- }
-
-
-
- //! Returns size of used array.
- //! \return Size of elements in the array.
- u32 size() const
- {
- return used;
- }
-
-
-
- //! Returns amount memory allocated.
- //! \return Returns amount of memory allocated. The amount of bytes
- //! allocated would be allocated_size() * sizeof(ElementsUsed);
- u32 allocated_size() const
- {
- return allocated;
- }
-
-
-
- //! Returns true if array is empty
- //! \return True if the array is empty, false if not.
- bool empty() const
- {
- return used == 0;
- }
-
-
-
- //! Sorts the array using heapsort. There is no additional memory waste and
- //! the algorithm performs (O) n log n in worst case.
- void sort()
- {
- if (is_sorted || used<2)
- return;
-
- heapsort(data, used);
- is_sorted = true;
- }
-
-
-
- //! Performs a binary search for an element, returns -1 if not found.
- //! The array will be sorted before the binary search if it is not
- //! already sorted.
- //! \param element: Element to search for.
- //! \return Returns position of the searched element if it was found,
- //! otherwise -1 is returned.
- s32 binary_search(const T& element)
- {
- return binary_search(element, 0, used-1);
- }
-
-
-
- //! Performs a binary search for an element, returns -1 if not found.
- //! The array will be sorted before the binary search if it is not
- //! already sorted.
- //! \param element: Element to search for.
- //! \param left: First left index
- //! \param right: Last right index.
- //! \return Returns position of the searched element if it was found,
- //! otherwise -1 is returned.
- s32 binary_search(const T& element, s32 left, s32 right)
- {
- if (!used)
- return -1;
-
- sort();
-
- s32 m;
-
- do
- {
- m = (left+right)>>1;
-
- if (element < data[m])
- right = m - 1;
- else
- left = m + 1;
-
- } while((element < data[m] || data[m] < element) && left<=right);
-
- // this last line equals to:
- // " while((element != array[m]) && left<=right);"
- // but we only want to use the '<' operator.
- // the same in next line, it is "(element == array[m])"
-
- if (!(element < data[m]) && !(data[m] < element))
- return m;
-
- return -1;
- }
-
-
- //! Finds an element in linear time, which is very slow. Use
- //! binary_search for faster finding. Only works if =operator is implemented.
- //! \param element: Element to search for.
- //! \return Returns position of the searched element if it was found,
- //! otherwise -1 is returned.
- s32 linear_search(T& element)
- {
- for (u32 i=0; i<used; ++i)
- if (!(element < data[i]) && !(data[i] < element))
- return (s32)i;
-
- return -1;
- }
-
-
- //! Finds an element in linear time, which is very slow. Use
- //! binary_search for faster finding. Only works if =operator is implemented.
- //! \param element: Element to search for.
- //! \return Returns position of the searched element if it was found,
- //! otherwise -1 is returned.
- s32 linear_reverse_search(T& element)
- {
- for (s32 i=used-1; i>=0; --i)
- if (data[i] == element)
- return (s32)i;
-
- return -1;
- }
-
-
-
- //! Erases an element from the array. May be slow, because all elements
- //! following after the erased element have to be copied.
- //! \param index: Index of element to be erased.
- void erase(u32 index)
- {
- _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
-
- for (u32 i=index+1; i<used; ++i)
- data[i-1] = data[i];
-
- --used;
- }
-
-
- //! Erases some elements from the array. may be slow, because all elements
- //! following after the erased element have to be copied.
- //! \param index: Index of the first element to be erased.
- //! \param count: Amount of elements to be erased.
- void erase(u32 index, s32 count)
- {
- _IRR_DEBUG_BREAK_IF(index>=used || index<0 || count<1 || index+count>used) // access violation
-
- for (u32 i=index+count; i<used; ++i)
- data[i-count] = data[i];
-
- used-= count;
- }
-
-
- //! Sets if the array is sorted
- void set_sorted(bool _is_sorted)
- {
- is_sorted = _is_sorted;
- }
-
-
- private:
-
- T* data;
- u32 allocated;
- u32 used;
- bool free_when_destroyed;
- bool is_sorted;
-};
-
-
-} // end namespace core
-} // end namespace irr
-
-
-
-#endif
-
diff --git a/src/3rdparty/assimp/contrib/irrXML/irrString.h b/src/3rdparty/assimp/contrib/irrXML/irrString.h
deleted file mode 100644
index af21b8e51..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/irrString.h
+++ /dev/null
@@ -1,664 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
-
-#ifndef __IRR_STRING_H_INCLUDED__
-#define __IRR_STRING_H_INCLUDED__
-
-#include "irrTypes.h"
-
-namespace irr
-{
-namespace core
-{
-
-//! Very simple string class with some useful features.
-/** string<c8> and string<wchar_t> work both with unicode AND ascii,
-so you can assign unicode to string<c8> and ascii to string<wchar_t>
-(and the other way round) if your ever would want to.
-Note that the conversation between both is not done using an encoding.
-
-Known bugs:
-Special characters like 'Ä', 'Ü' and 'Ö' are ignored in the
-methods make_upper, make_lower and equals_ignore_case.
-*/
-template <class T>
-class string
-{
-public:
-
- //! Default constructor
- string()
- : array(0), allocated(1), used(1)
- {
- array = new T[1];
- array[0] = 0x0;
- }
-
-
-
- //! Constructor
- string(const string<T>& other)
- : array(0), allocated(0), used(0)
- {
- *this = other;
- }
-
-
- //! Constructs a string from an int
- string(int number)
- : array(0), allocated(0), used(0)
- {
- // store if negative and make positive
-
- bool negative = false;
- if (number < 0)
- {
- number *= -1;
- negative = true;
- }
-
- // temporary buffer for 16 numbers
-
- c8 tmpbuf[16];
- tmpbuf[15] = 0;
- s32 idx = 15;
-
- // special case '0'
-
- if (!number)
- {
- tmpbuf[14] = '0';
- *this = &tmpbuf[14];
- return;
- }
-
- // add numbers
-
- while(number && idx)
- {
- idx--;
- tmpbuf[idx] = (c8)('0' + (number % 10));
- number = number / 10;
- }
-
- // add sign
-
- if (negative)
- {
- idx--;
- tmpbuf[idx] = '-';
- }
-
- *this = &tmpbuf[idx];
- }
-
-
-
- //! Constructor for copying a string from a pointer with a given lenght
- template <class B>
- string(const B* c, s32 lenght)
- : array(0), allocated(0), used(0)
- {
- if (!c)
- return;
-
- allocated = used = lenght+1;
- array = new T[used];
-
- for (s32 l = 0; l<lenght; ++l)
- array[l] = (T)c[l];
-
- array[lenght] = 0;
- }
-
-
-
- //! Constructor for unicode and ascii strings
- template <class B>
- string(const B* c)
- : array(0),allocated(0), used(0)
- {
- *this = c;
- }
-
-
-
- //! destructor
- ~string()
- {
- delete [] array;
- }
-
-
-
- //! Assignment operator
- string<T>& operator=(const string<T>& other)
- {
- if (this == &other)
- return *this;
-
- delete [] array;
- allocated = used = other.size()+1;
- array = new T[used];
-
- const T* p = other.c_str();
- for (s32 i=0; i<used; ++i, ++p)
- array[i] = *p;
-
- return *this;
- }
-
-
-
- //! Assignment operator for strings, ascii and unicode
- template <class B>
- string<T>& operator=(const B* c)
- {
- if (!c)
- {
- if (!array)
- {
- array = new T[1];
- allocated = 1;
- used = 1;
- }
- array[0] = 0x0;
- return *this;
- }
-
- if ((void*)c == (void*)array)
- return *this;
-
- s32 len = 0;
- const B* p = c;
- while(*p)
- {
- ++len;
- ++p;
- }
-
- // we'll take the old string for a while, because the new string could be
- // a part of the current string.
- T* oldArray = array;
-
- allocated = used = len+1;
- array = new T[used];
-
- for (s32 l = 0; l<len+1; ++l)
- array[l] = (T)c[l];
-
- delete [] oldArray;
- return *this;
- }
-
- //! Add operator for other strings
- string<T> operator+(const string<T>& other)
- {
- string<T> str(*this);
- str.append(other);
-
- return str;
- }
-
- //! Add operator for strings, ascii and unicode
- template <class B>
- string<T> operator+(const B* c)
- {
- string<T> str(*this);
- str.append(c);
-
- return str;
- }
-
-
-
- //! Direct access operator
- T& operator [](const s32 index) const
- {
- _IRR_DEBUG_BREAK_IF(index>=used) // bad index
-
- return array[index];
- }
-
-
- //! Comparison operator
- bool operator ==(const T* str) const
- {
- int i;
- for(i=0; array[i] && str[i]; ++i)
- if (array[i] != str[i])
- return false;
-
- return !array[i] && !str[i];
- }
-
-
-
- //! Comparison operator
- bool operator ==(const string<T>& other) const
- {
- for(s32 i=0; array[i] && other.array[i]; ++i)
- if (array[i] != other.array[i])
- return false;
-
- return used == other.used;
- }
-
-
-
- //! Is smaller operator
- bool operator <(const string<T>& other) const
- {
- for(s32 i=0; array[i] && other.array[i]; ++i)
- if (array[i] != other.array[i])
- return (array[i] < other.array[i]);
-
- return used < other.used;
- }
-
-
-
- //! Equals not operator
- bool operator !=(const string<T>& other) const
- {
- return !(*this == other);
- }
-
-
-
- //! Returns length of string
- /** \return Returns length of the string in characters. */
- s32 size() const
- {
- return used-1;
- }
-
-
-
- //! Returns character string
- /** \return Returns pointer to C-style zero terminated string. */
- const T* c_str() const
- {
- return array;
- }
-
-
-
- //! Makes the string lower case.
- void make_lower()
- {
- const T A = (T)'A';
- const T Z = (T)'Z';
- const T diff = (T)'a' - A;
-
- for (s32 i=0; i<used; ++i)
- {
- if (array[i]>=A && array[i]<=Z)
- array[i] += diff;
- }
- }
-
-
-
- //! Makes the string upper case.
- void make_upper()
- {
- const T a = (T)'a';
- const T z = (T)'z';
- const T diff = (T)'A' - a;
-
- for (s32 i=0; i<used; ++i)
- {
- if (array[i]>=a && array[i]<=z)
- array[i] += diff;
- }
- }
-
-
-
- //! Compares the string ignoring case.
- /** \param other: Other string to compare.
- \return Returns true if the string are equal ignoring case. */
- bool equals_ignore_case(const string<T>& other) const
- {
- for(s32 i=0; array[i] && other[i]; ++i)
- if (toLower(array[i]) != toLower(other[i]))
- return false;
-
- return used == other.used;
- }
-
-
- //! compares the first n characters of the strings
- bool equalsn(const string<T>& other, int len)
- {
- int i;
- for(i=0; array[i] && other[i] && i < len; ++i)
- if (array[i] != other[i])
- return false;
-
- // if one (or both) of the strings was smaller then they
- // are only equal if they have the same lenght
- return (i == len) || (used == other.used);
- }
-
-
- //! compares the first n characters of the strings
- bool equalsn(const T* str, int len)
- {
- int i;
- for(i=0; array[i] && str[i] && i < len; ++i)
- if (array[i] != str[i])
- return false;
-
- // if one (or both) of the strings was smaller then they
- // are only equal if they have the same lenght
- return (i == len) || (array[i] == 0 && str[i] == 0);
- }
-
-
- //! Appends a character to this string
- /** \param character: Character to append. */
- void append(T character)
- {
- if (used + 1 > allocated)
- reallocate((s32)used + 1);
-
- used += 1;
-
- array[used-2] = character;
- array[used-1] = 0;
- }
-
- //! Appends a string to this string
- /** \param other: String to append. */
- void append(const string<T>& other)
- {
- --used;
-
- s32 len = other.size();
-
- if (used + len + 1 > allocated)
- reallocate((s32)used + (s32)len + 1);
-
- for (s32 l=0; l<len+1; ++l)
- array[l+used] = other[l];
-
- used = used + len + 1;
- }
-
-
- //! Appends a string of the length l to this string.
- /** \param other: other String to append to this string.
- \param length: How much characters of the other string to add to this one. */
- void append(const string<T>& other, s32 length)
- {
- s32 len = other.size();
-
- if (len < length)
- {
- append(other);
- return;
- }
-
- len = length;
- --used;
-
- if (used + len > allocated)
- reallocate((s32)used + (s32)len);
-
- for (s32 l=0; l<len; ++l)
- array[l+used] = other[l];
-
- used = used + len;
- }
-
-
- //! Reserves some memory.
- /** \param count: Amount of characters to reserve. */
- void reserve(s32 count)
- {
- if (count < allocated)
- return;
-
- reallocate(count);
- }
-
-
- //! finds first occurrence of character in string
- /** \param c: Character to search for.
- \return Returns position where the character has been found,
- or -1 if not found. */
- s32 findFirst(T c) const
- {
- for (s32 i=0; i<used; ++i)
- if (array[i] == c)
- return i;
-
- return -1;
- }
-
- //! finds first occurrence of a character of a list in string
- /** \param c: List of strings to find. For example if the method
- should find the first occurance of 'a' or 'b', this parameter should be "ab".
- \param count: Amount of characters in the list. Ususally,
- this should be strlen(ofParameter1)
- \return Returns position where one of the character has been found,
- or -1 if not found. */
- s32 findFirstChar(T* c, int count) const
- {
- for (s32 i=0; i<used; ++i)
- for (int j=0; j<count; ++j)
- if (array[i] == c[j])
- return i;
-
- return -1;
- }
-
-
- //! Finds first position of a character not in a given list.
- /** \param c: List of characters not to find. For example if the method
- should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
- \param count: Amount of characters in the list. Ususally,
- this should be strlen(ofParameter1)
- \return Returns position where the character has been found,
- or -1 if not found. */
- template <class B>
- s32 findFirstCharNotInList(B* c, int count) const
- {
- for (int i=0; i<used; ++i)
- {
- int j;
- for (j=0; j<count; ++j)
- if (array[i] == c[j])
- break;
-
- if (j==count)
- return i;
- }
-
- return -1;
- }
-
- //! Finds last position of a character not in a given list.
- /** \param c: List of characters not to find. For example if the method
- should find the first occurance of a character not 'a' or 'b', this parameter should be "ab".
- \param count: Amount of characters in the list. Ususally,
- this should be strlen(ofParameter1)
- \return Returns position where the character has been found,
- or -1 if not found. */
- template <class B>
- s32 findLastCharNotInList(B* c, int count) const
- {
- for (int i=used-2; i>=0; --i)
- {
- int j;
- for (j=0; j<count; ++j)
- if (array[i] == c[j])
- break;
-
- if (j==count)
- return i;
- }
-
- return -1;
- }
-
- //! finds next occurrence of character in string
- /** \param c: Character to search for.
- \param startPos: Position in string to start searching.
- \return Returns position where the character has been found,
- or -1 if not found. */
- s32 findNext(T c, s32 startPos) const
- {
- for (s32 i=startPos; i<used; ++i)
- if (array[i] == c)
- return i;
-
- return -1;
- }
-
-
- //! finds last occurrence of character in string
- //! \param c: Character to search for.
- //! \return Returns position where the character has been found,
- //! or -1 if not found.
- s32 findLast(T c) const
- {
- for (s32 i=used-1; i>=0; --i)
- if (array[i] == c)
- return i;
-
- return -1;
- }
-
-
- //! Returns a substring
- //! \param begin: Start of substring.
- //! \param length: Length of substring.
- string<T> subString(s32 begin, s32 length)
- {
- if (length <= 0)
- return string<T>("");
-
- string<T> o;
- o.reserve(length+1);
-
- for (s32 i=0; i<length; ++i)
- o.array[i] = array[i+begin];
-
- o.array[length] = 0;
- o.used = o.allocated;
-
- return o;
- }
-
-
- void operator += (T c)
- {
- append(c);
- }
-
- void operator += (const string<T>& other)
- {
- append(other);
- }
-
- void operator += (int i)
- {
- append(string<T>(i));
- }
-
- //! replaces all characters of a special type with another one
- void replace(T toReplace, T replaceWith)
- {
- for (s32 i=0; i<used; ++i)
- if (array[i] == toReplace)
- array[i] = replaceWith;
- }
-
- //! trims the string.
- /** Removes whitespace from begin and end of the string. */
- void trim()
- {
- const char whitespace[] = " \t\n";
- const int whitespacecount = 3;
-
- // find start and end of real string without whitespace
- int begin = findFirstCharNotInList(whitespace, whitespacecount);
- if (begin == -1)
- return;
-
- int end = findLastCharNotInList(whitespace, whitespacecount);
- if (end == -1)
- return;
-
- *this = subString(begin, (end +1) - begin);
- }
-
-
- //! Erases a character from the string. May be slow, because all elements
- //! following after the erased element have to be copied.
- //! \param index: Index of element to be erased.
- void erase(int index)
- {
- _IRR_DEBUG_BREAK_IF(index>=used || index<0) // access violation
-
- for (int i=index+1; i<used; ++i)
- array[i-1] = array[i];
-
- --used;
- }
-
-
-
-private:
-
- //! Returns a character converted to lower case
- T toLower(const T& t) const
- {
- if (t>=(T)'A' && t<=(T)'Z')
- return t + ((T)'a' - (T)'A');
- else
- return t;
- }
-
- //! Reallocate the array, make it bigger or smaler
- void reallocate(s32 new_size)
- {
- T* old_array = array;
-
- array = new T[new_size];
- allocated = new_size;
-
- s32 amount = used < new_size ? used : new_size;
- for (s32 i=0; i<amount; ++i)
- array[i] = old_array[i];
-
- if (allocated < used)
- used = allocated;
-
- delete [] old_array;
- }
-
-
- //--- member variables
-
- T* array;
- s32 allocated;
- s32 used;
-};
-
-
-//! Typedef for character strings
-typedef string<irr::c8> stringc;
-
-//! Typedef for wide character strings
-typedef string<wchar_t> stringw;
-
-} // end namespace core
-} // end namespace irr
-
-#endif
-
diff --git a/src/3rdparty/assimp/contrib/irrXML/irrTypes.h b/src/3rdparty/assimp/contrib/irrXML/irrTypes.h
deleted file mode 100644
index a7f12ec75..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/irrTypes.h
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine".
-// For conditions of distribution and use, see copyright notice in irrlicht.h
-
-#ifndef __IRR_TYPES_H_INCLUDED__
-#define __IRR_TYPES_H_INCLUDED__
-
-namespace irr
-{
-
-//! 8 bit unsigned variable.
-/** This is a typedef for unsigned char, it ensures portability of the engine. */
-typedef unsigned char u8;
-
-//! 8 bit signed variable.
-/** This is a typedef for signed char, it ensures portability of the engine. */
-typedef signed char s8;
-
-//! 8 bit character variable.
-/** This is a typedef for char, it ensures portability of the engine. */
-typedef char c8;
-
-
-
-//! 16 bit unsigned variable.
-/** This is a typedef for unsigned short, it ensures portability of the engine. */
-typedef unsigned short u16;
-
-//! 16 bit signed variable.
-/** This is a typedef for signed short, it ensures portability of the engine. */
-typedef signed short s16;
-
-
-
-//! 32 bit unsigned variable.
-/** This is a typedef for unsigned int, it ensures portability of the engine. */
-typedef unsigned int u32;
-
-//! 32 bit signed variable.
-/** This is a typedef for signed int, it ensures portability of the engine. */
-typedef signed int s32;
-
-
-
-// 64 bit signed variable.
-// This is a typedef for __int64, it ensures portability of the engine.
-// This type is currently not used by the engine and not supported by compilers
-// other than Microsoft Compilers, so it is outcommented.
-//typedef __int64 s64;
-
-
-
-//! 32 bit floating point variable.
-/** This is a typedef for float, it ensures portability of the engine. */
-typedef float f32;
-
-//! 64 bit floating point variable.
-/** This is a typedef for double, it ensures portability of the engine. */
-typedef double f64;
-
-
-} // end namespace
-
-
-// define the wchar_t type if not already built in.
-#ifdef _MSC_VER
-#ifndef _WCHAR_T_DEFINED
-//! A 16 bit wide character type.
-/**
- Defines the wchar_t-type.
- In VS6, its not possible to tell
- the standard compiler to treat wchar_t as a built-in type, and
- sometimes we just don't want to include the huge stdlib.h or wchar.h,
- so we'll use this.
-*/
-typedef unsigned short wchar_t;
-#define _WCHAR_T_DEFINED
-#endif // wchar is not defined
-#endif // microsoft compiler
-
-//! define a break macro for debugging only in Win32 mode.
-// WORKAROUND (assimp): remove __asm
-#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
-#if defined(_M_IX86)
-#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/
-#else
-#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
-#endif
-#else
-#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
-#endif
-
-//! Defines a small statement to work around a microsoft compiler bug.
-/** The microsft compiler 7.0 - 7.1 has a bug:
-When you call unmanaged code that returns a bool type value of false from managed code,
-the return value may appear as true. See
-http://support.microsoft.com/default.aspx?kbid=823071 for details.
-Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
-
-// WORKAROUND (assimp): remove __asm
-#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
-#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/
-#else
-#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
-#endif // _IRR_MANAGED_MARSHALLING_BUGFIX
-
-#endif // __IRR_TYPES_H_INCLUDED__
-
diff --git a/src/3rdparty/assimp/contrib/irrXML/irrXML.cpp b/src/3rdparty/assimp/contrib/irrXML/irrXML.cpp
deleted file mode 100644
index 42509b5f3..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/irrXML.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
-
-// Need to include Assimp, too. We're using Assimp's version of fast_atof
-// so we need stdint.h. But no PCH.
-
-
-#include "irrXML.h"
-#include "irrString.h"
-#include "irrArray.h"
-#include "./../../code/fast_atof.h"
-#include "CXMLReaderImpl.h"
-
-namespace irr
-{
-namespace io
-{
-
-//! Implementation of the file read callback for ordinary files
-class CFileReadCallBack : public IFileReadCallBack
-{
-public:
-
- //! construct from filename
- CFileReadCallBack(const char* filename)
- : File(0), Size(0), Close(true)
- {
- // open file
- File = fopen(filename, "rb");
-
- if (File)
- getFileSize();
- }
-
- //! construct from FILE pointer
- CFileReadCallBack(FILE* file)
- : File(file), Size(0), Close(false)
- {
- if (File)
- getFileSize();
- }
-
- //! destructor
- virtual ~CFileReadCallBack()
- {
- if (Close && File)
- fclose(File);
- }
-
- //! Reads an amount of bytes from the file.
- virtual int read(void* buffer, int sizeToRead)
- {
- if (!File)
- return 0;
-
- return (int)fread(buffer, 1, sizeToRead, File);
- }
-
- //! Returns size of file in bytes
- virtual int getSize()
- {
- return Size;
- }
-
-private:
-
- //! retrieves the file size of the open file
- void getFileSize()
- {
- fseek(File, 0, SEEK_END);
- Size = ftell(File);
- fseek(File, 0, SEEK_SET);
- }
-
- FILE* File;
- int Size;
- bool Close;
-
-}; // end class CFileReadCallBack
-
-
-
-// FACTORY FUNCTIONS:
-
-
-//! Creates an instance of an UFT-8 or ASCII character xml parser.
-IrrXMLReader* createIrrXMLReader(const char* filename)
-{
- return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(filename));
-}
-
-
-//! Creates an instance of an UFT-8 or ASCII character xml parser.
-IrrXMLReader* createIrrXMLReader(FILE* file)
-{
- return new CXMLReaderImpl<char, IXMLBase>(new CFileReadCallBack(file));
-}
-
-
-//! Creates an instance of an UFT-8 or ASCII character xml parser.
-IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback)
-{
- return new CXMLReaderImpl<char, IXMLBase>(callback, false);
-}
-
-
-//! Creates an instance of an UTF-16 xml parser.
-IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename)
-{
- return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(filename));
-}
-
-
-//! Creates an instance of an UTF-16 xml parser.
-IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file)
-{
- return new CXMLReaderImpl<char16, IXMLBase>(new CFileReadCallBack(file));
-}
-
-
-//! Creates an instance of an UTF-16 xml parser.
-IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback)
-{
- return new CXMLReaderImpl<char16, IXMLBase>(callback, false);
-}
-
-
-//! Creates an instance of an UTF-32 xml parser.
-IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename)
-{
- return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(filename));
-}
-
-
-//! Creates an instance of an UTF-32 xml parser.
-IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file)
-{
- return new CXMLReaderImpl<char32, IXMLBase>(new CFileReadCallBack(file));
-}
-
-
-//! Creates an instance of an UTF-32 xml parser.
-IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback)
-{
- return new CXMLReaderImpl<char32, IXMLBase>(callback, false);
-}
-
-
-} // end namespace io
-} // end namespace irr
diff --git a/src/3rdparty/assimp/contrib/irrXML/irrXML.h b/src/3rdparty/assimp/contrib/irrXML/irrXML.h
deleted file mode 100644
index b51ddeb54..000000000
--- a/src/3rdparty/assimp/contrib/irrXML/irrXML.h
+++ /dev/null
@@ -1,540 +0,0 @@
-// Copyright (C) 2002-2005 Nikolaus Gebhardt
-// This file is part of the "Irrlicht Engine" and the "irrXML" project.
-// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
-
-#ifndef __IRR_XML_H_INCLUDED__
-#define __IRR_XML_H_INCLUDED__
-
-#include <stdio.h>
-
-/** \mainpage irrXML 1.2 API documentation
- <div align="center"><img src="logobig.png" ></div>
-
- \section intro Introduction
-
- Welcome to the irrXML API documentation.
- Here you'll find any information you'll need to develop applications with
- irrXML. If you look for a tutorial on how to start, take a look at the \ref irrxmlexample,
- at the homepage of irrXML at <A HREF="http://xml.irrlicht3d.org" >xml.irrlicht3d.org</A>
- or into the SDK in the directory \example.
-
- irrXML is intended to be a high speed and easy-to-use XML Parser for C++, and
- this documentation is an important part of it. If you have any questions or
- suggestions, just send a email to the author of the engine, Nikolaus Gebhardt
- (niko (at) irrlicht3d.org). For more informations about this parser, see \ref history.
-
- \section features Features
-
- irrXML provides forward-only, read-only
- access to a stream of non validated XML data. It was fully implemented by
- Nikolaus Gebhardt. Its current features are:
-
- - It it fast as lighting and has very low memory usage. It was
- developed with the intention of being used in 3D games, as it already has been.
- - irrXML is very small: It only consists of 60 KB of code and can be added easily
- to your existing project.
- - Of course, it is platform independent and works with lots of compilers.
- - It is able to parse ASCII, UTF-8, UTF-16 and UTF-32 text files, both in
- little and big endian format.
- - Independent of the input file format, the parser can return all strings in ASCII, UTF-8,
- UTF-16 and UTF-32 format.
- - With its optional file access abstraction it has the advantage that it can read not
- only from files but from any type of data (memory, network, ...). For example when
- used with the Irrlicht Engine, it directly reads from compressed .zip files.
- - Just like the Irrlicht Engine for which it was originally created, it is extremely easy
- to use.
- - It has no external dependencies, it does not even need the STL.
-
- Although irrXML has some strenghts, it currently also has the following limitations:
-
- - The input xml file is not validated and assumed to be correct.
-
- \section irrxmlexample Example
-
- The following code demonstrates the basic usage of irrXML. A simple xml
- file like this is parsed:
- \code
- <?xml version="1.0"?>
- <config>
- <!-- This is a config file for the mesh viewer -->
- <model file="dwarf.dea" />
- <messageText caption="Irrlicht Engine Mesh Viewer">
- Welcome to the Mesh Viewer of the &quot;Irrlicht Engine&quot;.
- </messageText>
- </config>
- \endcode
-
- The code for parsing this file would look like this:
- \code
- #include <irrXML.h>
- using namespace irr; // irrXML is located in the namespace irr::io
- using namespace io;
-
- #include <string> // we use STL strings to store data in this example
-
- void main()
- {
- // create the reader using one of the factory functions
-
- IrrXMLReader* xml = createIrrXMLReader("config.xml");
-
- // strings for storing the data we want to get out of the file
- std::string modelFile;
- std::string messageText;
- std::string caption;
-
- // parse the file until end reached
-
- while(xml && xml->read())
- {
- switch(xml->getNodeType())
- {
- case EXN_TEXT:
- // in this xml file, the only text which occurs is the messageText
- messageText = xml->getNodeData();
- break;
- case EXN_ELEMENT:
- {
- if (!strcmp("model", xml->getNodeName()))
- modelFile = xml->getAttributeValue("file");
- else
- if (!strcmp("messageText", xml->getNodeName()))
- caption = xml->getAttributeValue("caption");
- }
- break;
- }
- }
-
- // delete the xml parser after usage
- delete xml;
- }
- \endcode
-
- \section howto How to use
-
- Simply add the source files in the /src directory of irrXML to your project. Done.
-
- \section license License
-
- The irrXML license is based on the zlib license. Basicly, this means you can do with
- irrXML whatever you want:
-
- Copyright (C) 2002-2005 Nikolaus Gebhardt
-
- 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.
-
- \section history History
-
- As lots of references in this documentation and the source show, this xml
- parser has originally been a part of the
- <A HREF="http://irrlicht.sourceforge.net" >Irrlicht Engine</A>. But because
- the parser has become very useful with the latest release, people asked for a
- separate version of it, to be able to use it in non Irrlicht projects. With
- irrXML 1.0, this has now been done.
-*/
-
-namespace irr
-{
-namespace io
-{
- //! Enumeration of all supported source text file formats
- enum ETEXT_FORMAT
- {
- //! ASCII, file without byte order mark, or not a text file
- ETF_ASCII,
-
- //! UTF-8 format
- ETF_UTF8,
-
- //! UTF-16 format, big endian
- ETF_UTF16_BE,
-
- //! UTF-16 format, little endian
- ETF_UTF16_LE,
-
- //! UTF-32 format, big endian
- ETF_UTF32_BE,
-
- //! UTF-32 format, little endian
- ETF_UTF32_LE
- };
-
-
- //! Enumeration for all xml nodes which are parsed by IrrXMLReader
- enum EXML_NODE
- {
- //! No xml node. This is usually the node if you did not read anything yet.
- EXN_NONE,
-
- //! A xml element, like <foo>
- EXN_ELEMENT,
-
- //! End of an xml element, like </foo>
- EXN_ELEMENT_END,
-
- //! Text within a xml element: <foo> this is the text. </foo>
- EXN_TEXT,
-
- //! An xml comment like &lt;!-- I am a comment --&gt; or a DTD definition.
- EXN_COMMENT,
-
- //! An xml cdata section like &lt;![CDATA[ this is some CDATA ]]&gt;
- EXN_CDATA,
-
- //! Unknown element.
- EXN_UNKNOWN
- };
-
- //! Callback class for file read abstraction.
- /** With this, it is possible to make the xml parser read in other things
- than just files. The Irrlicht engine is using this for example to
- read xml from compressed .zip files. To make the parser read in
- any other data, derive a class from this interface, implement the
- two methods to read your data and give a pointer to an instance of
- your implementation when calling createIrrXMLReader(),
- createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
- class IFileReadCallBack
- {
- public:
-
- //! virtual destructor
- virtual ~IFileReadCallBack() {};
-
- //! Reads an amount of bytes from the file.
- /** \param buffer: Pointer to buffer where to read bytes will be written to.
- \param sizeToRead: Amount of bytes to read from the file.
- \return Returns how much bytes were read. */
- virtual int read(void* buffer, int sizeToRead) = 0;
-
- //! Returns size of file in bytes
- virtual int getSize() = 0;
- };
-
- //! Empty class to be used as parent class for IrrXMLReader.
- /** If you need another class as base class for the xml reader, you can do this by creating
- the reader using for example new CXMLReaderImpl<char, YourBaseClass>(yourcallback);
- The Irrlicht Engine for example needs IUnknown as base class for every object to
- let it automaticly reference countend, hence it replaces IXMLBase with IUnknown.
- See irrXML.cpp on how this can be done in detail. */
- class IXMLBase
- {
- };
-
- //! Interface providing easy read access to a XML file.
- /** You can create an instance of this reader using one of the factory functions
- createIrrXMLReader(), createIrrXMLReaderUTF16() and createIrrXMLReaderUTF32().
- If using the parser from the Irrlicht Engine, please use IFileSystem::createXMLReader()
- instead.
- For a detailed intro how to use the parser, see \ref irrxmlexample and \ref features.
-
- The typical usage of this parser looks like this:
- \code
- #include <irrXML.h>
- using namespace irr; // irrXML is located in the namespace irr::io
- using namespace io;
-
- void main()
- {
- // create the reader using one of the factory functions
- IrrXMLReader* xml = createIrrXMLReader("config.xml");
-
- if (xml == 0)
- return; // file could not be opened
-
- // parse the file until end reached
- while(xml->read())
- {
- // based on xml->getNodeType(), do something.
- }
-
- // delete the xml parser after usage
- delete xml;
- }
- \endcode
- See \ref irrxmlexample for a more detailed example.
- */
- template<class char_type, class super_class>
- class IIrrXMLReader : public super_class
- {
- public:
-
- //! Destructor
- virtual ~IIrrXMLReader() {};
-
- //! Reads forward to the next xml node.
- /** \return Returns false, if there was no further node. */
- virtual bool read() = 0;
-
- //! Returns the type of the current XML node.
- virtual EXML_NODE getNodeType() const = 0;
-
- //! Returns attribute count of the current XML node.
- /** This is usually
- non null if the current node is EXN_ELEMENT, and the element has attributes.
- \return Returns amount of attributes of this xml node. */
- virtual int getAttributeCount() const = 0;
-
- //! Returns name of an attribute.
- /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
- \return Name of the attribute, 0 if an attribute with this index does not exist. */
- virtual const char_type* getAttributeName(int idx) const = 0;
-
- //! Returns the value of an attribute.
- /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
- \return Value of the attribute, 0 if an attribute with this index does not exist. */
- virtual const char_type* getAttributeValue(int idx) const = 0;
-
- //! Returns the value of an attribute.
- /** \param name: Name of the attribute.
- \return Value of the attribute, 0 if an attribute with this name does not exist. */
- virtual const char_type* getAttributeValue(const char_type* name) const = 0;
-
- //! Returns the value of an attribute in a safe way.
- /** Like getAttributeValue(), but does not
- return 0 if the attribute does not exist. An empty string ("") is returned then.
- \param name: Name of the attribute.
- \return Value of the attribute, and "" if an attribute with this name does not exist */
- virtual const char_type* getAttributeValueSafe(const char_type* name) const = 0;
-
- //! Returns the value of an attribute as integer.
- /** \param name Name of the attribute.
- \return Value of the attribute as integer, and 0 if an attribute with this name does not exist or
- the value could not be interpreted as integer. */
- virtual int getAttributeValueAsInt(const char_type* name) const = 0;
-
- //! Returns the value of an attribute as integer.
- /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
- \return Value of the attribute as integer, and 0 if an attribute with this index does not exist or
- the value could not be interpreted as integer. */
- virtual int getAttributeValueAsInt(int idx) const = 0;
-
- //! Returns the value of an attribute as float.
- /** \param name: Name of the attribute.
- \return Value of the attribute as float, and 0 if an attribute with this name does not exist or
- the value could not be interpreted as float. */
- virtual float getAttributeValueAsFloat(const char_type* name) const = 0;
-
- //! Returns the value of an attribute as float.
- /** \param idx: Zero based index, should be something between 0 and getAttributeCount()-1.
- \return Value of the attribute as float, and 0 if an attribute with this index does not exist or
- the value could not be interpreted as float. */
- virtual float getAttributeValueAsFloat(int idx) const = 0;
-
- //! Returns the name of the current node.
- /** Only non null, if the node type is EXN_ELEMENT.
- \return Name of the current node or 0 if the node has no name. */
- virtual const char_type* getNodeName() const = 0;
-
- //! Returns data of the current node.
- /** Only non null if the node has some
- data and it is of type EXN_TEXT or EXN_UNKNOWN. */
- virtual const char_type* getNodeData() const = 0;
-
- //! Returns if an element is an empty element, like <foo />
- virtual bool isEmptyElement() const = 0;
-
- //! Returns format of the source xml file.
- /** It is not necessary to use
- this method because the parser will convert the input file format
- to the format wanted by the user when creating the parser. This
- method is useful to get/display additional informations. */
- virtual ETEXT_FORMAT getSourceFormat() const = 0;
-
- //! Returns format of the strings returned by the parser.
- /** This will be UTF8 for example when you created a parser with
- IrrXMLReaderUTF8() and UTF32 when it has been created using
- IrrXMLReaderUTF32. It should not be necessary to call this
- method and only exists for informational purposes. */
- virtual ETEXT_FORMAT getParserFormat() const = 0;
- };
-
-
- //! defines the utf-16 type.
- /** Not using wchar_t for this because
- wchar_t has 16 bit on windows and 32 bit on other operating systems. */
- typedef unsigned short char16;
-
- //! defines the utf-32 type.
- /** Not using wchar_t for this because
- wchar_t has 16 bit on windows and 32 bit on other operating systems. */
- typedef unsigned long char32;
-
- //! A UTF-8 or ASCII character xml parser.
- /** This means that all character data will be returned in 8 bit ASCII or UTF-8 by this parser.
- The file to read can be in any format, it will be converted to UTF-8 if it is not
- in this format.
- Create an instance of this with createIrrXMLReader();
- See IIrrXMLReader for description on how to use it. */
- typedef IIrrXMLReader<char, IXMLBase> IrrXMLReader;
-
- //! A UTF-16 xml parser.
- /** This means that all character data will be returned in UTF-16 by this parser.
- The file to read can be in any format, it will be converted to UTF-16 if it is not
- in this format.
- Create an instance of this with createIrrXMLReaderUTF16();
- See IIrrXMLReader for description on how to use it. */
- typedef IIrrXMLReader<char16, IXMLBase> IrrXMLReaderUTF16;
-
- //! A UTF-32 xml parser.
- /** This means that all character data will be returned in UTF-32 by this parser.
- The file to read can be in any format, it will be converted to UTF-32 if it is not
- in this format.
- Create an instance of this with createIrrXMLReaderUTF32();
- See IIrrXMLReader for description on how to use it. */
- typedef IIrrXMLReader<char32, IXMLBase> IrrXMLReaderUTF32;
-
-
- //! Creates an instance of an UFT-8 or ASCII character xml parser.
- /** This means that all character data will be returned in 8 bit ASCII or UTF-8.
- The file to read can be in any format, it will be converted to UTF-8 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReaderUTF8() instead.
- \param filename: Name of file to be opened.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReader* createIrrXMLReader(const char* filename);
-
- //! Creates an instance of an UFT-8 or ASCII character xml parser.
- /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
- be in any format, it will be converted to UTF-8 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReaderUTF8() instead.
- \param file: Pointer to opened file, must have been opened in binary mode, e.g.
- using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReader* createIrrXMLReader(FILE* file);
-
- //! Creates an instance of an UFT-8 or ASCII character xml parser.
- /** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
- be in any format, it will be converted to UTF-8 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReaderUTF8() instead.
- \param callback: Callback for file read abstraction. Implement your own
- callback to make the xml parser read in other things than just files. See
- IFileReadCallBack for more information about this.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
-
- //! Creates an instance of an UFT-16 xml parser.
- /** This means that
- all character data will be returned in UTF-16. The file to read can
- be in any format, it will be converted to UTF-16 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param filename: Name of file to be opened.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
-
- //! Creates an instance of an UFT-16 xml parser.
- /** This means that all character data will be returned in UTF-16. The file to read can
- be in any format, it will be converted to UTF-16 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param file: Pointer to opened file, must have been opened in binary mode, e.g.
- using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
-
- //! Creates an instance of an UFT-16 xml parser.
- /** This means that all character data will be returned in UTF-16. The file to read can
- be in any format, it will be converted to UTF-16 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param callback: Callback for file read abstraction. Implement your own
- callback to make the xml parser read in other things than just files. See
- IFileReadCallBack for more information about this.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
-
-
- //! Creates an instance of an UFT-32 xml parser.
- /** This means that all character data will be returned in UTF-32. The file to read can
- be in any format, it will be converted to UTF-32 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param filename: Name of file to be opened.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
-
- //! Creates an instance of an UFT-32 xml parser.
- /** This means that all character data will be returned in UTF-32. The file to read can
- be in any format, it will be converted to UTF-32 if it is not in this format.
- if you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param file: Pointer to opened file, must have been opened in binary mode, e.g.
- using fopen("foo.bar", "wb"); The file will not be closed after it has been read.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
-
- //! Creates an instance of an UFT-32 xml parser.
- /** This means that
- all character data will be returned in UTF-32. The file to read can
- be in any format, it will be converted to UTF-32 if it is not in this format.
- If you are using the Irrlicht Engine, it is better not to use this function but
- IFileSystem::createXMLReader() instead.
- \param callback: Callback for file read abstraction. Implement your own
- callback to make the xml parser read in other things than just files. See
- IFileReadCallBack for more information about this.
- \return Returns a pointer to the created xml parser. This pointer should be
- deleted using 'delete' after no longer needed. Returns 0 if an error occured
- and the file could not be opened. */
- IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
-
-
- /*! \file irrxml.h
- \brief Header file of the irrXML, the Irrlicht XML parser.
-
- This file includes everything needed for using irrXML,
- the XML parser of the Irrlicht Engine. To use irrXML,
- you only need to include this file in your project:
-
- \code
- #include <irrXML.h>
- \endcode
-
- It is also common to use the two namespaces in which irrXML is included,
- directly after #including irrXML.h:
-
- \code
- #include <irrXML.h>
- using namespace irr;
- using namespace io;
- \endcode
- */
-
-} // end namespace io
-} // end namespace irr
-
-#endif // __IRR_XML_H_INCLUDED__
-
diff --git a/src/3rdparty/assimp/contrib/irrXML_note.txt b/src/3rdparty/assimp/contrib/irrXML_note.txt
deleted file mode 100644
index ff7897ec2..000000000
--- a/src/3rdparty/assimp/contrib/irrXML_note.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-
-IrrXML
-Downloaded September 2008
-
-- fixed a minor compiler warning (vs 2005, shift too large)
-- fixed an issue regarding wchar_t/unsigned short
diff --git a/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt b/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt
deleted file mode 100644
index 9e903ca3f..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/CMakeLists.txt
+++ /dev/null
@@ -1,170 +0,0 @@
-CMAKE_MINIMUM_REQUIRED( VERSION 2.6 )
-PROJECT( OpenDDL-Parser )
-SET ( OPENDDL_PARSER_VERSION_MAJOR 0 )
-SET ( OPENDDL_PARSER_VERSION_MINOR 1 )
-SET ( OPENDDL_PARSER_VERSION_PATCH 0 )
-SET ( OPENDDL_PARSER_VERSION ${OPENDDL_PARSER_VERSION_MAJOR}.${OPENDDL_PARSER_VERSION_MINOR}.${OPENDDL_PARSER_VERSION_PATCH} )
-SET ( PROJECT_VERSION "${OPENDDL_PARSER_VERSION}" )
-
-option( DDL_USE_CPP11 "Set to ON to use C++11 features ( always on on windows )." ON )
-option( DDL_DEBUG_OUTPUT "Set to ON to use output debug texts" OFF )
-option( DDL_STATIC_LIBRARY "Set to ON to build static libary of OpenDDL Parser." ON )
-option( COVERALLS "Generate coveralls data" OFF )
-
-if ( DDL_USE_CPP11 )
- if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
- set( OPENDDL_CXXFLAGS -std=c++0x )
- elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
- set( OPENDDL_CXXFLAGS --std=c++11 )
- endif()
-else( DDL_USE_CPP11 )
- add_definitions( -DOPENDDL_NO_USE_CPP11 )
-endif( DDL_USE_CPP11)
-
-if( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
- find_package(Threads)
-else()
- add_definitions( -D_CRT_SECURE_NO_WARNINGS )
-endif()
-
-if ( DDL_STATIC_LIBRARY )
- add_definitions( -DOPENDDL_STATIC_LIBARY )
-endif()
-
-add_definitions( -DOPENDDLPARSER_BUILD )
-add_definitions( -D_VARIADIC_MAX=10 )
-add_definitions( -DGTEST_HAS_PTHREAD=0 )
-if ( DDL_DEBUG_OUTPUT )
- add_definitions( -DDDL_DEBUG_HEADER_NAME)
-endif()
-
-INCLUDE_DIRECTORIES(
- ./
- include/
- contrib/gtest-1.7.0/include
- contrib/gtest-1.7.0/
-)
-
-link_directories(
- ${CMAKE_HOME_DIRECTORY}/lib
-)
-
-set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake )
-SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
-SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/lib )
-SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin )
-
-if( WIN32 AND NOT CYGWIN )
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc" ) # Force to always compile with W4
- if( CMAKE_CXX_FLAGS MATCHES "/W[0-4]" )
- string( REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" )
- else()
- set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4" )
- endif()
-elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX )
- # Update if necessary
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS}")
-elseif ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic ${OPENDDL_CXXFLAGS} -Wwrite-strings")
-endif()
-
-if (COVERALLS)
- include(Coveralls)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-endif()
-
-# Include the doc component.
-FIND_PACKAGE( doxygen )
-IF ( DOXYGEN_FOUND )
- CONFIGURE_FILE( doc/openddlparser_doc.in doc/doxygenfile @ONLY )
- ADD_CUSTOM_TARGET( doc ALL ${DOXYGEN_EXECUTABLE} doc/doxygenfile
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- COMMENT "Generating API documentation with Doxygen" VERBATIM )
-ENDIF ( DOXYGEN_FOUND )
-
-SET ( openddl_parser_src
- code/OpenDDLCommon.cpp
- code/OpenDDLExport.cpp
- code/OpenDDLParser.cpp
- code/OpenDDLStream.cpp
- code/DDLNode.cpp
- code/Value.cpp
- include/openddlparser/OpenDDLCommon.h
- include/openddlparser/OpenDDLExport.h
- include/openddlparser/OpenDDLParser.h
- include/openddlparser/OpenDDLParserUtils.h
- include/openddlparser/OpenDDLStream.h
- include/openddlparser/DDLNode.h
- include/openddlparser/Value.h
- README.md
-)
-
-SOURCE_GROUP( code FILES ${openddl_parser_src} )
-
-if ( DDL_STATIC_LIBRARY )
- ADD_LIBRARY( openddl_parser STATIC
- ${openddl_parser_src}
- )
-else()
- ADD_LIBRARY( openddl_parser SHARED
- ${openddl_parser_src}
- )
-endif()
-
-SET ( GTEST_PATH contrib/gtest-1.7.0 )
-
-SET ( gtest_src
- ${GTEST_PATH}/src/gtest-death-test.cc
- ${GTEST_PATH}/src/gtest-filepath.cc
- ${GTEST_PATH}/src/gtest-internal-inl.h
- ${GTEST_PATH}/src/gtest-port.cc
- ${GTEST_PATH}/src/gtest-printers.cc
- ${GTEST_PATH}/src/gtest-test-part.cc
- ${GTEST_PATH}/src/gtest-typed-test.cc
- ${GTEST_PATH}/src/gtest.cc
- ${GTEST_PATH}/src/gtest_main.cc
-)
-
-SET( openddl_parser_unittest_src
- test/UnitTestCommon.h
- test/DDLNodeTest.cpp
- test/OpenDDLCommonTest.cpp
- test/OpenDDLExportTest.cpp
- test/OpenDDLParserTest.cpp
- test/OpenDDLParserUtilsTest.cpp
- test/OpenDDLStreamTest.cpp
- test/OpenDDLIntegrationTest.cpp
- test/ValueTest.cpp
- test/OpenDDLDefectsTest.cpp
-)
-
-SOURCE_GROUP( code FILES ${openddl_parser_unittest_src} )
-SOURCE_GROUP( gtest FILES ${gtest_src} )
-
-ADD_EXECUTABLE( openddl_parser_unittest
- ${gtest_src}
- ${openddl_parser_unittest_src}
-)
-
-target_link_libraries( openddl_parser_unittest openddl_parser ${CMAKE_THREAD_LIBS_INIT} )
-
-SET( openddl_parser_demo_src
- demo/main.cpp
-)
-
-if (COVERALLS)
- set(COVERAGE_SRCS ${gtest_src} ${openddl_parser_unittest_src} )
-
- # Create the coveralls target.
- coveralls_setup(
- "${COVERAGE_SRCS}" # The source files.
- ON # If we should upload.
- "${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path.
-endif()
-
-ADD_EXECUTABLE( openddl_parser_demo
- ${openddl_parser_demo_src}
-)
-
-target_link_libraries( openddl_parser_demo openddl_parser )
diff --git a/src/3rdparty/assimp/contrib/openddlparser/CREDITS b/src/3rdparty/assimp/contrib/openddlparser/CREDITS
deleted file mode 100644
index d3936af83..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/CREDITS
+++ /dev/null
@@ -1,19 +0,0 @@
-===============================================================
-OpenDDL-Parser
-Developers and Contributors
-===============================================================
-
-- Kim Kulling ( kimmi ):
-Founder
-
-- Fredrik Hansson ( FredrikHson ):
-Improvements value interface, serveral bugfixes.
-
-- Henry Read ( henrya2 ):
-Static build option, Interface improvements
-
-- (wise86-android)
-fix several mem-leaks
-
-- Paul Holland ( pkholland ):
-Bugfixes.
diff --git a/src/3rdparty/assimp/contrib/openddlparser/LICENSE b/src/3rdparty/assimp/contrib/openddlparser/LICENSE
deleted file mode 100644
index 4c1476bc4..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
diff --git a/src/3rdparty/assimp/contrib/openddlparser/README.md b/src/3rdparty/assimp/contrib/openddlparser/README.md
deleted file mode 100644
index a48ea1be0..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/README.md
+++ /dev/null
@@ -1,136 +0,0 @@
-The OpenDDL-Parser
-==================
-
-The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-parsing. OpenDDL is the shortcut for Open Data Description Language, a data-declaration language introduced by Eric Lengyel. Please check http://openddl.org/ if you want to learn more about it.
-
-Build status
-============
-Linux build status: [![Build Status](https://travis-ci.org/kimkulling/openddl-parser.png)](https://travis-ci.org/kimkulling/openddl-parser)
-Current coverity check status:
-<a href="https://scan.coverity.com/projects/5606">
- <img alt="Coverity Scan Build Status"
- src="https://scan.coverity.com/projects/5606/badge.svg"/>
-</a>
-Current test coverage:[![Coverage Status](https://coveralls.io/repos/github/kimkulling/openddl-parser/badge.svg?branch=master)](https://coveralls.io/github/kimkulling/openddl-parser?branch=cpp_coveralls)
-Get the source code
-===================
-You can get the code from our git repository, which is located at GitHub. You can clone the repository with the following command:
-
-> git clone https://github.com/kimkulling/openddl-parser.git
-
-Building the source from the GitHub-Repo
-========================================
-To build the library you need to install cmake first ( see http://www.cmake.org/ for more information ). Make also sure that a compiler tool-chain is installed on your machine.
-After installing it you can open a console and enter:
-
-> cmake CMakeLists.txt
-
-This command will generate a build environment for your preferred build tool ( for Visual-Studio-users the project files will be generated, for gcc-users the makefiles will be generated ).
-When using an IDE open the IDE and run the build. When using GNU-make type in your console:
-
-> make
-
-and that's all.
-
-When using Visual Studio CMake will generate you a solution for ythe library. Just build it there.
-
-Use the library
-===============
-To use the OpenDDL-parser you need to build the lib first. Now add the
-> <Repo-folder>/include
-
-to your include-path and the
-
-> <Repo-folder>/lib
-
-to your lib-folder. Link the openddl.lib to your application.
-
-Here is a small example how to use the lib:
-
-```cpp
-
-#include <iostream>
-#include <cassert>
-#include <openddlparser/OpenDDLParser.h>
-
-USE_ODDLPARSER_NS;
-
-int main( int argc, char *argv[] ) {
- if( argc < 3 ) {
- return 1;
- }
-
- char *filename( nullptr );
- if( 0 == strncmp( FileOption, argv[ 1 ], strlen( FileOption ) ) ) {
- filename = argv[ 2 ];
- }
- std::cout << "file to import: " << filename << std::endl;
- if( nullptr == filename ) {
- std::cerr << "Invalid filename." << std::endl;
- return Error;
- }
-
- FILE *fileStream = fopen( filename, "r+" );
- if( NULL == filename ) {
- std::cerr << "Cannot open file " << filename << std::endl;
- return 1;
- }
-
- // obtain file size:
- fseek( fileStream, 0, SEEK_END );
- const size_t size( ftell( fileStream ) );
- rewind( fileStream );
- if( size > 0 ) {
- char *buffer = new char[ size ];
- const size_t readSize( fread( buffer, sizeof( char ), size, fileStream ) );
- assert( readSize == size );
- OpenDDLParser theParser;
- theParser.setBuffer( buffer, size );
- const bool result( theParser.parse() );
- if( !result ) {
- std::cerr << "Error while parsing file " << filename << "." << std::endl;
- }
- }
- return 0;
-}
-
-```
-
-How to access the imported data
-===============================
-The data is organized as a tree. You can get the root-node of the tree with the following code:
-
-```cpp
-OpenDDLParser theParser;
-theParser.setBuffer( buffer, size );
-const bool result( theParser.parse() );
-if ( result ) {
- DDLNode *root = theParser.getRoot();
- DDLNode::DllNodeList childs = root->getChildNodeList();
- for ( size_t i=0; i<childs.size(); i++ ) {
- DDLNode *child = childs[ i ];
- Property *prop = child->getProperty(); // to get properties
- std::string type = child->getType(); // to get the node type
- Value *values = child->getValue(); // to get the data;
-
- // to loop through all values
- while ( values != ddl_nullptr ) {
- int current = values->getInt32();
- values = value->getNext();
- }
- }
-}
-
-```
-
-The node instance called root contains the data.
-
-All data lists are organized as linked lists.
-
-Reference documentation
-=======================
-Please check http://kimkulling.github.io/openddl-parser/doxygen_html/index.html.
-
-Projects using OpenDDL-Parser
-=============================
-- Asset Importer Lib: https://github.com/assimp/assimp .
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp
deleted file mode 100644
index a7c557fc5..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/DDLNode.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/DDLNode.h>
-#include <openddlparser/OpenDDLParser.h>
-
-#include <algorithm>
-
-BEGIN_ODDLPARSER_NS
-
-DDLNode::DllNodeList DDLNode::s_allocatedNodes;
-
-template<class T>
-inline
-static void releaseDataType( T *ptr ) {
- if( ddl_nullptr == ptr ) {
- return;
- }
-
- T *current( ddl_nullptr );
- while( ptr ) {
- current = ptr;
- ptr = ptr->m_next;
- delete current;
- }
-}
-
-static void releaseReferencedNames( Reference *ref ) {
- if( ddl_nullptr == ref ) {
- return;
- }
-
- delete ref;
-}
-
-DDLNode::DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent )
-: m_type( type )
-, m_name( name )
-, m_parent( parent )
-, m_children()
-, m_properties( ddl_nullptr )
-, m_value( ddl_nullptr )
-, m_dtArrayList( ddl_nullptr )
-, m_references( ddl_nullptr )
-, m_idx( idx ) {
- if( m_parent ) {
- m_parent->m_children.push_back( this );
- }
-}
-
-DDLNode::~DDLNode() {
- delete m_properties;
- delete m_value;
- releaseReferencedNames( m_references );
-
- delete m_dtArrayList;
- m_dtArrayList = ddl_nullptr;
- if( s_allocatedNodes[ m_idx ] == this ) {
- s_allocatedNodes[ m_idx ] = ddl_nullptr;
- }
- for ( size_t i = 0; i<m_children.size(); i++ ){
- delete m_children[ i ];
- }
-}
-
-void DDLNode::attachParent( DDLNode *parent ) {
- if( m_parent == parent ) {
- return;
- }
-
- m_parent = parent;
- if( ddl_nullptr != m_parent ) {
- m_parent->m_children.push_back( this );
- }
-}
-
-void DDLNode::detachParent() {
- if( ddl_nullptr != m_parent ) {
- DDLNodeIt it = std::find( m_parent->m_children.begin(), m_parent->m_children.end(), this );
- if( m_parent->m_children.end() != it ) {
- m_parent->m_children.erase( it );
- }
- m_parent = ddl_nullptr;
- }
-}
-
-DDLNode *DDLNode::getParent() const {
- return m_parent;
-}
-
-const DDLNode::DllNodeList &DDLNode::getChildNodeList() const {
- return m_children;
-}
-
-void DDLNode::setType( const std::string &type ) {
- m_type = type;
-}
-
-const std::string &DDLNode::getType() const {
- return m_type;
-}
-
-void DDLNode::setName( const std::string &name ) {
- m_name = name;
-}
-
-const std::string &DDLNode::getName() const {
- return m_name;
-}
-
-void DDLNode::setProperties( Property *prop ) {
- if(m_properties!=ddl_nullptr)
- delete m_properties;
- m_properties = prop;
-}
-
-Property *DDLNode::getProperties() const {
- return m_properties;
-}
-
-bool DDLNode::hasProperty( const std::string &name ) {
- const Property *prop( findPropertyByName( name ) );
- return ( ddl_nullptr != prop );
-}
-
-bool DDLNode::hasProperties() const {
- return( ddl_nullptr != m_properties );
-}
-
-Property *DDLNode::findPropertyByName( const std::string &name ) {
- if( name.empty() ) {
- return ddl_nullptr;
- }
-
- if( ddl_nullptr == m_properties ) {
- return ddl_nullptr;
- }
-
- Property *current( m_properties );
- while( ddl_nullptr != current ) {
- int res = strncmp( current->m_key->m_buffer, name.c_str(), name.size() );
- if( 0 == res ) {
- return current;
- }
- current = current->m_next;
- }
-
- return ddl_nullptr;
-}
-
-void DDLNode::setValue( Value *val ) {
- m_value = val;
-}
-
-Value *DDLNode::getValue() const {
- return m_value;
-}
-
-void DDLNode::setDataArrayList( DataArrayList *dtArrayList ) {
- m_dtArrayList = dtArrayList;
-}
-
-DataArrayList *DDLNode::getDataArrayList() const {
- return m_dtArrayList;
-}
-
-void DDLNode::setReferences( Reference *refs ) {
- m_references = refs;
-}
-
-Reference *DDLNode::getReferences() const {
- return m_references;
-}
-
-void DDLNode::dump(IOStreamBase &/*stream*/) {
- // Todo!
-}
-
-DDLNode *DDLNode::create( const std::string &type, const std::string &name, DDLNode *parent ) {
- const size_t idx( s_allocatedNodes.size() );
- DDLNode *node = new DDLNode( type, name, idx, parent );
- s_allocatedNodes.push_back( node );
-
- return node;
-}
-
-void DDLNode::releaseNodes() {
- if( s_allocatedNodes.size() > 0 ) {
- for( DDLNodeIt it = s_allocatedNodes.begin(); it != s_allocatedNodes.end(); it++ ) {
- if( *it ) {
- delete *it;
- }
- }
- s_allocatedNodes.clear();
- }
-}
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp
deleted file mode 100644
index 5c341a780..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLCommon.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/OpenDDLCommon.h>
-#include <openddlparser/DDLNode.h>
-#include <openddlparser/Value.h>
-
-BEGIN_ODDLPARSER_NS
-
-Text::Text( const char *buffer, size_t numChars )
-: m_capacity( 0 )
-, m_len( 0 )
-, m_buffer( ddl_nullptr ) {
- set( buffer, numChars );
-}
-
-Text::~Text() {
- clear();
-}
-
-void Text::clear() {
- delete[] m_buffer;
- m_buffer = ddl_nullptr;
- m_capacity = 0;
- m_len = 0;
-}
-
-void Text::set( const char *buffer, size_t numChars ) {
- clear();
- if( numChars > 0 ) {
- m_len = numChars;
- m_capacity = m_len + 1;
- m_buffer = new char[ m_capacity ];
- strncpy( m_buffer, buffer, numChars );
- m_buffer[ numChars ] = '\0';
- }
-}
-
-bool Text::operator == ( const std::string &name ) const {
- if( m_len != name.size() ) {
- return false;
- }
- const int res( strncmp( m_buffer, name.c_str(), name.size() ) );
-
- return ( 0 == res );
-}
-
-bool Text::operator == ( const Text &rhs ) const {
- if( m_len != rhs.m_len ) {
- return false;
- }
-
- const int res( strncmp( m_buffer, rhs.m_buffer, m_len ) );
-
- return ( 0 == res );
-}
-
-Name::Name( NameType type, Text *id )
-: m_type( type )
-, m_id( id ) {
- // empty
-}
-
-Name::~Name() {
- delete m_id;
- m_id = ddl_nullptr;
-}
-
-Name::Name( const Name &name ){
- m_type=name.m_type;
- m_id=new Text(name.m_id->m_buffer,name.m_id->m_len);
-}
-
-
-
- Reference::Reference()
-: m_numRefs( 0 )
-, m_referencedName( ddl_nullptr ) {
- // empty
-}
-
-Reference::Reference( size_t numrefs, Name **names )
-: m_numRefs( numrefs )
-, m_referencedName( ddl_nullptr ) {
- if ( numrefs > 0 ) {
- m_referencedName = new Name *[ numrefs ];
- for ( size_t i = 0; i < numrefs; i++ ) {
- m_referencedName[ i ] = names[i];
- }
- }
-}
-Reference::Reference(const Reference &ref) {
- m_numRefs=ref.m_numRefs;
- if(m_numRefs!=0){
- m_referencedName = new Name*[m_numRefs];
- for ( size_t i = 0; i < m_numRefs; i++ ) {
- m_referencedName[i] = new Name(*ref.m_referencedName[i]);
- }
- }
-}
-
-Reference::~Reference() {
- for( size_t i = 0; i < m_numRefs; i++ ) {
- delete m_referencedName[ i ];
- }
- m_numRefs = 0;
- delete [] m_referencedName;
- m_referencedName = ddl_nullptr;
-}
-
-size_t Reference::sizeInBytes() {
- if ( 0 == m_numRefs ) {
- return 0;
- }
-
- size_t size( 0 );
- for ( size_t i = 0; i < m_numRefs; i++ ) {
- Name *name( m_referencedName[ i ] );
- if ( ddl_nullptr != name ) {
- size += name->m_id->m_len;
- }
- }
-
- return size;
-}
-
-Property::Property( Text *id )
-: m_key( id )
-, m_value( ddl_nullptr )
-, m_ref( ddl_nullptr )
-, m_next( ddl_nullptr ) {
- // empty
-}
-
-Property::~Property() {
- delete m_key;
- if(m_value!=ddl_nullptr)
- delete m_value;
- if(m_ref!=ddl_nullptr)
- delete(m_ref);
- if(m_next!=ddl_nullptr)
- delete m_next;
-}
-
-DataArrayList::DataArrayList()
-: m_numItems( 0 )
-, m_dataList( ddl_nullptr )
-, m_next( ddl_nullptr )
-, m_refs(ddl_nullptr)
-, m_numRefs(0){
- // empty
-}
-
-DataArrayList::~DataArrayList() {
- delete m_dataList;
- if(m_next!=ddl_nullptr)
- delete m_next;
- if(m_refs!=ddl_nullptr)
- delete m_refs;
-}
-
-size_t DataArrayList::size() {
- size_t result( 0 );
- if ( ddl_nullptr == m_next ) {
- if ( m_dataList != ddl_nullptr ) {
- result = 1;
- }
- return result;
- }
-
- DataArrayList *n( m_next );
- while( ddl_nullptr != n ) {
- result++;
- n = n->m_next;
- }
- return result;
-}
-
-Context::Context()
-: m_root( ddl_nullptr ) {
- // empty
-}
-
-Context::~Context() {
- clear();
-}
-
-void Context::clear() {
- delete m_root;
- m_root = ddl_nullptr;
-}
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp
deleted file mode 100644
index e45fb041a..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLExport.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/OpenDDLExport.h>
-#include <openddlparser/DDLNode.h>
-#include <openddlparser/Value.h>
-#include <openddlparser/OpenDDLParser.h>
-
-#include <sstream>
-
-BEGIN_ODDLPARSER_NS
-
-struct DDLNodeIterator {
- const DDLNode::DllNodeList &m_childs;
- size_t m_idx;
-
- DDLNodeIterator( const DDLNode::DllNodeList &childs )
- : m_childs( childs )
- , m_idx( 0 ) {
- // empty
- }
-
- ~DDLNodeIterator() {
- // empty
- }
-
- bool getNext( DDLNode **node ) {
- if( m_childs.size() > (m_idx+1) ) {
- m_idx++;
- *node = m_childs[ m_idx ];
- return true;
- }
-
- return false;
- }
-
-private:
- DDLNodeIterator() ddl_no_copy;
- DDLNodeIterator &operator = ( const DDLNodeIterator & ) ddl_no_copy;
-};
-
-static void writeLineEnd( std::string &statement ) {
- statement += "\n";
-}
-
-OpenDDLExport::OpenDDLExport( IOStreamBase *stream )
-: m_stream( stream ) {
- if (ddl_nullptr == m_stream) {
- m_stream = new IOStreamBase();
- }
-}
-
-OpenDDLExport::~OpenDDLExport() {
- if (ddl_nullptr != m_stream) {
- m_stream->close();
- }
- delete m_stream;
-}
-
-bool OpenDDLExport::exportContext( Context *ctx, const std::string &filename ) {
- if( ddl_nullptr == ctx ) {
- return false;
- }
-
- DDLNode *root( ctx->m_root );
- if ( ddl_nullptr == root ) {
- return true;
- }
-
- if (!filename.empty()) {
- if (!m_stream->open( filename )) {
- return false;
- }
- }
-
- const bool retValue( handleNode( root ) );
-
- return retValue;
-}
-
-bool OpenDDLExport::handleNode( DDLNode *node ) {
- if( ddl_nullptr == node ) {
- return true;
- }
-
- const DDLNode::DllNodeList &childs = node->getChildNodeList();
- if( childs.empty() ) {
- return true;
- }
- DDLNode *current( ddl_nullptr );
- DDLNodeIterator it( childs );
- std::string statement;
- bool success( true );
- while( it.getNext( &current ) ) {
- if( ddl_nullptr != current ) {
- success |= writeNode( current, statement );
- if( !handleNode( current ) ) {
- success = false;
- }
- }
- }
-
- return success;
-}
-
-bool OpenDDLExport::writeToStream( const std::string &statement ) {
- if (ddl_nullptr == m_stream ) {
- return false;
- }
-
- if ( !statement.empty()) {
- m_stream->write( statement );
- }
-
- return true;
-}
-
-bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) {
- writeNodeHeader( node, statement );
- if (node->hasProperties()) {
- writeProperties( node, statement );
- }
- writeLineEnd( statement );
-
- statement = "}";
- DataArrayList *al( node->getDataArrayList() );
- if ( ddl_nullptr != al ) {
- writeValueType( al->m_dataList->m_type, al->m_numItems, statement );
- writeValueArray( al, statement );
- }
- Value *v( node->getValue() );
- if (ddl_nullptr != v ) {
- writeValueType( v->m_type, 1, statement );
- statement = "{";
- writeLineEnd( statement );
- writeValue( v, statement );
- statement = "}";
- writeLineEnd( statement );
- }
- statement = "}";
- writeLineEnd( statement );
-
- writeToStream( statement );
-
- return true;
-}
-
-bool OpenDDLExport::writeNodeHeader( DDLNode *node, std::string &statement ) {
- if (ddl_nullptr == node) {
- return false;
- }
-
- statement += node->getType();
- const std::string &name( node->getName() );
- if ( !name.empty() ) {
- statement += " ";
- statement += "$";
- statement += name;
- }
-
- return true;
-}
-
-bool OpenDDLExport::writeProperties( DDLNode *node, std::string &statement ) {
- if ( ddl_nullptr == node ) {
- return false;
- }
-
- Property *prop( node->getProperties() );
- // if no properties are there, return
- if ( ddl_nullptr == prop ) {
- return true;
- }
-
- if ( ddl_nullptr != prop ) {
- // for instance (attrib = "position", bla=2)
- statement += "(";
- bool first( true );
- while ( ddl_nullptr != prop ) {
- if (!first) {
- statement += ", ";
- } else {
- first = false;
- }
- statement += std::string( prop->m_key->m_buffer );
- statement += " = ";
- writeValue( prop->m_value, statement );
- prop = prop->m_next;
- }
-
- statement += ")";
- }
-
- return true;
-}
-
-bool OpenDDLExport::writeValueType( Value::ValueType type, size_t numItems, std::string &statement ) {
- if ( Value::ddl_types_max == type) {
- return false;
- }
-
- const std::string typeStr( getTypeToken( type ) );
- statement += typeStr;
- // if we have an array to write
- if ( numItems > 1 ) {
- statement += "[";
- char buffer[ 256 ];
- ::memset( buffer, '\0', 256 * sizeof( char ) );
- sprintf( buffer, "%d", static_cast<int>( numItems ) );
- statement += buffer;
- statement += "]";
- }
-
- return true;
-}
-
-bool OpenDDLExport::writeValue( Value *val, std::string &statement ) {
- if (ddl_nullptr == val) {
- return false;
- }
-
- switch ( val->m_type ) {
- case Value::ddl_bool:
- if ( true == val->getBool() ) {
- statement += "true";
- } else {
- statement += "false";
- }
- break;
- case Value::ddl_int8:
- {
- std::stringstream stream;
- const int i = static_cast<int>( val->getInt8() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_int16:
- {
- std::stringstream stream;
- char buffer[ 256 ];
- ::memset( buffer, '\0', 256 * sizeof( char ) );
- sprintf( buffer, "%d", val->getInt16() );
- statement += buffer;
- }
- break;
- case Value::ddl_int32:
- {
- std::stringstream stream;
- char buffer[ 256 ];
- ::memset( buffer, '\0', 256 * sizeof( char ) );
- const int i = static_cast< int >( val->getInt32() );
- sprintf( buffer, "%d", i );
- statement += buffer;
- }
- break;
- case Value::ddl_int64:
- {
- std::stringstream stream;
- const int i = static_cast< int >( val->getInt64() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_unsigned_int8:
- {
- std::stringstream stream;
- const int i = static_cast< unsigned int >( val->getUnsignedInt8() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_unsigned_int16:
- {
- std::stringstream stream;
- const int i = static_cast< unsigned int >( val->getUnsignedInt16() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_unsigned_int32:
- {
- std::stringstream stream;
- const int i = static_cast< unsigned int >( val->getUnsignedInt32() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_unsigned_int64:
- {
- std::stringstream stream;
- const int i = static_cast< unsigned int >( val->getUnsignedInt64() );
- stream << i;
- statement += stream.str();
- }
- break;
- case Value::ddl_half:
- break;
- case Value::ddl_float:
- {
- std::stringstream stream;
- stream << val->getFloat();
- statement += stream.str();
- }
- break;
- case Value::ddl_double:
- {
- std::stringstream stream;
- stream << val->getDouble();
- statement += stream.str();
- }
- break;
- case Value::ddl_string:
- {
- std::stringstream stream;
- stream << val->getString();
- statement += "\"";
- statement += stream.str();
- statement += "\"";
- }
- break;
- case Value::ddl_ref:
- break;
- case Value::ddl_none:
- case Value::ddl_types_max:
- default:
- break;
- }
-
- return true;
-}
-
-bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement ) {
- if (ddl_nullptr == al) {
- return false;
- }
-
- if (0 == al->m_numItems) {
- return true;
- }
-
- DataArrayList *nextDataArrayList = al ;
- while (ddl_nullptr != nextDataArrayList) {
- if (ddl_nullptr != nextDataArrayList) {
- statement += "{ ";
- Value *nextValue( nextDataArrayList->m_dataList );
- size_t idx( 0 );
- while (ddl_nullptr != nextValue) {
- if (idx > 0) {
- statement += ", ";
- }
- writeValue( nextValue, statement );
- nextValue = nextValue->m_next;
- idx++;
- }
- statement += " }";
- }
- nextDataArrayList = nextDataArrayList->m_next;
- }
-
- return true;
-}
-
-END_ODDLPARSER_NS
-
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp
deleted file mode 100644
index caa281364..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLParser.cpp
+++ /dev/null
@@ -1,1025 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/OpenDDLParser.h>
-#include <openddlparser/OpenDDLExport.h>
-
-#include <cassert>
-#include <iostream>
-#include <sstream>
-#include <algorithm>
-#include <memory>
-#include <math.h>
-
-#ifdef _WIN32
-# include <windows.h>
-#endif // _WIN32
-
-
-BEGIN_ODDLPARSER_NS
-
-static const char *Version = "0.4.0";
-
-namespace Grammar {
- static const char *OpenBracketToken = "{";
- static const char *CloseBracketToken = "}";
- static const char *OpenPropertyToken = "(";
- static const char *ClosePropertyToken = ")";
- static const char *OpenArrayToken = "[";
- static const char *CloseArrayToken = "]";
- static const char *BoolTrue = "true";
- static const char *BoolFalse = "false";
- static const char *CommaSeparator = ",";
-
- static const char *PrimitiveTypeToken[ Value::ddl_types_max ] = {
- "bool",
- "int8",
- "int16",
- "int32",
- "int64",
- "unsigned_int8",
- "unsigned_int16",
- "unsigned_int32",
- "unsigned_int64",
- "half",
- "float",
- "double",
- "string",
- "ref"
- };
-} // Namespace Grammar
-
-const char *getTypeToken( Value::ValueType type ) {
- return Grammar::PrimitiveTypeToken[ type ];
-}
-
-static void logInvalidTokenError( char *in, const std::string &exp, OpenDDLParser::logCallback callback ) {
- std::stringstream stream;
- stream << "Invalid token \"" << *in << "\"" << " expected \"" << exp << "\"" << std::endl;
- std::string full( in );
- std::string part( full.substr( 0, 50 ) );
- stream << part;
- callback( ddl_error_msg, stream.str() );
-}
-
-static bool isIntegerType( Value::ValueType integerType ) {
- if( integerType != Value::ddl_int8 && integerType != Value::ddl_int16 &&
- integerType != Value::ddl_int32 && integerType != Value::ddl_int64 ) {
- return false;
- }
-
- return true;
-}
-
-static bool isUnsignedIntegerType( Value::ValueType integerType ) {
- if( integerType != Value::ddl_unsigned_int8 && integerType != Value::ddl_unsigned_int16 &&
- integerType != Value::ddl_unsigned_int32 && integerType != Value::ddl_unsigned_int64 ) {
- return false;
- }
-
- return true;
-}
-
-static DDLNode *createDDLNode( Text *id, OpenDDLParser *parser ) {
- if( ddl_nullptr == id || ddl_nullptr == parser ) {
- return ddl_nullptr;
- }
-
- const std::string type( id->m_buffer );
- DDLNode *parent( parser->top() );
- DDLNode *node = DDLNode::create( type, "", parent );
-
- return node;
-}
-
-static void logMessage( LogSeverity severity, const std::string &msg ) {
- std::string log;
- if( ddl_debug_msg == severity ) {
- log += "Debug:";
- } else if( ddl_info_msg == severity ) {
- log += "Info :";
- } else if( ddl_warn_msg == severity ) {
- log += "Warn :";
- } else if( ddl_error_msg == severity ) {
- log += "Error:";
- } else {
- log += "None :";
- }
-
- log += msg;
- std::cout << log;
-}
-
-OpenDDLParser::OpenDDLParser()
-: m_logCallback( logMessage )
-, m_buffer()
-, m_stack()
-, m_context( ddl_nullptr ) {
- // empty
-}
-
-OpenDDLParser::OpenDDLParser( const char *buffer, size_t len )
-: m_logCallback( &logMessage )
-, m_buffer()
-, m_context( ddl_nullptr ) {
- if( 0 != len ) {
- setBuffer( buffer, len );
- }
-}
-
-OpenDDLParser::~OpenDDLParser() {
- clear();
-}
-
-void OpenDDLParser::setLogCallback( logCallback callback ) {
- if( ddl_nullptr != callback ) {
- // install user-specific log callback
- m_logCallback = callback;
- } else {
- // install default log callback
- m_logCallback = &logMessage;
- }
-}
-
-OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
- return m_logCallback;
-}
-
-void OpenDDLParser::setBuffer( const char *buffer, size_t len ) {
- clear();
- if( 0 == len ) {
- return;
- }
-
- m_buffer.resize( len );
- ::memcpy(&m_buffer[ 0 ], buffer, len );
-}
-
-void OpenDDLParser::setBuffer( const std::vector<char> &buffer ) {
- clear();
- m_buffer.resize( buffer.size() );
- std::copy( buffer.begin(), buffer.end(), m_buffer.begin() );
-}
-
-const char *OpenDDLParser::getBuffer() const {
- if( m_buffer.empty() ) {
- return ddl_nullptr;
- }
-
- return &m_buffer[ 0 ];
-}
-
-size_t OpenDDLParser::getBufferSize() const {
- return m_buffer.size();
-}
-
-void OpenDDLParser::clear() {
- m_buffer.resize( 0 );
- if( ddl_nullptr != m_context ) {
- delete m_context;
- m_context=ddl_nullptr;
- }
-
-// DDLNode::releaseNodes();
-}
-
-bool OpenDDLParser::parse() {
- if( m_buffer.empty() ) {
- return false;
- }
-
- normalizeBuffer( m_buffer );
-
- m_context = new Context;
- m_context->m_root = DDLNode::create( "root", "", ddl_nullptr );
- pushNode( m_context->m_root );
-
- // do the main parsing
- char *current( &m_buffer[ 0 ] );
- char *end( &m_buffer[m_buffer.size() - 1 ] + 1 );
- size_t pos( current - &m_buffer[ 0 ] );
- while( pos < m_buffer.size() ) {
- current = parseNextNode( current, end );
- if ( current == ddl_nullptr ) {
- return false;
- }
- pos = current - &m_buffer[ 0 ];
- }
- return true;
-}
-
-bool OpenDDLParser::exportContext( Context *ctx, const std::string &filename ) {
- if( ddl_nullptr == ctx ) {
- return false;
- }
-
- OpenDDLExport myExporter;
- return myExporter.exportContext( ctx, filename );
-}
-
-char *OpenDDLParser::parseNextNode( char *in, char *end ) {
- in = parseHeader( in, end );
- in = parseStructure( in, end );
-
- return in;
-}
-
-#ifdef DEBUG_HEADER_NAME
-static void dumpId( Identifier *id ) {
- if( ddl_nullptr != id ) {
- if ( ddl_nullptr != id->m_text.m_buffer ) {
- std::cout << id->m_text.m_buffer << std::endl;
- }
- }
-}
-#endif
-
-char *OpenDDLParser::parseHeader( char *in, char *end ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- Text *id( ddl_nullptr );
- in = OpenDDLParser::parseIdentifier( in, end, &id );
-
-#ifdef DEBUG_HEADER_NAME
- dumpId( id );
-#endif // DEBUG_HEADER_NAME
-
- in = lookForNextToken( in, end );
- if( ddl_nullptr != id ) {
- // store the node
- DDLNode *node( createDDLNode( id, this ) );
- if( ddl_nullptr != node ) {
- pushNode( node );
- } else {
- std::cerr << "nullptr returned by creating DDLNode." << std::endl;
- }
- delete id;
-
- Name *name_(ddl_nullptr);
- in = OpenDDLParser::parseName(in, end, &name_);
- std::unique_ptr<Name> name(name_);
- if( ddl_nullptr != name && ddl_nullptr != node ) {
- const std::string nodeName( name->m_id->m_buffer );
- node->setName( nodeName );
- }
-
-
- std::unique_ptr<Property> first;
- in = lookForNextToken(in, end);
- if (*in == Grammar::OpenPropertyToken[0]) {
- in++;
- std::unique_ptr<Property> prop, prev;
- while (*in != Grammar::ClosePropertyToken[0] && in != end) {
- Property *prop_(ddl_nullptr);
- in = OpenDDLParser::parseProperty(in, end, &prop_);
- prop.reset(prop_);
- in = lookForNextToken(in, end);
-
- if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
- logInvalidTokenError(in, Grammar::ClosePropertyToken, m_logCallback);
- return ddl_nullptr;
- }
-
- if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
- if (ddl_nullptr == first) {
- first = std::move(prop);
- }
- if (ddl_nullptr != prev) {
- prev->m_next = prop.release();
- }
- prev = std::move(prop);
- }
- }
- ++in;
- }
-
- // set the properties
- if (first && ddl_nullptr != node) {
- node->setProperties(first.release());
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseStructure( char *in, char *end ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- bool error( false );
- in = lookForNextToken( in, end );
- if( *in == *Grammar::OpenBracketToken) {
- // loop over all children ( data and nodes )
- do {
- in = parseStructureBody( in, end, error );
- if(in == ddl_nullptr){
- return ddl_nullptr;
- }
- } while ( *in != *Grammar::CloseBracketToken);
- ++in;
- } else {
- ++in;
- logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
- return ddl_nullptr;
- }
- in = lookForNextToken( in, end );
-
- // pop node from stack after successful parsing
- if( !error ) {
- popNode();
- }
-
- return in;
-}
-
-static void setNodeValues( DDLNode *currentNode, Value *values ) {
- if( ddl_nullptr != values ){
- if( ddl_nullptr != currentNode ) {
- currentNode->setValue( values );
- }
- }
-}
-
-static void setNodeReferences( DDLNode *currentNode, Reference *refs ) {
- if( ddl_nullptr != refs ) {
- if( ddl_nullptr != currentNode ) {
- currentNode->setReferences( refs );
- }
- }
-}
-
-static void setNodeDataArrayList( DDLNode *currentNode, DataArrayList *dtArrayList ) {
- if( ddl_nullptr != dtArrayList ) {
- if( ddl_nullptr != currentNode ) {
- currentNode->setDataArrayList( dtArrayList );
- }
- }
-}
-
-char *OpenDDLParser::parseStructureBody( char *in, char *end, bool &error ) {
- if( !isNumeric( *in ) && !isCharacter( *in ) ) {
- ++in;
- }
-
- in = lookForNextToken( in, end );
- Value::ValueType type( Value::ddl_none );
- size_t arrayLen( 0 );
- in = OpenDDLParser::parsePrimitiveDataType( in, end, type, arrayLen );
- if( Value::ddl_none != type ) {
- // parse a primitive data type
- in = lookForNextToken( in, end );
- if( *in == Grammar::OpenBracketToken[ 0 ] ) {
- Reference *refs( ddl_nullptr );
- DataArrayList *dtArrayList( ddl_nullptr );
- Value *values( ddl_nullptr );
- if( 1 == arrayLen ) {
- size_t numRefs( 0 ), numValues( 0 );
- in = parseDataList( in, end, type, &values, numValues, &refs, numRefs );
- setNodeValues( top(), values );
- setNodeReferences( top(), refs );
- } else if( arrayLen > 1 ) {
- in = parseDataArrayList( in, end, type, &dtArrayList );
- setNodeDataArrayList( top(), dtArrayList );
- } else {
- std::cerr << "0 for array is invalid." << std::endl;
- error = true;
- }
- }
-
- in = lookForNextToken( in, end );
- if( *in != '}' ) {
- logInvalidTokenError( in, std::string( Grammar::CloseBracketToken ), m_logCallback );
- return ddl_nullptr;
- } else {
- //in++;
- }
- } else {
- // parse a complex data type
- in = parseNextNode( in, end );
- }
-
- return in;
-}
-
-void OpenDDLParser::pushNode( DDLNode *node ) {
- if( ddl_nullptr == node ) {
- return;
- }
-
- m_stack.push_back( node );
-}
-
-DDLNode *OpenDDLParser::popNode() {
- if( m_stack.empty() ) {
- return ddl_nullptr;
- }
-
- DDLNode *topNode( top() );
- m_stack.pop_back();
- return topNode;
-}
-
-DDLNode *OpenDDLParser::top() {
- if( m_stack.empty() ) {
- return ddl_nullptr;
- }
-
- DDLNode *top( m_stack.back() );
- return top;
-}
-
-DDLNode *OpenDDLParser::getRoot() const {
- if( ddl_nullptr == m_context ) {
- return ddl_nullptr;
- }
-
- return m_context->m_root;
-}
-
-Context *OpenDDLParser::getContext() const {
- return m_context;
-}
-
-void OpenDDLParser::normalizeBuffer( std::vector<char> &buffer) {
- if( buffer.empty() ) {
- return;
- }
-
- std::vector<char> newBuffer;
- const size_t len( buffer.size() );
- char *end( &buffer[ len-1 ] + 1 );
- for( size_t readIdx = 0; readIdx<len; ++readIdx ) {
- char *c( &buffer[readIdx] );
- // check for a comment
- if (isCommentOpenTag(c, end)) {
- ++readIdx;
- while (!isCommentCloseTag(&buffer[readIdx], end)) {
- ++readIdx;
- }
- ++readIdx;
- ++readIdx;
- } else if( !isComment<char>( c, end ) && !isNewLine( *c ) ) {
- newBuffer.push_back( buffer[ readIdx ] );
- } else {
- if( isComment<char>( c, end ) ) {
- ++readIdx;
- // skip the comment and the rest of the line
- while( !isEndofLine( buffer[ readIdx ] ) ) {
- ++readIdx;
- }
- }
- }
- }
- buffer = newBuffer;
-}
-
-char *OpenDDLParser::parseName( char *in, char *end, Name **name ) {
- *name = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- // ignore blanks
- in = lookForNextToken( in, end );
- if( *in != '$' && *in != '%' ) {
- return in;
- }
-
- NameType ntype( GlobalName );
- if( *in == '%' ) {
- ntype = LocalName;
- }
- in++;
- Name *currentName( ddl_nullptr );
- Text *id( ddl_nullptr );
- in = parseIdentifier( in, end, &id );
- if( id ) {
- currentName = new Name( ntype, id );
- if( currentName ) {
- *name = currentName;
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseIdentifier( char *in, char *end, Text **id ) {
- *id = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- // ignore blanks
- in = lookForNextToken( in, end );
-
- // staring with a number is forbidden
- if( isNumeric<const char>( *in ) ) {
- return in;
- }
-
- // get size of id
- size_t idLen( 0 );
- char *start( in );
- while( !isSeparator( *in ) &&
- !isNewLine( *in ) && ( in != end ) &&
- *in != Grammar::OpenPropertyToken[ 0 ] &&
- *in != Grammar::ClosePropertyToken[ 0 ] &&
- *in != '$' ) {
- ++in;
- ++idLen;
- }
-
- const size_t len( idLen );
- *id = new Text( start, len );
-
- return in;
-}
-
-char *OpenDDLParser::parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len ) {
- type = Value::ddl_none;
- len = 0;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- size_t prim_len( 0 );
- for( unsigned int i = 0; i < Value::ddl_types_max; i++ ) {
- prim_len = strlen( Grammar::PrimitiveTypeToken[ i ] );
- if( 0 == strncmp( in, Grammar::PrimitiveTypeToken[ i ], prim_len ) ) {
- type = static_cast<Value::ValueType>( i );
- break;
- }
- }
-
- if( Value::ddl_none == type ) {
- in = lookForNextToken( in, end );
- return in;
- } else {
- in += prim_len;
- }
-
- bool ok( true );
- if( *in == Grammar::OpenArrayToken[ 0 ] ) {
- ok = false;
- ++in;
- char *start( in );
- while ( in != end ) {
- ++in;
- if( *in == Grammar::CloseArrayToken[ 0 ] ) {
- len = ::atoi( start );
- ok = true;
- ++in;
- break;
- }
- }
- } else {
- len = 1;
- }
- if( !ok ) {
- type = Value::ddl_none;
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseReference( char *in, char *end, std::vector<Name*> &names ) {
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- Name *nextName( ddl_nullptr );
- in = parseName( in, end, &nextName );
- if( nextName ) {
- names.push_back( nextName );
- }
- while( Grammar::CommaSeparator[ 0 ] == *in ) {
- in = getNextSeparator( in, end );
- if( Grammar::CommaSeparator[ 0 ] == *in ) {
- in = parseName( in, end, &nextName );
- if( nextName ) {
- names.push_back( nextName );
- }
- } else {
- break;
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseBooleanLiteral( char *in, char *end, Value **boolean ) {
- *boolean = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- char *start( in );
- size_t len( 0 );
- while( !isSeparator( *in ) && in != end ) {
- ++in;
- ++len;
- }
- ++len;
- int res = ::strncmp( Grammar::BoolTrue, start, strlen( Grammar::BoolTrue ) );
- if( 0 != res ) {
- res = ::strncmp( Grammar::BoolFalse, start, strlen( Grammar::BoolFalse ) );
- if( 0 != res ) {
- *boolean = ddl_nullptr;
- return in;
- }
- *boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
- (*boolean)->setBool( false );
- } else {
- *boolean = ValueAllocator::allocPrimData( Value::ddl_bool );
- (*boolean)->setBool( true );
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType ) {
- *integer = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- if( !(isIntegerType( integerType ) || isUnsignedIntegerType(integerType)) ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- char *start( in );
- while( !isSeparator( *in ) && in != end ) {
- ++in;
- }
-
- if( isNumeric( *start ) ) {
-#ifdef OPENDDL_NO_USE_CPP11
- const int64 value( atol( start ) ); // maybe not really 64bit as atoll is but exists without c++11
- const uint64 uvalue( strtoul( start,ddl_nullptr,10 ) );
-#else
- const int64 value( atoll( start ) );
- const uint64 uvalue( strtoull( start,ddl_nullptr,10 ) );
-#endif
- *integer = ValueAllocator::allocPrimData( integerType );
- switch( integerType ) {
- case Value::ddl_int8:
- ( *integer )->setInt8( (int8) value );
- break;
- case Value::ddl_int16:
- ( *integer )->setInt16( ( int16 ) value );
- break;
- case Value::ddl_int32:
- ( *integer )->setInt32( ( int32 ) value );
- break;
- case Value::ddl_int64:
- ( *integer )->setInt64( ( int64 ) value );
- break;
- case Value::ddl_unsigned_int8:
- ( *integer )->setUnsignedInt8( (uint8) uvalue );
- break;
- case Value::ddl_unsigned_int16:
- ( *integer )->setUnsignedInt16( ( uint16 ) uvalue );
- break;
- case Value::ddl_unsigned_int32:
- ( *integer )->setUnsignedInt32( ( uint32 ) uvalue );
- break;
- case Value::ddl_unsigned_int64:
- ( *integer )->setUnsignedInt64( ( uint64 ) uvalue );
- break;
- default:
- break;
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType) {
- *floating = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- char *start( in );
- while( !isSeparator( *in ) && in != end ) {
- ++in;
- }
-
- // parse the float value
- bool ok( false );
- if ( isHexLiteral( start, end ) ) {
- parseHexaLiteral( start, end, floating );
- return in;
- }
-
- if( isNumeric( *start ) ) {
- ok = true;
- } else {
- if( *start == '-' ) {
- if( isNumeric( *(start+1) ) ) {
- ok = true;
- }
- }
- }
-
- if( ok ) {
- if ( floatType == Value::ddl_double ) {
- const double value( atof( start ) );
- *floating = ValueAllocator::allocPrimData( Value::ddl_double );
- ( *floating )->setDouble( value );
- } else {
- const float value( ( float ) atof( start ) );
- *floating = ValueAllocator::allocPrimData( Value::ddl_float );
- ( *floating )->setFloat( value );
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseStringLiteral( char *in, char *end, Value **stringData ) {
- *stringData = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- size_t len( 0 );
- char *start( in );
- if( *start == '\"' ) {
- ++start;
- ++in;
- while( *in != '\"' && in != end ) {
- ++in;
- ++len;
- }
-
- *stringData = ValueAllocator::allocPrimData( Value::ddl_string, len );
- ::strncpy( ( char* ) ( *stringData )->m_data, start, len );
- ( *stringData )->m_data[len] = '\0';
- ++in;
- }
-
- return in;
-}
-
-static void createPropertyWithData( Text *id, Value *primData, Property **prop ) {
- if( ddl_nullptr != primData ) {
- ( *prop ) = new Property( id );
- ( *prop )->m_value = primData;
- }
-}
-
-char *OpenDDLParser::parseHexaLiteral( char *in, char *end, Value **data ) {
- *data = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- if( *in != '0' ) {
- return in;
- }
-
- ++in;
- if( *in != 'x' && *in != 'X' ) {
- return in;
- }
-
- ++in;
- bool ok( true );
- char *start( in );
- int pos( 0 );
- while( !isSeparator( *in ) && in != end ) {
- if( ( *in < '0' && *in > '9' ) || ( *in < 'a' && *in > 'f' ) || ( *in < 'A' && *in > 'F' ) ) {
- ok = false;
- break;
- }
- ++pos;
- ++in;
- }
-
- if( !ok ) {
- return in;
- }
-
- int value( 0 );
- while( pos > 0 ) {
- int v = hex2Decimal( *start );
- --pos;
- value = ( value << 4 ) | v;
- ++start;
- }
-
- *data = ValueAllocator::allocPrimData( Value::ddl_unsigned_int64 );
- if( ddl_nullptr != *data ) {
- ( *data )->setUnsignedInt64( value );
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseProperty( char *in, char *end, Property **prop ) {
- *prop = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- Text *id( ddl_nullptr );
- in = parseIdentifier( in, end, &id );
- if( ddl_nullptr != id ) {
- in = lookForNextToken( in, end );
- if( *in == '=' ) {
- ++in;
- in = getNextToken( in, end );
- Value *primData( ddl_nullptr );
- if( isInteger( in, end ) ) {
- in = parseIntegerLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else if( isFloat( in, end ) ) {
- in = parseFloatingLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else if( isStringLiteral( *in ) ) { // string data
- in = parseStringLiteral( in, end, &primData );
- createPropertyWithData( id, primData, prop );
- } else { // reference data
- std::vector<Name*> names;
- in = parseReference( in, end, names );
- if( !names.empty() ) {
- Reference *ref = new Reference( names.size(), &names[ 0 ] );
- ( *prop ) = new Property( id );
- ( *prop )->m_ref = ref;
- }
- }
- } else {
- delete id;
- }
- }
-
- return in;
-}
-
-char *OpenDDLParser::parseDataList( char *in, char *end, Value::ValueType type, Value **data,
- size_t &numValues, Reference **refs, size_t &numRefs ) {
- *data = ddl_nullptr;
- numValues = numRefs = 0;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- if( *in == '{' ) {
- ++in;
- Value *current( ddl_nullptr ), *prev( ddl_nullptr );
- while( '}' != *in ) {
- current = ddl_nullptr;
- in = lookForNextToken( in, end );
- if ( Value::ddl_ref == type ) {
- std::vector<Name*> names;
- in = parseReference( in, end, names );
- if ( !names.empty() ) {
- Reference *ref = new Reference( names.size(), &names[ 0 ] );
- *refs = ref;
- numRefs = names.size();
- }
- } else if ( Value::ddl_none == type ) {
- if (isInteger( in, end )) {
- in = parseIntegerLiteral( in, end, &current );
- } else if (isFloat( in, end )) {
- in = parseFloatingLiteral( in, end, &current );
- } else if (isStringLiteral( *in )) {
- in = parseStringLiteral( in, end, &current );
- } else if (isHexLiteral( in, end )) {
- in = parseHexaLiteral( in, end, &current );
- }
- } else {
- switch(type){
- case Value::ddl_int8:
- case Value::ddl_int16:
- case Value::ddl_int32:
- case Value::ddl_int64:
- case Value::ddl_unsigned_int8:
- case Value::ddl_unsigned_int16:
- case Value::ddl_unsigned_int32:
- case Value::ddl_unsigned_int64:
- in = parseIntegerLiteral( in, end, &current, type);
- break;
- case Value::ddl_half:
- case Value::ddl_float:
- case Value::ddl_double:
- in = parseFloatingLiteral( in, end, &current, type);
- break;
- case Value::ddl_string:
- in = parseStringLiteral( in, end, &current );
- break;
- default:
- break;
- }
- }
-
- if( ddl_nullptr != current ) {
- if( ddl_nullptr == *data ) {
- *data = current;
- prev = current;
- } else {
- prev->setNext( current );
- prev = current;
- }
- ++numValues;
- }
-
- in = getNextSeparator( in, end );
- if( ',' != *in && Grammar::CloseBracketToken[ 0 ] != *in && !isSpace( *in ) ) {
- break;
- }
- }
- ++in;
- }
-
- return in;
-}
-
-static DataArrayList *createDataArrayList( Value *currentValue, size_t numValues,
- Reference *refs, size_t numRefs ) {
- DataArrayList *dataList( new DataArrayList );
- dataList->m_dataList = currentValue;
- dataList->m_numItems = numValues;
- dataList->m_refs = refs;
- dataList->m_numRefs = numRefs;
-
- return dataList;
-}
-
-char *OpenDDLParser::parseDataArrayList( char *in, char *end,Value::ValueType type,
- DataArrayList **dataArrayList ) {
- if ( ddl_nullptr == dataArrayList ) {
- return in;
- }
-
- *dataArrayList = ddl_nullptr;
- if( ddl_nullptr == in || in == end ) {
- return in;
- }
-
- in = lookForNextToken( in, end );
- if( *in == Grammar::OpenBracketToken[ 0 ] ) {
- ++in;
- Value *currentValue( ddl_nullptr );
- Reference *refs( ddl_nullptr );
- DataArrayList *prev( ddl_nullptr ), *currentDataList( ddl_nullptr );
- do {
- size_t numRefs( 0 ), numValues( 0 );
- currentValue = ddl_nullptr;
-
- in = parseDataList( in, end, type, &currentValue, numValues, &refs, numRefs );
- if( ddl_nullptr != currentValue || 0 != numRefs ) {
- if( ddl_nullptr == prev ) {
- *dataArrayList = createDataArrayList( currentValue, numValues, refs, numRefs );
- prev = *dataArrayList;
- } else {
- currentDataList = createDataArrayList( currentValue, numValues, refs, numRefs );
- if( ddl_nullptr != prev ) {
- prev->m_next = currentDataList;
- prev = currentDataList;
- }
- }
- }
- } while( Grammar::CommaSeparator[ 0 ] == *in && in != end );
- in = lookForNextToken( in, end );
- ++in;
- }
-
- return in;
-}
-
-const char *OpenDDLParser::getVersion() {
- return Version;
-}
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLStream.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLStream.cpp
deleted file mode 100644
index 7ea8331bd..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/OpenDDLStream.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/OpenDDLStream.h>
-
-BEGIN_ODDLPARSER_NS
-
-StreamFormatterBase::StreamFormatterBase() {
- // empty
-}
-
-StreamFormatterBase::~StreamFormatterBase() {
- // empty
-}
-
-std::string StreamFormatterBase::format(const std::string &statement) {
- std::string tmp(statement);
- return tmp;
-}
-
-IOStreamBase::IOStreamBase(StreamFormatterBase *formatter)
- : m_formatter(formatter)
- , m_file(ddl_nullptr) {
- if (ddl_nullptr == m_formatter) {
- m_formatter = new StreamFormatterBase;
- }
-}
-
-IOStreamBase::~IOStreamBase() {
- delete m_formatter;
- m_formatter = ddl_nullptr;
-}
-
-bool IOStreamBase::open(const std::string &name) {
- m_file = ::fopen(name.c_str(), "a");
- if (m_file == ddl_nullptr) {
- return false;
- }
-
- return true;
-}
-
-bool IOStreamBase::close() {
- if (ddl_nullptr == m_file) {
- return false;
- }
-
- ::fclose(m_file);
- m_file = ddl_nullptr;
-
- return true;
-}
-
-bool IOStreamBase::isOpen() const {
- return ( ddl_nullptr != m_file );
-}
-
-size_t IOStreamBase::read( size_t sizeToRead, std::string &statement ) {
- if (ddl_nullptr == m_file) {
- return 0;
- }
-
- statement.resize(sizeToRead);
- const size_t readBytes = ::fread( &statement[0], 1, sizeToRead, m_file );
-
- return readBytes;
-}
-
-size_t IOStreamBase::write(const std::string &statement) {
- if (ddl_nullptr == m_file) {
- return 0;
- }
- std::string formatStatement = m_formatter->format(statement);
- return ::fwrite(formatStatement.c_str(), sizeof(char), formatStatement.size(), m_file);
-}
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp b/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp
deleted file mode 100644
index b5a35e722..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/code/Value.cpp
+++ /dev/null
@@ -1,439 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#include <openddlparser/Value.h>
-
-#include <iostream>
-#include <cassert>
-
-BEGIN_ODDLPARSER_NS
-
-static Value::Iterator end( ddl_nullptr );
-
-Value::Iterator::Iterator()
-: m_start( ddl_nullptr )
-, m_current( ddl_nullptr ) {
- // empty
-}
-
-Value::Iterator::Iterator( Value *start )
-: m_start( start )
-, m_current( start ) {
- // empty
-}
-
-Value::Iterator::Iterator( const Iterator &rhs )
-: m_start( rhs.m_start )
-, m_current( rhs.m_current ) {
- // empty
-}
-
-Value::Iterator::~Iterator() {
- // empty
-}
-
-bool Value::Iterator::hasNext() const {
- if( ddl_nullptr == m_current ) {
- return false;
- }
- return ( ddl_nullptr != m_current->getNext() );
-}
-
-Value *Value::Iterator::getNext() {
- if( !hasNext() ) {
- return ddl_nullptr;
- }
-
- Value *v( m_current->getNext() );
- m_current = v;
-
- return v;
-}
-
-const Value::Iterator Value::Iterator::operator++( int ) {
- if( ddl_nullptr == m_current ) {
- return end;
- }
-
- m_current = m_current->getNext();
- Iterator inst( m_current );
-
- return inst;
-}
-
-Value::Iterator &Value::Iterator::operator++( ) {
- if( ddl_nullptr == m_current ) {
- return end;
- }
-
- m_current = m_current->getNext();
-
- return *this;
-}
-
-bool Value::Iterator::operator == ( const Iterator &rhs ) const {
- return ( m_current == rhs.m_current );
-}
-
-Value *Value::Iterator::operator->( ) const {
- if(ddl_nullptr == m_current ) {
- return ddl_nullptr;
- }
- return m_current;
-}
-
-Value::Value( ValueType type )
-: m_type( type )
-, m_size( 0 )
-, m_data( ddl_nullptr )
-, m_next( ddl_nullptr ) {
- // empty
-}
-
-Value::~Value() {
- if(m_data!=ddl_nullptr) {
- if (m_type == ddl_ref ) {
- Reference *tmp = (Reference *) m_data;
- if (tmp != ddl_nullptr)
- delete tmp;
- }else
- delete[] m_data;
-
- }
- if(m_next!=ddl_nullptr)
- delete m_next;
-}
-
-void Value::setBool( bool value ) {
- assert( ddl_bool == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-bool Value::getBool() {
- assert( ddl_bool == m_type );
- return ( *m_data == 1 );
-}
-
-void Value::setInt8( int8 value ) {
- assert( ddl_int8 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-int8 Value::getInt8() {
- assert( ddl_int8 == m_type );
- return ( int8 ) ( *m_data );
-}
-
-void Value::setInt16( int16 value ) {
- assert( ddl_int16 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-int16 Value::getInt16() {
- assert( ddl_int16 == m_type );
- int16 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setInt32( int32 value ) {
- assert( ddl_int32 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-int32 Value::getInt32() {
- assert( ddl_int32 == m_type );
- int32 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setInt64( int64 value ) {
- assert( ddl_int64 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-int64 Value::getInt64() {
- assert( ddl_int64 == m_type );
- int64 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setUnsignedInt8( uint8 value ) {
- assert( ddl_unsigned_int8 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-uint8 Value::getUnsignedInt8() const {
- assert( ddl_unsigned_int8 == m_type );
- uint8 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setUnsignedInt16( uint16 value ) {
- assert( ddl_unsigned_int16 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-uint16 Value::getUnsignedInt16() const {
- assert( ddl_unsigned_int16 == m_type );
- uint16 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setUnsignedInt32( uint32 value ) {
- assert( ddl_unsigned_int32 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-uint32 Value::getUnsignedInt32() const {
- assert( ddl_unsigned_int32 == m_type );
- uint32 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setUnsignedInt64( uint64 value ) {
- assert( ddl_unsigned_int64 == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-uint64 Value::getUnsignedInt64() const {
- assert( ddl_unsigned_int64 == m_type );
- uint64 i;
- ::memcpy( &i, m_data, m_size );
- return i;
-}
-
-void Value::setFloat( float value ) {
- assert( ddl_float == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-float Value::getFloat() const {
- if( m_type == ddl_float ) {
- float v;
- ::memcpy( &v, m_data, m_size );
- return ( float ) v;
- } else {
- float tmp;
- ::memcpy( &tmp, m_data, 4 );
- return ( float ) tmp;
- }
-}
-
-void Value::setDouble( double value ) {
- assert( ddl_double == m_type );
- ::memcpy( m_data, &value, m_size );
-}
-
-double Value::getDouble() const {
- if ( m_type == ddl_double ) {
- double v;
- ::memcpy( &v, m_data, m_size );
- return ( float ) v;
- }
- else {
- double tmp;
- ::memcpy( &tmp, m_data, 4 );
- return ( double ) tmp;
- }
-}
-
-void Value::setString( const std::string &str ) {
- assert( ddl_string == m_type );
- ::memcpy( m_data, str.c_str(), str.size() );
- m_data[ str.size() ] = '\0';
-}
-
-const char *Value::getString() const {
- assert( ddl_string == m_type );
- return (const char*) m_data;
-}
-
-void Value::setRef( Reference *ref ) {
- assert( ddl_ref == m_type );
-
- if ( ddl_nullptr != ref ) {
- const size_t sizeInBytes( ref->sizeInBytes() );
- if ( sizeInBytes > 0 ) {
- if ( ddl_nullptr != m_data ) {
- delete [] m_data;
- }
-
- m_data = (unsigned char*) new Reference(*ref);
- }
- }
-}
-
-Reference *Value::getRef() const {
- assert( ddl_ref == m_type );
-
- return (Reference*) m_data;
-}
-
-void Value::dump( IOStreamBase &/*stream*/ ) {
- switch( m_type ) {
- case ddl_none:
- std::cout << "None" << std::endl;
- break;
- case ddl_bool:
- std::cout << getBool() << std::endl;
- break;
- case ddl_int8:
- std::cout << getInt8() << std::endl;
- break;
- case ddl_int16:
- std::cout << getInt16() << std::endl;
- break;
- case ddl_int32:
- std::cout << getInt32() << std::endl;
- break;
- case ddl_int64:
- std::cout << getInt64() << std::endl;
- break;
- case ddl_unsigned_int8:
- std::cout << "Not supported" << std::endl;
- break;
- case ddl_unsigned_int16:
- std::cout << "Not supported" << std::endl;
- break;
- case ddl_unsigned_int32:
- std::cout << "Not supported" << std::endl;
- break;
- case ddl_unsigned_int64:
- std::cout << "Not supported" << std::endl;
- break;
- case ddl_half:
- std::cout << "Not supported" << std::endl;
- break;
- case ddl_float:
- std::cout << getFloat() << std::endl;
- break;
- case ddl_double:
- std::cout << getDouble() << std::endl;
- break;
- case ddl_string:
- std::cout << getString() << std::endl;
- break;
- case ddl_ref:
- std::cout << "Not supported" << std::endl;
- break;
- default:
- break;
- }
-}
-
-void Value::setNext( Value *next ) {
- m_next = next;
-}
-
-Value *Value::getNext() const {
- return m_next;
-}
-
-size_t Value::size() const{
- size_t result=1;
- Value *n=m_next;
- while( n!=ddl_nullptr) {
- result++;
- n=n->m_next;
- }
- return result;
-}
-
-Value *ValueAllocator::allocPrimData( Value::ValueType type, size_t len ) {
- if( type == Value::ddl_none || Value::ddl_types_max == type ) {
- return ddl_nullptr;
- }
-
- Value *data = new Value( type );
- switch( type ) {
- case Value::ddl_bool:
- data->m_size = sizeof( bool );
- break;
- case Value::ddl_int8:
- data->m_size = sizeof( int8 );
- break;
- case Value::ddl_int16:
- data->m_size = sizeof( int16 );
- break;
- case Value::ddl_int32:
- data->m_size = sizeof( int32 );
- break;
- case Value::ddl_int64:
- data->m_size = sizeof( int64 );
- break;
- case Value::ddl_unsigned_int8:
- data->m_size = sizeof( uint8 );
- break;
- case Value::ddl_unsigned_int16:
- data->m_size = sizeof( uint16 );
- break;
- case Value::ddl_unsigned_int32:
- data->m_size = sizeof( uint32 );
- break;
- case Value::ddl_unsigned_int64:
- data->m_size = sizeof( uint64 );
- break;
- case Value::ddl_half:
- data->m_size = sizeof( short );
- break;
- case Value::ddl_float:
- data->m_size = sizeof( float );
- break;
- case Value::ddl_double:
- data->m_size = sizeof( double );
- break;
- case Value::ddl_string:
- data->m_size = sizeof( char )*(len+1);
- break;
- case Value::ddl_ref:
- data->m_size = 0;
- break;
- case Value::ddl_none:
- case Value::ddl_types_max:
- default:
- break;
- }
-
- if( data->m_size ) {
- data->m_data = new unsigned char[ data->m_size ];
- ::memset(data->m_data,0,data->m_size);
- }
-
- return data;
-}
-
-void ValueAllocator::releasePrimData( Value **data ) {
- if( !data ) {
- return;
- }
-
- delete *data;
- *data = ddl_nullptr;
-}
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h
deleted file mode 100644
index 915bd3041..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/DDLNode.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-
-#include <vector>
-#include <string>
-
-BEGIN_ODDLPARSER_NS
-
-// Forward declarations
-class IOStreamBase;
-class Value;
-class OpenDDLParser;
-
-struct Identifier;
-struct Reference;
-struct Property;
-struct DataArrayList;
-
-///
-/// @ingroup OpenDDLParser
-/// @brief This class represents one single instance in the object tree of the parsed OpenDDL-file.
-///
-/// A DDLNode represents one leaf in the OpenDDL-node tree. It can have one parent node and multiple children.
-/// You can assign special properties to a single DDLNode instance.
-/// A node instance can store values via a linked list. You can get the first value from the DDLNode.
-/// A node can store data-array-lists and references as well.
-///
-class DLL_ODDLPARSER_EXPORT DDLNode {
-public:
- friend class OpenDDLParser;
-
- /// @brief The child-node-list type.
- typedef std::vector<DDLNode*> DllNodeList;
-
- /// @brief The child-node-list iterator.
- typedef std::vector<DDLNode*>::iterator DDLNodeIt;
-
-public:
- /// @brief The class destructor.
- ~DDLNode();
-
- /// @brief Will attach a parent node instance, an older one will be released.
- /// @param parent [in] The parent node instance.
- void attachParent( DDLNode *parent );
-
- /// @brief Will try to detach a parent node instance, if there is any.
- void detachParent();
-
- /// @brief Returns the assigned parent node instance, will return ddl_nullptr id no parent is assigned.
- /// @return The parent node instance.
- DDLNode *getParent() const;
-
- /// @brief Returns the child node list.
- /// @return The list of child nodes.
- const DllNodeList &getChildNodeList() const;
-
- /// Set the type of the DDLNode instance.
- /// @param type [in] The type.
- void setType( const std::string &type );
-
- /// @brief Returns the type of the DDLNode instance.
- /// @return The type of the DDLNode instance.
- const std::string &getType() const;
-
- /// Set the name of the DDLNode instance.
- /// @param name [in] The name.
- void setName( const std::string &name );
-
- /// @brief Returns the name of the DDLNode instance.
- /// @return The name of the DDLNode instance.
- const std::string &getName() const;
-
- /// @brief Set a new property set.
- /// @param prop [in] The first element of the property set.
- void setProperties( Property *prop );
-
- /// @brief Returns the first element of the assigned property set.
- /// @return The first property of the assigned property set.
- Property *getProperties() const;
-
- /// @brief Looks for a given property.
- /// @param name [in] The name for the property to look for.
- /// @return true, if a corresponding property is assigned to the node, false if not.
- bool hasProperty( const std::string &name );
-
- /// @brief Will return true, if any properties are assigned to the node instance.
- /// @return True, if properties are assigned.
- bool hasProperties() const;
-
- /// @brief Search for a given property and returns it. Will return ddl_nullptr if no property was found.
- /// @param name [in] The name for the property to look for.
- /// @return The property or ddl_nullptr if no property was found.
- Property *findPropertyByName( const std::string &name );
-
- /// @brief Set a new value set.
- /// @param val [in] The first value instance of the value set.
- void setValue( Value *val );
-
- /// @brief Returns the first element of the assigned value set.
- /// @return The first property of the assigned value set.
- Value *getValue() const;
-
- /// @brief Set a new DataArrayList.
- /// @param dtArrayList [in] The DataArrayList instance.
- void setDataArrayList( DataArrayList *dtArrayList );
-
- /// @brief Returns the DataArrayList.
- /// @return The DataArrayList.
- DataArrayList *getDataArrayList() const;
-
- /// @brief Set a new Reference set.
- /// @param refs [in] The first value instance of the Reference set.
- void setReferences( Reference *refs );
-
- /// @brief Returns the first element of the assigned Reference set.
- /// @return The first property of the assigned Reference set.
- Reference *getReferences() const;
-
- /// @brief Will dump the node into the stream.
- /// @param stream [in] The stream to write to.
- void dump(IOStreamBase &stream);
-
- /// @brief The creation method.
- /// @param type [in] The DDLNode type.
- /// @param name [in] The name for the new DDLNode instance.
- /// @param parent [in] The parent node instance or ddl_nullptr if no parent node is there.
- /// @return The new created node instance.
- static DDLNode *create( const std::string &type, const std::string &name, DDLNode *parent = ddl_nullptr );
-
-private:
- DDLNode( const std::string &type, const std::string &name, size_t idx, DDLNode *parent = ddl_nullptr );
- DDLNode();
- DDLNode( const DDLNode & ) ddl_no_copy;
- DDLNode &operator = ( const DDLNode & ) ddl_no_copy;
- static void releaseNodes();
-
-private:
- std::string m_type;
- std::string m_name;
- DDLNode *m_parent;
- std::vector<DDLNode*> m_children;
- Property *m_properties;
- Value *m_value;
- DataArrayList *m_dtArrayList;
- Reference *m_references;
- size_t m_idx;
- static DllNodeList s_allocatedNodes;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
deleted file mode 100644
index bec62cc9d..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
+++ /dev/null
@@ -1,246 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <cstddef>
-#include <vector>
-#include <string>
-
-#include <stdio.h>
-#include <string.h>
-#ifndef _WIN32
-# include <inttypes.h>
-#endif
-
-#if defined(_MSC_VER) && !defined( OPENDDL_STATIC_LIBARY )
-
-# define TAG_DLL_EXPORT __declspec(dllexport)
-# define TAG_DLL_IMPORT __declspec(dllimport )
-# ifdef OPENDDLPARSER_BUILD
-# define DLL_ODDLPARSER_EXPORT TAG_DLL_EXPORT
-# else
-# define DLL_ODDLPARSER_EXPORT TAG_DLL_IMPORT
-# endif // OPENDDLPARSER_BUILD
-# pragma warning( disable : 4251 )
-#else
-# define DLL_ODDLPARSER_EXPORT
-#endif // _WIN32
-
-// Namespace declarations, override this to avoid any conflicts
-#define BEGIN_ODDLPARSER_NS namespace ODDLParser {
-#define END_ODDLPARSER_NS } // namespace ODDLParser
-#define USE_ODDLPARSER_NS using namespace ODDLParser;
-
-BEGIN_ODDLPARSER_NS
-
-// We will use C++11 optional
-#ifndef OPENDDL_NO_USE_CPP11
- // All C++11 constructs
-# define ddl_nullptr nullptr
-# define ddl_override override
-# define ddl_final final
-# define ddl_no_copy = delete
-#else
- // Fall-back for older compilers
-# define ddl_nullptr NULL
-# define ddl_override
-# define ddl_final
-# define ddl_no_copy
-#endif // OPENDDL_NO_USE_CPP11
-
-// Forward declarations
-class DDLNode;
-class Value;
-
-struct Name;
-struct Identifier;
-struct Reference;
-struct Property;
-struct DataArrayList;
-
-// Platform-specific typedefs
-#ifdef _WIN32
-typedef signed __int64 int64_impl;
-typedef unsigned __int64 uint64_impl;
-#else
-typedef int64_t int64_impl;
-typedef uint64_t uint64_impl;
-#endif
-
-// OpenDDL-specific data typedefs
-typedef signed char int8; ///< Signed integer, 1 byte
-typedef signed short int16; ///< Signed integer, 2 byte
-typedef signed int int32; ///< Signed integer, 4 byte
-typedef int64_impl int64; ///< Signed integer, 8 byte
-typedef unsigned char uint8; ///< Unsigned integer, 1 byte
-typedef unsigned short uint16; ///< Unsigned integer, 2 byte
-typedef unsigned int uint32; ///< Unsigned integer, 4 byte
-typedef uint64_impl uint64; ///< Unsigned integer, 8 byte
-
-/// @brief Stores a text.
-///
-/// A text is stored in a simple character buffer. Texts buffer can be
-/// greater than the number of stored characters in them.
-struct DLL_ODDLPARSER_EXPORT Text {
- size_t m_capacity; ///< The capacity of the text.
- size_t m_len; ///< The length of the text.
- char *m_buffer; ///< The buffer with the text.
-
- /// @brief The constructor with a given text buffer.
- /// @param buffer [in] The buffer.
- /// @param numChars [in] The number of characters in the buffer.
- Text( const char *buffer, size_t numChars );
-
- /// @brief The destructor.
- ~Text();
-
- /// @brief Clears the text.
- void clear();
-
- /// @brief Set a new text.
- /// @param buffer [in] The buffer.
- /// @param numChars [in] The number of characters in the buffer.
- void set( const char *buffer, size_t numChars );
-
- /// @brief The compare operator for std::strings.
- bool operator == ( const std::string &name ) const;
-
- /// @brief The compare operator for Texts.
- bool operator == ( const Text &rhs ) const;
-
-private:
- Text( const Text & ) ddl_no_copy;
- Text &operator = ( const Text & ) ddl_no_copy;
-};
-
-/// @brief Description of the type of a name.
-enum NameType {
- GlobalName, ///< Name is global.
- LocalName ///< Name is local.
-};
-
-/// @brief Stores an OpenDDL-specific name
-struct DLL_ODDLPARSER_EXPORT Name {
- NameType m_type; ///< The type of the name ( @see NameType ).
- Text *m_id; ///< The id.
-
- /// @brief The constructor with the type and the id.
- /// @param type [in] The name type.
- /// @param id [in] The id.
- Name( NameType type, Text *id );
- Name( const Name &name );
- /// @brief The destructor.
- ~Name();
-
-private:
-
- Name &operator = ( const Name& ) ddl_no_copy;
-};
-
-/// @brief Stores a bundle of references.
-struct DLL_ODDLPARSER_EXPORT Reference {
- size_t m_numRefs; ///< The number of stored references.
- Name **m_referencedName; ///< The reference names.
-
- /// @brief The default constructor.
- Reference();
- Reference( const Reference &ref );
- /// @brief The constructor with an array of ref names.
- /// @param numrefs [in] The number of ref names.
- /// @param names [in] The ref names.
- Reference( size_t numrefs, Name **names );
-
- /// @brief The destructor.
- ~Reference();
-
- /// @brief Returns the size in bytes to store one deep reference copy.
- /// @return The size on bytes.
- size_t sizeInBytes();
-
-private:
- Reference &operator = ( const Reference & ) ddl_no_copy;
-};
-
-/// @brief Stores a property list.
-struct DLL_ODDLPARSER_EXPORT Property {
- Text *m_key; ///< The identifier / key of the property.
- Value *m_value; ///< The value assigned to its key / id ( ddl_nullptr if none ).
- Reference *m_ref; ///< References assigned to its key / id ( ddl_nullptr if none ).
- Property *m_next; ///< The next property ( ddl_nullptr if none ).
-
- /// @brief The default constructor.
- Property();
-
- /// @brief The constructor for initialization.
- /// @param id [in] The identifier
- Property( Text *id );
-
- /// @brief The destructor.
- ~Property();
-
-private:
- Property( const Property & ) ddl_no_copy;
- Property &operator = ( const Property & ) ddl_no_copy;
-};
-
-/// @brief Stores a data array list.
-struct DLL_ODDLPARSER_EXPORT DataArrayList {
- size_t m_numItems; ///< The number of items in the list.
- Value *m_dataList; ///< The data list ( a Value ).
- DataArrayList *m_next; ///< The next data array list ( ddl_nullptr if last ).
- Reference *m_refs;
- size_t m_numRefs;
-
- /// @brief The default constructor for initialization.
- DataArrayList();
-
- /// @brief The destructor.
- ~DataArrayList();
-
- /// @brief Gets the length of the array
- size_t size();
-
-private:
- DataArrayList( const DataArrayList & ) ddl_no_copy;
- DataArrayList &operator = ( const DataArrayList & ) ddl_no_copy;
-};
-
-/// @brief Stores the context of a parsed OpenDDL declaration.
-struct DLL_ODDLPARSER_EXPORT Context {
- DDLNode *m_root; ///< The root node of the OpenDDL node tree.
-
- /// @brief Constructor for initialization.
- Context();
-
- /// @brief Destructor.
- ~Context();
-
- /// @brief Clears the whole node tree.
- void clear();
-
-private:
- Context( const Context & ) ddl_no_copy;
- Context &operator = ( const Context & ) ddl_no_copy;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h
deleted file mode 100644
index 020d662a0..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLExport.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-#include <openddlparser/OpenDDLStream.h>
-#include <openddlparser/Value.h>
-
-BEGIN_ODDLPARSER_NS
-
-// Forward declarations
-class IOStreamBase;
-
-//-------------------------------------------------------------------------------------------------
-///
-/// @ingroup OpenDDLParser
-/// @brief This class represents the OpenDDLExporter.
-///
-//-------------------------------------------------------------------------------------------------
-class DLL_ODDLPARSER_EXPORT OpenDDLExport {
-public:
- /// @brief The class constructor
- OpenDDLExport( IOStreamBase *stream = ddl_nullptr );
-
- /// @brief The class destructor.
- ~OpenDDLExport();
-
- /// @brief Export the data of a parser context.
- /// @param ctx [in] Pointer to the context.
- /// @param filename [in] The filename for the export.
- /// @return True in case of success, false in case of an error.
- bool exportContext( Context *ctx, const std::string &filename );
-
- /// @brief Handles a node export.
- /// @param node [in] The node to handle with.
- /// @return True in case of success, false in case of an error.
- bool handleNode( DDLNode *node );
-
- /// @brief Writes the statement to the stream.
- /// @param statement [in] The content to write.
- /// @return True in case of success, false in case of an error.
- bool writeToStream( const std::string &statement );
-
-protected:
- bool writeNode( DDLNode *node, std::string &statement );
- bool writeNodeHeader( DDLNode *node, std::string &statement );
- bool writeProperties( DDLNode *node, std::string &statement );
- bool writeValueType( Value::ValueType type, size_t numItems, std::string &statement );
- bool writeValue( Value *val, std::string &statement );
- bool writeValueArray( DataArrayList *al, std::string &statement );
-
-private:
- OpenDDLExport( const OpenDDLExport & ) ddl_no_copy;
- OpenDDLExport &operator = ( const OpenDDLExport & ) ddl_no_copy;
-
-private:
- IOStreamBase *m_stream;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h
deleted file mode 100644
index ef7f3a72e..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParser.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-#include <openddlparser/DDLNode.h>
-#include <openddlparser/OpenDDLParserUtils.h>
-#include <openddlparser/Value.h>
-
-#include <vector>
-#include <string>
-
-BEGIN_ODDLPARSER_NS
-
-class DDLNode;
-class Value;
-
-struct Identifier;
-struct Reference;
-struct Property;
-
-template<class T>
-inline
-bool isEmbeddedCommentOpenTag( T *in, T *end ) {
- if ( in == end ) {
- return false;
- }
-
- if ( in == '/' && in+1 == '*' ) {
- return true;
- }
-
- return false;
-}
-
-/// @brief Utility function to search for the next token or the end of the buffer.
-/// @param in [in] The start position in the buffer.
-/// @param end [in] The end position in the buffer.
-/// @return Pointer showing to the next token or the end of the buffer.
-/// @detail Will not increase buffer when already a valid buffer was found.
-template<class T>
-inline
-T *lookForNextToken( T *in, T *end ) {
- while( ( in != end ) && ( isSpace( *in ) || isNewLine( *in ) || ',' == *in ) ) {
- in++;
- }
- return in;
-}
-
-/// @brief Utility function to go for the next token or the end of the buffer.
-/// @param in [in] The start position in the buffer.
-/// @param end [in] The end position in the buffer.
-/// @return Pointer showing to the next token or the end of the buffer.
-/// @detail Will increase buffer by a minimum of one.
-template<class T>
-inline
-T *getNextToken( T *in, T *end ) {
- T *tmp( in );
- in = lookForNextToken( in, end );
- if( tmp == in ) {
- in++;
- }
- return in;
-}
-
-/// @brief Defines the log severity.
-enum LogSeverity {
- ddl_debug_msg = 0, ///< Debug message, for debugging
- ddl_info_msg, ///< Info messages, normal mode
- ddl_warn_msg, ///< Parser warnings
- ddl_error_msg ///< Parser errors
-};
-
-DLL_ODDLPARSER_EXPORT const char *getTypeToken( Value::ValueType type );
-
-//-------------------------------------------------------------------------------------------------
-/// @class OpenDDLParser
-/// @ingroup OpenDDLParser
-
-///
-/// @brief This is the main API for the OpenDDL-parser.
-///
-/// Use instances of this class to manage the parsing and handling of your parser contexts.
-//-------------------------------------------------------------------------------------------------
-class DLL_ODDLPARSER_EXPORT OpenDDLParser {
-public:
- /// @brief The log callback function pointer.
- typedef void( *logCallback )( LogSeverity severity, const std::string &msg );
-
-public:
- /// @brief The default class constructor.
- OpenDDLParser();
-
- /// @brief The class constructor.
- /// @param buffer [in] The buffer
- /// @param len [in] Size of the buffer
- OpenDDLParser( const char *buffer, size_t len );
-
- /// @brief The class destructor.
- ~OpenDDLParser();
-
- /// @brief Setter for an own log callback function.
- /// @param callback [in] The own callback.
- void setLogCallback( logCallback callback );
-
- /// @brief Getter for the log callback.
- /// @return The current log callback.
- logCallback getLogCallback() const;
-
- /// @brief Assigns a new buffer to parse.
- /// @param buffer [in] The buffer
- /// @param len [in] Size of the buffer
- void setBuffer( const char *buffer, size_t len );
-
- /// @brief Assigns a new buffer to parse.
- /// @param buffer [in] The buffer as a std::vector.
- void setBuffer( const std::vector<char> &buffer );
-
- /// @brief Returns the buffer pointer.
- /// @return The buffer pointer.
- const char *getBuffer() const;
-
- /// @brief Returns the size of the buffer.
- /// @return The buffer size.
- size_t getBufferSize() const;
-
- /// @brief Clears all parser data, including buffer and active context.
- void clear();
-
- /// @brief Starts the parsing of the OpenDDL-file.
- /// @return True in case of success, false in case of an error.
- /// @remark In case of errors check log.
- bool parse();
-
- bool exportContext( Context *ctx, const std::string &filename );
-
- /// @brief Returns the root node.
- /// @return The root node.
- DDLNode *getRoot() const;
-
- /// @brief Returns the parser context, only available in case of a succeeded parsing.
- /// @return Pointer to the active context or ddl_nullptr.
- Context *getContext() const;
-
-public: // parser helpers
- char *parseNextNode( char *current, char *end );
- char *parseHeader( char *in, char *end );
- char *parseStructure( char *in, char *end );
- char *parseStructureBody( char *in, char *end, bool &error );
- void pushNode( DDLNode *node );
- DDLNode *popNode();
- DDLNode *top();
- static void normalizeBuffer( std::vector<char> &buffer );
- static char *parseName( char *in, char *end, Name **name );
- static char *parseIdentifier( char *in, char *end, Text **id );
- static char *parsePrimitiveDataType( char *in, char *end, Value::ValueType &type, size_t &len );
- static char *parseReference( char *in, char *end, std::vector<Name*> &names );
- static char *parseBooleanLiteral( char *in, char *end, Value **boolean );
- static char *parseIntegerLiteral( char *in, char *end, Value **integer, Value::ValueType integerType = Value::ddl_int32 );
- static char *parseFloatingLiteral( char *in, char *end, Value **floating, Value::ValueType floatType= Value::ddl_float );
- static char *parseStringLiteral( char *in, char *end, Value **stringData );
- static char *parseHexaLiteral( char *in, char *end, Value **data );
- static char *parseProperty( char *in, char *end, Property **prop );
- static char *parseDataList( char *in, char *end, Value::ValueType type, Value **data, size_t &numValues, Reference **refs, size_t &numRefs );
- static char *parseDataArrayList( char *in, char *end, Value::ValueType type, DataArrayList **dataList );
- static const char *getVersion();
-
-private:
- OpenDDLParser( const OpenDDLParser & ) ddl_no_copy;
- OpenDDLParser &operator = ( const OpenDDLParser & ) ddl_no_copy;
-
-private:
- logCallback m_logCallback;
- std::vector<char> m_buffer;
-
- typedef std::vector<DDLNode*> DDLNodeStack;
- DDLNodeStack m_stack;
- Context *m_context;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
deleted file mode 100644
index 64897436e..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-
-BEGIN_ODDLPARSER_NS
-
-template<class T>
-inline
-bool isUpperCase( T in ) {
- return ( in >= 'A' && in <= 'Z' );
-}
-
-template<class T>
-inline
-bool isLowerCase( T in ) {
- return ( in >= 'a' && in <= 'z' );
-}
-
-template<class T>
-inline
-bool isSpace( const T in ) {
- return ( ' ' == in || '\t' == in );
-}
-
-template<class T>
-inline
-bool isNewLine( const T in ) {
- return ( '\n' == in || ( '\r' == in ) );
-}
-
-template<class T>
-inline
-bool isSeparator( T in ) {
- if( isSpace( in ) || ',' == in || '{' == in || '}' == in || '[' == in || '(' == in || ')' == in ) {
- return true;
- }
- return false;
-}
-
-static const unsigned char chartype_table[ 256 ] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, // 48-63
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 112-127
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // > 127
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-template<class T>
-inline
-bool isNumeric( const T in ) {
- return ( chartype_table[ static_cast<size_t>( in ) ] == 1 );
-}
-
-template<class T>
-inline
-bool isNotEndOfToken( T *in, T *end ) {
- return ( '}' != *in && ',' != *in && !isSpace( *in ) && ')' != *in && in != end );
-}
-
-template<class T>
-inline
-bool isInteger( T *in, T *end ) {
- if( in != end ) {
- if( *in == '-' ) {
- ++in;
- }
- }
-
- bool result( false );
- while( isNotEndOfToken( in, end ) ) {
- result = isNumeric( *in );
- if( !result ) {
- break;
- }
- ++in;
- }
-
- return result;
-}
-
-template<class T>
-inline
-bool isFloat( T *in, T *end ) {
- if( in != end ) {
- if( *in == '-' ) {
- ++in;
- }
- }
-
- // check for <1>.0f
- bool result( false );
- while( isNotEndOfToken( in, end ) ) {
- if( *in == '.' ) {
- result = true;
- break;
- }
- result = isNumeric( *in );
- if( !result ) {
- return false;
- }
- ++in;
- }
-
- // check for 1<.>0f
- if( *in == '.' ) {
- ++in;
- } else {
- return false;
- }
-
- // check for 1.<0>f
- while( isNotEndOfToken( in, end ) ) {
- result = isNumeric( *in );
- if( !result ) {
- return false;
- }
- ++in;
- }
-
- return result;
-}
-
-template<class T>
-inline
-bool isCharacter( const T in ) {
- return ( ( in >= 'a' && in <= 'z' ) || ( in >= 'A' && in <= 'Z' ) );
-}
-
-template<class T>
-inline
-bool isStringLiteral( const T in ) {
- return ( in == '\"' );
-}
-
-template<class T>
-inline
-bool isHexLiteral( T *in, T *end ) {
- if( *in == '0' ) {
- if( in + 1 != end ) {
- if( *( in + 1 ) == 'x' || *( in + 1 ) == 'X' ) {
- return true;
- }
- }
- }
-
- return false;
-}
-
-template<class T>
-inline
-bool isReference( T *in, T *end ) {
- if( *in == 'r' ) {
- if( *(in+1) == 'e' ) {
- if( *(in+2) == 'f' ) {
- if( ( in + 2 ) != end ) {
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-template<class T>
-inline
-bool isEndofLine( const T in ) {
- return ( '\n' == in );
-}
-
-template<class T>
-inline
-static T *getNextSeparator( T *in, T *end ) {
- while( !isSeparator( *in ) || in == end ) {
- ++in;
- }
- return in;
-}
-
-static const int ErrorHex2Decimal = 9999999;
-
-inline
-int hex2Decimal( char in ) {
- if( isNumeric( in ) ) {
- return ( in - 48 );
- }
-
- char hexCodeLower( 'a' ), hexCodeUpper( 'A' );
- for( int i = 0; i<16; i++ ) {
- if( in == hexCodeLower + i || in == hexCodeUpper + i ) {
- return ( i+10 );
- }
- }
-
- return ErrorHex2Decimal;
-}
-
-template<class T>
-inline
-bool isComment( T *in, T *end ) {
- if ( *in=='/' ) {
- if ( in+1!=end ) {
- if ( *( in+1 )=='/' ) {
- char *drive( ( in+2 ) );
- if ( (isUpperCase<T>( *drive )||isLowerCase<T>( *drive ))&&*( drive+1 )=='/' ) {
- return false;
- } else {
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-template<class T>
-inline
-bool isCommentOpenTag(T *in, T *end ) {
- if (*in == '/') {
- if (in + 1 != end) {
- if (*(in + 1) == '*') {
- return true;
- }
- }
- }
-
- return false;
-}
-
-template<class T>
-inline
-bool isCommentCloseTag(T *in, T *end) {
- if (*in == '*') {
- if (in + 1 != end) {
- if (*(in + 1) == '/') {
- return true;
- }
- }
- }
-
- return false;
-}
-
-END_ODDLPARSER_NS
-
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h
deleted file mode 100644
index 93370da03..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/OpenDDLStream.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-
-BEGIN_ODDLPARSER_NS
-
-//-------------------------------------------------------------------------------------------------
-/// @ingroup IOStreamBase
-/// @brief This class represents the stream to write out.
-//-------------------------------------------------------------------------------------------------
-class DLL_ODDLPARSER_EXPORT StreamFormatterBase {
-public:
- /// @brief The class constructor.
- StreamFormatterBase();
-
- /// @brief The class destructor, virtual.
- virtual ~StreamFormatterBase();
-
- /// @brief Will format the sring and return the new formatted result.
- /// @param statement [in] The string to reformat.
- /// @return The reformatted result.
- virtual std::string format(const std::string &statement);
-};
-
-//-------------------------------------------------------------------------------------------------
-/// @ingroup IOStreamBase
-/// @brief This class represents the stream to write out.
-//-------------------------------------------------------------------------------------------------
-class DLL_ODDLPARSER_EXPORT IOStreamBase {
-public:
- /// @brief The class constructor with the formatter.
- /// @param formatter [in] The formatter to use.
- explicit IOStreamBase(StreamFormatterBase *formatter = ddl_nullptr);
-
- /// @brief The class destructor, virtual.
- virtual ~IOStreamBase();
-
- /// @brief Will open the stream.
- /// @param name [in] The name for the stream.
- /// @return true, if the stream was opened successfully, false if not.
- virtual bool open(const std::string &name);
-
- /// @brief Will close the stream.
- /// @return true, if the stream was closed successfully, false if not.
- virtual bool close();
-
- /// @brief Returns true, if the stream is open.
- /// @return true, if the stream is open, false if not.
- virtual bool isOpen() const;
-
- /// @brief Will read a string from the stream.
- /// @param sizeToRead [in] The size to read in bytes.
- /// @param statement [out] The read statements.
- /// @return The bytes read from the stream.
- virtual size_t read( size_t sizeToRead, std::string &statement );
-
- /// @brief Will write a string into the stream.
- /// @param statement [in] The string to write.
- /// @return The bytes written into the stream.
- virtual size_t write(const std::string &statement);
-
-private:
- StreamFormatterBase *m_formatter;
- FILE *m_file;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h b/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h
deleted file mode 100644
index 77c6da06b..000000000
--- a/src/3rdparty/assimp/contrib/openddlparser/include/openddlparser/Value.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*-----------------------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Kim Kulling
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------------------------*/
-#pragma once
-
-#include <openddlparser/OpenDDLCommon.h>
-
-#include <string>
-
-BEGIN_ODDLPARSER_NS
-
-// Forward declarations
-struct ValueAllocator;
-
-class IOStreamBase;
-
-///------------------------------------------------------------------------------------------------
-/// @brief This class implements a value.
-///
-/// Values are used to store data types like boolean, integer, floats, double and many mode. To get
-/// an overview please check the enum VylueType ( @see Value::ValueType ).
-/// Values can be single items or lists of items. They are implemented as linked lists.
-///------------------------------------------------------------------------------------------------
-class DLL_ODDLPARSER_EXPORT Value {
- friend struct ValueAllocator;
-
-public:
- /// @brief This class implements an iterator through a Value list.
- ///
- /// When getting a new value you need to know how to iterate through it. The Value::Iterator
- /// will help you here:
- /// @code
- /// Value *val = node->getValue();
- /// Value::Iterator it( val );
- /// while( it.hasNext() ) {
- /// Value v( it.getNext );
- /// }
- /// @endcode
- class DLL_ODDLPARSER_EXPORT Iterator {
- public:
- /// @brief The default class constructor.
- Iterator();
-
- /// @brief The class constructor with the start value.
- /// @param start [in] The first value for iteration,
- Iterator( Value *start );
-
- Iterator( const Iterator &rhs );
-
- /// @brief The class destructor.
- ~Iterator();
-
- /// @brief Will return true, if another value is in the list.
- /// @return true if another value is there.
- bool hasNext() const;
-
- /// @brief Returns the next item and moves the iterator to it.
- /// @return The next value, is ddl_nullptr in case of being the last item.
- Value *getNext();
-
- /// @brief The post-increment operator.
- const Iterator operator++( int );
-
- /// @brief The pre-increment operator.
- Iterator &operator++( );
-
- /// @brief The compare operator.
- /// @param rhs [in] The instance to compare.
- /// @return true if equal.
- bool operator == ( const Iterator &rhs ) const;
-
- /// @brief The * operator.
- /// @return The instance or ddl_nullptr if end of list is reached.
- Value *operator->( ) const;
-
- private:
- Value *m_start;
- Value *m_current;
-
- private:
- Iterator &operator = ( const Iterator & );
- };
-
- /// @brief This enum describes the data type stored in the value.
- enum ValueType {
- ddl_none = -1, ///< Nothing specified
- ddl_bool = 0, ///< A boolean type
- ddl_int8, ///< Integer type, 8 bytes
- ddl_int16, ///< Integer type, 16 bytes
- ddl_int32, ///< Integer type, 32 bytes
- ddl_int64, ///< Integer type, 64 bytes
- ddl_unsigned_int8, ///< Unsigned integer type, 8 bytes
- ddl_unsigned_int16, ///< Unsigned integer type, 16 bytes
- ddl_unsigned_int32, ///< Unsigned integer type, 32 bytes
- ddl_unsigned_int64, ///< Unsigned integer type, 64 bytes
- ddl_half, ///< Half data type.
- ddl_float, ///< float data type
- ddl_double, ///< Double data type.
- ddl_string, ///< String data type.
- ddl_ref, ///< Reference, used to define references to other data definitions.
- ddl_types_max ///< Upper limit.
- };
-
- /// @brief The class constructor.
- /// @param type [in] The value type.
- Value( ValueType type );
-
- /// @brief The class destructor.
- ~Value();
-
- /// @brief Assigns a boolean to the value.
- /// @param value [in9 The value.
- void setBool( bool value );
-
- /// @brief Returns the boolean value.
- /// @return The boolean value.
- bool getBool();
-
- /// @brief Assigns a int8 to the value.
- /// @param value [in] The value.
- void setInt8( int8 value );
-
- /// @brief Returns the int8 value.
- /// @return The int8 value.
- int8 getInt8();
-
- /// @brief Assigns a int16 to the value.
- /// @param value [in] The value.
- void setInt16( int16 value );
-
- /// @brief Returns the int16 value.
- /// @return The int16 value.
- int16 getInt16();
-
- /// @brief Assigns a int32 to the value.
- /// @param value [in] The value.
- void setInt32( int32 value );
-
- /// @brief Returns the int16 value.
- /// @return The int32 value.
- int32 getInt32();
-
- /// @brief Assigns a int64 to the value.
- /// @param value [in] The value.
- void setInt64( int64 value );
-
- /// @brief Returns the int16 value.
- /// @return The int64 value.
- int64 getInt64();
-
- /// @brief Assigns a unsigned int8 to the value.
- /// @param value [in] The value.
- void setUnsignedInt8( uint8 value );
-
- /// @brief Returns the unsigned int8 value.
- /// @return The unsigned int8 value.
- uint8 getUnsignedInt8() const;
-
- /// @brief Assigns a unsigned int16 to the value.
- /// @param value [in] The value.
- void setUnsignedInt16( uint16 value );
-
- /// @brief Returns the unsigned int16 value.
- /// @return The unsigned int16 value.
- uint16 getUnsignedInt16() const;
-
- /// @brief Assigns a unsigned int32 to the value.
- /// @param value [in] The value.
- void setUnsignedInt32( uint32 value );
-
- /// @brief Returns the unsigned int8 value.
- /// @return The unsigned int32 value.
- uint32 getUnsignedInt32() const;
-
- /// @brief Assigns a unsigned int64 to the value.
- /// @param value [in] The value.
- void setUnsignedInt64( uint64 value );
-
- /// @brief Returns the unsigned int64 value.
- /// @return The unsigned int64 value.
- uint64 getUnsignedInt64() const;
-
- /// @brief Assigns a float to the value.
- /// @param value [in] The value.
- void setFloat( float value );
-
- /// @brief Returns the float value.
- /// @return The float value.
- float getFloat() const;
-
- /// @brief Assigns a double to the value.
- /// @param value [in] The value.
- void setDouble( double value );
-
- /// @brief Returns the double value.
- /// @return The double value.
- double getDouble() const;
-
- /// @brief Assigns a std::string to the value.
- /// @param str [in] The value.
- void setString( const std::string &str );
-
- /// @brief Returns the std::string value.
- /// @return The std::string value.
- const char *getString() const;
-
- /// @brief Set the reference.
- /// @param ref [in] Pointer showing to the reference.
- void setRef( Reference *ref );
-
- /// @brief Returns the pointer showing to the reference.
- /// @return Pointer showing to the reference.
- Reference *getRef() const;
-
- /// @brief Dumps the value.
- /// @param stream [in] The stream to write in.
- void dump( IOStreamBase &stream );
-
- /// @brief Assigns the next value.
- /// @param next [n] The next value.
- void setNext( Value *next );
-
- /// @brief Returns the next value.
- /// @return The next value.s
- Value *getNext() const;
-
- /// @brief Gets the length of the array.
- /// @return The number of items in the array.
- size_t size() const;
-
- ValueType m_type;
- size_t m_size;
- unsigned char *m_data;
- Value *m_next;
-
-private:
- Value &operator =( const Value & ) ddl_no_copy;
- Value( const Value & ) ddl_no_copy;
-};
-
-///------------------------------------------------------------------------------------------------
-/// @brief This class implements the value allocator.
-///------------------------------------------------------------------------------------------------
-struct DLL_ODDLPARSER_EXPORT ValueAllocator {
- static Value *allocPrimData( Value::ValueType type, size_t len = 1 );
- static void releasePrimData( Value **data );
-
-private:
- ValueAllocator() ddl_no_copy;
- ValueAllocator( const ValueAllocator & ) ddl_no_copy;
- ValueAllocator &operator = ( const ValueAllocator & ) ddl_no_copy;
-};
-
-END_ODDLPARSER_NS
diff --git a/src/3rdparty/assimp/contrib/poly2tri/AUTHORS b/src/3rdparty/assimp/contrib/poly2tri/AUTHORS
deleted file mode 100644
index 1736f14bb..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/AUTHORS
+++ /dev/null
@@ -1,8 +0,0 @@
-Primary Contributors:
-
- Mason Green <mason.green@gmail.com> (C++, Python)
- Thomas Åhlén <thahlen@gmail.com> (Java)
-
-Other Contributors:
-
-
diff --git a/src/3rdparty/assimp/contrib/poly2tri/LICENSE b/src/3rdparty/assimp/contrib/poly2tri/LICENSE
deleted file mode 100644
index 9417c0836..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
-http://code.google.com/p/poly2tri/
-
-All rights reserved.
-Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- used to endorse or promote products derived from this software without specific
- prior written permission.
-
-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.
diff --git a/src/3rdparty/assimp/contrib/poly2tri/README b/src/3rdparty/assimp/contrib/poly2tri/README
deleted file mode 100644
index 2857e2983..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/README
+++ /dev/null
@@ -1,51 +0,0 @@
-==================
-INSTALLATION GUIDE
-==================
-
-------------
-Dependencies
-------------
-
- Core poly2tri lib:
- - Standard Template Library (STL)
-
- Testbed:
- - gcc
- - OpenGL
- - GLFW (http://glfw.sf.net)
- - Python
-
-Waf (http://code.google.com/p/waf/) is used to compile the testbed.
-A waf script (86kb) is included in the repositoty.
-
-----------------------------------------------
-Building the Testbed
-----------------------------------------------
-
-Posix/MSYS environment:
-
- ./waf configure
- ./waf build
-
-Windows command line:
-
- python waf configure
- python waf build
-
-----------------------------------------------
-Running the Examples
-----------------------------------------------
-
-Load data points from a file:
-p2t <filename> <center_x> <center_y> <zoom>
-
-Random distribution of points inside a consrained box:
-p2t random <num_points> <box_radius> <zoom>
-
-Examples:
-
- ./p2t dude.dat 300 500 2
- ./p2t nazca_monkey.dat 0 0 9
-
- ./p2t random 10 100 5.0
- ./p2t random 1000 20000 0.025 \ No newline at end of file
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc
deleted file mode 100644
index c94e11c03..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.cc
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-#include "shapes.h"
-#include <iostream>
-
-namespace p2t {
-
-Triangle::Triangle(Point& a, Point& b, Point& c)
-{
- points_[0] = &a; points_[1] = &b; points_[2] = &c;
- neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL;
- constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false;
- delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
- interior_ = false;
-}
-
-// Update neighbor pointers
-void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t)
-{
- if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2]))
- neighbors_[0] = t;
- else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0]))
- neighbors_[1] = t;
- else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0]))
- neighbors_[2] = t;
- else
- assert(0);
-}
-
-// Exhaustive search to update neighbor pointers
-void Triangle::MarkNeighbor(Triangle& t)
-{
- if (t.Contains(points_[1], points_[2])) {
- neighbors_[0] = &t;
- t.MarkNeighbor(points_[1], points_[2], this);
- } else if (t.Contains(points_[0], points_[2])) {
- neighbors_[1] = &t;
- t.MarkNeighbor(points_[0], points_[2], this);
- } else if (t.Contains(points_[0], points_[1])) {
- neighbors_[2] = &t;
- t.MarkNeighbor(points_[0], points_[1], this);
- }
-}
-
-/**
- * Clears all references to all other triangles and points
- */
-void Triangle::Clear()
-{
- Triangle *t;
- for( int i=0; i<3; i++ )
- {
- t = neighbors_[i];
- if( t != NULL )
- {
- t->ClearNeighbor( this );
- }
- }
- ClearNeighbors();
- points_[0]=points_[1]=points_[2] = NULL;
-}
-
-void Triangle::ClearNeighbor(const Triangle *triangle )
-{
- if( neighbors_[0] == triangle )
- {
- neighbors_[0] = NULL;
- }
- else if( neighbors_[1] == triangle )
- {
- neighbors_[1] = NULL;
- }
- else
- {
- neighbors_[2] = NULL;
- }
-}
-
-void Triangle::ClearNeighbors()
-{
- neighbors_[0] = NULL;
- neighbors_[1] = NULL;
- neighbors_[2] = NULL;
-}
-
-void Triangle::ClearDelunayEdges()
-{
- delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
-}
-
-Point* Triangle::OppositePoint(Triangle& t, const Point& p)
-{
- Point *cw = t.PointCW(p);
- return PointCW(*cw);
-}
-
-// Legalized triangle by rotating clockwise around point(0)
-void Triangle::Legalize(Point& point)
-{
- points_[1] = points_[0];
- points_[0] = points_[2];
- points_[2] = &point;
-}
-
-// Legalize triagnle by rotating clockwise around oPoint
-void Triangle::Legalize(Point& opoint, Point& npoint)
-{
- if (&opoint == points_[0]) {
- points_[1] = points_[0];
- points_[0] = points_[2];
- points_[2] = &npoint;
- } else if (&opoint == points_[1]) {
- points_[2] = points_[1];
- points_[1] = points_[0];
- points_[0] = &npoint;
- } else if (&opoint == points_[2]) {
- points_[0] = points_[2];
- points_[2] = points_[1];
- points_[1] = &npoint;
- } else {
- assert(0);
- }
-}
-
-int Triangle::Index(const Point* p)
-{
- if (p == points_[0]) {
- return 0;
- } else if (p == points_[1]) {
- return 1;
- } else if (p == points_[2]) {
- return 2;
- }
- assert(0);
- return -1;
-}
-
-int Triangle::EdgeIndex(const Point* p1, const Point* p2)
-{
- if (points_[0] == p1) {
- if (points_[1] == p2) {
- return 2;
- } else if (points_[2] == p2) {
- return 1;
- }
- } else if (points_[1] == p1) {
- if (points_[2] == p2) {
- return 0;
- } else if (points_[0] == p2) {
- return 2;
- }
- } else if (points_[2] == p1) {
- if (points_[0] == p2) {
- return 1;
- } else if (points_[1] == p2) {
- return 0;
- }
- }
- return -1;
-}
-
-void Triangle::MarkConstrainedEdge(int index)
-{
- constrained_edge[index] = true;
-}
-
-void Triangle::MarkConstrainedEdge(Edge& edge)
-{
- MarkConstrainedEdge(edge.p, edge.q);
-}
-
-// Mark edge as constrained
-void Triangle::MarkConstrainedEdge(Point* p, Point* q)
-{
- if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) {
- constrained_edge[2] = true;
- } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) {
- constrained_edge[1] = true;
- } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) {
- constrained_edge[0] = true;
- }
-}
-
-// The point counter-clockwise to given point
-Point* Triangle::PointCW(const Point& point)
-{
- if (&point == points_[0]) {
- return points_[2];
- } else if (&point == points_[1]) {
- return points_[0];
- } else if (&point == points_[2]) {
- return points_[1];
- }
- assert(0);
- return NULL;
-}
-
-// The point counter-clockwise to given point
-Point* Triangle::PointCCW(const Point& point)
-{
- if (&point == points_[0]) {
- return points_[1];
- } else if (&point == points_[1]) {
- return points_[2];
- } else if (&point == points_[2]) {
- return points_[0];
- }
- assert(0);
- return NULL;
-}
-
-// The neighbor clockwise to given point
-Triangle* Triangle::NeighborCW(const Point& point)
-{
- if (&point == points_[0]) {
- return neighbors_[1];
- } else if (&point == points_[1]) {
- return neighbors_[2];
- }
- return neighbors_[0];
-}
-
-// The neighbor counter-clockwise to given point
-Triangle* Triangle::NeighborCCW(const Point& point)
-{
- if (&point == points_[0]) {
- return neighbors_[2];
- } else if (&point == points_[1]) {
- return neighbors_[0];
- }
- return neighbors_[1];
-}
-
-bool Triangle::GetConstrainedEdgeCCW(const Point& p)
-{
- if (&p == points_[0]) {
- return constrained_edge[2];
- } else if (&p == points_[1]) {
- return constrained_edge[0];
- }
- return constrained_edge[1];
-}
-
-bool Triangle::GetConstrainedEdgeCW(const Point& p)
-{
- if (&p == points_[0]) {
- return constrained_edge[1];
- } else if (&p == points_[1]) {
- return constrained_edge[2];
- }
- return constrained_edge[0];
-}
-
-void Triangle::SetConstrainedEdgeCCW(const Point& p, bool ce)
-{
- if (&p == points_[0]) {
- constrained_edge[2] = ce;
- } else if (&p == points_[1]) {
- constrained_edge[0] = ce;
- } else {
- constrained_edge[1] = ce;
- }
-}
-
-void Triangle::SetConstrainedEdgeCW(const Point& p, bool ce)
-{
- if (&p == points_[0]) {
- constrained_edge[1] = ce;
- } else if (&p == points_[1]) {
- constrained_edge[2] = ce;
- } else {
- constrained_edge[0] = ce;
- }
-}
-
-bool Triangle::GetDelunayEdgeCCW(const Point& p)
-{
- if (&p == points_[0]) {
- return delaunay_edge[2];
- } else if (&p == points_[1]) {
- return delaunay_edge[0];
- }
- return delaunay_edge[1];
-}
-
-bool Triangle::GetDelunayEdgeCW(const Point& p)
-{
- if (&p == points_[0]) {
- return delaunay_edge[1];
- } else if (&p == points_[1]) {
- return delaunay_edge[2];
- }
- return delaunay_edge[0];
-}
-
-void Triangle::SetDelunayEdgeCCW(const Point& p, bool e)
-{
- if (&p == points_[0]) {
- delaunay_edge[2] = e;
- } else if (&p == points_[1]) {
- delaunay_edge[0] = e;
- } else {
- delaunay_edge[1] = e;
- }
-}
-
-void Triangle::SetDelunayEdgeCW(const Point& p, bool e)
-{
- if (&p == points_[0]) {
- delaunay_edge[1] = e;
- } else if (&p == points_[1]) {
- delaunay_edge[2] = e;
- } else {
- delaunay_edge[0] = e;
- }
-}
-
-// The neighbor across to given point
-Triangle& Triangle::NeighborAcross(const Point& opoint)
-{
- if (&opoint == points_[0]) {
- return *neighbors_[0];
- } else if (&opoint == points_[1]) {
- return *neighbors_[1];
- }
- return *neighbors_[2];
-}
-
-void Triangle::DebugPrint()
-{
- using namespace std;
- cout << points_[0]->x << "," << points_[0]->y << " ";
- cout << points_[1]->x << "," << points_[1]->y << " ";
- cout << points_[2]->x << "," << points_[2]->y << endl;
-}
-
-}
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h
deleted file mode 100644
index d3660f716..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/shapes.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-
-// Include guard
-#ifndef SHAPES_H
-#define SHAPES_H
-
-#include <vector>
-#include <cstddef>
-#include <stdexcept>
-#include <assert.h>
-#include <cmath>
-#include <string>
-
-namespace p2t {
-
-struct Edge;
-
-struct Point {
-
- double x, y;
-
- /// Default constructor does nothing (for performance).
- Point()
- {
- x = 0.0;
- y = 0.0;
- }
-
- /// The edges this point constitutes an upper ending point
- std::vector<Edge*> edge_list;
-
- /// Construct using coordinates.
- Point(double x, double y) : x(x), y(y) {}
-
- /// Set this point to all zeros.
- void set_zero()
- {
- x = 0.0;
- y = 0.0;
- }
-
- /// Set this point to some specified coordinates.
- void set(double x_, double y_)
- {
- x = x_;
- y = y_;
- }
-
- /// Negate this point.
- Point operator -() const
- {
- Point v;
- v.set(-x, -y);
- return v;
- }
-
- /// Add a point to this point.
- void operator +=(const Point& v)
- {
- x += v.x;
- y += v.y;
- }
-
- /// Subtract a point from this point.
- void operator -=(const Point& v)
- {
- x -= v.x;
- y -= v.y;
- }
-
- /// Multiply this point by a scalar.
- void operator *=(double a)
- {
- x *= a;
- y *= a;
- }
-
- /// Get the length of this point (the norm).
- double Length() const
- {
- return sqrt(x * x + y * y);
- }
-
- /// Convert this point into a unit point. Returns the Length.
- double Normalize()
- {
- const double len = Length();
- x /= len;
- y /= len;
- return len;
- }
-
-};
-
-// Represents a simple polygon's edge
-struct Edge {
-
- Point* p, *q;
-
- /// Constructor
- Edge(Point& p1, Point& p2) : p(&p1), q(&p2)
- {
- if (p1.y > p2.y) {
- q = &p1;
- p = &p2;
- } else if (p1.y == p2.y) {
- if (p1.x > p2.x) {
- q = &p1;
- p = &p2;
- } else if (p1.x == p2.x) {
- // Repeat points
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error(std::string("repeat points"));
- //assert(false);
- }
- }
-
- q->edge_list.push_back(this);
- }
-};
-
-// Triangle-based data structures are know to have better performance than quad-edge structures
-// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
-// "Triangulations in CGAL"
-class Triangle {
-public:
-
-/// Constructor
-Triangle(Point& a, Point& b, Point& c);
-
-/// Flags to determine if an edge is a Constrained edge
-bool constrained_edge[3];
-/// Flags to determine if an edge is a Delauney edge
-bool delaunay_edge[3];
-
-Point* GetPoint(int index);
-Point* PointCW(const Point& point);
-Point* PointCCW(const Point& point);
-Point* OppositePoint(Triangle& t, const Point& p);
-
-Triangle* GetNeighbor(int index);
-void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
-void MarkNeighbor(Triangle& t);
-
-void MarkConstrainedEdge(int index);
-void MarkConstrainedEdge(Edge& edge);
-void MarkConstrainedEdge(Point* p, Point* q);
-
-int Index(const Point* p);
-int EdgeIndex(const Point* p1, const Point* p2);
-
-Triangle* NeighborCW(const Point& point);
-Triangle* NeighborCCW(const Point& point);
-bool GetConstrainedEdgeCCW(const Point& p);
-bool GetConstrainedEdgeCW(const Point& p);
-void SetConstrainedEdgeCCW(const Point& p, bool ce);
-void SetConstrainedEdgeCW(const Point& p, bool ce);
-bool GetDelunayEdgeCCW(const Point& p);
-bool GetDelunayEdgeCW(const Point& p);
-void SetDelunayEdgeCCW(const Point& p, bool e);
-void SetDelunayEdgeCW(const Point& p, bool e);
-
-bool Contains(const Point* p);
-bool Contains(const Edge& e);
-bool Contains(const Point* p, const Point* q);
-void Legalize(Point& point);
-void Legalize(Point& opoint, Point& npoint);
-/**
- * Clears all references to all other triangles and points
- */
-void Clear();
-void ClearNeighbor(const Triangle *triangle);
-void ClearNeighbors();
-void ClearDelunayEdges();
-
-inline bool IsInterior();
-inline void IsInterior(bool b);
-
-Triangle& NeighborAcross(const Point& opoint);
-
-void DebugPrint();
-
-private:
-
-/// Triangle points
-Point* points_[3];
-/// Neighbor list
-Triangle* neighbors_[3];
-
-/// Has this triangle been marked as an interior triangle?
-bool interior_;
-};
-
-inline bool cmp(const Point* a, const Point* b)
-{
- if (a->y < b->y) {
- return true;
- } else if (a->y == b->y) {
- // Make sure q is point with greater x value
- if (a->x < b->x) {
- return true;
- }
- }
- return false;
-}
-
-/// Add two points_ component-wise.
-inline Point operator +(const Point& a, const Point& b)
-{
- return Point(a.x + b.x, a.y + b.y);
-}
-
-/// Subtract two points_ component-wise.
-inline Point operator -(const Point& a, const Point& b)
-{
- return Point(a.x - b.x, a.y - b.y);
-}
-
-/// Multiply point by scalar
-inline Point operator *(double s, const Point& a)
-{
- return Point(s * a.x, s * a.y);
-}
-
-inline bool operator ==(const Point& a, const Point& b)
-{
- return a.x == b.x && a.y == b.y;
-}
-
-inline bool operator !=(const Point& a, const Point& b)
-{
- return !(a.x == b.x) && !(a.y == b.y);
-}
-
-/// Peform the dot product on two vectors.
-inline double Dot(const Point& a, const Point& b)
-{
- return a.x * b.x + a.y * b.y;
-}
-
-/// Perform the cross product on two vectors. In 2D this produces a scalar.
-inline double Cross(const Point& a, const Point& b)
-{
- return a.x * b.y - a.y * b.x;
-}
-
-/// Perform the cross product on a point and a scalar. In 2D this produces
-/// a point.
-inline Point Cross(const Point& a, double s)
-{
- return Point(s * a.y, -s * a.x);
-}
-
-/// Perform the cross product on a scalar and a point. In 2D this produces
-/// a point.
-inline Point Cross(double s, const Point& a)
-{
- return Point(-s * a.y, s * a.x);
-}
-
-inline Point* Triangle::GetPoint(int index)
-{
- return points_[index];
-}
-
-inline Triangle* Triangle::GetNeighbor(int index)
-{
- return neighbors_[index];
-}
-
-inline bool Triangle::Contains(const Point* p)
-{
- return p == points_[0] || p == points_[1] || p == points_[2];
-}
-
-inline bool Triangle::Contains(const Edge& e)
-{
- return Contains(e.p) && Contains(e.q);
-}
-
-inline bool Triangle::Contains(const Point* p, const Point* q)
-{
- return Contains(p) && Contains(q);
-}
-
-inline bool Triangle::IsInterior()
-{
- return interior_;
-}
-
-inline void Triangle::IsInterior(bool b)
-{
- interior_ = b;
-}
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/utils.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/utils.h
deleted file mode 100644
index 2424c712c..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/common/utils.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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 UTILS_H
-#define UTILS_H
-
-// Otherwise #defines like M_PI are undeclared under Visual Studio
-#define _USE_MATH_DEFINES
-
-#include <exception>
-#include <math.h>
-
-// C99 removes M_PI from math.h
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338327
-#endif
-
-namespace p2t {
-
-const double PI_3div4 = 3 * M_PI / 4;
-const double PI_div2 = 1.57079632679489661923;
-const double EPSILON = 1e-12;
-
-enum Orientation { CW, CCW, COLLINEAR };
-
-/**
- * Forumla to calculate signed area<br>
- * Positive if CCW<br>
- * Negative if CW<br>
- * 0 if collinear<br>
- * <pre>
- * A[P1,P2,P3] = (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
- * = (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
- * </pre>
- */
-Orientation Orient2d(const Point& pa, const Point& pb, const Point& pc)
-{
- double detleft = (pa.x - pc.x) * (pb.y - pc.y);
- double detright = (pa.y - pc.y) * (pb.x - pc.x);
- double val = detleft - detright;
- if (val > -EPSILON && val < EPSILON) {
- return COLLINEAR;
- } else if (val > 0) {
- return CCW;
- }
- return CW;
-}
-
-/*
-bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
-{
- double pdx = pd.x;
- double pdy = pd.y;
- double adx = pa.x - pdx;
- double ady = pa.y - pdy;
- double bdx = pb.x - pdx;
- double bdy = pb.y - pdy;
-
- double adxbdy = adx * bdy;
- double bdxady = bdx * ady;
- double oabd = adxbdy - bdxady;
-
- if (oabd <= EPSILON) {
- return false;
- }
-
- double cdx = pc.x - pdx;
- double cdy = pc.y - pdy;
-
- double cdxady = cdx * ady;
- double adxcdy = adx * cdy;
- double ocad = cdxady - adxcdy;
-
- if (ocad <= EPSILON) {
- return false;
- }
-
- return true;
-}
-
-*/
-
-bool InScanArea(const Point& pa, const Point& pb, const Point& pc, const Point& pd)
-{
- double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y);
- if (oadb >= -EPSILON) {
- return false;
- }
-
- double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y);
- if (oadc <= EPSILON) {
- return false;
- }
- return true;
-}
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/poly2tri.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/poly2tri.h
deleted file mode 100644
index ba5cc159e..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/poly2tri.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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 POLY2TRI_H
-#define POLY2TRI_H
-
-#include "common/shapes.h"
-#include "sweep/cdt.h"
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.cc
deleted file mode 100644
index 9739babce..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-#include "advancing_front.h"
-
-namespace p2t {
-
-AdvancingFront::AdvancingFront(Node& head, Node& tail)
-{
- head_ = &head;
- tail_ = &tail;
- search_node_ = &head;
-}
-
-Node* AdvancingFront::LocateNode(double x)
-{
- Node* node = search_node_;
-
- if (x < node->value) {
- while ((node = node->prev) != NULL) {
- if (x >= node->value) {
- search_node_ = node;
- return node;
- }
- }
- } else {
- while ((node = node->next) != NULL) {
- if (x < node->value) {
- search_node_ = node->prev;
- return node->prev;
- }
- }
- }
- return NULL;
-}
-
-Node* AdvancingFront::FindSearchNode(double x)
-{
- (void)x; // suppress compiler warnings "unused parameter 'x'"
- // TODO: implement BST index
- return search_node_;
-}
-
-Node* AdvancingFront::LocatePoint(const Point* point)
-{
- const double px = point->x;
- Node* node = FindSearchNode(px);
- const double nx = node->point->x;
-
- if (px == nx) {
- if (point != node->point) {
- // We might have two nodes with same x value for a short time
- if (point == node->prev->point) {
- node = node->prev;
- } else if (point == node->next->point) {
- node = node->next;
- } else {
- assert(0);
- }
- }
- } else if (px < nx) {
- while ((node = node->prev) != NULL) {
- if (point == node->point) {
- break;
- }
- }
- } else {
- while ((node = node->next) != NULL) {
- if (point == node->point)
- break;
- }
- }
- if(node) search_node_ = node;
- return node;
-}
-
-AdvancingFront::~AdvancingFront()
-{
-}
-
-}
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.h
deleted file mode 100644
index 3bfec5368..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/advancing_front.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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 ADVANCED_FRONT_H
-#define ADVANCED_FRONT_H
-
-#include "../common/shapes.h"
-
-namespace p2t {
-
-struct Node;
-
-// Advancing front node
-struct Node {
- Point* point;
- Triangle* triangle;
-
- Node* next;
- Node* prev;
-
- double value;
-
- Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), value(p.x)
- {
- }
-
- Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), prev(NULL), value(p.x)
- {
- }
-
-};
-
-// Advancing front
-class AdvancingFront {
-public:
-
-AdvancingFront(Node& head, Node& tail);
-// Destructor
-~AdvancingFront();
-
-Node* head();
-void set_head(Node* node);
-Node* tail();
-void set_tail(Node* node);
-Node* search();
-void set_search(Node* node);
-
-/// Locate insertion point along advancing front
-Node* LocateNode(double x);
-
-Node* LocatePoint(const Point* point);
-
-private:
-
-Node* head_, *tail_, *search_node_;
-
-Node* FindSearchNode(double x);
-};
-
-inline Node* AdvancingFront::head()
-{
- return head_;
-}
-inline void AdvancingFront::set_head(Node* node)
-{
- head_ = node;
-}
-
-inline Node* AdvancingFront::tail()
-{
- return tail_;
-}
-inline void AdvancingFront::set_tail(Node* node)
-{
- tail_ = node;
-}
-
-inline Node* AdvancingFront::search()
-{
- return search_node_;
-}
-
-inline void AdvancingFront::set_search(Node* node)
-{
- search_node_ = node;
-}
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.cc
deleted file mode 100644
index b79f5a8de..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-#include "cdt.h"
-
-namespace p2t {
-
-CDT::CDT(const std::vector<Point*>& polyline)
-{
- sweep_context_ = new SweepContext(polyline);
- sweep_ = new Sweep;
-}
-
-void CDT::AddHole(const std::vector<Point*>& polyline)
-{
- sweep_context_->AddHole(polyline);
-}
-
-void CDT::AddPoint(Point* point) {
- sweep_context_->AddPoint(point);
-}
-
-void CDT::Triangulate()
-{
- sweep_->Triangulate(*sweep_context_);
-}
-
-std::vector<p2t::Triangle*> CDT::GetTriangles()
-{
- return sweep_context_->GetTriangles();
-}
-
-std::list<p2t::Triangle*> CDT::GetMap()
-{
- return sweep_context_->GetMap();
-}
-
-CDT::~CDT()
-{
- delete sweep_context_;
- delete sweep_;
-}
-
-}
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.h
deleted file mode 100644
index 4a9a292d3..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/cdt.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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 CDT_H
-#define CDT_H
-
-#include "advancing_front.h"
-#include "sweep_context.h"
-#include "sweep.h"
-
-/**
- *
- * @author Mason Green <mason.green@gmail.com>
- *
- */
-
-namespace p2t {
-
-class CDT
-{
-public:
-
- /**
- * Constructor - add polyline with non repeating points
- *
- * @param polyline
- */
- CDT(const std::vector<Point*>& polyline);
-
- /**
- * Destructor - clean up memory
- */
- ~CDT();
-
- /**
- * Add a hole
- *
- * @param polyline
- */
- void AddHole(const std::vector<Point*>& polyline);
-
- /**
- * Add a steiner point
- *
- * @param point
- */
- void AddPoint(Point* point);
-
- /**
- * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
- */
- void Triangulate();
-
- /**
- * Get CDT triangles
- */
- std::vector<Triangle*> GetTriangles();
-
- /**
- * Get triangle map
- */
- std::list<Triangle*> GetMap();
-
- private:
-
- /**
- * Internals
- */
-
- SweepContext* sweep_context_;
- Sweep* sweep_;
-
-};
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc
deleted file mode 100644
index 826905ceb..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.cc
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-#include <stdexcept>
-#include "sweep.h"
-#include "sweep_context.h"
-#include "advancing_front.h"
-#include "../common/utils.h"
-
-namespace p2t {
-
-// Triangulate simple polygon with holes
-void Sweep::Triangulate(SweepContext& tcx)
-{
- tcx.InitTriangulation();
- tcx.CreateAdvancingFront(nodes_);
- // Sweep points; build mesh
- SweepPoints(tcx);
- // Clean up
- FinalizationPolygon(tcx);
-}
-
-void Sweep::SweepPoints(SweepContext& tcx)
-{
- for (size_t i = 1; i < tcx.point_count(); i++) {
- Point& point = *tcx.GetPoint(i);
- Node* node = &PointEvent(tcx, point);
- for (unsigned int i = 0; i < point.edge_list.size(); i++) {
- EdgeEvent(tcx, point.edge_list[i], node);
- }
- }
-}
-
-void Sweep::FinalizationPolygon(SweepContext& tcx)
-{
- // Get an Internal triangle to start with
- Triangle* t = tcx.front()->head()->next->triangle;
- Point* p = tcx.front()->head()->next->point;
- while (!t->GetConstrainedEdgeCW(*p)) {
- t = t->NeighborCCW(*p);
- }
-
- // Collect interior triangles constrained by edges
- tcx.MeshClean(*t);
-}
-
-Node& Sweep::PointEvent(SweepContext& tcx, Point& point)
-{
- Node& node = tcx.LocateNode(point);
- Node& new_node = NewFrontTriangle(tcx, point, node);
-
- // Only need to check +epsilon since point never have smaller
- // x value than node due to how we fetch nodes from the front
- if (point.x <= node.point->x + EPSILON) {
- Fill(tcx, node);
- }
-
- //tcx.AddNode(new_node);
-
- FillAdvancingFront(tcx, new_node);
- return new_node;
-}
-
-void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
-{
- tcx.edge_event.constrained_edge = edge;
- tcx.edge_event.right = (edge->p->x > edge->q->x);
-
- if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) {
- return;
- }
-
- // For now we will do all needed filling
- // TODO: integrate with flip process might give some better performance
- // but for now this avoid the issue with cases that needs both flips and fills
- FillEdgeEvent(tcx, edge, node);
- EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q);
-}
-
-void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
-{
- if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {
- return;
- }
-
- Point* p1 = triangle->PointCCW(point);
- Orientation o1 = Orient2d(eq, *p1, ep);
- if (o1 == COLLINEAR) {
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error("EdgeEvent - collinear points not supported");
- if( triangle->Contains(&eq, p1)) {
- triangle->MarkConstrainedEdge(&eq, p1 );
- // We are modifying the constraint maybe it would be better to
- // not change the given constraint and just keep a variable for the new constraint
- tcx.edge_event.constrained_edge->q = p1;
- triangle = &triangle->NeighborAcross(point);
- EdgeEvent( tcx, ep, *p1, triangle, *p1 );
- } else {
- // ASSIMP_CHANGE (aramis_acg)
- std::runtime_error("EdgeEvent - collinear points not supported");
- }
- return;
- }
-
- Point* p2 = triangle->PointCW(point);
- Orientation o2 = Orient2d(eq, *p2, ep);
- if (o2 == COLLINEAR) {
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error("EdgeEvent - collinear points not supported");
-
- if( triangle->Contains(&eq, p2)) {
- triangle->MarkConstrainedEdge(&eq, p2 );
- // We are modifying the constraint maybe it would be better to
- // not change the given constraint and just keep a variable for the new constraint
- tcx.edge_event.constrained_edge->q = p2;
- triangle = &triangle->NeighborAcross(point);
- EdgeEvent( tcx, ep, *p2, triangle, *p2 );
- } else {
- // ASSIMP_CHANGE (aramis_acg)
- throw std::runtime_error("EdgeEvent - collinear points not supported");
- }
- return;
- }
-
- if (o1 == o2) {
- // Need to decide if we are rotating CW or CCW to get to a triangle
- // that will cross edge
- if (o1 == CW) {
- triangle = triangle->NeighborCCW(point);
- } else{
- triangle = triangle->NeighborCW(point);
- }
- EdgeEvent(tcx, ep, eq, triangle, point);
- } else {
- // This triangle crosses constraint so lets flippin start!
- FlipEdgeEvent(tcx, ep, eq, triangle, point);
- }
-}
-
-bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)
-{
- const int index = triangle.EdgeIndex(&ep, &eq);
-
- if (index != -1) {
- triangle.MarkConstrainedEdge(index);
- Triangle* t = triangle.GetNeighbor(index);
- if (t) {
- t->MarkConstrainedEdge(&ep, &eq);
- }
- return true;
- }
- return false;
-}
-
-Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node)
-{
- Triangle* triangle = new Triangle(point, *node.point, *node.next->point);
-
- triangle->MarkNeighbor(*node.triangle);
- tcx.AddToMap(triangle);
-
- Node* new_node = new Node(point);
- nodes_.push_back(new_node);
-
- new_node->next = node.next;
- new_node->prev = &node;
- node.next->prev = new_node;
- node.next = new_node;
-
- if (!Legalize(tcx, *triangle)) {
- tcx.MapTriangleToNodes(*triangle);
- }
-
- return *new_node;
-}
-
-void Sweep::Fill(SweepContext& tcx, Node& node)
-{
- Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point);
-
- // TODO: should copy the constrained_edge value from neighbor triangles
- // for now constrained_edge values are copied during the legalize
- triangle->MarkNeighbor(*node.prev->triangle);
- triangle->MarkNeighbor(*node.triangle);
-
- tcx.AddToMap(triangle);
-
- // Update the advancing front
- node.prev->next = node.next;
- node.next->prev = node.prev;
-
- // If it was legalized the triangle has already been mapped
- if (!Legalize(tcx, *triangle)) {
- tcx.MapTriangleToNodes(*triangle);
- }
-
-}
-
-void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
-{
-
- // Fill right holes
- Node* node = n.next;
-
- while (node->next) {
- // if HoleAngle exceeds 90 degrees then break.
- if (LargeHole_DontFill(node)) break;
- Fill(tcx, *node);
- node = node->next;
- }
-
- // Fill left holes
- node = n.prev;
-
- while (node->prev) {
- // if HoleAngle exceeds 90 degrees then break.
- if (LargeHole_DontFill(node)) break;
- Fill(tcx, *node);
- node = node->prev;
- }
-
- // Fill right basins
- if (n.next && n.next->next) {
- const double angle = BasinAngle(n);
- if (angle < PI_3div4) {
- FillBasin(tcx, n);
- }
- }
-}
-
-// True if HoleAngle exceeds 90 degrees.
-bool Sweep::LargeHole_DontFill(const Node* node) const {
-
- const Node* nextNode = node->next;
- const Node* prevNode = node->prev;
- if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point))
- return false;
-
- // Check additional points on front.
- const Node* next2Node = nextNode->next;
- // "..Plus.." because only want angles on same side as point being added.
- if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point))
- return false;
-
- const Node* prev2Node = prevNode->prev;
- // "..Plus.." because only want angles on same side as point being added.
- if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point))
- return false;
-
- return true;
-}
-
-bool Sweep::AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const {
- const double angle = Angle(origin, pa, pb);
- return ((angle > PI_div2) || (angle < -PI_div2));
-}
-
-bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const {
- const double angle = Angle(origin, pa, pb);
- return (angle > PI_div2) || (angle < 0);
-}
-
-double Sweep::Angle(const Point* origin, const Point* pa, const Point* pb) const {
- /* Complex plane
- * ab = cosA +i*sinA
- * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
- * atan2(y,x) computes the principal value of the argument function
- * applied to the complex number x+iy
- * Where x = ax*bx + ay*by
- * y = ax*by - ay*bx
- */
- const double px = origin->x;
- const double py = origin->y;
- const double ax = pa->x- px;
- const double ay = pa->y - py;
- const double bx = pb->x - px;
- const double by = pb->y - py;
- const double x = ax * by - ay * bx;
- const double y = ax * bx + ay * by;
- return atan2(x, y);
-}
-
-double Sweep::BasinAngle(const Node& node) const
-{
- const double ax = node.point->x - node.next->next->point->x;
- const double ay = node.point->y - node.next->next->point->y;
- return atan2(ay, ax);
-}
-
-double Sweep::HoleAngle(const Node& node) const
-{
- /* Complex plane
- * ab = cosA +i*sinA
- * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
- * atan2(y,x) computes the principal value of the argument function
- * applied to the complex number x+iy
- * Where x = ax*bx + ay*by
- * y = ax*by - ay*bx
- */
- const double ax = node.next->point->x - node.point->x;
- const double ay = node.next->point->y - node.point->y;
- const double bx = node.prev->point->x - node.point->x;
- const double by = node.prev->point->y - node.point->y;
- return atan2(ax * by - ay * bx, ax * bx + ay * by);
-}
-
-bool Sweep::Legalize(SweepContext& tcx, Triangle& t)
-{
- // To legalize a triangle we start by finding if any of the three edges
- // violate the Delaunay condition
- for (int i = 0; i < 3; i++) {
- if (t.delaunay_edge[i])
- continue;
-
- Triangle* ot = t.GetNeighbor(i);
-
- if (ot) {
- Point* p = t.GetPoint(i);
- Point* op = ot->OppositePoint(t, *p);
- int oi = ot->Index(op);
-
- // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
- // then we should not try to legalize
- if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) {
- t.constrained_edge[i] = ot->constrained_edge[oi];
- continue;
- }
-
- bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op);
-
- if (inside) {
- // Lets mark this shared edge as Delaunay
- t.delaunay_edge[i] = true;
- ot->delaunay_edge[oi] = true;
-
- // Lets rotate shared edge one vertex CW to legalize it
- RotateTrianglePair(t, *p, *ot, *op);
-
- // We now got one valid Delaunay Edge shared by two triangles
- // This gives us 4 new edges to check for Delaunay
-
- // Make sure that triangle to node mapping is done only one time for a specific triangle
- bool not_legalized = !Legalize(tcx, t);
- if (not_legalized) {
- tcx.MapTriangleToNodes(t);
- }
-
- not_legalized = !Legalize(tcx, *ot);
- if (not_legalized)
- tcx.MapTriangleToNodes(*ot);
-
- // Reset the Delaunay edges, since they only are valid Delaunay edges
- // until we add a new triangle or point.
- // XXX: need to think about this. Can these edges be tried after we
- // return to previous recursive level?
- t.delaunay_edge[i] = false;
- ot->delaunay_edge[oi] = false;
-
- // If triangle have been legalized no need to check the other edges since
- // the recursive legalization will handles those so we can end here.
- return true;
- }
- }
- }
- return false;
-}
-
-bool Sweep::Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const
-{
- const double adx = pa.x - pd.x;
- const double ady = pa.y - pd.y;
- const double bdx = pb.x - pd.x;
- const double bdy = pb.y - pd.y;
-
- const double adxbdy = adx * bdy;
- const double bdxady = bdx * ady;
- const double oabd = adxbdy - bdxady;
-
- if (oabd <= 0)
- return false;
-
- const double cdx = pc.x - pd.x;
- const double cdy = pc.y - pd.y;
-
- const double cdxady = cdx * ady;
- const double adxcdy = adx * cdy;
- const double ocad = cdxady - adxcdy;
-
- if (ocad <= 0)
- return false;
-
- const double bdxcdy = bdx * cdy;
- const double cdxbdy = cdx * bdy;
-
- const double alift = adx * adx + ady * ady;
- const double blift = bdx * bdx + bdy * bdy;
- const double clift = cdx * cdx + cdy * cdy;
-
- const double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
-
- return det > 0;
-}
-
-void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const
-{
- Triangle* n1, *n2, *n3, *n4;
- n1 = t.NeighborCCW(p);
- n2 = t.NeighborCW(p);
- n3 = ot.NeighborCCW(op);
- n4 = ot.NeighborCW(op);
-
- bool ce1, ce2, ce3, ce4;
- ce1 = t.GetConstrainedEdgeCCW(p);
- ce2 = t.GetConstrainedEdgeCW(p);
- ce3 = ot.GetConstrainedEdgeCCW(op);
- ce4 = ot.GetConstrainedEdgeCW(op);
-
- bool de1, de2, de3, de4;
- de1 = t.GetDelunayEdgeCCW(p);
- de2 = t.GetDelunayEdgeCW(p);
- de3 = ot.GetDelunayEdgeCCW(op);
- de4 = ot.GetDelunayEdgeCW(op);
-
- t.Legalize(p, op);
- ot.Legalize(op, p);
-
- // Remap delaunay_edge
- ot.SetDelunayEdgeCCW(p, de1);
- t.SetDelunayEdgeCW(p, de2);
- t.SetDelunayEdgeCCW(op, de3);
- ot.SetDelunayEdgeCW(op, de4);
-
- // Remap constrained_edge
- ot.SetConstrainedEdgeCCW(p, ce1);
- t.SetConstrainedEdgeCW(p, ce2);
- t.SetConstrainedEdgeCCW(op, ce3);
- ot.SetConstrainedEdgeCW(op, ce4);
-
- // Remap neighbors
- // XXX: might optimize the markNeighbor by keeping track of
- // what side should be assigned to what neighbor after the
- // rotation. Now mark neighbor does lots of testing to find
- // the right side.
- t.ClearNeighbors();
- ot.ClearNeighbors();
- if (n1) ot.MarkNeighbor(*n1);
- if (n2) t.MarkNeighbor(*n2);
- if (n3) t.MarkNeighbor(*n3);
- if (n4) ot.MarkNeighbor(*n4);
- t.MarkNeighbor(ot);
-}
-
-void Sweep::FillBasin(SweepContext& tcx, Node& node)
-{
- if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
- tcx.basin.left_node = node.next->next;
- } else {
- tcx.basin.left_node = node.next;
- }
-
- // Find the bottom and right node
- tcx.basin.bottom_node = tcx.basin.left_node;
- while (tcx.basin.bottom_node->next
- && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) {
- tcx.basin.bottom_node = tcx.basin.bottom_node->next;
- }
- if (tcx.basin.bottom_node == tcx.basin.left_node) {
- // No valid basin
- return;
- }
-
- tcx.basin.right_node = tcx.basin.bottom_node;
- while (tcx.basin.right_node->next
- && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) {
- tcx.basin.right_node = tcx.basin.right_node->next;
- }
- if (tcx.basin.right_node == tcx.basin.bottom_node) {
- // No valid basins
- return;
- }
-
- tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x;
- tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y;
-
- FillBasinReq(tcx, tcx.basin.bottom_node);
-}
-
-void Sweep::FillBasinReq(SweepContext& tcx, Node* node)
-{
- // if shallow stop filling
- if (IsShallow(tcx, *node)) {
- return;
- }
-
- Fill(tcx, *node);
-
- if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) {
- return;
- } else if (node->prev == tcx.basin.left_node) {
- Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point);
- if (o == CW) {
- return;
- }
- node = node->next;
- } else if (node->next == tcx.basin.right_node) {
- Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point);
- if (o == CCW) {
- return;
- }
- node = node->prev;
- } else {
- // Continue with the neighbor node with lowest Y value
- if (node->prev->point->y < node->next->point->y) {
- node = node->prev;
- } else {
- node = node->next;
- }
- }
-
- FillBasinReq(tcx, node);
-}
-
-bool Sweep::IsShallow(SweepContext& tcx, Node& node)
-{
- double height;
-
- if (tcx.basin.left_highest) {
- height = tcx.basin.left_node->point->y - node.point->y;
- } else {
- height = tcx.basin.right_node->point->y - node.point->y;
- }
-
- // if shallow stop filling
- if (tcx.basin.width > height) {
- return true;
- }
- return false;
-}
-
-void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
-{
- if (tcx.edge_event.right) {
- FillRightAboveEdgeEvent(tcx, edge, node);
- } else {
- FillLeftAboveEdgeEvent(tcx, edge, node);
- }
-}
-
-void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
-{
- while (node->next->point->x < edge->p->x) {
- // Check if next node is below the edge
- if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) {
- FillRightBelowEdgeEvent(tcx, edge, *node);
- } else {
- node = node->next;
- }
- }
-}
-
-void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- if (node.point->x < edge->p->x) {
- if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
- // Concave
- FillRightConcaveEdgeEvent(tcx, edge, node);
- } else{
- // Convex
- FillRightConvexEdgeEvent(tcx, edge, node);
- // Retry this one
- FillRightBelowEdgeEvent(tcx, edge, node);
- }
- }
-}
-
-void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- Fill(tcx, *node.next);
- if (node.next->point != edge->p) {
- // Next above or below edge?
- if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
- // Below
- if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
- // Next is concave
- FillRightConcaveEdgeEvent(tcx, edge, node);
- } else {
- // Next is convex
- }
- }
- }
-
-}
-
-void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- // Next concave or convex?
- if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) {
- // Concave
- FillRightConcaveEdgeEvent(tcx, edge, *node.next);
- } else{
- // Convex
- // Next above or below edge?
- if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) {
- // Below
- FillRightConvexEdgeEvent(tcx, edge, *node.next);
- } else{
- // Above
- }
- }
-}
-
-void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
-{
- while (node->prev->point->x > edge->p->x) {
- // Check if next node is below the edge
- if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) {
- FillLeftBelowEdgeEvent(tcx, edge, *node);
- } else {
- node = node->prev;
- }
- }
-}
-
-void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- if (node.point->x > edge->p->x) {
- if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
- // Concave
- FillLeftConcaveEdgeEvent(tcx, edge, node);
- } else {
- // Convex
- FillLeftConvexEdgeEvent(tcx, edge, node);
- // Retry this one
- FillLeftBelowEdgeEvent(tcx, edge, node);
- }
- }
-}
-
-void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- // Next concave or convex?
- if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) {
- // Concave
- FillLeftConcaveEdgeEvent(tcx, edge, *node.prev);
- } else{
- // Convex
- // Next above or below edge?
- if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) {
- // Below
- FillLeftConvexEdgeEvent(tcx, edge, *node.prev);
- } else{
- // Above
- }
- }
-}
-
-void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
-{
- Fill(tcx, *node.prev);
- if (node.prev->point != edge->p) {
- // Next above or below edge?
- if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
- // Below
- if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
- // Next is concave
- FillLeftConcaveEdgeEvent(tcx, edge, node);
- } else{
- // Next is convex
- }
- }
- }
-
-}
-
-void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p)
-{
- Triangle& ot = t->NeighborAcross(p);
- Point& op = *ot.OppositePoint(*t, p);
-
- if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) {
- // Lets rotate shared edge one vertex CW
- RotateTrianglePair(*t, p, ot, op);
- tcx.MapTriangleToNodes(*t);
- tcx.MapTriangleToNodes(ot);
-
- if (p == eq && op == ep) {
- if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) {
- t->MarkConstrainedEdge(&ep, &eq);
- ot.MarkConstrainedEdge(&ep, &eq);
- Legalize(tcx, *t);
- Legalize(tcx, ot);
- } else {
- // XXX: I think one of the triangles should be legalized here?
- }
- } else {
- Orientation o = Orient2d(eq, op, ep);
- t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op);
- FlipEdgeEvent(tcx, ep, eq, t, p);
- }
- } else {
- Point& newP = NextFlipPoint(ep, eq, ot, op);
- FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP);
- EdgeEvent(tcx, ep, eq, t, p);
- }
-}
-
-Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op)
-{
- if (o == CCW) {
- // ot is not crossing edge after flip
- int edge_index = ot.EdgeIndex(&p, &op);
- ot.delaunay_edge[edge_index] = true;
- Legalize(tcx, ot);
- ot.ClearDelunayEdges();
- return t;
- }
-
- // t is not crossing edge after flip
- int edge_index = t.EdgeIndex(&p, &op);
-
- t.delaunay_edge[edge_index] = true;
- Legalize(tcx, t);
- t.ClearDelunayEdges();
- return ot;
-}
-
-Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)
-{
- Orientation o2d = Orient2d(eq, op, ep);
- if (o2d == CW) {
- // Right
- return *ot.PointCCW(op);
- } else if (o2d == CCW) {
- // Left
- return *ot.PointCW(op);
- }
- throw std::runtime_error("[Unsupported] Opposing point on constrained edge");
-}
-
-void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,
- Triangle& t, Point& p)
-{
- Triangle& ot = t.NeighborAcross(p);
- Point& op = *ot.OppositePoint(t, p);
-
- if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) {
- // flip with new edge op->eq
- FlipEdgeEvent(tcx, eq, op, &ot, op);
- // TODO: Actually I just figured out that it should be possible to
- // improve this by getting the next ot and op before the the above
- // flip and continue the flipScanEdgeEvent here
- // set new ot and op here and loop back to inScanArea test
- // also need to set a new flip_triangle first
- // Turns out at first glance that this is somewhat complicated
- // so it will have to wait.
- } else{
- Point& newP = NextFlipPoint(ep, eq, ot, op);
- FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);
- }
-}
-
-Sweep::~Sweep() {
-
- // Clean up memory
- for(size_t i = 0; i < nodes_.size(); i++) {
- delete nodes_[i];
- }
-
-}
-
-}
-
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.h
deleted file mode 100644
index ad429fd96..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep.h
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-/**
- * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and
- * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
- * International Journal of Geographical Information Science
- *
- * "FlipScan" Constrained Edge Algorithm invented by Thomas ?hl?n, thahlen@gmail.com
- */
-
-#ifndef SWEEP_H
-#define SWEEP_H
-
-#include <vector>
-
-namespace p2t {
-
-class SweepContext;
-struct Node;
-struct Point;
-struct Edge;
-class Triangle;
-
-class Sweep
-{
-public:
-
- /**
- * Triangulate
- *
- * @param tcx
- */
- void Triangulate(SweepContext& tcx);
-
- /**
- * Destructor - clean up memory
- */
- ~Sweep();
-
-private:
-
- /**
- * Start sweeping the Y-sorted point set from bottom to top
- *
- * @param tcx
- */
- void SweepPoints(SweepContext& tcx);
-
- /**
- * Find closes node to the left of the new point and
- * create a new triangle. If needed new holes and basins
- * will be filled to.
- *
- * @param tcx
- * @param point
- * @return
- */
- Node& PointEvent(SweepContext& tcx, Point& point);
-
- /**
- *
- *
- * @param tcx
- * @param edge
- * @param node
- */
- void EdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
-
- void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point);
-
- /**
- * Creates a new front triangle and legalize it
- *
- * @param tcx
- * @param point
- * @param node
- * @return
- */
- Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node);
-
- /**
- * Adds a triangle to the advancing front to fill a hole.
- * @param tcx
- * @param node - middle node, that is the bottom of the hole
- */
- void Fill(SweepContext& tcx, Node& node);
-
- /**
- * Returns true if triangle was legalized
- */
- bool Legalize(SweepContext& tcx, Triangle& t);
-
- /**
- * <b>Requirement</b>:<br>
- * 1. a,b and c form a triangle.<br>
- * 2. a and d is know to be on opposite side of bc<br>
- * <pre>
- * a
- * +
- * / \
- * / \
- * b/ \c
- * +-------+
- * / d \
- * / \
- * </pre>
- * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
- * a,b and c<br>
- * d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
- * This preknowledge gives us a way to optimize the incircle test
- * @param a - triangle point, opposite d
- * @param b - triangle point
- * @param c - triangle point
- * @param d - point opposite a
- * @return true if d is inside circle, false if on circle edge
- */
- bool Incircle(const Point& pa, const Point& pb, const Point& pc, const Point& pd) const;
-
- /**
- * Rotates a triangle pair one vertex CW
- *<pre>
- * n2 n2
- * P +-----+ P +-----+
- * | t /| |\ t |
- * | / | | \ |
- * n1| / |n3 n1| \ |n3
- * | / | after CW | \ |
- * |/ oT | | oT \|
- * +-----+ oP +-----+
- * n4 n4
- * </pre>
- */
- void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op) const;
-
- /**
- * Fills holes in the Advancing Front
- *
- *
- * @param tcx
- * @param n
- */
- void FillAdvancingFront(SweepContext& tcx, Node& n);
-
- // Decision-making about when to Fill hole.
- // Contributed by ToolmakerSteve2
- bool LargeHole_DontFill(const Node* node) const;
- bool AngleExceeds90Degrees(const Point* origin, const Point* pa, const Point* pb) const;
- bool AngleExceedsPlus90DegreesOrIsNegative(const Point* origin, const Point* pa, const Point* pb) const;
- double Angle(const Point* origin, const Point* pa, const Point* pb) const;
-
- /**
- *
- * @param node - middle node
- * @return the angle between 3 front nodes
- */
- double HoleAngle(const Node& node) const;
-
- /**
- * The basin angle is decided against the horizontal line [1,0]
- */
- double BasinAngle(const Node& node) const;
-
- /**
- * Fills a basin that has formed on the Advancing Front to the right
- * of given node.<br>
- * First we decide a left,bottom and right node that forms the
- * boundaries of the basin. Then we do a reqursive fill.
- *
- * @param tcx
- * @param node - starting node, this or next node will be left node
- */
- void FillBasin(SweepContext& tcx, Node& node);
-
- /**
- * Recursive algorithm to fill a Basin with triangles
- *
- * @param tcx
- * @param node - bottom_node
- * @param cnt - counter used to alternate on even and odd numbers
- */
- void FillBasinReq(SweepContext& tcx, Node* node);
-
- bool IsShallow(SweepContext& tcx, Node& node);
-
- bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq);
-
- void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
-
- void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
-
- void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);
-
- void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);
-
- void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p);
-
- /**
- * After a flip we have two triangles and know that only one will still be
- * intersecting the edge. So decide which to contiune with and legalize the other
- *
- * @param tcx
- * @param o - should be the result of an orient2d( eq, op, ep )
- * @param t - triangle 1
- * @param ot - triangle 2
- * @param p - a point shared by both triangles
- * @param op - another point shared by both triangles
- * @return returns the triangle still intersecting the edge
- */
- Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op);
-
- /**
- * When we need to traverse from one triangle to the next we need
- * the point in current triangle that is the opposite point to the next
- * triangle.
- *
- * @param ep
- * @param eq
- * @param ot
- * @param op
- * @return
- */
- Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op);
-
- /**
- * Scan part of the FlipScan algorithm<br>
- * When a triangle pair isn't flippable we will scan for the next
- * point that is inside the flip triangle scan area. When found
- * we generate a new flipEdgeEvent
- *
- * @param tcx
- * @param ep - last point on the edge we are traversing
- * @param eq - first point on the edge we are traversing
- * @param flipTriangle - the current triangle sharing the point eq with edge
- * @param t
- * @param p
- */
- void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p);
-
- void FinalizationPolygon(SweepContext& tcx);
-
- std::vector<Node*> nodes_;
-
-};
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc
deleted file mode 100644
index a9f1fdf8e..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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.
- */
-#include "sweep_context.h"
-#include <algorithm>
-#include "advancing_front.h"
-
-namespace p2t {
-
-SweepContext::SweepContext(const std::vector<Point*>& polyline) : points_(polyline),
- front_(0),
- head_(0),
- tail_(0),
- af_head_(0),
- af_middle_(0),
- af_tail_(0)
-{
- InitEdges(points_);
-}
-
-void SweepContext::AddHole(const std::vector<Point*>& polyline)
-{
- InitEdges(polyline);
- for(unsigned int i = 0; i < polyline.size(); i++) {
- points_.push_back(polyline[i]);
- }
-}
-
-void SweepContext::AddPoint(Point* point) {
- points_.push_back(point);
-}
-
-std::vector<Triangle*> &SweepContext::GetTriangles()
-{
- return triangles_;
-}
-
-std::list<Triangle*> &SweepContext::GetMap()
-{
- return map_;
-}
-
-void SweepContext::InitTriangulation()
-{
- double xmax(points_[0]->x), xmin(points_[0]->x);
- double ymax(points_[0]->y), ymin(points_[0]->y);
-
- // Calculate bounds.
- for (unsigned int i = 0; i < points_.size(); i++) {
- Point& p = *points_[i];
- if (p.x > xmax)
- xmax = p.x;
- if (p.x < xmin)
- xmin = p.x;
- if (p.y > ymax)
- ymax = p.y;
- if (p.y < ymin)
- ymin = p.y;
- }
-
- double dx = kAlpha * (xmax - xmin);
- double dy = kAlpha * (ymax - ymin);
- head_ = new Point(xmax + dx, ymin - dy);
- tail_ = new Point(xmin - dx, ymin - dy);
-
- // Sort points along y-axis
- std::sort(points_.begin(), points_.end(), cmp);
-
-}
-
-void SweepContext::InitEdges(const std::vector<Point*>& polyline)
-{
- size_t num_points = polyline.size();
- for (size_t i = 0; i < num_points; i++) {
- size_t j = i < num_points - 1 ? i + 1 : 0;
- edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
- }
-}
-
-Point* SweepContext::GetPoint(size_t index)
-{
- return points_[index];
-}
-
-void SweepContext::AddToMap(Triangle* triangle)
-{
- map_.push_back(triangle);
-}
-
-Node& SweepContext::LocateNode(const Point& point)
-{
- // TODO implement search tree
- return *front_->LocateNode(point.x);
-}
-
-void SweepContext::CreateAdvancingFront(const std::vector<Node*>& nodes)
-{
-
- (void) nodes;
- // Initial triangle
- Triangle* triangle = new Triangle(*points_[0], *tail_, *head_);
-
- map_.push_back(triangle);
-
- af_head_ = new Node(*triangle->GetPoint(1), *triangle);
- af_middle_ = new Node(*triangle->GetPoint(0), *triangle);
- af_tail_ = new Node(*triangle->GetPoint(2));
- front_ = new AdvancingFront(*af_head_, *af_tail_);
-
- // TODO: More intuitive if head is middles next and not previous?
- // so swap head and tail
- af_head_->next = af_middle_;
- af_middle_->next = af_tail_;
- af_middle_->prev = af_head_;
- af_tail_->prev = af_middle_;
-}
-
-void SweepContext::RemoveNode(Node* node)
-{
- delete node;
-}
-
-void SweepContext::MapTriangleToNodes(Triangle& t)
-{
- for (int i = 0; i < 3; i++) {
- if (!t.GetNeighbor(i)) {
- Node* n = front_->LocatePoint(t.PointCW(*t.GetPoint(i)));
- if (n)
- n->triangle = &t;
- }
- }
-}
-
-void SweepContext::RemoveFromMap(Triangle* triangle)
-{
- map_.remove(triangle);
-}
-
-void SweepContext::MeshClean(Triangle& triangle)
-{
- std::vector<Triangle *> triangles;
- triangles.push_back(&triangle);
-
- while(!triangles.empty()){
- Triangle *t = triangles.back();
- triangles.pop_back();
-
- if (t != NULL && !t->IsInterior()) {
- t->IsInterior(true);
- triangles_.push_back(t);
- for (int i = 0; i < 3; i++) {
- if (!t->constrained_edge[i])
- triangles.push_back(t->GetNeighbor(i));
- }
- }
- }
-}
-
-SweepContext::~SweepContext()
-{
-
- // Clean up memory
-
- delete head_;
- delete tail_;
- delete front_;
- delete af_head_;
- delete af_middle_;
- delete af_tail_;
-
- typedef std::list<Triangle*> type_list;
-
- for(type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
- Triangle* ptr = *iter;
- delete ptr;
- }
-
- for(unsigned int i = 0; i < edge_list.size(); i++) {
- delete edge_list[i];
- }
-
-}
-
-}
diff --git a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h b/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h
deleted file mode 100644
index ba0d06581..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri/poly2tri/sweep/sweep_context.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
- * http://code.google.com/p/poly2tri/
- *
- * All rights reserved.
- *
- * Redistribution and use 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 Poly2Tri nor the names of its contributors may be
- * used to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * 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 SWEEP_CONTEXT_H
-#define SWEEP_CONTEXT_H
-
-#include <list>
-#include <vector>
-#include <cstddef>
-
-namespace p2t {
-
-// Inital triangle factor, seed triangle will extend 30% of
-// PointSet width to both left and right.
-const double kAlpha = 0.3;
-
-struct Point;
-class Triangle;
-struct Node;
-struct Edge;
-class AdvancingFront;
-
-class SweepContext {
-public:
-
-/// Constructor
-SweepContext(const std::vector<Point*>& polyline);
-/// Destructor
-~SweepContext();
-
-void set_head(Point* p1);
-
-Point* head() const;
-
-void set_tail(Point* p1);
-
-Point* tail() const;
-
-size_t point_count() const;
-
-Node& LocateNode(const Point& point);
-
-void RemoveNode(Node* node);
-
-void CreateAdvancingFront(const std::vector<Node*>& nodes);
-
-/// Try to map a node to all sides of this triangle that don't have a neighbor
-void MapTriangleToNodes(Triangle& t);
-
-void AddToMap(Triangle* triangle);
-
-Point* GetPoint(size_t index);
-
-Point* GetPoints();
-
-void RemoveFromMap(Triangle* triangle);
-
-void AddHole(const std::vector<Point*>& polyline);
-
-void AddPoint(Point* point);
-
-AdvancingFront* front() const;
-
-void MeshClean(Triangle& triangle);
-
-std::vector<Triangle*> &GetTriangles();
-std::list<Triangle*> &GetMap();
-
-std::vector<Edge*> edge_list;
-
-struct Basin {
- Node* left_node;
- Node* bottom_node;
- Node* right_node;
- double width;
- bool left_highest;
-
- Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false)
- {
- }
-
- void Clear()
- {
- left_node = NULL;
- bottom_node = NULL;
- right_node = NULL;
- width = 0.0;
- left_highest = false;
- }
-};
-
-struct EdgeEvent {
- Edge* constrained_edge;
- bool right;
-
- EdgeEvent() : constrained_edge(NULL), right(false)
- {
- }
-};
-
-Basin basin;
-EdgeEvent edge_event;
-
-private:
-
-friend class Sweep;
-
-std::vector<Triangle*> triangles_;
-std::list<Triangle*> map_;
-std::vector<Point*> points_;
-
-// Advancing front
-AdvancingFront* front_;
-// head point used with advancing front
-Point* head_;
-// tail point used with advancing front
-Point* tail_;
-
-Node *af_head_, *af_middle_, *af_tail_;
-
-void InitTriangulation();
-void InitEdges(const std::vector<Point*>& polyline);
-
-};
-
-inline AdvancingFront* SweepContext::front() const
-{
- return front_;
-}
-
-inline size_t SweepContext::point_count() const
-{
- return points_.size();
-}
-
-inline void SweepContext::set_head(Point* p1)
-{
- head_ = p1;
-}
-
-inline Point* SweepContext::head() const
-{
- return head_;
-}
-
-inline void SweepContext::set_tail(Point* p1)
-{
- tail_ = p1;
-}
-
-inline Point* SweepContext::tail() const
-{
- return tail_;
-}
-
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/poly2tri_patch.txt b/src/3rdparty/assimp/contrib/poly2tri_patch.txt
deleted file mode 100644
index e9cca4cec..000000000
--- a/src/3rdparty/assimp/contrib/poly2tri_patch.txt
+++ /dev/null
@@ -1,75 +0,0 @@
-diff -r 5de9623d6a50 poly2tri/common/shapes.h
---- a/poly2tri/common/shapes.h Mon Aug 08 22:26:41 2011 -0400
-+++ b/poly2tri/common/shapes.h Tue Jan 17 02:36:52 2012 +0100
-@@ -35,6 +35,7 @@
-
- #include <vector>
- #include <cstddef>
-+#include <stdexcept>
- #include <assert.h>
- #include <cmath>
-
-@@ -136,7 +137,9 @@
- p = &p2;
- } else if (p1.x == p2.x) {
- // Repeat points
-- assert(false);
-+ // ASSIMP_CHANGE (aramis_acg)
-+ throw std::runtime_error("repeat points");
-+ //assert(false);
- }
- }
-
-diff -r 5de9623d6a50 poly2tri/sweep/sweep.cc
---- a/poly2tri/sweep/sweep.cc Mon Aug 08 22:26:41 2011 -0400
-+++ b/poly2tri/sweep/sweep.cc Tue Jan 17 02:36:52 2012 +0100
-@@ -113,6 +113,8 @@
- Point* p1 = triangle->PointCCW(point);
- Orientation o1 = Orient2d(eq, *p1, ep);
- if (o1 == COLLINEAR) {
-+ // ASSIMP_CHANGE (aramis_acg)
-+ throw std::runtime_error("EdgeEvent - collinear points not supported");
- if( triangle->Contains(&eq, p1)) {
- triangle->MarkConstrainedEdge(&eq, p1 );
- // We are modifying the constraint maybe it would be better to
-@@ -121,8 +123,8 @@
- triangle = &triangle->NeighborAcross(point);
- EdgeEvent( tcx, ep, *p1, triangle, *p1 );
- } else {
-+ // ASSIMP_CHANGE (aramis_acg)
- std::runtime_error("EdgeEvent - collinear points not supported");
-- assert(0);
- }
- return;
- }
-@@ -130,6 +132,9 @@
- Point* p2 = triangle->PointCW(point);
- Orientation o2 = Orient2d(eq, *p2, ep);
- if (o2 == COLLINEAR) {
-+ // ASSIMP_CHANGE (aramis_acg)
-+ throw std::runtime_error("EdgeEvent - collinear points not supported");
-+
- if( triangle->Contains(&eq, p2)) {
- triangle->MarkConstrainedEdge(&eq, p2 );
- // We are modifying the constraint maybe it would be better to
-@@ -138,8 +143,8 @@
- triangle = &triangle->NeighborAcross(point);
- EdgeEvent( tcx, ep, *p2, triangle, *p2 );
- } else {
-- std::runtime_error("EdgeEvent - collinear points not supported");
-- assert(0);
-+ // ASSIMP_CHANGE (aramis_acg)
-+ throw std::runtime_error("EdgeEvent - collinear points not supported");
- }
- return;
- }
-@@ -712,7 +717,8 @@
- return *ot.PointCW(op);
- } else{
- //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
-- assert(0);
-+ // ASSIMP_CHANGE (aramis_acg)
-+ throw std::runtime_error("[Unsupported] Opposing point on constrained edge");
- }
- }
-
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/allocators.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/allocators.h
deleted file mode 100644
index 655f4a385..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/allocators.h
+++ /dev/null
@@ -1,271 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ALLOCATORS_H_
-#define RAPIDJSON_ALLOCATORS_H_
-
-#include "rapidjson.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Allocator
-
-/*! \class rapidjson::Allocator
- \brief Concept for allocating, resizing and freeing memory block.
-
- Note that Malloc() and Realloc() are non-static but Free() is static.
-
- So if an allocator need to support Free(), it needs to put its pointer in
- the header of memory block.
-
-\code
-concept Allocator {
- static const bool kNeedFree; //!< Whether this allocator needs to call Free().
-
- // Allocate a memory block.
- // \param size of the memory block in bytes.
- // \returns pointer to the memory block.
- void* Malloc(size_t size);
-
- // Resize a memory block.
- // \param originalPtr The pointer to current memory block. Null pointer is permitted.
- // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
- // \param newSize the new size in bytes.
- void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
-
- // Free a memory block.
- // \param pointer to the memory block. Null pointer is permitted.
- static void Free(void *ptr);
-};
-\endcode
-*/
-
-///////////////////////////////////////////////////////////////////////////////
-// CrtAllocator
-
-//! C-runtime library allocator.
-/*! This class is just wrapper for standard C library memory routines.
- \note implements Allocator concept
-*/
-class CrtAllocator {
-public:
- static const bool kNeedFree = true;
- void* Malloc(size_t size) {
- if (size) // behavior of malloc(0) is implementation defined.
- return std::malloc(size);
- else
- return NULL; // standardize to returning NULL.
- }
- void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
- (void)originalSize;
- if (newSize == 0) {
- std::free(originalPtr);
- return NULL;
- }
- return std::realloc(originalPtr, newSize);
- }
- static void Free(void *ptr) { std::free(ptr); }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// MemoryPoolAllocator
-
-//! Default memory allocator used by the parser and DOM.
-/*! This allocator allocate memory blocks from pre-allocated memory chunks.
-
- It does not free memory blocks. And Realloc() only allocate new memory.
-
- The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
-
- User may also supply a buffer as the first chunk.
-
- If the user-buffer is full then additional chunks are allocated by BaseAllocator.
-
- The user-buffer is not deallocated by this allocator.
-
- \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
- \note implements Allocator concept
-*/
-template <typename BaseAllocator = CrtAllocator>
-class MemoryPoolAllocator {
-public:
- static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
-
- //! Constructor with chunkSize.
- /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
- \param baseAllocator The allocator for allocating memory chunks.
- */
- MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
- chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
- {
- }
-
- //! Constructor with user-supplied buffer.
- /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
-
- The user buffer will not be deallocated when this allocator is destructed.
-
- \param buffer User supplied buffer.
- \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
- \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
- \param baseAllocator The allocator for allocating memory chunks.
- */
- MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
- chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
- {
- RAPIDJSON_ASSERT(buffer != 0);
- RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
- chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
- chunkHead_->capacity = size - sizeof(ChunkHeader);
- chunkHead_->size = 0;
- chunkHead_->next = 0;
- }
-
- //! Destructor.
- /*! This deallocates all memory chunks, excluding the user-supplied buffer.
- */
- ~MemoryPoolAllocator() {
- Clear();
- RAPIDJSON_DELETE(ownBaseAllocator_);
- }
-
- //! Deallocates all memory chunks, excluding the user-supplied buffer.
- void Clear() {
- while (chunkHead_ && chunkHead_ != userBuffer_) {
- ChunkHeader* next = chunkHead_->next;
- baseAllocator_->Free(chunkHead_);
- chunkHead_ = next;
- }
- if (chunkHead_ && chunkHead_ == userBuffer_)
- chunkHead_->size = 0; // Clear user buffer
- }
-
- //! Computes the total capacity of allocated memory chunks.
- /*! \return total capacity in bytes.
- */
- size_t Capacity() const {
- size_t capacity = 0;
- for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
- capacity += c->capacity;
- return capacity;
- }
-
- //! Computes the memory blocks allocated.
- /*! \return total used bytes.
- */
- size_t Size() const {
- size_t size = 0;
- for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
- size += c->size;
- return size;
- }
-
- //! Allocates a memory block. (concept Allocator)
- void* Malloc(size_t size) {
- if (!size)
- return NULL;
-
- size = RAPIDJSON_ALIGN(size);
- if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
- if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
- return NULL;
-
- void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
- chunkHead_->size += size;
- return buffer;
- }
-
- //! Resizes a memory block (concept Allocator)
- void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
- if (originalPtr == 0)
- return Malloc(newSize);
-
- if (newSize == 0)
- return NULL;
-
- originalSize = RAPIDJSON_ALIGN(originalSize);
- newSize = RAPIDJSON_ALIGN(newSize);
-
- // Do not shrink if new size is smaller than original
- if (originalSize >= newSize)
- return originalPtr;
-
- // Simply expand it if it is the last allocation and there is sufficient space
- if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
- size_t increment = static_cast<size_t>(newSize - originalSize);
- if (chunkHead_->size + increment <= chunkHead_->capacity) {
- chunkHead_->size += increment;
- return originalPtr;
- }
- }
-
- // Realloc process: allocate and copy memory, do not free original buffer.
- if (void* newBuffer = Malloc(newSize)) {
- if (originalSize)
- std::memcpy(newBuffer, originalPtr, originalSize);
- return newBuffer;
- }
- else
- return NULL;
- }
-
- //! Frees a memory block (concept Allocator)
- static void Free(void *ptr) { (void)ptr; } // Do nothing
-
-private:
- //! Copy constructor is not permitted.
- MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
- //! Copy assignment operator is not permitted.
- MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
-
- //! Creates a new chunk.
- /*! \param capacity Capacity of the chunk in bytes.
- \return true if success.
- */
- bool AddChunk(size_t capacity) {
- if (!baseAllocator_)
- ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
- if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
- chunk->capacity = capacity;
- chunk->size = 0;
- chunk->next = chunkHead_;
- chunkHead_ = chunk;
- return true;
- }
- else
- return false;
- }
-
- static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
-
- //! Chunk header for perpending to each chunk.
- /*! Chunks are stored as a singly linked list.
- */
- struct ChunkHeader {
- size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
- size_t size; //!< Current size of allocated memory in bytes.
- ChunkHeader *next; //!< Next chunk in the linked list.
- };
-
- ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
- size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
- void *userBuffer_; //!< User supplied buffer.
- BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
- BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_ENCODINGS_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/document.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/document.h
deleted file mode 100644
index 93b091f64..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/document.h
+++ /dev/null
@@ -1,2613 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_DOCUMENT_H_
-#define RAPIDJSON_DOCUMENT_H_
-
-/*! \file document.h */
-
-#include "reader.h"
-#include "internal/meta.h"
-#include "internal/strfunc.h"
-#include "memorystream.h"
-#include "encodedstream.h"
-#include <new> // placement new
-#include <limits>
-
-RAPIDJSON_DIAG_PUSH
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
-RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_OFF(padded)
-RAPIDJSON_DIAG_OFF(switch-enum)
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_OFF(effc++)
-#if __GNUC__ >= 6
-RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
-#endif
-#endif // __GNUC__
-
-#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
-#include <iterator> // std::iterator, std::random_access_iterator_tag
-#endif
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
-#include <utility> // std::move
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-// Forward declaration.
-template <typename Encoding, typename Allocator>
-class GenericValue;
-
-template <typename Encoding, typename Allocator, typename StackAllocator>
-class GenericDocument;
-
-//! Name-value pair in a JSON object value.
-/*!
- This class was internal to GenericValue. It used to be a inner struct.
- But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
- https://code.google.com/p/rapidjson/issues/detail?id=64
-*/
-template <typename Encoding, typename Allocator>
-struct GenericMember {
- GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
- GenericValue<Encoding, Allocator> value; //!< value of member.
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericMemberIterator
-
-#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
-
-//! (Constant) member iterator for a JSON object value
-/*!
- \tparam Const Is this a constant iterator?
- \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
- \tparam Allocator Allocator type for allocating memory of object, array and string.
-
- This class implements a Random Access Iterator for GenericMember elements
- of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
-
- \note This iterator implementation is mainly intended to avoid implicit
- conversions from iterator values to \c NULL,
- e.g. from GenericValue::FindMember.
-
- \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
- pointer-based implementation, if your platform doesn't provide
- the C++ <iterator> header.
-
- \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
- */
-template <bool Const, typename Encoding, typename Allocator>
-class GenericMemberIterator
- : public std::iterator<std::random_access_iterator_tag
- , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
-
- friend class GenericValue<Encoding,Allocator>;
- template <bool, typename, typename> friend class GenericMemberIterator;
-
- typedef GenericMember<Encoding,Allocator> PlainType;
- typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
- typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
-
-public:
- //! Iterator type itself
- typedef GenericMemberIterator Iterator;
- //! Constant iterator type
- typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
- //! Non-constant iterator type
- typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
-
- //! Pointer to (const) GenericMember
- typedef typename BaseType::pointer Pointer;
- //! Reference to (const) GenericMember
- typedef typename BaseType::reference Reference;
- //! Signed integer type (e.g. \c ptrdiff_t)
- typedef typename BaseType::difference_type DifferenceType;
-
- //! Default constructor (singular value)
- /*! Creates an iterator pointing to no element.
- \note All operations, except for comparisons, are undefined on such values.
- */
- GenericMemberIterator() : ptr_() {}
-
- //! Iterator conversions to more const
- /*!
- \param it (Non-const) iterator to copy from
-
- Allows the creation of an iterator from another GenericMemberIterator
- that is "less const". Especially, creating a non-constant iterator
- from a constant iterator are disabled:
- \li const -> non-const (not ok)
- \li const -> const (ok)
- \li non-const -> const (ok)
- \li non-const -> non-const (ok)
-
- \note If the \c Const template parameter is already \c false, this
- constructor effectively defines a regular copy-constructor.
- Otherwise, the copy constructor is implicitly defined.
- */
- GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
- Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
-
- //! @name stepping
- //@{
- Iterator& operator++(){ ++ptr_; return *this; }
- Iterator& operator--(){ --ptr_; return *this; }
- Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
- Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
- //@}
-
- //! @name increment/decrement
- //@{
- Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
- Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
-
- Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
- Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
- //@}
-
- //! @name relations
- //@{
- bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
- bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
- bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
- bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
- bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
- bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
- //@}
-
- //! @name dereference
- //@{
- Reference operator*() const { return *ptr_; }
- Pointer operator->() const { return ptr_; }
- Reference operator[](DifferenceType n) const { return ptr_[n]; }
- //@}
-
- //! Distance
- DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
-
-private:
- //! Internal constructor from plain pointer
- explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
-
- Pointer ptr_; //!< raw pointer
-};
-
-#else // RAPIDJSON_NOMEMBERITERATORCLASS
-
-// class-based member iterator implementation disabled, use plain pointers
-
-template <bool Const, typename Encoding, typename Allocator>
-struct GenericMemberIterator;
-
-//! non-const GenericMemberIterator
-template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<false,Encoding,Allocator> {
- //! use plain pointer as iterator type
- typedef GenericMember<Encoding,Allocator>* Iterator;
-};
-//! const GenericMemberIterator
-template <typename Encoding, typename Allocator>
-struct GenericMemberIterator<true,Encoding,Allocator> {
- //! use plain const pointer as iterator type
- typedef const GenericMember<Encoding,Allocator>* Iterator;
-};
-
-#endif // RAPIDJSON_NOMEMBERITERATORCLASS
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericStringRef
-
-//! Reference to a constant string (not taking a copy)
-/*!
- \tparam CharType character type of the string
-
- This helper class is used to automatically infer constant string
- references for string literals, especially from \c const \b (!)
- character arrays.
-
- The main use is for creating JSON string values without copying the
- source string via an \ref Allocator. This requires that the referenced
- string pointers have a sufficient lifetime, which exceeds the lifetime
- of the associated GenericValue.
-
- \b Example
- \code
- Value v("foo"); // ok, no need to copy & calculate length
- const char foo[] = "foo";
- v.SetString(foo); // ok
-
- const char* bar = foo;
- // Value x(bar); // not ok, can't rely on bar's lifetime
- Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
- Value y(StringRef(bar, 3)); // ok, explicitly pass length
- \endcode
-
- \see StringRef, GenericValue::SetString
-*/
-template<typename CharType>
-struct GenericStringRef {
- typedef CharType Ch; //!< character type of the string
-
- //! Create string reference from \c const character array
-#ifndef __clang__ // -Wdocumentation
- /*!
- This constructor implicitly creates a constant string reference from
- a \c const character array. It has better performance than
- \ref StringRef(const CharType*) by inferring the string \ref length
- from the array length, and also supports strings containing null
- characters.
-
- \tparam N length of the string, automatically inferred
-
- \param str Constant character array, lifetime assumed to be longer
- than the use of the string in e.g. a GenericValue
-
- \post \ref s == str
-
- \note Constant complexity.
- \note There is a hidden, private overload to disallow references to
- non-const character arrays to be created via this constructor.
- By this, e.g. function-scope arrays used to be filled via
- \c snprintf are excluded from consideration.
- In such cases, the referenced string should be \b copied to the
- GenericValue instead.
- */
-#endif
- template<SizeType N>
- GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
- : s(str), length(N-1) {}
-
- //! Explicitly create string reference from \c const character pointer
-#ifndef __clang__ // -Wdocumentation
- /*!
- This constructor can be used to \b explicitly create a reference to
- a constant string pointer.
-
- \see StringRef(const CharType*)
-
- \param str Constant character pointer, lifetime assumed to be longer
- than the use of the string in e.g. a GenericValue
-
- \post \ref s == str
-
- \note There is a hidden, private overload to disallow references to
- non-const character arrays to be created via this constructor.
- By this, e.g. function-scope arrays used to be filled via
- \c snprintf are excluded from consideration.
- In such cases, the referenced string should be \b copied to the
- GenericValue instead.
- */
-#endif
- explicit GenericStringRef(const CharType* str)
- : s(str), length(NotNullStrLen(str)) {}
-
- //! Create constant string reference from pointer and length
-#ifndef __clang__ // -Wdocumentation
- /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
- \param len length of the string, excluding the trailing NULL terminator
-
- \post \ref s == str && \ref length == len
- \note Constant complexity.
- */
-#endif
- GenericStringRef(const CharType* str, SizeType len)
- : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
-
- GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
-
- //! implicit conversion to plain CharType pointer
- operator const Ch *() const { return s; }
-
- const Ch* const s; //!< plain CharType pointer
- const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
-
-private:
- SizeType NotNullStrLen(const CharType* str) {
- RAPIDJSON_ASSERT(str != 0);
- return internal::StrLen(str);
- }
-
- /// Empty string - used when passing in a NULL pointer
- static const Ch emptyString[];
-
- //! Disallow construction from non-const array
- template<SizeType N>
- GenericStringRef(CharType (&str)[N]) /* = delete */;
- //! Copy assignment operator not permitted - immutable type
- GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
-};
-
-template<typename CharType>
-const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
-
-//! Mark a character pointer as constant string
-/*! Mark a plain character pointer as a "string literal". This function
- can be used to avoid copying a character string to be referenced as a
- value in a JSON GenericValue object, if the string's lifetime is known
- to be valid long enough.
- \tparam CharType Character type of the string
- \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
- \return GenericStringRef string reference object
- \relatesalso GenericStringRef
-
- \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
-*/
-template<typename CharType>
-inline GenericStringRef<CharType> StringRef(const CharType* str) {
- return GenericStringRef<CharType>(str);
-}
-
-//! Mark a character pointer as constant string
-/*! Mark a plain character pointer as a "string literal". This function
- can be used to avoid copying a character string to be referenced as a
- value in a JSON GenericValue object, if the string's lifetime is known
- to be valid long enough.
-
- This version has better performance with supplied length, and also
- supports string containing null characters.
-
- \tparam CharType character type of the string
- \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
- \param length The length of source string.
- \return GenericStringRef string reference object
- \relatesalso GenericStringRef
-*/
-template<typename CharType>
-inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
- return GenericStringRef<CharType>(str, SizeType(length));
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-//! Mark a string object as constant string
-/*! Mark a string object (e.g. \c std::string) as a "string literal".
- This function can be used to avoid copying a string to be referenced as a
- value in a JSON GenericValue object, if the string's lifetime is known
- to be valid long enough.
-
- \tparam CharType character type of the string
- \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
- \return GenericStringRef string reference object
- \relatesalso GenericStringRef
- \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
-*/
-template<typename CharType>
-inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
- return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
-}
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericValue type traits
-namespace internal {
-
-template <typename T, typename Encoding = void, typename Allocator = void>
-struct IsGenericValueImpl : FalseType {};
-
-// select candidates according to nested encoding and allocator types
-template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
- : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
-
-// helper to match arbitrary GenericValue instantiations, including derived classes
-template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
-
-} // namespace internal
-
-///////////////////////////////////////////////////////////////////////////////
-// TypeHelper
-
-namespace internal {
-
-template <typename ValueType, typename T>
-struct TypeHelper {};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, bool> {
- static bool Is(const ValueType& v) { return v.IsBool(); }
- static bool Get(const ValueType& v) { return v.GetBool(); }
- static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
- static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, int> {
- static bool Is(const ValueType& v) { return v.IsInt(); }
- static int Get(const ValueType& v) { return v.GetInt(); }
- static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
- static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, unsigned> {
- static bool Is(const ValueType& v) { return v.IsUint(); }
- static unsigned Get(const ValueType& v) { return v.GetUint(); }
- static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
- static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, int64_t> {
- static bool Is(const ValueType& v) { return v.IsInt64(); }
- static int64_t Get(const ValueType& v) { return v.GetInt64(); }
- static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
- static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, uint64_t> {
- static bool Is(const ValueType& v) { return v.IsUint64(); }
- static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
- static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
- static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, double> {
- static bool Is(const ValueType& v) { return v.IsDouble(); }
- static double Get(const ValueType& v) { return v.GetDouble(); }
- static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
- static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, float> {
- static bool Is(const ValueType& v) { return v.IsFloat(); }
- static float Get(const ValueType& v) { return v.GetFloat(); }
- static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
- static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, const typename ValueType::Ch*> {
- typedef const typename ValueType::Ch* StringType;
- static bool Is(const ValueType& v) { return v.IsString(); }
- static StringType Get(const ValueType& v) { return v.GetString(); }
- static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
- static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
-};
-
-#if RAPIDJSON_HAS_STDSTRING
-template<typename ValueType>
-struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
- typedef std::basic_string<typename ValueType::Ch> StringType;
- static bool Is(const ValueType& v) { return v.IsString(); }
- static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
- static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
-};
-#endif
-
-template<typename ValueType>
-struct TypeHelper<ValueType, typename ValueType::Array> {
- typedef typename ValueType::Array ArrayType;
- static bool Is(const ValueType& v) { return v.IsArray(); }
- static ArrayType Get(ValueType& v) { return v.GetArray(); }
- static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
- static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, typename ValueType::ConstArray> {
- typedef typename ValueType::ConstArray ArrayType;
- static bool Is(const ValueType& v) { return v.IsArray(); }
- static ArrayType Get(const ValueType& v) { return v.GetArray(); }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, typename ValueType::Object> {
- typedef typename ValueType::Object ObjectType;
- static bool Is(const ValueType& v) { return v.IsObject(); }
- static ObjectType Get(ValueType& v) { return v.GetObject(); }
- static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
- static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
-};
-
-template<typename ValueType>
-struct TypeHelper<ValueType, typename ValueType::ConstObject> {
- typedef typename ValueType::ConstObject ObjectType;
- static bool Is(const ValueType& v) { return v.IsObject(); }
- static ObjectType Get(const ValueType& v) { return v.GetObject(); }
-};
-
-} // namespace internal
-
-// Forward declarations
-template <bool, typename> class GenericArray;
-template <bool, typename> class GenericObject;
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericValue
-
-//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
-/*!
- A JSON value can be one of 7 types. This class is a variant type supporting
- these types.
-
- Use the Value if UTF8 and default allocator
-
- \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
- \tparam Allocator Allocator type for allocating memory of object, array and string.
-*/
-template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
-class GenericValue {
-public:
- //! Name-value pair in an object.
- typedef GenericMember<Encoding, Allocator> Member;
- typedef Encoding EncodingType; //!< Encoding type from template parameter.
- typedef Allocator AllocatorType; //!< Allocator type from template parameter.
- typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
- typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string
- typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object.
- typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
- typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
- typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
- typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
- typedef GenericArray<false, ValueType> Array;
- typedef GenericArray<true, ValueType> ConstArray;
- typedef GenericObject<false, ValueType> Object;
- typedef GenericObject<true, ValueType> ConstObject;
-
- //!@name Constructors and destructor.
- //@{
-
- //! Default constructor creates a null value.
- GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Move constructor in C++11
- GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
- rhs.data_.f.flags = kNullFlag; // give up contents
- }
-#endif
-
-private:
- //! Copy constructor is not permitted.
- GenericValue(const GenericValue& rhs);
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Moving from a GenericDocument is not permitted.
- template <typename StackAllocator>
- GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
-
- //! Move assignment from a GenericDocument is not permitted.
- template <typename StackAllocator>
- GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
-#endif
-
-public:
-
- //! Constructor with JSON value type.
- /*! This creates a Value of specified type with default content.
- \param type Type of the value.
- \note Default content for number is zero.
- */
- explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
- static const uint16_t defaultFlags[7] = {
- kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
- kNumberAnyFlag
- };
- RAPIDJSON_ASSERT(type >= kNullType && type <= kNumberType);
- data_.f.flags = defaultFlags[type];
-
- // Use ShortString to store empty string.
- if (type == kStringType)
- data_.ss.SetLength(0);
- }
-
- //! Explicit copy constructor (with allocator)
- /*! Creates a copy of a Value by using the given Allocator
- \tparam SourceAllocator allocator of \c rhs
- \param rhs Value to copy from (read-only)
- \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
- \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
- \see CopyFrom()
- */
- template <typename SourceAllocator>
- GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
- switch (rhs.GetType()) {
- case kObjectType: {
- SizeType count = rhs.data_.o.size;
- Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
- const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
- for (SizeType i = 0; i < count; i++) {
- new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
- new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
- }
- data_.f.flags = kObjectFlag;
- data_.o.size = data_.o.capacity = count;
- SetMembersPointer(lm);
- }
- break;
- case kArrayType: {
- SizeType count = rhs.data_.a.size;
- GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
- const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
- for (SizeType i = 0; i < count; i++)
- new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
- data_.f.flags = kArrayFlag;
- data_.a.size = data_.a.capacity = count;
- SetElementsPointer(le);
- }
- break;
- case kStringType:
- if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
- data_.f.flags = rhs.data_.f.flags;
- data_ = *reinterpret_cast<const Data*>(&rhs.data_);
- }
- else
- SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
- break;
- default:
- data_.f.flags = rhs.data_.f.flags;
- data_ = *reinterpret_cast<const Data*>(&rhs.data_);
- break;
- }
- }
-
- //! Constructor for boolean value.
- /*! \param b Boolean value
- \note This constructor is limited to \em real boolean values and rejects
- implicitly converted types like arbitrary pointers. Use an explicit cast
- to \c bool, if you want to construct a boolean JSON value in such cases.
- */
-#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
- template <typename T>
- explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
-#else
- explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
-#endif
- : data_() {
- // safe-guard against failing SFINAE
- RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
- data_.f.flags = b ? kTrueFlag : kFalseFlag;
- }
-
- //! Constructor for int value.
- explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
- data_.n.i64 = i;
- data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
- }
-
- //! Constructor for unsigned value.
- explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
- data_.n.u64 = u;
- data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
- }
-
- //! Constructor for int64_t value.
- explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
- data_.n.i64 = i64;
- data_.f.flags = kNumberInt64Flag;
- if (i64 >= 0) {
- data_.f.flags |= kNumberUint64Flag;
- if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
- data_.f.flags |= kUintFlag;
- if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
- data_.f.flags |= kIntFlag;
- }
- else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
- data_.f.flags |= kIntFlag;
- }
-
- //! Constructor for uint64_t value.
- explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
- data_.n.u64 = u64;
- data_.f.flags = kNumberUint64Flag;
- if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
- data_.f.flags |= kInt64Flag;
- if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
- data_.f.flags |= kUintFlag;
- if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
- data_.f.flags |= kIntFlag;
- }
-
- //! Constructor for double value.
- explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
-
- //! Constructor for float value.
- explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
-
- //! Constructor for constant string (i.e. do not make a copy of string)
- GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
-
- //! Constructor for constant string (i.e. do not make a copy of string)
- explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
-
- //! Constructor for copy-string (i.e. do make a copy of string)
- GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
-
- //! Constructor for copy-string (i.e. do make a copy of string)
- GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Constructor for copy-string from a string object (i.e. do make a copy of string)
- /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
- */
- GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
-#endif
-
- //! Constructor for Array.
- /*!
- \param a An array obtained by \c GetArray().
- \note \c Array is always pass-by-value.
- \note the source array is moved into this value and the sourec array becomes empty.
- */
- GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
- a.value_.data_ = Data();
- a.value_.data_.f.flags = kArrayFlag;
- }
-
- //! Constructor for Object.
- /*!
- \param o An object obtained by \c GetObject().
- \note \c Object is always pass-by-value.
- \note the source object is moved into this value and the sourec object becomes empty.
- */
- GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
- o.value_.data_ = Data();
- o.value_.data_.f.flags = kObjectFlag;
- }
-
- //! Destructor.
- /*! Need to destruct elements of array, members of object, or copy-string.
- */
- ~GenericValue() {
- if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
- switch(data_.f.flags) {
- case kArrayFlag:
- {
- GenericValue* e = GetElementsPointer();
- for (GenericValue* v = e; v != e + data_.a.size; ++v)
- v->~GenericValue();
- Allocator::Free(e);
- }
- break;
-
- case kObjectFlag:
- for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
- m->~Member();
- Allocator::Free(GetMembersPointer());
- break;
-
- case kCopyStringFlag:
- Allocator::Free(const_cast<Ch*>(GetStringPointer()));
- break;
-
- default:
- break; // Do nothing for other types.
- }
- }
- }
-
- //@}
-
- //!@name Assignment operators
- //@{
-
- //! Assignment with move semantics.
- /*! \param rhs Source of the assignment. It will become a null value after assignment.
- */
- GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
- RAPIDJSON_ASSERT(this != &rhs);
- this->~GenericValue();
- RawAssign(rhs);
- return *this;
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Move assignment in C++11
- GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
- return *this = rhs.Move();
- }
-#endif
-
- //! Assignment of constant string reference (no copy)
- /*! \param str Constant string reference to be assigned
- \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
- \see GenericStringRef, operator=(T)
- */
- GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
- GenericValue s(str);
- return *this = s;
- }
-
- //! Assignment with primitive types.
- /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
- \param value The value to be assigned.
-
- \note The source type \c T explicitly disallows all pointer types,
- especially (\c const) \ref Ch*. This helps avoiding implicitly
- referencing character strings with insufficient lifetime, use
- \ref SetString(const Ch*, Allocator&) (for copying) or
- \ref StringRef() (to explicitly mark the pointer as constant) instead.
- All other pointer types would implicitly convert to \c bool,
- use \ref SetBool() instead.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
- operator=(T value) {
- GenericValue v(value);
- return *this = v;
- }
-
- //! Deep-copy assignment from Value
- /*! Assigns a \b copy of the Value to the current Value object
- \tparam SourceAllocator Allocator type of \c rhs
- \param rhs Value to copy from (read-only)
- \param allocator Allocator to use for copying
- \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
- */
- template <typename SourceAllocator>
- GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
- RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
- this->~GenericValue();
- new (this) GenericValue(rhs, allocator, copyConstStrings);
- return *this;
- }
-
- //! Exchange the contents of this value with those of other.
- /*!
- \param other Another value.
- \note Constant complexity.
- */
- GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
- GenericValue temp;
- temp.RawAssign(*this);
- RawAssign(other);
- other.RawAssign(temp);
- return *this;
- }
-
- //! free-standing swap function helper
- /*!
- Helper function to enable support for common swap implementation pattern based on \c std::swap:
- \code
- void swap(MyClass& a, MyClass& b) {
- using std::swap;
- swap(a.value, b.value);
- // ...
- }
- \endcode
- \see Swap()
- */
- friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
-
- //! Prepare Value for move semantics
- /*! \return *this */
- GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
- //@}
-
- //!@name Equal-to and not-equal-to operators
- //@{
- //! Equal-to operator
- /*!
- \note If an object contains duplicated named member, comparing equality with any object is always \c false.
- \note Linear time complexity (number of all values in the subtree and total lengths of all strings).
- */
- template <typename SourceAllocator>
- bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
- typedef GenericValue<Encoding, SourceAllocator> RhsType;
- if (GetType() != rhs.GetType())
- return false;
-
- switch (GetType()) {
- case kObjectType: // Warning: O(n^2) inner-loop
- if (data_.o.size != rhs.data_.o.size)
- return false;
- for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
- typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
- if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
- return false;
- }
- return true;
-
- case kArrayType:
- if (data_.a.size != rhs.data_.a.size)
- return false;
- for (SizeType i = 0; i < data_.a.size; i++)
- if ((*this)[i] != rhs[i])
- return false;
- return true;
-
- case kStringType:
- return StringEqual(rhs);
-
- case kNumberType:
- if (IsDouble() || rhs.IsDouble()) {
- double a = GetDouble(); // May convert from integer to double.
- double b = rhs.GetDouble(); // Ditto
- return a >= b && a <= b; // Prevent -Wfloat-equal
- }
- else
- return data_.n.u64 == rhs.data_.n.u64;
-
- default:
- return true;
- }
- }
-
- //! Equal-to operator with const C-string pointer
- bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Equal-to operator with string object
- /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
- */
- bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
-#endif
-
- //! Equal-to operator with primitive types
- /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
- */
- template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
-
- //! Not-equal-to operator
- /*! \return !(*this == rhs)
- */
- template <typename SourceAllocator>
- bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
-
- //! Not-equal-to operator with const C-string pointer
- bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
-
- //! Not-equal-to operator with arbitrary types
- /*! \return !(*this == rhs)
- */
- template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
-
- //! Equal-to operator with arbitrary types (symmetric version)
- /*! \return (rhs == lhs)
- */
- template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
-
- //! Not-Equal-to operator with arbitrary types (symmetric version)
- /*! \return !(rhs == lhs)
- */
- template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
- //@}
-
- //!@name Type
- //@{
-
- Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
- bool IsNull() const { return data_.f.flags == kNullFlag; }
- bool IsFalse() const { return data_.f.flags == kFalseFlag; }
- bool IsTrue() const { return data_.f.flags == kTrueFlag; }
- bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
- bool IsObject() const { return data_.f.flags == kObjectFlag; }
- bool IsArray() const { return data_.f.flags == kArrayFlag; }
- bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
- bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
- bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
- bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
- bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
- bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
- bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
-
- // Checks whether a number can be losslessly converted to a double.
- bool IsLosslessDouble() const {
- if (!IsNumber()) return false;
- if (IsUint64()) {
- uint64_t u = GetUint64();
- volatile double d = static_cast<double>(u);
- return (d >= 0.0)
- && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
- && (u == static_cast<uint64_t>(d));
- }
- if (IsInt64()) {
- int64_t i = GetInt64();
- volatile double d = static_cast<double>(i);
- return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
- && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
- && (i == static_cast<int64_t>(d));
- }
- return true; // double, int, uint are always lossless
- }
-
- // Checks whether a number is a float (possible lossy).
- bool IsFloat() const {
- if ((data_.f.flags & kDoubleFlag) == 0)
- return false;
- double d = GetDouble();
- return d >= -3.4028234e38 && d <= 3.4028234e38;
- }
- // Checks whether a number can be losslessly converted to a float.
- bool IsLosslessFloat() const {
- if (!IsNumber()) return false;
- double a = GetDouble();
- if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
- || a > static_cast<double>((std::numeric_limits<float>::max)()))
- return false;
- double b = static_cast<double>(static_cast<float>(a));
- return a >= b && a <= b; // Prevent -Wfloat-equal
- }
-
- //@}
-
- //!@name Null
- //@{
-
- GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
-
- //@}
-
- //!@name Bool
- //@{
-
- bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
- //!< Set boolean value
- /*! \post IsBool() == true */
- GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
-
- //@}
-
- //!@name Object
- //@{
-
- //! Set this value as an empty object.
- /*! \post IsObject() == true */
- GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
-
- //! Get the number of members in the object.
- SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
-
- //! Check whether the object is empty.
- bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
-
- //! Get a value from an object associated with the name.
- /*! \pre IsObject() == true
- \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
- \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
- Since 0.2, if the name is not correct, it will assert.
- If user is unsure whether a member exists, user should use HasMember() first.
- A better approach is to use FindMember().
- \note Linear time complexity.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
- GenericValue n(StringRef(name));
- return (*this)[n];
- }
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
-
- //! Get a value from an object associated with the name.
- /*! \pre IsObject() == true
- \tparam SourceAllocator Allocator of the \c name value
-
- \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
- And it can also handle strings with embedded null characters.
-
- \note Linear time complexity.
- */
- template <typename SourceAllocator>
- GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
- MemberIterator member = FindMember(name);
- if (member != MemberEnd())
- return member->value;
- else {
- RAPIDJSON_ASSERT(false); // see above note
-
- // This will generate -Wexit-time-destructors in clang
- // static GenericValue NullValue;
- // return NullValue;
-
- // Use static buffer and placement-new to prevent destruction
- static char buffer[sizeof(GenericValue)];
- return *new (buffer) GenericValue();
- }
- }
- template <typename SourceAllocator>
- const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Get a value from an object associated with name (string object).
- GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
- const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
-#endif
-
- //! Const member iterator
- /*! \pre IsObject() == true */
- ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
- //! Const \em past-the-end member iterator
- /*! \pre IsObject() == true */
- ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
- //! Member iterator
- /*! \pre IsObject() == true */
- MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
- //! \em Past-the-end member iterator
- /*! \pre IsObject() == true */
- MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
-
- //! Check whether a member exists in the object.
- /*!
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Whether a member with that name exists.
- \note It is better to use FindMember() directly if you need the obtain the value as well.
- \note Linear time complexity.
- */
- bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Check whether a member exists in the object with string object.
- /*!
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Whether a member with that name exists.
- \note It is better to use FindMember() directly if you need the obtain the value as well.
- \note Linear time complexity.
- */
- bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
-#endif
-
- //! Check whether a member exists in the object with GenericValue name.
- /*!
- This version is faster because it does not need a StrLen(). It can also handle string with null character.
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Whether a member with that name exists.
- \note It is better to use FindMember() directly if you need the obtain the value as well.
- \note Linear time complexity.
- */
- template <typename SourceAllocator>
- bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
-
- //! Find member by name.
- /*!
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Iterator to member, if it exists.
- Otherwise returns \ref MemberEnd().
-
- \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
- the requested member doesn't exist. For consistency with e.g.
- \c std::map, this has been changed to MemberEnd() now.
- \note Linear time complexity.
- */
- MemberIterator FindMember(const Ch* name) {
- GenericValue n(StringRef(name));
- return FindMember(n);
- }
-
- ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
-
- //! Find member by name.
- /*!
- This version is faster because it does not need a StrLen(). It can also handle string with null character.
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Iterator to member, if it exists.
- Otherwise returns \ref MemberEnd().
-
- \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
- the requested member doesn't exist. For consistency with e.g.
- \c std::map, this has been changed to MemberEnd() now.
- \note Linear time complexity.
- */
- template <typename SourceAllocator>
- MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
- RAPIDJSON_ASSERT(IsObject());
- RAPIDJSON_ASSERT(name.IsString());
- MemberIterator member = MemberBegin();
- for ( ; member != MemberEnd(); ++member)
- if (name.StringEqual(member->name))
- break;
- return member;
- }
- template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Find member by string object name.
- /*!
- \param name Member name to be searched.
- \pre IsObject() == true
- \return Iterator to member, if it exists.
- Otherwise returns \ref MemberEnd().
- */
- MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
- ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
-#endif
-
- //! Add a member (name-value pair) to the object.
- /*! \param name A string value as name of member.
- \param value Value of any type.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \note The ownership of \c name and \c value will be transferred to this object on success.
- \pre IsObject() && name.IsString()
- \post name.IsNull() && value.IsNull()
- \note Amortized Constant time complexity.
- */
- GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
- RAPIDJSON_ASSERT(IsObject());
- RAPIDJSON_ASSERT(name.IsString());
-
- ObjectData& o = data_.o;
- if (o.size >= o.capacity) {
- if (o.capacity == 0) {
- o.capacity = kDefaultObjectCapacity;
- SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));
- }
- else {
- SizeType oldCapacity = o.capacity;
- o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
- SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));
- }
- }
- Member* members = GetMembersPointer();
- members[o.size].name.RawAssign(name);
- members[o.size].value.RawAssign(value);
- o.size++;
- return *this;
- }
-
- //! Add a constant string value as member (name-value pair) to the object.
- /*! \param name A string value as name of member.
- \param value constant string reference as value of member.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \pre IsObject()
- \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
- \note Amortized Constant time complexity.
- */
- GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
- GenericValue v(value);
- return AddMember(name, v, allocator);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Add a string object as member (name-value pair) to the object.
- /*! \param name A string value as name of member.
- \param value constant string reference as value of member.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \pre IsObject()
- \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
- \note Amortized Constant time complexity.
- */
- GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
- GenericValue v(value, allocator);
- return AddMember(name, v, allocator);
- }
-#endif
-
- //! Add any primitive value as member (name-value pair) to the object.
- /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
- \param name A string value as name of member.
- \param value Value of primitive type \c T as value of member
- \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \pre IsObject()
-
- \note The source type \c T explicitly disallows all pointer types,
- especially (\c const) \ref Ch*. This helps avoiding implicitly
- referencing character strings with insufficient lifetime, use
- \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
- AddMember(StringRefType, StringRefType, Allocator&).
- All other pointer types would implicitly convert to \c bool,
- use an explicit cast instead, if needed.
- \note Amortized Constant time complexity.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
- AddMember(GenericValue& name, T value, Allocator& allocator) {
- GenericValue v(value);
- return AddMember(name, v, allocator);
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
- return AddMember(name, value, allocator);
- }
- GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
- return AddMember(name, value, allocator);
- }
- GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
- return AddMember(name, value, allocator);
- }
- GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
- GenericValue n(name);
- return AddMember(n, value, allocator);
- }
-#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
-
-
- //! Add a member (name-value pair) to the object.
- /*! \param name A constant string reference as name of member.
- \param value Value of any type.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \note The ownership of \c value will be transferred to this object on success.
- \pre IsObject()
- \post value.IsNull()
- \note Amortized Constant time complexity.
- */
- GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
- GenericValue n(name);
- return AddMember(n, value, allocator);
- }
-
- //! Add a constant string value as member (name-value pair) to the object.
- /*! \param name A constant string reference as name of member.
- \param value constant string reference as value of member.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \pre IsObject()
- \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
- \note Amortized Constant time complexity.
- */
- GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
- GenericValue v(value);
- return AddMember(name, v, allocator);
- }
-
- //! Add any primitive value as member (name-value pair) to the object.
- /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
- \param name A constant string reference as name of member.
- \param value Value of primitive type \c T as value of member
- \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \pre IsObject()
-
- \note The source type \c T explicitly disallows all pointer types,
- especially (\c const) \ref Ch*. This helps avoiding implicitly
- referencing character strings with insufficient lifetime, use
- \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
- AddMember(StringRefType, StringRefType, Allocator&).
- All other pointer types would implicitly convert to \c bool,
- use an explicit cast instead, if needed.
- \note Amortized Constant time complexity.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
- AddMember(StringRefType name, T value, Allocator& allocator) {
- GenericValue n(name);
- return AddMember(n, value, allocator);
- }
-
- //! Remove all members in the object.
- /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
- \note Linear time complexity.
- */
- void RemoveAllMembers() {
- RAPIDJSON_ASSERT(IsObject());
- for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
- m->~Member();
- data_.o.size = 0;
- }
-
- //! Remove a member in object by its name.
- /*! \param name Name of member to be removed.
- \return Whether the member existed.
- \note This function may reorder the object members. Use \ref
- EraseMember(ConstMemberIterator) if you need to preserve the
- relative order of the remaining members.
- \note Linear time complexity.
- */
- bool RemoveMember(const Ch* name) {
- GenericValue n(StringRef(name));
- return RemoveMember(n);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
-#endif
-
- template <typename SourceAllocator>
- bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
- MemberIterator m = FindMember(name);
- if (m != MemberEnd()) {
- RemoveMember(m);
- return true;
- }
- else
- return false;
- }
-
- //! Remove a member in object by iterator.
- /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
- \return the new iterator after removal.
- \note This function may reorder the object members. Use \ref
- EraseMember(ConstMemberIterator) if you need to preserve the
- relative order of the remaining members.
- \note Constant time complexity.
- */
- MemberIterator RemoveMember(MemberIterator m) {
- RAPIDJSON_ASSERT(IsObject());
- RAPIDJSON_ASSERT(data_.o.size > 0);
- RAPIDJSON_ASSERT(GetMembersPointer() != 0);
- RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
-
- MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
- if (data_.o.size > 1 && m != last)
- *m = *last; // Move the last one to this place
- else
- m->~Member(); // Only one left, just destroy
- --data_.o.size;
- return m;
- }
-
- //! Remove a member from an object by iterator.
- /*! \param pos iterator to the member to remove
- \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
- \return Iterator following the removed element.
- If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
- \note This function preserves the relative order of the remaining object
- members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
- \note Linear time complexity.
- */
- MemberIterator EraseMember(ConstMemberIterator pos) {
- return EraseMember(pos, pos +1);
- }
-
- //! Remove members in the range [first, last) from an object.
- /*! \param first iterator to the first member to remove
- \param last iterator following the last member to remove
- \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
- \return Iterator following the last removed element.
- \note This function preserves the relative order of the remaining object
- members.
- \note Linear time complexity.
- */
- MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
- RAPIDJSON_ASSERT(IsObject());
- RAPIDJSON_ASSERT(data_.o.size > 0);
- RAPIDJSON_ASSERT(GetMembersPointer() != 0);
- RAPIDJSON_ASSERT(first >= MemberBegin());
- RAPIDJSON_ASSERT(first <= last);
- RAPIDJSON_ASSERT(last <= MemberEnd());
-
- MemberIterator pos = MemberBegin() + (first - MemberBegin());
- for (MemberIterator itr = pos; itr != last; ++itr)
- itr->~Member();
- std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
- data_.o.size -= static_cast<SizeType>(last - first);
- return pos;
- }
-
- //! Erase a member in object by its name.
- /*! \param name Name of member to be removed.
- \return Whether the member existed.
- \note Linear time complexity.
- */
- bool EraseMember(const Ch* name) {
- GenericValue n(StringRef(name));
- return EraseMember(n);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
-#endif
-
- template <typename SourceAllocator>
- bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
- MemberIterator m = FindMember(name);
- if (m != MemberEnd()) {
- EraseMember(m);
- return true;
- }
- else
- return false;
- }
-
- Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
- ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
-
- //@}
-
- //!@name Array
- //@{
-
- //! Set this value as an empty array.
- /*! \post IsArray == true */
- GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
-
- //! Get the number of elements in array.
- SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
-
- //! Get the capacity of array.
- SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
-
- //! Check whether the array is empty.
- bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
-
- //! Remove all elements in the array.
- /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
- \note Linear time complexity.
- */
- void Clear() {
- RAPIDJSON_ASSERT(IsArray());
- GenericValue* e = GetElementsPointer();
- for (GenericValue* v = e; v != e + data_.a.size; ++v)
- v->~GenericValue();
- data_.a.size = 0;
- }
-
- //! Get an element from array by index.
- /*! \pre IsArray() == true
- \param index Zero-based index of element.
- \see operator[](T*)
- */
- GenericValue& operator[](SizeType index) {
- RAPIDJSON_ASSERT(IsArray());
- RAPIDJSON_ASSERT(index < data_.a.size);
- return GetElementsPointer()[index];
- }
- const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
-
- //! Element iterator
- /*! \pre IsArray() == true */
- ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
- //! \em Past-the-end element iterator
- /*! \pre IsArray() == true */
- ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
- //! Constant element iterator
- /*! \pre IsArray() == true */
- ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
- //! Constant \em past-the-end element iterator
- /*! \pre IsArray() == true */
- ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
-
- //! Request the array to have enough capacity to store elements.
- /*! \param newCapacity The capacity that the array at least need to have.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \note Linear time complexity.
- */
- GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
- RAPIDJSON_ASSERT(IsArray());
- if (newCapacity > data_.a.capacity) {
- SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
- data_.a.capacity = newCapacity;
- }
- return *this;
- }
-
- //! Append a GenericValue at the end of the array.
- /*! \param value Value to be appended.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \pre IsArray() == true
- \post value.IsNull() == true
- \return The value itself for fluent API.
- \note The ownership of \c value will be transferred to this array on success.
- \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
- \note Amortized constant time complexity.
- */
- GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
- RAPIDJSON_ASSERT(IsArray());
- if (data_.a.size >= data_.a.capacity)
- Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
- GetElementsPointer()[data_.a.size++].RawAssign(value);
- return *this;
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
- return PushBack(value, allocator);
- }
-#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
-
- //! Append a constant string reference at the end of the array.
- /*! \param value Constant string reference to be appended.
- \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
- \pre IsArray() == true
- \return The value itself for fluent API.
- \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
- \note Amortized constant time complexity.
- \see GenericStringRef
- */
- GenericValue& PushBack(StringRefType value, Allocator& allocator) {
- return (*this).template PushBack<StringRefType>(value, allocator);
- }
-
- //! Append a primitive value at the end of the array.
- /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
- \param value Value of primitive type T to be appended.
- \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
- \pre IsArray() == true
- \return The value itself for fluent API.
- \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
-
- \note The source type \c T explicitly disallows all pointer types,
- especially (\c const) \ref Ch*. This helps avoiding implicitly
- referencing character strings with insufficient lifetime, use
- \ref PushBack(GenericValue&, Allocator&) or \ref
- PushBack(StringRefType, Allocator&).
- All other pointer types would implicitly convert to \c bool,
- use an explicit cast instead, if needed.
- \note Amortized constant time complexity.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
- PushBack(T value, Allocator& allocator) {
- GenericValue v(value);
- return PushBack(v, allocator);
- }
-
- //! Remove the last element in the array.
- /*!
- \note Constant time complexity.
- */
- GenericValue& PopBack() {
- RAPIDJSON_ASSERT(IsArray());
- RAPIDJSON_ASSERT(!Empty());
- GetElementsPointer()[--data_.a.size].~GenericValue();
- return *this;
- }
-
- //! Remove an element of array by iterator.
- /*!
- \param pos iterator to the element to remove
- \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
- \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
- \note Linear time complexity.
- */
- ValueIterator Erase(ConstValueIterator pos) {
- return Erase(pos, pos + 1);
- }
-
- //! Remove elements in the range [first, last) of the array.
- /*!
- \param first iterator to the first element to remove
- \param last iterator following the last element to remove
- \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
- \return Iterator following the last removed element.
- \note Linear time complexity.
- */
- ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
- RAPIDJSON_ASSERT(IsArray());
- RAPIDJSON_ASSERT(data_.a.size > 0);
- RAPIDJSON_ASSERT(GetElementsPointer() != 0);
- RAPIDJSON_ASSERT(first >= Begin());
- RAPIDJSON_ASSERT(first <= last);
- RAPIDJSON_ASSERT(last <= End());
- ValueIterator pos = Begin() + (first - Begin());
- for (ValueIterator itr = pos; itr != last; ++itr)
- itr->~GenericValue();
- std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
- data_.a.size -= static_cast<SizeType>(last - first);
- return pos;
- }
-
- Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
- ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
-
- //@}
-
- //!@name Number
- //@{
-
- int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
- unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
- int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
- uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
-
- //! Get the value as double type.
- /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
- */
- double GetDouble() const {
- RAPIDJSON_ASSERT(IsNumber());
- if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
- if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
- if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
- if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
- RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
- }
-
- //! Get the value as float type.
- /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
- */
- float GetFloat() const {
- return static_cast<float>(GetDouble());
- }
-
- GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
- GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
- GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
- GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
- GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
- GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
-
- //@}
-
- //!@name String
- //@{
-
- const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
-
- //! Get the length of string.
- /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
- */
- SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
-
- //! Set this value as a string without copying source string.
- /*! This version has better performance with supplied length, and also support string containing null character.
- \param s source string pointer.
- \param length The length of source string, excluding the trailing null terminator.
- \return The value itself for fluent API.
- \post IsString() == true && GetString() == s && GetStringLength() == length
- \see SetString(StringRefType)
- */
- GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
-
- //! Set this value as a string without copying source string.
- /*! \param s source string reference
- \return The value itself for fluent API.
- \post IsString() == true && GetString() == s && GetStringLength() == s.length
- */
- GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
-
- //! Set this value as a string by copying from source string.
- /*! This version has better performance with supplied length, and also support string containing null character.
- \param s source string.
- \param length The length of source string, excluding the trailing null terminator.
- \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
- */
- GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
-
- //! Set this value as a string by copying from source string.
- /*! \param s source string.
- \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
- */
- GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
-
- //! Set this value as a string by copying from source string.
- /*! \param s source string reference
- \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
- */
- GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Set this value as a string by copying from source string.
- /*! \param s source string.
- \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
- \return The value itself for fluent API.
- \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
- \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
- */
- GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
-#endif
-
- //@}
-
- //!@name Array
- //@{
-
- //! Templated version for checking whether this value is type T.
- /*!
- \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string<Ch>
- */
- template <typename T>
- bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
-
- template <typename T>
- T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
-
- template <typename T>
- T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
-
- template<typename T>
- ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
-
- template<typename T>
- ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
-
- //@}
-
- //! Generate events of this value to a Handler.
- /*! This function adopts the GoF visitor pattern.
- Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
- It can also be used to deep clone this value via GenericDocument, which is also a Handler.
- \tparam Handler type of handler.
- \param handler An object implementing concept Handler.
- */
- template <typename Handler>
- bool Accept(Handler& handler) const {
- switch(GetType()) {
- case kNullType: return handler.Null();
- case kFalseType: return handler.Bool(false);
- case kTrueType: return handler.Bool(true);
-
- case kObjectType:
- if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
- return false;
- for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
- RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
- if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
- return false;
- if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
- return false;
- }
- return handler.EndObject(data_.o.size);
-
- case kArrayType:
- if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
- return false;
- for (const GenericValue* v = Begin(); v != End(); ++v)
- if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
- return false;
- return handler.EndArray(data_.a.size);
-
- case kStringType:
- return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
-
- default:
- RAPIDJSON_ASSERT(GetType() == kNumberType);
- if (IsDouble()) return handler.Double(data_.n.d);
- else if (IsInt()) return handler.Int(data_.n.i.i);
- else if (IsUint()) return handler.Uint(data_.n.u.u);
- else if (IsInt64()) return handler.Int64(data_.n.i64);
- else return handler.Uint64(data_.n.u64);
- }
- }
-
-private:
- template <typename, typename> friend class GenericValue;
- template <typename, typename, typename> friend class GenericDocument;
-
- enum {
- kBoolFlag = 0x0008,
- kNumberFlag = 0x0010,
- kIntFlag = 0x0020,
- kUintFlag = 0x0040,
- kInt64Flag = 0x0080,
- kUint64Flag = 0x0100,
- kDoubleFlag = 0x0200,
- kStringFlag = 0x0400,
- kCopyFlag = 0x0800,
- kInlineStrFlag = 0x1000,
-
- // Initial flags of different types.
- kNullFlag = kNullType,
- kTrueFlag = kTrueType | kBoolFlag,
- kFalseFlag = kFalseType | kBoolFlag,
- kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
- kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
- kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
- kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
- kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
- kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
- kConstStringFlag = kStringType | kStringFlag,
- kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
- kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
- kObjectFlag = kObjectType,
- kArrayFlag = kArrayType,
-
- kTypeMask = 0x07
- };
-
- static const SizeType kDefaultArrayCapacity = 16;
- static const SizeType kDefaultObjectCapacity = 16;
-
- struct Flag {
-#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
- char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
-#elif RAPIDJSON_64BIT
- char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
-#else
- char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
-#endif
- uint16_t flags;
- };
-
- struct String {
- SizeType length;
- SizeType hashcode; //!< reserved
- const Ch* str;
- }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
-
- // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
- // (excluding the terminating zero) and store a value to determine the length of the contained
- // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
- // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
- // the string terminator as well. For getting the string length back from that value just use
- // "MaxSize - str[LenPos]".
- // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
- // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
- struct ShortString {
- enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
- Ch str[MaxChars];
-
- inline static bool Usable(SizeType len) { return (MaxSize >= len); }
- inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
- inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
- }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
-
- // By using proper binary layout, retrieval of different integer types do not need conversions.
- union Number {
-#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
- struct I {
- int i;
- char padding[4];
- }i;
- struct U {
- unsigned u;
- char padding2[4];
- }u;
-#else
- struct I {
- char padding[4];
- int i;
- }i;
- struct U {
- char padding2[4];
- unsigned u;
- }u;
-#endif
- int64_t i64;
- uint64_t u64;
- double d;
- }; // 8 bytes
-
- struct ObjectData {
- SizeType size;
- SizeType capacity;
- Member* members;
- }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
-
- struct ArrayData {
- SizeType size;
- SizeType capacity;
- GenericValue* elements;
- }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
-
- union Data {
- String s;
- ShortString ss;
- Number n;
- ObjectData o;
- ArrayData a;
- Flag f;
- }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
-
- RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
- RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
- RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
- RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
- RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
- RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
-
- // Initialize this value as array with initial data, without calling destructor.
- void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
- data_.f.flags = kArrayFlag;
- if (count) {
- GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
- SetElementsPointer(e);
- std::memcpy(e, values, count * sizeof(GenericValue));
- }
- else
- SetElementsPointer(0);
- data_.a.size = data_.a.capacity = count;
- }
-
- //! Initialize this value as object with initial data, without calling destructor.
- void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
- data_.f.flags = kObjectFlag;
- if (count) {
- Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
- SetMembersPointer(m);
- std::memcpy(m, members, count * sizeof(Member));
- }
- else
- SetMembersPointer(0);
- data_.o.size = data_.o.capacity = count;
- }
-
- //! Initialize this value as constant string, without calling destructor.
- void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
- data_.f.flags = kConstStringFlag;
- SetStringPointer(s);
- data_.s.length = s.length;
- }
-
- //! Initialize this value as copy string with initial data, without calling destructor.
- void SetStringRaw(StringRefType s, Allocator& allocator) {
- Ch* str = 0;
- if (ShortString::Usable(s.length)) {
- data_.f.flags = kShortStringFlag;
- data_.ss.SetLength(s.length);
- str = data_.ss.str;
- } else {
- data_.f.flags = kCopyStringFlag;
- data_.s.length = s.length;
- str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
- SetStringPointer(str);
- }
- std::memcpy(str, s, s.length * sizeof(Ch));
- str[s.length] = '\0';
- }
-
- //! Assignment without calling destructor
- void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
- data_ = rhs.data_;
- // data_.f.flags = rhs.data_.f.flags;
- rhs.data_.f.flags = kNullFlag;
- }
-
- template <typename SourceAllocator>
- bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
- RAPIDJSON_ASSERT(IsString());
- RAPIDJSON_ASSERT(rhs.IsString());
-
- const SizeType len1 = GetStringLength();
- const SizeType len2 = rhs.GetStringLength();
- if(len1 != len2) { return false; }
-
- const Ch* const str1 = GetString();
- const Ch* const str2 = rhs.GetString();
- if(str1 == str2) { return true; } // fast path for constant string
-
- return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
- }
-
- Data data_;
-};
-
-//! GenericValue with UTF8 encoding
-typedef GenericValue<UTF8<> > Value;
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericDocument
-
-//! A document for parsing JSON text as DOM.
-/*!
- \note implements Handler concept
- \tparam Encoding Encoding for both parsing and string storage.
- \tparam Allocator Allocator for allocating memory for the DOM
- \tparam StackAllocator Allocator for allocating memory for stack during parsing.
- \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
-*/
-template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
-class GenericDocument : public GenericValue<Encoding, Allocator> {
-public:
- typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
- typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
- typedef Allocator AllocatorType; //!< Allocator type from template parameter.
-
- //! Constructor
- /*! Creates an empty document of specified type.
- \param type Mandatory type of object to create.
- \param allocator Optional allocator for allocating memory.
- \param stackCapacity Optional initial capacity of stack in bytes.
- \param stackAllocator Optional allocator for allocating memory for stack.
- */
- explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
- GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
- {
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
- }
-
- //! Constructor
- /*! Creates an empty document which type is Null.
- \param allocator Optional allocator for allocating memory.
- \param stackCapacity Optional initial capacity of stack in bytes.
- \param stackAllocator Optional allocator for allocating memory for stack.
- */
- GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
- allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
- {
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Move constructor in C++11
- GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
- : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
- allocator_(rhs.allocator_),
- ownAllocator_(rhs.ownAllocator_),
- stack_(std::move(rhs.stack_)),
- parseResult_(rhs.parseResult_)
- {
- rhs.allocator_ = 0;
- rhs.ownAllocator_ = 0;
- rhs.parseResult_ = ParseResult();
- }
-#endif
-
- ~GenericDocument() {
- Destroy();
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Move assignment in C++11
- GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
- {
- // The cast to ValueType is necessary here, because otherwise it would
- // attempt to call GenericValue's templated assignment operator.
- ValueType::operator=(std::forward<ValueType>(rhs));
-
- // Calling the destructor here would prematurely call stack_'s destructor
- Destroy();
-
- allocator_ = rhs.allocator_;
- ownAllocator_ = rhs.ownAllocator_;
- stack_ = std::move(rhs.stack_);
- parseResult_ = rhs.parseResult_;
-
- rhs.allocator_ = 0;
- rhs.ownAllocator_ = 0;
- rhs.parseResult_ = ParseResult();
-
- return *this;
- }
-#endif
-
- //! Exchange the contents of this document with those of another.
- /*!
- \param rhs Another document.
- \note Constant complexity.
- \see GenericValue::Swap
- */
- GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
- ValueType::Swap(rhs);
- stack_.Swap(rhs.stack_);
- internal::Swap(allocator_, rhs.allocator_);
- internal::Swap(ownAllocator_, rhs.ownAllocator_);
- internal::Swap(parseResult_, rhs.parseResult_);
- return *this;
- }
-
- // Allow Swap with ValueType.
- // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
- using ValueType::Swap;
-
- //! free-standing swap function helper
- /*!
- Helper function to enable support for common swap implementation pattern based on \c std::swap:
- \code
- void swap(MyClass& a, MyClass& b) {
- using std::swap;
- swap(a.doc, b.doc);
- // ...
- }
- \endcode
- \see Swap()
- */
- friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
-
- //! Populate this document by a generator which produces SAX events.
- /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
- \param g Generator functor which sends SAX events to the parameter.
- \return The document itself for fluent API.
- */
- template <typename Generator>
- GenericDocument& Populate(Generator& g) {
- ClearStackOnExit scope(*this);
- if (g(*this)) {
- RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
- ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
- }
- return *this;
- }
-
- //!@name Parse from stream
- //!@{
-
- //! Parse JSON text from an input stream (with Encoding conversion)
- /*! \tparam parseFlags Combination of \ref ParseFlag.
- \tparam SourceEncoding Encoding of input stream
- \tparam InputStream Type of input stream, implementing Stream concept
- \param is Input stream to be parsed.
- \return The document itself for fluent API.
- */
- template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
- GenericDocument& ParseStream(InputStream& is) {
- GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
- stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
- ClearStackOnExit scope(*this);
- parseResult_ = reader.template Parse<parseFlags>(is, *this);
- if (parseResult_) {
- RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
- ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
- }
- return *this;
- }
-
- //! Parse JSON text from an input stream
- /*! \tparam parseFlags Combination of \ref ParseFlag.
- \tparam InputStream Type of input stream, implementing Stream concept
- \param is Input stream to be parsed.
- \return The document itself for fluent API.
- */
- template <unsigned parseFlags, typename InputStream>
- GenericDocument& ParseStream(InputStream& is) {
- return ParseStream<parseFlags, Encoding, InputStream>(is);
- }
-
- //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
- /*! \tparam InputStream Type of input stream, implementing Stream concept
- \param is Input stream to be parsed.
- \return The document itself for fluent API.
- */
- template <typename InputStream>
- GenericDocument& ParseStream(InputStream& is) {
- return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
- }
- //!@}
-
- //!@name Parse in-place from mutable string
- //!@{
-
- //! Parse JSON text from a mutable string
- /*! \tparam parseFlags Combination of \ref ParseFlag.
- \param str Mutable zero-terminated string to be parsed.
- \return The document itself for fluent API.
- */
- template <unsigned parseFlags>
- GenericDocument& ParseInsitu(Ch* str) {
- GenericInsituStringStream<Encoding> s(str);
- return ParseStream<parseFlags | kParseInsituFlag>(s);
- }
-
- //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
- /*! \param str Mutable zero-terminated string to be parsed.
- \return The document itself for fluent API.
- */
- GenericDocument& ParseInsitu(Ch* str) {
- return ParseInsitu<kParseDefaultFlags>(str);
- }
- //!@}
-
- //!@name Parse from read-only string
- //!@{
-
- //! Parse JSON text from a read-only string (with Encoding conversion)
- /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
- \tparam SourceEncoding Transcoding from input Encoding
- \param str Read-only zero-terminated string to be parsed.
- */
- template <unsigned parseFlags, typename SourceEncoding>
- GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
- RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
- GenericStringStream<SourceEncoding> s(str);
- return ParseStream<parseFlags, SourceEncoding>(s);
- }
-
- //! Parse JSON text from a read-only string
- /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
- \param str Read-only zero-terminated string to be parsed.
- */
- template <unsigned parseFlags>
- GenericDocument& Parse(const Ch* str) {
- return Parse<parseFlags, Encoding>(str);
- }
-
- //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
- /*! \param str Read-only zero-terminated string to be parsed.
- */
- GenericDocument& Parse(const Ch* str) {
- return Parse<kParseDefaultFlags>(str);
- }
-
- template <unsigned parseFlags, typename SourceEncoding>
- GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
- RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
- MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
- EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
- ParseStream<parseFlags, SourceEncoding>(is);
- return *this;
- }
-
- template <unsigned parseFlags>
- GenericDocument& Parse(const Ch* str, size_t length) {
- return Parse<parseFlags, Encoding>(str, length);
- }
-
- GenericDocument& Parse(const Ch* str, size_t length) {
- return Parse<kParseDefaultFlags>(str, length);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- template <unsigned parseFlags, typename SourceEncoding>
- GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
- // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
- return Parse<parseFlags, SourceEncoding>(str.c_str());
- }
-
- template <unsigned parseFlags>
- GenericDocument& Parse(const std::basic_string<Ch>& str) {
- return Parse<parseFlags, Encoding>(str.c_str());
- }
-
- GenericDocument& Parse(const std::basic_string<Ch>& str) {
- return Parse<kParseDefaultFlags>(str);
- }
-#endif // RAPIDJSON_HAS_STDSTRING
-
- //!@}
-
- //!@name Handling parse errors
- //!@{
-
- //! Whether a parse error has occured in the last parsing.
- bool HasParseError() const { return parseResult_.IsError(); }
-
- //! Get the \ref ParseErrorCode of last parsing.
- ParseErrorCode GetParseError() const { return parseResult_.Code(); }
-
- //! Get the position of last parsing error in input, 0 otherwise.
- size_t GetErrorOffset() const { return parseResult_.Offset(); }
-
- //! Implicit conversion to get the last parse result
-#ifndef __clang // -Wdocumentation
- /*! \return \ref ParseResult of the last parse operation
-
- \code
- Document doc;
- ParseResult ok = doc.Parse(json);
- if (!ok)
- printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
- \endcode
- */
-#endif
- operator ParseResult() const { return parseResult_; }
- //!@}
-
- //! Get the allocator of this document.
- Allocator& GetAllocator() {
- RAPIDJSON_ASSERT(allocator_);
- return *allocator_;
- }
-
- //! Get the capacity of stack in bytes.
- size_t GetStackCapacity() const { return stack_.GetCapacity(); }
-
-private:
- // clear stack on any exit from ParseStream, e.g. due to exception
- struct ClearStackOnExit {
- explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
- ~ClearStackOnExit() { d_.ClearStack(); }
- private:
- ClearStackOnExit(const ClearStackOnExit&);
- ClearStackOnExit& operator=(const ClearStackOnExit&);
- GenericDocument& d_;
- };
-
- // callers of the following private Handler functions
- // template <typename,typename,typename> friend class GenericReader; // for parsing
- template <typename, typename> friend class GenericValue; // for deep copying
-
-public:
- // Implementation of Handler
- bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
- bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
- bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
- bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
- bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
- bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
- bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
-
- bool RawNumber(const Ch* str, SizeType length, bool copy) {
- if (copy)
- new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
- else
- new (stack_.template Push<ValueType>()) ValueType(str, length);
- return true;
- }
-
- bool String(const Ch* str, SizeType length, bool copy) {
- if (copy)
- new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
- else
- new (stack_.template Push<ValueType>()) ValueType(str, length);
- return true;
- }
-
- bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
-
- bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
-
- bool EndObject(SizeType memberCount) {
- typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
- stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
- return true;
- }
-
- bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
-
- bool EndArray(SizeType elementCount) {
- ValueType* elements = stack_.template Pop<ValueType>(elementCount);
- stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
- return true;
- }
-
-private:
- //! Prohibit copying
- GenericDocument(const GenericDocument&);
- //! Prohibit assignment
- GenericDocument& operator=(const GenericDocument&);
-
- void ClearStack() {
- if (Allocator::kNeedFree)
- while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
- (stack_.template Pop<ValueType>(1))->~ValueType();
- else
- stack_.Clear();
- stack_.ShrinkToFit();
- }
-
- void Destroy() {
- RAPIDJSON_DELETE(ownAllocator_);
- }
-
- static const size_t kDefaultStackCapacity = 1024;
- Allocator* allocator_;
- Allocator* ownAllocator_;
- internal::Stack<StackAllocator> stack_;
- ParseResult parseResult_;
-};
-
-//! GenericDocument with UTF8 encoding
-typedef GenericDocument<UTF8<> > Document;
-
-//! Helper class for accessing Value of array type.
-/*!
- Instance of this helper class is obtained by \c GenericValue::GetArray().
- In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
-*/
-template <bool Const, typename ValueT>
-class GenericArray {
-public:
- typedef GenericArray<true, ValueT> ConstArray;
- typedef GenericArray<false, ValueT> Array;
- typedef ValueT PlainType;
- typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
- typedef ValueType* ValueIterator; // This may be const or non-const iterator
- typedef const ValueT* ConstValueIterator;
- typedef typename ValueType::AllocatorType AllocatorType;
- typedef typename ValueType::StringRefType StringRefType;
-
- template <typename, typename>
- friend class GenericValue;
-
- GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
- GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
- ~GenericArray() {}
-
- SizeType Size() const { return value_.Size(); }
- SizeType Capacity() const { return value_.Capacity(); }
- bool Empty() const { return value_.Empty(); }
- void Clear() const { value_.Clear(); }
- ValueType& operator[](SizeType index) const { return value_[index]; }
- ValueIterator Begin() const { return value_.Begin(); }
- ValueIterator End() const { return value_.End(); }
- GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
- GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
-#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
- template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
- GenericArray PopBack() const { value_.PopBack(); return *this; }
- ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
- ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
-
-#if RAPIDJSON_HAS_CXX11_RANGE_FOR
- ValueIterator begin() const { return value_.Begin(); }
- ValueIterator end() const { return value_.End(); }
-#endif
-
-private:
- GenericArray();
- GenericArray(ValueType& value) : value_(value) {}
- ValueType& value_;
-};
-
-//! Helper class for accessing Value of object type.
-/*!
- Instance of this helper class is obtained by \c GenericValue::GetObject().
- In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
-*/
-template <bool Const, typename ValueT>
-class GenericObject {
-public:
- typedef GenericObject<true, ValueT> ConstObject;
- typedef GenericObject<false, ValueT> Object;
- typedef ValueT PlainType;
- typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
- typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
- typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
- typedef typename ValueType::AllocatorType AllocatorType;
- typedef typename ValueType::StringRefType StringRefType;
- typedef typename ValueType::EncodingType EncodingType;
- typedef typename ValueType::Ch Ch;
-
- template <typename, typename>
- friend class GenericValue;
-
- GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
- GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
- ~GenericObject() {}
-
- SizeType MemberCount() const { return value_.MemberCount(); }
- bool ObjectEmpty() const { return value_.ObjectEmpty(); }
- template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
- template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
-#if RAPIDJSON_HAS_STDSTRING
- ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
-#endif
- MemberIterator MemberBegin() const { return value_.MemberBegin(); }
- MemberIterator MemberEnd() const { return value_.MemberEnd(); }
- bool HasMember(const Ch* name) const { return value_.HasMember(name); }
-#if RAPIDJSON_HAS_STDSTRING
- bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
-#endif
- template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
- MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
- template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
-#if RAPIDJSON_HAS_STDSTRING
- MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
-#endif
- GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
-#if RAPIDJSON_HAS_STDSTRING
- GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
-#endif
- template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
-#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
- void RemoveAllMembers() { value_.RemoveAllMembers(); }
- bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
-#if RAPIDJSON_HAS_STDSTRING
- bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
-#endif
- template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
- MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
- MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
- MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
- bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
-#if RAPIDJSON_HAS_STDSTRING
- bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
-#endif
- template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
-
-#if RAPIDJSON_HAS_CXX11_RANGE_FOR
- MemberIterator begin() const { return value_.MemberBegin(); }
- MemberIterator end() const { return value_.MemberEnd(); }
-#endif
-
-private:
- GenericObject();
- GenericObject(ValueType& value) : value_(value) {}
- ValueType& value_;
-};
-
-RAPIDJSON_NAMESPACE_END
-RAPIDJSON_DIAG_POP
-
-#endif // RAPIDJSON_DOCUMENT_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodedstream.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodedstream.h
deleted file mode 100644
index 223601c05..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodedstream.h
+++ /dev/null
@@ -1,299 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ENCODEDSTREAM_H_
-#define RAPIDJSON_ENCODEDSTREAM_H_
-
-#include "stream.h"
-#include "memorystream.h"
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Input byte stream wrapper with a statically bound encoding.
-/*!
- \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
- \tparam InputByteStream Type of input byte stream. For example, FileReadStream.
-*/
-template <typename Encoding, typename InputByteStream>
-class EncodedInputStream {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-public:
- typedef typename Encoding::Ch Ch;
-
- EncodedInputStream(InputByteStream& is) : is_(is) {
- current_ = Encoding::TakeBOM(is_);
- }
-
- Ch Peek() const { return current_; }
- Ch Take() { Ch c = current_; current_ = Encoding::Take(is_); return c; }
- size_t Tell() const { return is_.Tell(); }
-
- // Not implemented
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- EncodedInputStream(const EncodedInputStream&);
- EncodedInputStream& operator=(const EncodedInputStream&);
-
- InputByteStream& is_;
- Ch current_;
-};
-
-//! Specialized for UTF8 MemoryStream.
-template <>
-class EncodedInputStream<UTF8<>, MemoryStream> {
-public:
- typedef UTF8<>::Ch Ch;
-
- EncodedInputStream(MemoryStream& is) : is_(is) {
- if (static_cast<unsigned char>(is_.Peek()) == 0xEFu) is_.Take();
- if (static_cast<unsigned char>(is_.Peek()) == 0xBBu) is_.Take();
- if (static_cast<unsigned char>(is_.Peek()) == 0xBFu) is_.Take();
- }
- Ch Peek() const { return is_.Peek(); }
- Ch Take() { return is_.Take(); }
- size_t Tell() const { return is_.Tell(); }
-
- // Not implemented
- void Put(Ch) {}
- void Flush() {}
- Ch* PutBegin() { return 0; }
- size_t PutEnd(Ch*) { return 0; }
-
- MemoryStream& is_;
-
-private:
- EncodedInputStream(const EncodedInputStream&);
- EncodedInputStream& operator=(const EncodedInputStream&);
-};
-
-//! Output byte stream wrapper with statically bound encoding.
-/*!
- \tparam Encoding The interpretation of encoding of the stream. Either UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE.
- \tparam OutputByteStream Type of input byte stream. For example, FileWriteStream.
-*/
-template <typename Encoding, typename OutputByteStream>
-class EncodedOutputStream {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-public:
- typedef typename Encoding::Ch Ch;
-
- EncodedOutputStream(OutputByteStream& os, bool putBOM = true) : os_(os) {
- if (putBOM)
- Encoding::PutBOM(os_);
- }
-
- void Put(Ch c) { Encoding::Put(os_, c); }
- void Flush() { os_.Flush(); }
-
- // Not implemented
- Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
- Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
- size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- EncodedOutputStream(const EncodedOutputStream&);
- EncodedOutputStream& operator=(const EncodedOutputStream&);
-
- OutputByteStream& os_;
-};
-
-#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
-
-//! Input stream wrapper with dynamically bound encoding and automatic encoding detection.
-/*!
- \tparam CharType Type of character for reading.
- \tparam InputByteStream type of input byte stream to be wrapped.
-*/
-template <typename CharType, typename InputByteStream>
-class AutoUTFInputStream {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
-public:
- typedef CharType Ch;
-
- //! Constructor.
- /*!
- \param is input stream to be wrapped.
- \param type UTF encoding type if it is not detected from the stream.
- */
- AutoUTFInputStream(InputByteStream& is, UTFType type = kUTF8) : is_(&is), type_(type), hasBOM_(false) {
- RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
- DetectType();
- static const TakeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Take) };
- takeFunc_ = f[type_];
- current_ = takeFunc_(*is_);
- }
-
- UTFType GetType() const { return type_; }
- bool HasBOM() const { return hasBOM_; }
-
- Ch Peek() const { return current_; }
- Ch Take() { Ch c = current_; current_ = takeFunc_(*is_); return c; }
- size_t Tell() const { return is_->Tell(); }
-
- // Not implemented
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- AutoUTFInputStream(const AutoUTFInputStream&);
- AutoUTFInputStream& operator=(const AutoUTFInputStream&);
-
- // Detect encoding type with BOM or RFC 4627
- void DetectType() {
- // BOM (Byte Order Mark):
- // 00 00 FE FF UTF-32BE
- // FF FE 00 00 UTF-32LE
- // FE FF UTF-16BE
- // FF FE UTF-16LE
- // EF BB BF UTF-8
-
- const unsigned char* c = reinterpret_cast<const unsigned char *>(is_->Peek4());
- if (!c)
- return;
-
- unsigned bom = static_cast<unsigned>(c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24));
- hasBOM_ = false;
- if (bom == 0xFFFE0000) { type_ = kUTF32BE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
- else if (bom == 0x0000FEFF) { type_ = kUTF32LE; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); is_->Take(); }
- else if ((bom & 0xFFFF) == 0xFFFE) { type_ = kUTF16BE; hasBOM_ = true; is_->Take(); is_->Take(); }
- else if ((bom & 0xFFFF) == 0xFEFF) { type_ = kUTF16LE; hasBOM_ = true; is_->Take(); is_->Take(); }
- else if ((bom & 0xFFFFFF) == 0xBFBBEF) { type_ = kUTF8; hasBOM_ = true; is_->Take(); is_->Take(); is_->Take(); }
-
- // RFC 4627: Section 3
- // "Since the first two characters of a JSON text will always be ASCII
- // characters [RFC0020], it is possible to determine whether an octet
- // stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking
- // at the pattern of nulls in the first four octets."
- // 00 00 00 xx UTF-32BE
- // 00 xx 00 xx UTF-16BE
- // xx 00 00 00 UTF-32LE
- // xx 00 xx 00 UTF-16LE
- // xx xx xx xx UTF-8
-
- if (!hasBOM_) {
- int pattern = (c[0] ? 1 : 0) | (c[1] ? 2 : 0) | (c[2] ? 4 : 0) | (c[3] ? 8 : 0);
- switch (pattern) {
- case 0x08: type_ = kUTF32BE; break;
- case 0x0A: type_ = kUTF16BE; break;
- case 0x01: type_ = kUTF32LE; break;
- case 0x05: type_ = kUTF16LE; break;
- case 0x0F: type_ = kUTF8; break;
- default: break; // Use type defined by user.
- }
- }
-
- // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
- if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
- if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
- }
-
- typedef Ch (*TakeFunc)(InputByteStream& is);
- InputByteStream* is_;
- UTFType type_;
- Ch current_;
- TakeFunc takeFunc_;
- bool hasBOM_;
-};
-
-//! Output stream wrapper with dynamically bound encoding and automatic encoding detection.
-/*!
- \tparam CharType Type of character for writing.
- \tparam OutputByteStream type of output byte stream to be wrapped.
-*/
-template <typename CharType, typename OutputByteStream>
-class AutoUTFOutputStream {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
-public:
- typedef CharType Ch;
-
- //! Constructor.
- /*!
- \param os output stream to be wrapped.
- \param type UTF encoding type.
- \param putBOM Whether to write BOM at the beginning of the stream.
- */
- AutoUTFOutputStream(OutputByteStream& os, UTFType type, bool putBOM) : os_(&os), type_(type) {
- RAPIDJSON_ASSERT(type >= kUTF8 && type <= kUTF32BE);
-
- // Runtime check whether the size of character type is sufficient. It only perform checks with assertion.
- if (type_ == kUTF16LE || type_ == kUTF16BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 2);
- if (type_ == kUTF32LE || type_ == kUTF32BE) RAPIDJSON_ASSERT(sizeof(Ch) >= 4);
-
- static const PutFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Put) };
- putFunc_ = f[type_];
-
- if (putBOM)
- PutBOM();
- }
-
- UTFType GetType() const { return type_; }
-
- void Put(Ch c) { putFunc_(*os_, c); }
- void Flush() { os_->Flush(); }
-
- // Not implemented
- Ch Peek() const { RAPIDJSON_ASSERT(false); return 0;}
- Ch Take() { RAPIDJSON_ASSERT(false); return 0;}
- size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- AutoUTFOutputStream(const AutoUTFOutputStream&);
- AutoUTFOutputStream& operator=(const AutoUTFOutputStream&);
-
- void PutBOM() {
- typedef void (*PutBOMFunc)(OutputByteStream&);
- static const PutBOMFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(PutBOM) };
- f[type_](*os_);
- }
-
- typedef void (*PutFunc)(OutputByteStream&, Ch);
-
- OutputByteStream* os_;
- UTFType type_;
- PutFunc putFunc_;
-};
-
-#undef RAPIDJSON_ENCODINGS_FUNC
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_FILESTREAM_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodings.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodings.h
deleted file mode 100644
index 0df1c3435..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/encodings.h
+++ /dev/null
@@ -1,716 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ENCODINGS_H_
-#define RAPIDJSON_ENCODINGS_H_
-
-#include "rapidjson.h"
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4244) // conversion from 'type1' to 'type2', possible loss of data
-RAPIDJSON_DIAG_OFF(4702) // unreachable code
-#elif defined(__GNUC__)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-RAPIDJSON_DIAG_OFF(overflow)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Encoding
-
-/*! \class rapidjson::Encoding
- \brief Concept for encoding of Unicode characters.
-
-\code
-concept Encoding {
- typename Ch; //! Type of character. A "character" is actually a code unit in unicode's definition.
-
- enum { supportUnicode = 1 }; // or 0 if not supporting unicode
-
- //! \brief Encode a Unicode codepoint to an output stream.
- //! \param os Output stream.
- //! \param codepoint An unicode codepoint, ranging from 0x0 to 0x10FFFF inclusively.
- template<typename OutputStream>
- static void Encode(OutputStream& os, unsigned codepoint);
-
- //! \brief Decode a Unicode codepoint from an input stream.
- //! \param is Input stream.
- //! \param codepoint Output of the unicode codepoint.
- //! \return true if a valid codepoint can be decoded from the stream.
- template <typename InputStream>
- static bool Decode(InputStream& is, unsigned* codepoint);
-
- //! \brief Validate one Unicode codepoint from an encoded stream.
- //! \param is Input stream to obtain codepoint.
- //! \param os Output for copying one codepoint.
- //! \return true if it is valid.
- //! \note This function just validating and copying the codepoint without actually decode it.
- template <typename InputStream, typename OutputStream>
- static bool Validate(InputStream& is, OutputStream& os);
-
- // The following functions are deal with byte streams.
-
- //! Take a character from input byte stream, skip BOM if exist.
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is);
-
- //! Take a character from input byte stream.
- template <typename InputByteStream>
- static Ch Take(InputByteStream& is);
-
- //! Put BOM to output byte stream.
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os);
-
- //! Put a character to output byte stream.
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, Ch c);
-};
-\endcode
-*/
-
-///////////////////////////////////////////////////////////////////////////////
-// UTF8
-
-//! UTF-8 encoding.
-/*! http://en.wikipedia.org/wiki/UTF-8
- http://tools.ietf.org/html/rfc3629
- \tparam CharType Code unit for storing 8-bit UTF-8 data. Default is char.
- \note implements Encoding concept
-*/
-template<typename CharType = char>
-struct UTF8 {
- typedef CharType Ch;
-
- enum { supportUnicode = 1 };
-
- template<typename OutputStream>
- static void Encode(OutputStream& os, unsigned codepoint) {
- if (codepoint <= 0x7F)
- os.Put(static_cast<Ch>(codepoint & 0xFF));
- else if (codepoint <= 0x7FF) {
- os.Put(static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
- os.Put(static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
- }
- else if (codepoint <= 0xFFFF) {
- os.Put(static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
- os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
- os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
- }
- else {
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- os.Put(static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
- os.Put(static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
- os.Put(static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
- os.Put(static_cast<Ch>(0x80 | (codepoint & 0x3F)));
- }
- }
-
- template<typename OutputStream>
- static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
- if (codepoint <= 0x7F)
- PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
- else if (codepoint <= 0x7FF) {
- PutUnsafe(os, static_cast<Ch>(0xC0 | ((codepoint >> 6) & 0xFF)));
- PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint & 0x3F))));
- }
- else if (codepoint <= 0xFFFF) {
- PutUnsafe(os, static_cast<Ch>(0xE0 | ((codepoint >> 12) & 0xFF)));
- PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
- PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
- }
- else {
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- PutUnsafe(os, static_cast<Ch>(0xF0 | ((codepoint >> 18) & 0xFF)));
- PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 12) & 0x3F)));
- PutUnsafe(os, static_cast<Ch>(0x80 | ((codepoint >> 6) & 0x3F)));
- PutUnsafe(os, static_cast<Ch>(0x80 | (codepoint & 0x3F)));
- }
- }
-
- template <typename InputStream>
- static bool Decode(InputStream& is, unsigned* codepoint) {
-#define COPY() c = is.Take(); *codepoint = (*codepoint << 6) | (static_cast<unsigned char>(c) & 0x3Fu)
-#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
-#define TAIL() COPY(); TRANS(0x70)
- typename InputStream::Ch c = is.Take();
- if (!(c & 0x80)) {
- *codepoint = static_cast<unsigned char>(c);
- return true;
- }
-
- unsigned char type = GetRange(static_cast<unsigned char>(c));
- if (type >= 32) {
- *codepoint = 0;
- } else {
- *codepoint = (0xFFu >> type) & static_cast<unsigned char>(c);
- }
- bool result = true;
- switch (type) {
- case 2: TAIL(); return result;
- case 3: TAIL(); TAIL(); return result;
- case 4: COPY(); TRANS(0x50); TAIL(); return result;
- case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
- case 6: TAIL(); TAIL(); TAIL(); return result;
- case 10: COPY(); TRANS(0x20); TAIL(); return result;
- case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
- default: return false;
- }
-#undef COPY
-#undef TRANS
-#undef TAIL
- }
-
- template <typename InputStream, typename OutputStream>
- static bool Validate(InputStream& is, OutputStream& os) {
-#define COPY() os.Put(c = is.Take())
-#define TRANS(mask) result &= ((GetRange(static_cast<unsigned char>(c)) & mask) != 0)
-#define TAIL() COPY(); TRANS(0x70)
- Ch c;
- COPY();
- if (!(c & 0x80))
- return true;
-
- bool result = true;
- switch (GetRange(static_cast<unsigned char>(c))) {
- case 2: TAIL(); return result;
- case 3: TAIL(); TAIL(); return result;
- case 4: COPY(); TRANS(0x50); TAIL(); return result;
- case 5: COPY(); TRANS(0x10); TAIL(); TAIL(); return result;
- case 6: TAIL(); TAIL(); TAIL(); return result;
- case 10: COPY(); TRANS(0x20); TAIL(); return result;
- case 11: COPY(); TRANS(0x60); TAIL(); TAIL(); return result;
- default: return false;
- }
-#undef COPY
-#undef TRANS
-#undef TAIL
- }
-
- static unsigned char GetRange(unsigned char c) {
- // Referring to DFA of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
- // With new mapping 1 -> 0x10, 7 -> 0x20, 9 -> 0x40, such that AND operation can test multiple types.
- static const unsigned char type[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
- 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
- 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
- 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
- 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
- };
- return type[c];
- }
-
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- typename InputByteStream::Ch c = Take(is);
- if (static_cast<unsigned char>(c) != 0xEFu) return c;
- c = is.Take();
- if (static_cast<unsigned char>(c) != 0xBBu) return c;
- c = is.Take();
- if (static_cast<unsigned char>(c) != 0xBFu) return c;
- c = is.Take();
- return c;
- }
-
- template <typename InputByteStream>
- static Ch Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- return static_cast<Ch>(is.Take());
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(0xEFu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xBBu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xBFu));
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, Ch c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(c));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// UTF16
-
-//! UTF-16 encoding.
-/*! http://en.wikipedia.org/wiki/UTF-16
- http://tools.ietf.org/html/rfc2781
- \tparam CharType Type for storing 16-bit UTF-16 data. Default is wchar_t. C++11 may use char16_t instead.
- \note implements Encoding concept
-
- \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
- For streaming, use UTF16LE and UTF16BE, which handle endianness.
-*/
-template<typename CharType = wchar_t>
-struct UTF16 {
- typedef CharType Ch;
- RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 2);
-
- enum { supportUnicode = 1 };
-
- template<typename OutputStream>
- static void Encode(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
- if (codepoint <= 0xFFFF) {
- RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
- os.Put(static_cast<typename OutputStream::Ch>(codepoint));
- }
- else {
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- unsigned v = codepoint - 0x10000;
- os.Put(static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
- os.Put(static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
- }
- }
-
-
- template<typename OutputStream>
- static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
- if (codepoint <= 0xFFFF) {
- RAPIDJSON_ASSERT(codepoint < 0xD800 || codepoint > 0xDFFF); // Code point itself cannot be surrogate pair
- PutUnsafe(os, static_cast<typename OutputStream::Ch>(codepoint));
- }
- else {
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- unsigned v = codepoint - 0x10000;
- PutUnsafe(os, static_cast<typename OutputStream::Ch>((v >> 10) | 0xD800));
- PutUnsafe(os, static_cast<typename OutputStream::Ch>((v & 0x3FF) | 0xDC00));
- }
- }
-
- template <typename InputStream>
- static bool Decode(InputStream& is, unsigned* codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
- typename InputStream::Ch c = is.Take();
- if (c < 0xD800 || c > 0xDFFF) {
- *codepoint = static_cast<unsigned>(c);
- return true;
- }
- else if (c <= 0xDBFF) {
- *codepoint = (static_cast<unsigned>(c) & 0x3FF) << 10;
- c = is.Take();
- *codepoint |= (static_cast<unsigned>(c) & 0x3FF);
- *codepoint += 0x10000;
- return c >= 0xDC00 && c <= 0xDFFF;
- }
- return false;
- }
-
- template <typename InputStream, typename OutputStream>
- static bool Validate(InputStream& is, OutputStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 2);
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 2);
- typename InputStream::Ch c;
- os.Put(static_cast<typename OutputStream::Ch>(c = is.Take()));
- if (c < 0xD800 || c > 0xDFFF)
- return true;
- else if (c <= 0xDBFF) {
- os.Put(c = is.Take());
- return c >= 0xDC00 && c <= 0xDFFF;
- }
- return false;
- }
-};
-
-//! UTF-16 little endian encoding.
-template<typename CharType = wchar_t>
-struct UTF16LE : UTF16<CharType> {
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- CharType c = Take(is);
- return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
- }
-
- template <typename InputByteStream>
- static CharType Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- unsigned c = static_cast<uint8_t>(is.Take());
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
- return static_cast<CharType>(c);
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, CharType c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
- }
-};
-
-//! UTF-16 big endian encoding.
-template<typename CharType = wchar_t>
-struct UTF16BE : UTF16<CharType> {
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- CharType c = Take(is);
- return static_cast<uint16_t>(c) == 0xFEFFu ? Take(is) : c;
- }
-
- template <typename InputByteStream>
- static CharType Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
- c |= static_cast<uint8_t>(is.Take());
- return static_cast<CharType>(c);
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, CharType c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>((static_cast<unsigned>(c) >> 8) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>(static_cast<unsigned>(c) & 0xFFu));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// UTF32
-
-//! UTF-32 encoding.
-/*! http://en.wikipedia.org/wiki/UTF-32
- \tparam CharType Type for storing 32-bit UTF-32 data. Default is unsigned. C++11 may use char32_t instead.
- \note implements Encoding concept
-
- \note For in-memory access, no need to concern endianness. The code units and code points are represented by CPU's endianness.
- For streaming, use UTF32LE and UTF32BE, which handle endianness.
-*/
-template<typename CharType = unsigned>
-struct UTF32 {
- typedef CharType Ch;
- RAPIDJSON_STATIC_ASSERT(sizeof(Ch) >= 4);
-
- enum { supportUnicode = 1 };
-
- template<typename OutputStream>
- static void Encode(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- os.Put(codepoint);
- }
-
- template<typename OutputStream>
- static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputStream::Ch) >= 4);
- RAPIDJSON_ASSERT(codepoint <= 0x10FFFF);
- PutUnsafe(os, codepoint);
- }
-
- template <typename InputStream>
- static bool Decode(InputStream& is, unsigned* codepoint) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
- Ch c = is.Take();
- *codepoint = c;
- return c <= 0x10FFFF;
- }
-
- template <typename InputStream, typename OutputStream>
- static bool Validate(InputStream& is, OutputStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputStream::Ch) >= 4);
- Ch c;
- os.Put(c = is.Take());
- return c <= 0x10FFFF;
- }
-};
-
-//! UTF-32 little endian enocoding.
-template<typename CharType = unsigned>
-struct UTF32LE : UTF32<CharType> {
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- CharType c = Take(is);
- return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
- }
-
- template <typename InputByteStream>
- static CharType Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- unsigned c = static_cast<uint8_t>(is.Take());
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
- return static_cast<CharType>(c);
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
- os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, CharType c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
- }
-};
-
-//! UTF-32 big endian encoding.
-template<typename CharType = unsigned>
-struct UTF32BE : UTF32<CharType> {
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- CharType c = Take(is);
- return static_cast<uint32_t>(c) == 0x0000FEFFu ? Take(is) : c;
- }
-
- template <typename InputByteStream>
- static CharType Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- unsigned c = static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 24;
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 16;
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take())) << 8;
- c |= static_cast<unsigned>(static_cast<uint8_t>(is.Take()));
- return static_cast<CharType>(c);
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
- os.Put(static_cast<typename OutputByteStream::Ch>(0x00u));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFEu));
- os.Put(static_cast<typename OutputByteStream::Ch>(0xFFu));
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, CharType c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 24) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 16) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>((c >> 8) & 0xFFu));
- os.Put(static_cast<typename OutputByteStream::Ch>(c & 0xFFu));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ASCII
-
-//! ASCII encoding.
-/*! http://en.wikipedia.org/wiki/ASCII
- \tparam CharType Code unit for storing 7-bit ASCII data. Default is char.
- \note implements Encoding concept
-*/
-template<typename CharType = char>
-struct ASCII {
- typedef CharType Ch;
-
- enum { supportUnicode = 0 };
-
- template<typename OutputStream>
- static void Encode(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_ASSERT(codepoint <= 0x7F);
- os.Put(static_cast<Ch>(codepoint & 0xFF));
- }
-
- template<typename OutputStream>
- static void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
- RAPIDJSON_ASSERT(codepoint <= 0x7F);
- PutUnsafe(os, static_cast<Ch>(codepoint & 0xFF));
- }
-
- template <typename InputStream>
- static bool Decode(InputStream& is, unsigned* codepoint) {
- uint8_t c = static_cast<uint8_t>(is.Take());
- *codepoint = c;
- return c <= 0X7F;
- }
-
- template <typename InputStream, typename OutputStream>
- static bool Validate(InputStream& is, OutputStream& os) {
- uint8_t c = static_cast<uint8_t>(is.Take());
- os.Put(static_cast<typename OutputStream::Ch>(c));
- return c <= 0x7F;
- }
-
- template <typename InputByteStream>
- static CharType TakeBOM(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- uint8_t c = static_cast<uint8_t>(Take(is));
- return static_cast<Ch>(c);
- }
-
- template <typename InputByteStream>
- static Ch Take(InputByteStream& is) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename InputByteStream::Ch) == 1);
- return static_cast<Ch>(is.Take());
- }
-
- template <typename OutputByteStream>
- static void PutBOM(OutputByteStream& os) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- (void)os;
- }
-
- template <typename OutputByteStream>
- static void Put(OutputByteStream& os, Ch c) {
- RAPIDJSON_STATIC_ASSERT(sizeof(typename OutputByteStream::Ch) == 1);
- os.Put(static_cast<typename OutputByteStream::Ch>(c));
- }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// AutoUTF
-
-//! Runtime-specified UTF encoding type of a stream.
-enum UTFType {
- kUTF8 = 0, //!< UTF-8.
- kUTF16LE = 1, //!< UTF-16 little endian.
- kUTF16BE = 2, //!< UTF-16 big endian.
- kUTF32LE = 3, //!< UTF-32 little endian.
- kUTF32BE = 4 //!< UTF-32 big endian.
-};
-
-//! Dynamically select encoding according to stream's runtime-specified UTF encoding type.
-/*! \note This class can be used with AutoUTFInputtStream and AutoUTFOutputStream, which provides GetType().
-*/
-template<typename CharType>
-struct AutoUTF {
- typedef CharType Ch;
-
- enum { supportUnicode = 1 };
-
-#define RAPIDJSON_ENCODINGS_FUNC(x) UTF8<Ch>::x, UTF16LE<Ch>::x, UTF16BE<Ch>::x, UTF32LE<Ch>::x, UTF32BE<Ch>::x
-
- template<typename OutputStream>
- static RAPIDJSON_FORCEINLINE void Encode(OutputStream& os, unsigned codepoint) {
- typedef void (*EncodeFunc)(OutputStream&, unsigned);
- static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Encode) };
- (*f[os.GetType()])(os, codepoint);
- }
-
- template<typename OutputStream>
- static RAPIDJSON_FORCEINLINE void EncodeUnsafe(OutputStream& os, unsigned codepoint) {
- typedef void (*EncodeFunc)(OutputStream&, unsigned);
- static const EncodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(EncodeUnsafe) };
- (*f[os.GetType()])(os, codepoint);
- }
-
- template <typename InputStream>
- static RAPIDJSON_FORCEINLINE bool Decode(InputStream& is, unsigned* codepoint) {
- typedef bool (*DecodeFunc)(InputStream&, unsigned*);
- static const DecodeFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Decode) };
- return (*f[is.GetType()])(is, codepoint);
- }
-
- template <typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
- typedef bool (*ValidateFunc)(InputStream&, OutputStream&);
- static const ValidateFunc f[] = { RAPIDJSON_ENCODINGS_FUNC(Validate) };
- return (*f[is.GetType()])(is, os);
- }
-
-#undef RAPIDJSON_ENCODINGS_FUNC
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Transcoder
-
-//! Encoding conversion.
-template<typename SourceEncoding, typename TargetEncoding>
-struct Transcoder {
- //! Take one Unicode codepoint from source encoding, convert it to target encoding and put it to the output stream.
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
- unsigned codepoint;
- if (!SourceEncoding::Decode(is, &codepoint))
- return false;
- TargetEncoding::Encode(os, codepoint);
- return true;
- }
-
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
- unsigned codepoint;
- if (!SourceEncoding::Decode(is, &codepoint))
- return false;
- TargetEncoding::EncodeUnsafe(os, codepoint);
- return true;
- }
-
- //! Validate one Unicode codepoint from an encoded stream.
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
- return Transcode(is, os); // Since source/target encoding is different, must transcode.
- }
-};
-
-// Forward declaration.
-template<typename Stream>
-inline void PutUnsafe(Stream& stream, typename Stream::Ch c);
-
-//! Specialization of Transcoder with same source and target encoding.
-template<typename Encoding>
-struct Transcoder<Encoding, Encoding> {
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool Transcode(InputStream& is, OutputStream& os) {
- os.Put(is.Take()); // Just copy one code unit. This semantic is different from primary template class.
- return true;
- }
-
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool TranscodeUnsafe(InputStream& is, OutputStream& os) {
- PutUnsafe(os, is.Take()); // Just copy one code unit. This semantic is different from primary template class.
- return true;
- }
-
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE bool Validate(InputStream& is, OutputStream& os) {
- return Encoding::Validate(is, os); // source/target encoding are the same
- }
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__GNUC__) || defined(_MSC_VER)
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_ENCODINGS_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/en.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/en.h
deleted file mode 100644
index 2db838bff..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/en.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ERROR_EN_H_
-#define RAPIDJSON_ERROR_EN_H_
-
-#include "error.h"
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(switch-enum)
-RAPIDJSON_DIAG_OFF(covered-switch-default)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Maps error code of parsing into error message.
-/*!
- \ingroup RAPIDJSON_ERRORS
- \param parseErrorCode Error code obtained in parsing.
- \return the error message.
- \note User can make a copy of this function for localization.
- Using switch-case is safer for future modification of error codes.
-*/
-inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
- switch (parseErrorCode) {
- case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
-
- case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
- case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
-
- case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
-
- case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
- case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
- case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
-
- case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
-
- case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
- case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
- case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
- case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
- case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
-
- case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
- case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
- case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
-
- case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
- case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
-
- default: return RAPIDJSON_ERROR_STRING("Unknown error.");
- }
-}
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_ERROR_EN_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/error.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/error.h
deleted file mode 100644
index 9311d2f03..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/error/error.h
+++ /dev/null
@@ -1,161 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ERROR_ERROR_H_
-#define RAPIDJSON_ERROR_ERROR_H_
-
-#include "../rapidjson.h"
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-/*! \file error.h */
-
-/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_ERROR_CHARTYPE
-
-//! Character type of error messages.
-/*! \ingroup RAPIDJSON_ERRORS
- The default character type is \c char.
- On Windows, user can define this macro as \c TCHAR for supporting both
- unicode/non-unicode settings.
-*/
-#ifndef RAPIDJSON_ERROR_CHARTYPE
-#define RAPIDJSON_ERROR_CHARTYPE char
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_ERROR_STRING
-
-//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
-/*! \ingroup RAPIDJSON_ERRORS
- By default this conversion macro does nothing.
- On Windows, user can define this macro as \c _T(x) for supporting both
- unicode/non-unicode settings.
-*/
-#ifndef RAPIDJSON_ERROR_STRING
-#define RAPIDJSON_ERROR_STRING(x) x
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// ParseErrorCode
-
-//! Error code of parsing.
-/*! \ingroup RAPIDJSON_ERRORS
- \see GenericReader::Parse, GenericReader::GetParseErrorCode
-*/
-enum ParseErrorCode {
- kParseErrorNone = 0, //!< No error.
-
- kParseErrorDocumentEmpty, //!< The document is empty.
- kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
-
- kParseErrorValueInvalid, //!< Invalid value.
-
- kParseErrorObjectMissName, //!< Missing a name for object member.
- kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
- kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
-
- kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
-
- kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
- kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
- kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
- kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
- kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
-
- kParseErrorNumberTooBig, //!< Number too big to be stored in double.
- kParseErrorNumberMissFraction, //!< Miss fraction part in number.
- kParseErrorNumberMissExponent, //!< Miss exponent in number.
-
- kParseErrorTermination, //!< Parsing was terminated.
- kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
-};
-
-//! Result of parsing (wraps ParseErrorCode)
-/*!
- \ingroup RAPIDJSON_ERRORS
- \code
- Document doc;
- ParseResult ok = doc.Parse("[42]");
- if (!ok) {
- fprintf(stderr, "JSON parse error: %s (%u)",
- GetParseError_En(ok.Code()), ok.Offset());
- exit(EXIT_FAILURE);
- }
- \endcode
- \see GenericReader::Parse, GenericDocument::Parse
-*/
-struct ParseResult {
- //!! Unspecified boolean type
- typedef bool (ParseResult::*BooleanType)() const;
-public:
- //! Default constructor, no error.
- ParseResult() : code_(kParseErrorNone), offset_(0) {}
- //! Constructor to set an error.
- ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
-
- //! Get the error code.
- ParseErrorCode Code() const { return code_; }
- //! Get the error offset, if \ref IsError(), 0 otherwise.
- size_t Offset() const { return offset_; }
-
- //! Explicit conversion to \c bool, returns \c true, iff !\ref IsError().
- operator BooleanType() const { return !IsError() ? &ParseResult::IsError : NULL; }
- //! Whether the result is an error.
- bool IsError() const { return code_ != kParseErrorNone; }
-
- bool operator==(const ParseResult& that) const { return code_ == that.code_; }
- bool operator==(ParseErrorCode code) const { return code_ == code; }
- friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
-
- bool operator!=(const ParseResult& that) const { return !(*this == that); }
- bool operator!=(ParseErrorCode code) const { return !(*this == code); }
- friend bool operator!=(ParseErrorCode code, const ParseResult & err) { return err != code; }
-
- //! Reset error code.
- void Clear() { Set(kParseErrorNone); }
- //! Update error code and offset.
- void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
-
-private:
- ParseErrorCode code_;
- size_t offset_;
-};
-
-//! Function pointer type of GetParseError().
-/*! \ingroup RAPIDJSON_ERRORS
-
- This is the prototype for \c GetParseError_X(), where \c X is a locale.
- User can dynamically change locale in runtime, e.g.:
-\code
- GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
- const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
-\endcode
-*/
-typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_ERROR_ERROR_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filereadstream.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filereadstream.h
deleted file mode 100644
index b56ea13b3..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filereadstream.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_FILEREADSTREAM_H_
-#define RAPIDJSON_FILEREADSTREAM_H_
-
-#include "stream.h"
-#include <cstdio>
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-RAPIDJSON_DIAG_OFF(unreachable-code)
-RAPIDJSON_DIAG_OFF(missing-noreturn)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! File byte stream for input using fread().
-/*!
- \note implements Stream concept
-*/
-class FileReadStream {
-public:
- typedef char Ch; //!< Character type (byte).
-
- //! Constructor.
- /*!
- \param fp File pointer opened for read.
- \param buffer user-supplied buffer.
- \param bufferSize size of buffer in bytes. Must >=4 bytes.
- */
- FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
- RAPIDJSON_ASSERT(fp_ != 0);
- RAPIDJSON_ASSERT(bufferSize >= 4);
- Read();
- }
-
- Ch Peek() const { return *current_; }
- Ch Take() { Ch c = *current_; Read(); return c; }
- size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
-
- // Not implemented
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
- // For encoding detection only.
- const Ch* Peek4() const {
- return (current_ + 4 <= bufferLast_) ? current_ : 0;
- }
-
-private:
- void Read() {
- if (current_ < bufferLast_)
- ++current_;
- else if (!eof_) {
- count_ += readCount_;
- readCount_ = fread(buffer_, 1, bufferSize_, fp_);
- bufferLast_ = buffer_ + readCount_ - 1;
- current_ = buffer_;
-
- if (readCount_ < bufferSize_) {
- buffer_[readCount_] = '\0';
- ++bufferLast_;
- eof_ = true;
- }
- }
- }
-
- std::FILE* fp_;
- Ch *buffer_;
- size_t bufferSize_;
- Ch *bufferLast_;
- Ch *current_;
- size_t readCount_;
- size_t count_; //!< Number of characters read
- bool eof_;
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_FILESTREAM_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filewritestream.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filewritestream.h
deleted file mode 100644
index 6378dd60e..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/filewritestream.h
+++ /dev/null
@@ -1,104 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_FILEWRITESTREAM_H_
-#define RAPIDJSON_FILEWRITESTREAM_H_
-
-#include "stream.h"
-#include <cstdio>
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(unreachable-code)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Wrapper of C file stream for input using fread().
-/*!
- \note implements Stream concept
-*/
-class FileWriteStream {
-public:
- typedef char Ch; //!< Character type. Only support char.
-
- FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
- RAPIDJSON_ASSERT(fp_ != 0);
- }
-
- void Put(char c) {
- if (current_ >= bufferEnd_)
- Flush();
-
- *current_++ = c;
- }
-
- void PutN(char c, size_t n) {
- size_t avail = static_cast<size_t>(bufferEnd_ - current_);
- while (n > avail) {
- std::memset(current_, c, avail);
- current_ += avail;
- Flush();
- n -= avail;
- avail = static_cast<size_t>(bufferEnd_ - current_);
- }
-
- if (n > 0) {
- std::memset(current_, c, n);
- current_ += n;
- }
- }
-
- void Flush() {
- if (current_ != buffer_) {
- size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
- if (result < static_cast<size_t>(current_ - buffer_)) {
- // failure deliberately ignored at this time
- // added to avoid warn_unused_result build errors
- }
- current_ = buffer_;
- }
- }
-
- // Not implemented
- char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
- char Take() { RAPIDJSON_ASSERT(false); return 0; }
- size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
- char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- // Prohibit copy constructor & assignment operator.
- FileWriteStream(const FileWriteStream&);
- FileWriteStream& operator=(const FileWriteStream&);
-
- std::FILE* fp_;
- char *buffer_;
- char *bufferEnd_;
- char *current_;
-};
-
-//! Implement specialized version of PutN() with memset() for better performance.
-template<>
-inline void PutN(FileWriteStream& stream, char c, size_t n) {
- stream.PutN(c, n);
-}
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_FILESTREAM_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/fwd.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/fwd.h
deleted file mode 100644
index e8104e841..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/fwd.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_FWD_H_
-#define RAPIDJSON_FWD_H_
-
-#include "rapidjson.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-// encodings.h
-
-template<typename CharType> struct UTF8;
-template<typename CharType> struct UTF16;
-template<typename CharType> struct UTF16BE;
-template<typename CharType> struct UTF16LE;
-template<typename CharType> struct UTF32;
-template<typename CharType> struct UTF32BE;
-template<typename CharType> struct UTF32LE;
-template<typename CharType> struct ASCII;
-template<typename CharType> struct AutoUTF;
-
-template<typename SourceEncoding, typename TargetEncoding>
-struct Transcoder;
-
-// allocators.h
-
-class CrtAllocator;
-
-template <typename BaseAllocator>
-class MemoryPoolAllocator;
-
-// stream.h
-
-template <typename Encoding>
-struct GenericStringStream;
-
-typedef GenericStringStream<UTF8<char> > StringStream;
-
-template <typename Encoding>
-struct GenericInsituStringStream;
-
-typedef GenericInsituStringStream<UTF8<char> > InsituStringStream;
-
-// stringbuffer.h
-
-template <typename Encoding, typename Allocator>
-class GenericStringBuffer;
-
-typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;
-
-// filereadstream.h
-
-class FileReadStream;
-
-// filewritestream.h
-
-class FileWriteStream;
-
-// memorybuffer.h
-
-template <typename Allocator>
-struct GenericMemoryBuffer;
-
-typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;
-
-// memorystream.h
-
-struct MemoryStream;
-
-// reader.h
-
-template<typename Encoding, typename Derived>
-struct BaseReaderHandler;
-
-template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>
-class GenericReader;
-
-typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
-
-// writer.h
-
-template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
-class Writer;
-
-// prettywriter.h
-
-template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
-class PrettyWriter;
-
-// document.h
-
-template <typename Encoding, typename Allocator>
-struct GenericMember;
-
-template <bool Const, typename Encoding, typename Allocator>
-class GenericMemberIterator;
-
-template<typename CharType>
-struct GenericStringRef;
-
-template <typename Encoding, typename Allocator>
-class GenericValue;
-
-typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
-
-template <typename Encoding, typename Allocator, typename StackAllocator>
-class GenericDocument;
-
-typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;
-
-// pointer.h
-
-template <typename ValueType, typename Allocator>
-class GenericPointer;
-
-typedef GenericPointer<Value, CrtAllocator> Pointer;
-
-// schema.h
-
-template <typename SchemaDocumentType>
-class IGenericRemoteSchemaDocumentProvider;
-
-template <typename ValueT, typename Allocator>
-class GenericSchemaDocument;
-
-typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;
-typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;
-
-template <
- typename SchemaDocumentType,
- typename OutputHandler,
- typename StateAllocator>
-class GenericSchemaValidator;
-
-typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_RAPIDJSONFWD_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/biginteger.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/biginteger.h
deleted file mode 100644
index 9d3e88c99..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/biginteger.h
+++ /dev/null
@@ -1,290 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_BIGINTEGER_H_
-#define RAPIDJSON_BIGINTEGER_H_
-
-#include "../rapidjson.h"
-
-#if defined(_MSC_VER) && defined(_M_AMD64)
-#include <intrin.h> // for _umul128
-#pragma intrinsic(_umul128)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-class BigInteger {
-public:
- typedef uint64_t Type;
-
- BigInteger(const BigInteger& rhs) : count_(rhs.count_) {
- std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
- }
-
- explicit BigInteger(uint64_t u) : count_(1) {
- digits_[0] = u;
- }
-
- BigInteger(const char* decimals, size_t length) : count_(1) {
- RAPIDJSON_ASSERT(length > 0);
- digits_[0] = 0;
- size_t i = 0;
- const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19
- while (length >= kMaxDigitPerIteration) {
- AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);
- length -= kMaxDigitPerIteration;
- i += kMaxDigitPerIteration;
- }
-
- if (length > 0)
- AppendDecimal64(decimals + i, decimals + i + length);
- }
-
- BigInteger& operator=(const BigInteger &rhs)
- {
- if (this != &rhs) {
- count_ = rhs.count_;
- std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
- }
- return *this;
- }
-
- BigInteger& operator=(uint64_t u) {
- digits_[0] = u;
- count_ = 1;
- return *this;
- }
-
- BigInteger& operator+=(uint64_t u) {
- Type backup = digits_[0];
- digits_[0] += u;
- for (size_t i = 0; i < count_ - 1; i++) {
- if (digits_[i] >= backup)
- return *this; // no carry
- backup = digits_[i + 1];
- digits_[i + 1] += 1;
- }
-
- // Last carry
- if (digits_[count_ - 1] < backup)
- PushBack(1);
-
- return *this;
- }
-
- BigInteger& operator*=(uint64_t u) {
- if (u == 0) return *this = 0;
- if (u == 1) return *this;
- if (*this == 1) return *this = u;
-
- uint64_t k = 0;
- for (size_t i = 0; i < count_; i++) {
- uint64_t hi;
- digits_[i] = MulAdd64(digits_[i], u, k, &hi);
- k = hi;
- }
-
- if (k > 0)
- PushBack(k);
-
- return *this;
- }
-
- BigInteger& operator*=(uint32_t u) {
- if (u == 0) return *this = 0;
- if (u == 1) return *this;
- if (*this == 1) return *this = u;
-
- uint64_t k = 0;
- for (size_t i = 0; i < count_; i++) {
- const uint64_t c = digits_[i] >> 32;
- const uint64_t d = digits_[i] & 0xFFFFFFFF;
- const uint64_t uc = u * c;
- const uint64_t ud = u * d;
- const uint64_t p0 = ud + k;
- const uint64_t p1 = uc + (p0 >> 32);
- digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);
- k = p1 >> 32;
- }
-
- if (k > 0)
- PushBack(k);
-
- return *this;
- }
-
- BigInteger& operator<<=(size_t shift) {
- if (IsZero() || shift == 0) return *this;
-
- size_t offset = shift / kTypeBit;
- size_t interShift = shift % kTypeBit;
- RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
-
- if (interShift == 0) {
- std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
- count_ += offset;
- }
- else {
- digits_[count_] = 0;
- for (size_t i = count_; i > 0; i--)
- digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));
- digits_[offset] = digits_[0] << interShift;
- count_ += offset;
- if (digits_[count_])
- count_++;
- }
-
- std::memset(digits_, 0, offset * sizeof(Type));
-
- return *this;
- }
-
- bool operator==(const BigInteger& rhs) const {
- return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;
- }
-
- bool operator==(const Type rhs) const {
- return count_ == 1 && digits_[0] == rhs;
- }
-
- BigInteger& MultiplyPow5(unsigned exp) {
- static const uint32_t kPow5[12] = {
- 5,
- 5 * 5,
- 5 * 5 * 5,
- 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
- 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
- };
- if (exp == 0) return *this;
- for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27
- for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13
- if (exp > 0) *this *= kPow5[exp - 1];
- return *this;
- }
-
- // Compute absolute difference of this and rhs.
- // Assume this != rhs
- bool Difference(const BigInteger& rhs, BigInteger* out) const {
- int cmp = Compare(rhs);
- RAPIDJSON_ASSERT(cmp != 0);
- const BigInteger *a, *b; // Makes a > b
- bool ret;
- if (cmp < 0) { a = &rhs; b = this; ret = true; }
- else { a = this; b = &rhs; ret = false; }
-
- Type borrow = 0;
- for (size_t i = 0; i < a->count_; i++) {
- Type d = a->digits_[i] - borrow;
- if (i < b->count_)
- d -= b->digits_[i];
- borrow = (d > a->digits_[i]) ? 1 : 0;
- out->digits_[i] = d;
- if (d != 0)
- out->count_ = i + 1;
- }
-
- return ret;
- }
-
- int Compare(const BigInteger& rhs) const {
- if (count_ != rhs.count_)
- return count_ < rhs.count_ ? -1 : 1;
-
- for (size_t i = count_; i-- > 0;)
- if (digits_[i] != rhs.digits_[i])
- return digits_[i] < rhs.digits_[i] ? -1 : 1;
-
- return 0;
- }
-
- size_t GetCount() const { return count_; }
- Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }
- bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
-
-private:
- void AppendDecimal64(const char* begin, const char* end) {
- uint64_t u = ParseUint64(begin, end);
- if (IsZero())
- *this = u;
- else {
- unsigned exp = static_cast<unsigned>(end - begin);
- (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u
- }
- }
-
- void PushBack(Type digit) {
- RAPIDJSON_ASSERT(count_ < kCapacity);
- digits_[count_++] = digit;
- }
-
- static uint64_t ParseUint64(const char* begin, const char* end) {
- uint64_t r = 0;
- for (const char* p = begin; p != end; ++p) {
- RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
- r = r * 10u + static_cast<unsigned>(*p - '0');
- }
- return r;
- }
-
- // Assume a * b + k < 2^128
- static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {
-#if defined(_MSC_VER) && defined(_M_AMD64)
- uint64_t low = _umul128(a, b, outHigh) + k;
- if (low < k)
- (*outHigh)++;
- return low;
-#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
- __extension__ typedef unsigned __int128 uint128;
- uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
- p += k;
- *outHigh = static_cast<uint64_t>(p >> 64);
- return static_cast<uint64_t>(p);
-#else
- const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;
- uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;
- x1 += (x0 >> 32); // can't give carry
- x1 += x2;
- if (x1 < x2)
- x3 += (static_cast<uint64_t>(1) << 32);
- uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);
- uint64_t hi = x3 + (x1 >> 32);
-
- lo += k;
- if (lo < k)
- hi++;
- *outHigh = hi;
- return lo;
-#endif
- }
-
- static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000
- static const size_t kCapacity = kBitCount / sizeof(Type);
- static const size_t kTypeBit = sizeof(Type) * 8;
-
- Type digits_[kCapacity];
- size_t count_;
-};
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_BIGINTEGER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/diyfp.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/diyfp.h
deleted file mode 100644
index 29abf8046..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/diyfp.h
+++ /dev/null
@@ -1,258 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
-// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
-// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
-
-#ifndef RAPIDJSON_DIYFP_H_
-#define RAPIDJSON_DIYFP_H_
-
-#include "../rapidjson.h"
-
-#if defined(_MSC_VER) && defined(_M_AMD64) && !defined(__INTEL_COMPILER)
-#include <intrin.h>
-#pragma intrinsic(_BitScanReverse64)
-#pragma intrinsic(_umul128)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-struct DiyFp {
- DiyFp() : f(), e() {}
-
- DiyFp(uint64_t fp, int exp) : f(fp), e(exp) {}
-
- explicit DiyFp(double d) {
- union {
- double d;
- uint64_t u64;
- } u = { d };
-
- int biased_e = static_cast<int>((u.u64 & kDpExponentMask) >> kDpSignificandSize);
- uint64_t significand = (u.u64 & kDpSignificandMask);
- if (biased_e != 0) {
- f = significand + kDpHiddenBit;
- e = biased_e - kDpExponentBias;
- }
- else {
- f = significand;
- e = kDpMinExponent + 1;
- }
- }
-
- DiyFp operator-(const DiyFp& rhs) const {
- return DiyFp(f - rhs.f, e);
- }
-
- DiyFp operator*(const DiyFp& rhs) const {
-#if defined(_MSC_VER) && defined(_M_AMD64)
- uint64_t h;
- uint64_t l = _umul128(f, rhs.f, &h);
- if (l & (uint64_t(1) << 63)) // rounding
- h++;
- return DiyFp(h, e + rhs.e + 64);
-#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
- __extension__ typedef unsigned __int128 uint128;
- uint128 p = static_cast<uint128>(f) * static_cast<uint128>(rhs.f);
- uint64_t h = static_cast<uint64_t>(p >> 64);
- uint64_t l = static_cast<uint64_t>(p);
- if (l & (uint64_t(1) << 63)) // rounding
- h++;
- return DiyFp(h, e + rhs.e + 64);
-#else
- const uint64_t M32 = 0xFFFFFFFF;
- const uint64_t a = f >> 32;
- const uint64_t b = f & M32;
- const uint64_t c = rhs.f >> 32;
- const uint64_t d = rhs.f & M32;
- const uint64_t ac = a * c;
- const uint64_t bc = b * c;
- const uint64_t ad = a * d;
- const uint64_t bd = b * d;
- uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
- tmp += 1U << 31; /// mult_round
- return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
-#endif
- }
-
- DiyFp Normalize() const {
-#if defined(_MSC_VER) && defined(_M_AMD64)
- unsigned long index;
- _BitScanReverse64(&index, f);
- return DiyFp(f << (63 - index), e - (63 - index));
-#elif defined(__GNUC__) && __GNUC__ >= 4
- int s = __builtin_clzll(f);
- return DiyFp(f << s, e - s);
-#else
- DiyFp res = *this;
- while (!(res.f & (static_cast<uint64_t>(1) << 63))) {
- res.f <<= 1;
- res.e--;
- }
- return res;
-#endif
- }
-
- DiyFp NormalizeBoundary() const {
- DiyFp res = *this;
- while (!(res.f & (kDpHiddenBit << 1))) {
- res.f <<= 1;
- res.e--;
- }
- res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
- res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
- return res;
- }
-
- void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
- DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
- DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
- mi.f <<= mi.e - pl.e;
- mi.e = pl.e;
- *plus = pl;
- *minus = mi;
- }
-
- double ToDouble() const {
- union {
- double d;
- uint64_t u64;
- }u;
- const uint64_t be = (e == kDpDenormalExponent && (f & kDpHiddenBit) == 0) ? 0 :
- static_cast<uint64_t>(e + kDpExponentBias);
- u.u64 = (f & kDpSignificandMask) | (be << kDpSignificandSize);
- return u.d;
- }
-
- static const int kDiySignificandSize = 64;
- static const int kDpSignificandSize = 52;
- static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
- static const int kDpMaxExponent = 0x7FF - kDpExponentBias;
- static const int kDpMinExponent = -kDpExponentBias;
- static const int kDpDenormalExponent = -kDpExponentBias + 1;
- static const uint64_t kDpExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
- static const uint64_t kDpSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
- static const uint64_t kDpHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
-
- uint64_t f;
- int e;
-};
-
-inline DiyFp GetCachedPowerByIndex(size_t index) {
- // 10^-348, 10^-340, ..., 10^340
- static const uint64_t kCachedPowers_F[] = {
- RAPIDJSON_UINT64_C2(0xfa8fd5a0, 0x081c0288), RAPIDJSON_UINT64_C2(0xbaaee17f, 0xa23ebf76),
- RAPIDJSON_UINT64_C2(0x8b16fb20, 0x3055ac76), RAPIDJSON_UINT64_C2(0xcf42894a, 0x5dce35ea),
- RAPIDJSON_UINT64_C2(0x9a6bb0aa, 0x55653b2d), RAPIDJSON_UINT64_C2(0xe61acf03, 0x3d1a45df),
- RAPIDJSON_UINT64_C2(0xab70fe17, 0xc79ac6ca), RAPIDJSON_UINT64_C2(0xff77b1fc, 0xbebcdc4f),
- RAPIDJSON_UINT64_C2(0xbe5691ef, 0x416bd60c), RAPIDJSON_UINT64_C2(0x8dd01fad, 0x907ffc3c),
- RAPIDJSON_UINT64_C2(0xd3515c28, 0x31559a83), RAPIDJSON_UINT64_C2(0x9d71ac8f, 0xada6c9b5),
- RAPIDJSON_UINT64_C2(0xea9c2277, 0x23ee8bcb), RAPIDJSON_UINT64_C2(0xaecc4991, 0x4078536d),
- RAPIDJSON_UINT64_C2(0x823c1279, 0x5db6ce57), RAPIDJSON_UINT64_C2(0xc2109436, 0x4dfb5637),
- RAPIDJSON_UINT64_C2(0x9096ea6f, 0x3848984f), RAPIDJSON_UINT64_C2(0xd77485cb, 0x25823ac7),
- RAPIDJSON_UINT64_C2(0xa086cfcd, 0x97bf97f4), RAPIDJSON_UINT64_C2(0xef340a98, 0x172aace5),
- RAPIDJSON_UINT64_C2(0xb23867fb, 0x2a35b28e), RAPIDJSON_UINT64_C2(0x84c8d4df, 0xd2c63f3b),
- RAPIDJSON_UINT64_C2(0xc5dd4427, 0x1ad3cdba), RAPIDJSON_UINT64_C2(0x936b9fce, 0xbb25c996),
- RAPIDJSON_UINT64_C2(0xdbac6c24, 0x7d62a584), RAPIDJSON_UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
- RAPIDJSON_UINT64_C2(0xf3e2f893, 0xdec3f126), RAPIDJSON_UINT64_C2(0xb5b5ada8, 0xaaff80b8),
- RAPIDJSON_UINT64_C2(0x87625f05, 0x6c7c4a8b), RAPIDJSON_UINT64_C2(0xc9bcff60, 0x34c13053),
- RAPIDJSON_UINT64_C2(0x964e858c, 0x91ba2655), RAPIDJSON_UINT64_C2(0xdff97724, 0x70297ebd),
- RAPIDJSON_UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), RAPIDJSON_UINT64_C2(0xf8a95fcf, 0x88747d94),
- RAPIDJSON_UINT64_C2(0xb9447093, 0x8fa89bcf), RAPIDJSON_UINT64_C2(0x8a08f0f8, 0xbf0f156b),
- RAPIDJSON_UINT64_C2(0xcdb02555, 0x653131b6), RAPIDJSON_UINT64_C2(0x993fe2c6, 0xd07b7fac),
- RAPIDJSON_UINT64_C2(0xe45c10c4, 0x2a2b3b06), RAPIDJSON_UINT64_C2(0xaa242499, 0x697392d3),
- RAPIDJSON_UINT64_C2(0xfd87b5f2, 0x8300ca0e), RAPIDJSON_UINT64_C2(0xbce50864, 0x92111aeb),
- RAPIDJSON_UINT64_C2(0x8cbccc09, 0x6f5088cc), RAPIDJSON_UINT64_C2(0xd1b71758, 0xe219652c),
- RAPIDJSON_UINT64_C2(0x9c400000, 0x00000000), RAPIDJSON_UINT64_C2(0xe8d4a510, 0x00000000),
- RAPIDJSON_UINT64_C2(0xad78ebc5, 0xac620000), RAPIDJSON_UINT64_C2(0x813f3978, 0xf8940984),
- RAPIDJSON_UINT64_C2(0xc097ce7b, 0xc90715b3), RAPIDJSON_UINT64_C2(0x8f7e32ce, 0x7bea5c70),
- RAPIDJSON_UINT64_C2(0xd5d238a4, 0xabe98068), RAPIDJSON_UINT64_C2(0x9f4f2726, 0x179a2245),
- RAPIDJSON_UINT64_C2(0xed63a231, 0xd4c4fb27), RAPIDJSON_UINT64_C2(0xb0de6538, 0x8cc8ada8),
- RAPIDJSON_UINT64_C2(0x83c7088e, 0x1aab65db), RAPIDJSON_UINT64_C2(0xc45d1df9, 0x42711d9a),
- RAPIDJSON_UINT64_C2(0x924d692c, 0xa61be758), RAPIDJSON_UINT64_C2(0xda01ee64, 0x1a708dea),
- RAPIDJSON_UINT64_C2(0xa26da399, 0x9aef774a), RAPIDJSON_UINT64_C2(0xf209787b, 0xb47d6b85),
- RAPIDJSON_UINT64_C2(0xb454e4a1, 0x79dd1877), RAPIDJSON_UINT64_C2(0x865b8692, 0x5b9bc5c2),
- RAPIDJSON_UINT64_C2(0xc83553c5, 0xc8965d3d), RAPIDJSON_UINT64_C2(0x952ab45c, 0xfa97a0b3),
- RAPIDJSON_UINT64_C2(0xde469fbd, 0x99a05fe3), RAPIDJSON_UINT64_C2(0xa59bc234, 0xdb398c25),
- RAPIDJSON_UINT64_C2(0xf6c69a72, 0xa3989f5c), RAPIDJSON_UINT64_C2(0xb7dcbf53, 0x54e9bece),
- RAPIDJSON_UINT64_C2(0x88fcf317, 0xf22241e2), RAPIDJSON_UINT64_C2(0xcc20ce9b, 0xd35c78a5),
- RAPIDJSON_UINT64_C2(0x98165af3, 0x7b2153df), RAPIDJSON_UINT64_C2(0xe2a0b5dc, 0x971f303a),
- RAPIDJSON_UINT64_C2(0xa8d9d153, 0x5ce3b396), RAPIDJSON_UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
- RAPIDJSON_UINT64_C2(0xbb764c4c, 0xa7a44410), RAPIDJSON_UINT64_C2(0x8bab8eef, 0xb6409c1a),
- RAPIDJSON_UINT64_C2(0xd01fef10, 0xa657842c), RAPIDJSON_UINT64_C2(0x9b10a4e5, 0xe9913129),
- RAPIDJSON_UINT64_C2(0xe7109bfb, 0xa19c0c9d), RAPIDJSON_UINT64_C2(0xac2820d9, 0x623bf429),
- RAPIDJSON_UINT64_C2(0x80444b5e, 0x7aa7cf85), RAPIDJSON_UINT64_C2(0xbf21e440, 0x03acdd2d),
- RAPIDJSON_UINT64_C2(0x8e679c2f, 0x5e44ff8f), RAPIDJSON_UINT64_C2(0xd433179d, 0x9c8cb841),
- RAPIDJSON_UINT64_C2(0x9e19db92, 0xb4e31ba9), RAPIDJSON_UINT64_C2(0xeb96bf6e, 0xbadf77d9),
- RAPIDJSON_UINT64_C2(0xaf87023b, 0x9bf0ee6b)
- };
- static const int16_t kCachedPowers_E[] = {
- -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
- -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
- -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
- -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
- -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
- 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
- 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
- 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
- 907, 933, 960, 986, 1013, 1039, 1066
- };
- return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
-}
-
-inline DiyFp GetCachedPower(int e, int* K) {
-
- //int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
- double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
- int k = static_cast<int>(dk);
- if (dk - k > 0.0)
- k++;
-
- unsigned index = static_cast<unsigned>((k >> 3) + 1);
- *K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
-
- return GetCachedPowerByIndex(index);
-}
-
-inline DiyFp GetCachedPower10(int exp, int *outExp) {
- unsigned index = (static_cast<unsigned>(exp) + 348u) / 8u;
- *outExp = -348 + static_cast<int>(index) * 8;
- return GetCachedPowerByIndex(index);
- }
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_DIYFP_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/dtoa.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/dtoa.h
deleted file mode 100644
index bf2e9b2e5..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/dtoa.h
+++ /dev/null
@@ -1,245 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
-// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
-// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
-
-#ifndef RAPIDJSON_DTOA_
-#define RAPIDJSON_DTOA_
-
-#include "itoa.h" // GetDigitsLut()
-#include "diyfp.h"
-#include "ieee754.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
-#endif
-
-inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
- while (rest < wp_w && delta - rest >= ten_kappa &&
- (rest + ten_kappa < wp_w || /// closer
- wp_w - rest > rest + ten_kappa - wp_w)) {
- buffer[len - 1]--;
- rest += ten_kappa;
- }
-}
-
-inline int CountDecimalDigit32(uint32_t n) {
- // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
- if (n < 10) return 1;
- if (n < 100) return 2;
- if (n < 1000) return 3;
- if (n < 10000) return 4;
- if (n < 100000) return 5;
- if (n < 1000000) return 6;
- if (n < 10000000) return 7;
- if (n < 100000000) return 8;
- // Will not reach 10 digits in DigitGen()
- //if (n < 1000000000) return 9;
- //return 10;
- return 9;
-}
-
-inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
- static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
- const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
- const DiyFp wp_w = Mp - W;
- uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
- uint64_t p2 = Mp.f & (one.f - 1);
- int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
- *len = 0;
-
- while (kappa > 0) {
- uint32_t d = 0;
- switch (kappa) {
- case 9: d = p1 / 100000000; p1 %= 100000000; break;
- case 8: d = p1 / 10000000; p1 %= 10000000; break;
- case 7: d = p1 / 1000000; p1 %= 1000000; break;
- case 6: d = p1 / 100000; p1 %= 100000; break;
- case 5: d = p1 / 10000; p1 %= 10000; break;
- case 4: d = p1 / 1000; p1 %= 1000; break;
- case 3: d = p1 / 100; p1 %= 100; break;
- case 2: d = p1 / 10; p1 %= 10; break;
- case 1: d = p1; p1 = 0; break;
- default:;
- }
- if (d || *len)
- buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
- kappa--;
- uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
- if (tmp <= delta) {
- *K += kappa;
- GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
- return;
- }
- }
-
- // kappa = 0
- for (;;) {
- p2 *= 10;
- delta *= 10;
- char d = static_cast<char>(p2 >> -one.e);
- if (d || *len)
- buffer[(*len)++] = static_cast<char>('0' + d);
- p2 &= one.f - 1;
- kappa--;
- if (p2 < delta) {
- *K += kappa;
- int index = -kappa;
- GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
- return;
- }
- }
-}
-
-inline void Grisu2(double value, char* buffer, int* length, int* K) {
- const DiyFp v(value);
- DiyFp w_m, w_p;
- v.NormalizedBoundaries(&w_m, &w_p);
-
- const DiyFp c_mk = GetCachedPower(w_p.e, K);
- const DiyFp W = v.Normalize() * c_mk;
- DiyFp Wp = w_p * c_mk;
- DiyFp Wm = w_m * c_mk;
- Wm.f++;
- Wp.f--;
- DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
-}
-
-inline char* WriteExponent(int K, char* buffer) {
- if (K < 0) {
- *buffer++ = '-';
- K = -K;
- }
-
- if (K >= 100) {
- *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));
- K %= 100;
- const char* d = GetDigitsLut() + K * 2;
- *buffer++ = d[0];
- *buffer++ = d[1];
- }
- else if (K >= 10) {
- const char* d = GetDigitsLut() + K * 2;
- *buffer++ = d[0];
- *buffer++ = d[1];
- }
- else
- *buffer++ = static_cast<char>('0' + static_cast<char>(K));
-
- return buffer;
-}
-
-inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
- const int kk = length + k; // 10^(kk-1) <= v < 10^kk
-
- if (0 <= k && kk <= 21) {
- // 1234e7 -> 12340000000
- for (int i = length; i < kk; i++)
- buffer[i] = '0';
- buffer[kk] = '.';
- buffer[kk + 1] = '0';
- return &buffer[kk + 2];
- }
- else if (0 < kk && kk <= 21) {
- // 1234e-2 -> 12.34
- std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
- buffer[kk] = '.';
- if (0 > k + maxDecimalPlaces) {
- // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
- // Remove extra trailing zeros (at least one) after truncation.
- for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
- if (buffer[i] != '0')
- return &buffer[i + 1];
- return &buffer[kk + 2]; // Reserve one zero
- }
- else
- return &buffer[length + 1];
- }
- else if (-6 < kk && kk <= 0) {
- // 1234e-6 -> 0.001234
- const int offset = 2 - kk;
- std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
- buffer[0] = '0';
- buffer[1] = '.';
- for (int i = 2; i < offset; i++)
- buffer[i] = '0';
- if (length - kk > maxDecimalPlaces) {
- // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
- // Remove extra trailing zeros (at least one) after truncation.
- for (int i = maxDecimalPlaces + 1; i > 2; i--)
- if (buffer[i] != '0')
- return &buffer[i + 1];
- return &buffer[3]; // Reserve one zero
- }
- else
- return &buffer[length + offset];
- }
- else if (kk < -maxDecimalPlaces) {
- // Truncate to zero
- buffer[0] = '0';
- buffer[1] = '.';
- buffer[2] = '0';
- return &buffer[3];
- }
- else if (length == 1) {
- // 1e30
- buffer[1] = 'e';
- return WriteExponent(kk - 1, &buffer[2]);
- }
- else {
- // 1234e30 -> 1.234e33
- std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
- buffer[1] = '.';
- buffer[length + 1] = 'e';
- return WriteExponent(kk - 1, &buffer[0 + length + 2]);
- }
-}
-
-inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
- RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
- Double d(value);
- if (d.IsZero()) {
- if (d.Sign())
- *buffer++ = '-'; // -0.0, Issue #289
- buffer[0] = '0';
- buffer[1] = '.';
- buffer[2] = '0';
- return &buffer[3];
- }
- else {
- if (value < 0) {
- *buffer++ = '-';
- value = -value;
- }
- int length, K;
- Grisu2(value, buffer, &length, &K);
- return Prettify(buffer, length, K, maxDecimalPlaces);
- }
-}
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_POP
-#endif
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_DTOA_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/ieee754.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/ieee754.h
deleted file mode 100644
index c2684ba2a..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/ieee754.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_IEEE754_
-#define RAPIDJSON_IEEE754_
-
-#include "../rapidjson.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-class Double {
-public:
- Double() {}
- Double(double d) : d_(d) {}
- Double(uint64_t u) : u_(u) {}
-
- double Value() const { return d_; }
- uint64_t Uint64Value() const { return u_; }
-
- double NextPositiveDouble() const {
- RAPIDJSON_ASSERT(!Sign());
- return Double(u_ + 1).Value();
- }
-
- bool Sign() const { return (u_ & kSignMask) != 0; }
- uint64_t Significand() const { return u_ & kSignificandMask; }
- int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
-
- bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
- bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
- bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
- bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
- bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
-
- uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
- int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
- uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
-
- static int EffectiveSignificandSize(int order) {
- if (order >= -1021)
- return 53;
- else if (order <= -1074)
- return 0;
- else
- return order + 1074;
- }
-
-private:
- static const int kSignificandSize = 52;
- static const int kExponentBias = 0x3FF;
- static const int kDenormalExponent = 1 - kExponentBias;
- static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
- static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
- static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
- static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
-
- union {
- double d_;
- uint64_t u_;
- };
-};
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_IEEE754_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/itoa.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/itoa.h
deleted file mode 100644
index 01a4e7e72..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/itoa.h
+++ /dev/null
@@ -1,304 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ITOA_
-#define RAPIDJSON_ITOA_
-
-#include "../rapidjson.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-inline const char* GetDigitsLut() {
- static const char cDigitsLut[200] = {
- '0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
- '1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
- '2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
- '3','0','3','1','3','2','3','3','3','4','3','5','3','6','3','7','3','8','3','9',
- '4','0','4','1','4','2','4','3','4','4','4','5','4','6','4','7','4','8','4','9',
- '5','0','5','1','5','2','5','3','5','4','5','5','5','6','5','7','5','8','5','9',
- '6','0','6','1','6','2','6','3','6','4','6','5','6','6','6','7','6','8','6','9',
- '7','0','7','1','7','2','7','3','7','4','7','5','7','6','7','7','7','8','7','9',
- '8','0','8','1','8','2','8','3','8','4','8','5','8','6','8','7','8','8','8','9',
- '9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
- };
- return cDigitsLut;
-}
-
-inline char* u32toa(uint32_t value, char* buffer) {
- const char* cDigitsLut = GetDigitsLut();
-
- if (value < 10000) {
- const uint32_t d1 = (value / 100) << 1;
- const uint32_t d2 = (value % 100) << 1;
-
- if (value >= 1000)
- *buffer++ = cDigitsLut[d1];
- if (value >= 100)
- *buffer++ = cDigitsLut[d1 + 1];
- if (value >= 10)
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
- }
- else if (value < 100000000) {
- // value = bbbbcccc
- const uint32_t b = value / 10000;
- const uint32_t c = value % 10000;
-
- const uint32_t d1 = (b / 100) << 1;
- const uint32_t d2 = (b % 100) << 1;
-
- const uint32_t d3 = (c / 100) << 1;
- const uint32_t d4 = (c % 100) << 1;
-
- if (value >= 10000000)
- *buffer++ = cDigitsLut[d1];
- if (value >= 1000000)
- *buffer++ = cDigitsLut[d1 + 1];
- if (value >= 100000)
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
-
- *buffer++ = cDigitsLut[d3];
- *buffer++ = cDigitsLut[d3 + 1];
- *buffer++ = cDigitsLut[d4];
- *buffer++ = cDigitsLut[d4 + 1];
- }
- else {
- // value = aabbbbcccc in decimal
-
- const uint32_t a = value / 100000000; // 1 to 42
- value %= 100000000;
-
- if (a >= 10) {
- const unsigned i = a << 1;
- *buffer++ = cDigitsLut[i];
- *buffer++ = cDigitsLut[i + 1];
- }
- else
- *buffer++ = static_cast<char>('0' + static_cast<char>(a));
-
- const uint32_t b = value / 10000; // 0 to 9999
- const uint32_t c = value % 10000; // 0 to 9999
-
- const uint32_t d1 = (b / 100) << 1;
- const uint32_t d2 = (b % 100) << 1;
-
- const uint32_t d3 = (c / 100) << 1;
- const uint32_t d4 = (c % 100) << 1;
-
- *buffer++ = cDigitsLut[d1];
- *buffer++ = cDigitsLut[d1 + 1];
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
- *buffer++ = cDigitsLut[d3];
- *buffer++ = cDigitsLut[d3 + 1];
- *buffer++ = cDigitsLut[d4];
- *buffer++ = cDigitsLut[d4 + 1];
- }
- return buffer;
-}
-
-inline char* i32toa(int32_t value, char* buffer) {
- uint32_t u = static_cast<uint32_t>(value);
- if (value < 0) {
- *buffer++ = '-';
- u = ~u + 1;
- }
-
- return u32toa(u, buffer);
-}
-
-inline char* u64toa(uint64_t value, char* buffer) {
- const char* cDigitsLut = GetDigitsLut();
- const uint64_t kTen8 = 100000000;
- const uint64_t kTen9 = kTen8 * 10;
- const uint64_t kTen10 = kTen8 * 100;
- const uint64_t kTen11 = kTen8 * 1000;
- const uint64_t kTen12 = kTen8 * 10000;
- const uint64_t kTen13 = kTen8 * 100000;
- const uint64_t kTen14 = kTen8 * 1000000;
- const uint64_t kTen15 = kTen8 * 10000000;
- const uint64_t kTen16 = kTen8 * kTen8;
-
- if (value < kTen8) {
- uint32_t v = static_cast<uint32_t>(value);
- if (v < 10000) {
- const uint32_t d1 = (v / 100) << 1;
- const uint32_t d2 = (v % 100) << 1;
-
- if (v >= 1000)
- *buffer++ = cDigitsLut[d1];
- if (v >= 100)
- *buffer++ = cDigitsLut[d1 + 1];
- if (v >= 10)
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
- }
- else {
- // value = bbbbcccc
- const uint32_t b = v / 10000;
- const uint32_t c = v % 10000;
-
- const uint32_t d1 = (b / 100) << 1;
- const uint32_t d2 = (b % 100) << 1;
-
- const uint32_t d3 = (c / 100) << 1;
- const uint32_t d4 = (c % 100) << 1;
-
- if (value >= 10000000)
- *buffer++ = cDigitsLut[d1];
- if (value >= 1000000)
- *buffer++ = cDigitsLut[d1 + 1];
- if (value >= 100000)
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
-
- *buffer++ = cDigitsLut[d3];
- *buffer++ = cDigitsLut[d3 + 1];
- *buffer++ = cDigitsLut[d4];
- *buffer++ = cDigitsLut[d4 + 1];
- }
- }
- else if (value < kTen16) {
- const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
- const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
-
- const uint32_t b0 = v0 / 10000;
- const uint32_t c0 = v0 % 10000;
-
- const uint32_t d1 = (b0 / 100) << 1;
- const uint32_t d2 = (b0 % 100) << 1;
-
- const uint32_t d3 = (c0 / 100) << 1;
- const uint32_t d4 = (c0 % 100) << 1;
-
- const uint32_t b1 = v1 / 10000;
- const uint32_t c1 = v1 % 10000;
-
- const uint32_t d5 = (b1 / 100) << 1;
- const uint32_t d6 = (b1 % 100) << 1;
-
- const uint32_t d7 = (c1 / 100) << 1;
- const uint32_t d8 = (c1 % 100) << 1;
-
- if (value >= kTen15)
- *buffer++ = cDigitsLut[d1];
- if (value >= kTen14)
- *buffer++ = cDigitsLut[d1 + 1];
- if (value >= kTen13)
- *buffer++ = cDigitsLut[d2];
- if (value >= kTen12)
- *buffer++ = cDigitsLut[d2 + 1];
- if (value >= kTen11)
- *buffer++ = cDigitsLut[d3];
- if (value >= kTen10)
- *buffer++ = cDigitsLut[d3 + 1];
- if (value >= kTen9)
- *buffer++ = cDigitsLut[d4];
- if (value >= kTen8)
- *buffer++ = cDigitsLut[d4 + 1];
-
- *buffer++ = cDigitsLut[d5];
- *buffer++ = cDigitsLut[d5 + 1];
- *buffer++ = cDigitsLut[d6];
- *buffer++ = cDigitsLut[d6 + 1];
- *buffer++ = cDigitsLut[d7];
- *buffer++ = cDigitsLut[d7 + 1];
- *buffer++ = cDigitsLut[d8];
- *buffer++ = cDigitsLut[d8 + 1];
- }
- else {
- const uint32_t a = static_cast<uint32_t>(value / kTen16); // 1 to 1844
- value %= kTen16;
-
- if (a < 10)
- *buffer++ = static_cast<char>('0' + static_cast<char>(a));
- else if (a < 100) {
- const uint32_t i = a << 1;
- *buffer++ = cDigitsLut[i];
- *buffer++ = cDigitsLut[i + 1];
- }
- else if (a < 1000) {
- *buffer++ = static_cast<char>('0' + static_cast<char>(a / 100));
-
- const uint32_t i = (a % 100) << 1;
- *buffer++ = cDigitsLut[i];
- *buffer++ = cDigitsLut[i + 1];
- }
- else {
- const uint32_t i = (a / 100) << 1;
- const uint32_t j = (a % 100) << 1;
- *buffer++ = cDigitsLut[i];
- *buffer++ = cDigitsLut[i + 1];
- *buffer++ = cDigitsLut[j];
- *buffer++ = cDigitsLut[j + 1];
- }
-
- const uint32_t v0 = static_cast<uint32_t>(value / kTen8);
- const uint32_t v1 = static_cast<uint32_t>(value % kTen8);
-
- const uint32_t b0 = v0 / 10000;
- const uint32_t c0 = v0 % 10000;
-
- const uint32_t d1 = (b0 / 100) << 1;
- const uint32_t d2 = (b0 % 100) << 1;
-
- const uint32_t d3 = (c0 / 100) << 1;
- const uint32_t d4 = (c0 % 100) << 1;
-
- const uint32_t b1 = v1 / 10000;
- const uint32_t c1 = v1 % 10000;
-
- const uint32_t d5 = (b1 / 100) << 1;
- const uint32_t d6 = (b1 % 100) << 1;
-
- const uint32_t d7 = (c1 / 100) << 1;
- const uint32_t d8 = (c1 % 100) << 1;
-
- *buffer++ = cDigitsLut[d1];
- *buffer++ = cDigitsLut[d1 + 1];
- *buffer++ = cDigitsLut[d2];
- *buffer++ = cDigitsLut[d2 + 1];
- *buffer++ = cDigitsLut[d3];
- *buffer++ = cDigitsLut[d3 + 1];
- *buffer++ = cDigitsLut[d4];
- *buffer++ = cDigitsLut[d4 + 1];
- *buffer++ = cDigitsLut[d5];
- *buffer++ = cDigitsLut[d5 + 1];
- *buffer++ = cDigitsLut[d6];
- *buffer++ = cDigitsLut[d6 + 1];
- *buffer++ = cDigitsLut[d7];
- *buffer++ = cDigitsLut[d7 + 1];
- *buffer++ = cDigitsLut[d8];
- *buffer++ = cDigitsLut[d8 + 1];
- }
-
- return buffer;
-}
-
-inline char* i64toa(int64_t value, char* buffer) {
- uint64_t u = static_cast<uint64_t>(value);
- if (value < 0) {
- *buffer++ = '-';
- u = ~u + 1;
- }
-
- return u64toa(u, buffer);
-}
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_ITOA_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/meta.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/meta.h
deleted file mode 100644
index 5a9aaa428..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/meta.h
+++ /dev/null
@@ -1,181 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_INTERNAL_META_H_
-#define RAPIDJSON_INTERNAL_META_H_
-
-#include "../rapidjson.h"
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-#if defined(_MSC_VER)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(6334)
-#endif
-
-#if RAPIDJSON_HAS_CXX11_TYPETRAITS
-#include <type_traits>
-#endif
-
-//@cond RAPIDJSON_INTERNAL
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
-template <typename T> struct Void { typedef void Type; };
-
-///////////////////////////////////////////////////////////////////////////////
-// BoolType, TrueType, FalseType
-//
-template <bool Cond> struct BoolType {
- static const bool Value = Cond;
- typedef BoolType Type;
-};
-typedef BoolType<true> TrueType;
-typedef BoolType<false> FalseType;
-
-
-///////////////////////////////////////////////////////////////////////////////
-// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
-//
-
-template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
-template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
-template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
-template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
-
-template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
-template <> struct AndExprCond<true, true> : TrueType {};
-template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
-template <> struct OrExprCond<false, false> : FalseType {};
-
-template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
-template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
-template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
-template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// AddConst, MaybeAddConst, RemoveConst
-template <typename T> struct AddConst { typedef const T Type; };
-template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
-template <typename T> struct RemoveConst { typedef T Type; };
-template <typename T> struct RemoveConst<const T> { typedef T Type; };
-
-
-///////////////////////////////////////////////////////////////////////////////
-// IsSame, IsConst, IsMoreConst, IsPointer
-//
-template <typename T, typename U> struct IsSame : FalseType {};
-template <typename T> struct IsSame<T, T> : TrueType {};
-
-template <typename T> struct IsConst : FalseType {};
-template <typename T> struct IsConst<const T> : TrueType {};
-
-template <typename CT, typename T>
-struct IsMoreConst
- : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
- BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
-
-template <typename T> struct IsPointer : FalseType {};
-template <typename T> struct IsPointer<T*> : TrueType {};
-
-///////////////////////////////////////////////////////////////////////////////
-// IsBaseOf
-//
-#if RAPIDJSON_HAS_CXX11_TYPETRAITS
-
-template <typename B, typename D> struct IsBaseOf
- : BoolType< ::std::is_base_of<B,D>::value> {};
-
-#else // simplified version adopted from Boost
-
-template<typename B, typename D> struct IsBaseOfImpl {
- RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
- RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
-
- typedef char (&Yes)[1];
- typedef char (&No) [2];
-
- template <typename T>
- static Yes Check(const D*, T);
- static No Check(const B*, int);
-
- struct Host {
- operator const B*() const;
- operator const D*();
- };
-
- enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
-};
-
-template <typename B, typename D> struct IsBaseOf
- : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
-
-#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
-
-
-//////////////////////////////////////////////////////////////////////////
-// EnableIf / DisableIf
-//
-template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
-template <typename T> struct EnableIfCond<false, T> { /* empty */ };
-
-template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
-template <typename T> struct DisableIfCond<true, T> { /* empty */ };
-
-template <typename Condition, typename T = void>
-struct EnableIf : EnableIfCond<Condition::Value, T> {};
-
-template <typename Condition, typename T = void>
-struct DisableIf : DisableIfCond<Condition::Value, T> {};
-
-// SFINAE helpers
-struct SfinaeTag {};
-template <typename T> struct RemoveSfinaeTag;
-template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
-
-#define RAPIDJSON_REMOVEFPTR_(type) \
- typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
- < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
-
-#define RAPIDJSON_ENABLEIF(cond) \
- typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
- <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
-
-#define RAPIDJSON_DISABLEIF(cond) \
- typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
- <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
-
-#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
- typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
- <RAPIDJSON_REMOVEFPTR_(cond), \
- RAPIDJSON_REMOVEFPTR_(returntype)>::Type
-
-#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
- typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
- <RAPIDJSON_REMOVEFPTR_(cond), \
- RAPIDJSON_REMOVEFPTR_(returntype)>::Type
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-//@endcond
-
-#if defined(__GNUC__) || defined(_MSC_VER)
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_INTERNAL_META_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/pow10.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/pow10.h
deleted file mode 100644
index 02f475d70..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/pow10.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_POW10_
-#define RAPIDJSON_POW10_
-
-#include "../rapidjson.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-//! Computes integer powers of 10 in double (10.0^n).
-/*! This function uses lookup table for fast and accurate results.
- \param n non-negative exponent. Must <= 308.
- \return 10.0^n
-*/
-inline double Pow10(int n) {
- static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
- 1e+0,
- 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
- 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
- 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
- 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
- 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
- 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
- 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
- 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
- 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
- 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
- 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
- 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
- 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
- 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
- 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
- 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
- };
- RAPIDJSON_ASSERT(n >= 0 && n <= 308);
- return e[n];
-}
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_POW10_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/regex.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/regex.h
deleted file mode 100644
index e1a2faae5..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/regex.h
+++ /dev/null
@@ -1,734 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_INTERNAL_REGEX_H_
-#define RAPIDJSON_INTERNAL_REGEX_H_
-
-#include "../allocators.h"
-#include "../stream.h"
-#include "stack.h"
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-RAPIDJSON_DIAG_OFF(switch-enum)
-RAPIDJSON_DIAG_OFF(implicit-fallthrough)
-#endif
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#if __GNUC__ >= 7
-RAPIDJSON_DIAG_OFF(implicit-fallthrough)
-#endif
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
-#endif
-
-#ifndef RAPIDJSON_REGEX_VERBOSE
-#define RAPIDJSON_REGEX_VERBOSE 0
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-///////////////////////////////////////////////////////////////////////////////
-// DecodedStream
-
-template <typename SourceStream, typename Encoding>
-class DecodedStream {
-public:
- DecodedStream(SourceStream& ss) : ss_(ss), codepoint_() { Decode(); }
- unsigned Peek() { return codepoint_; }
- unsigned Take() {
- unsigned c = codepoint_;
- if (c) // No further decoding when '\0'
- Decode();
- return c;
- }
-
-private:
- void Decode() {
- if (!Encoding::Decode(ss_, &codepoint_))
- codepoint_ = 0;
- }
-
- SourceStream& ss_;
- unsigned codepoint_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericRegex
-
-static const SizeType kRegexInvalidState = ~SizeType(0); //!< Represents an invalid index in GenericRegex::State::out, out1
-static const SizeType kRegexInvalidRange = ~SizeType(0);
-
-template <typename Encoding, typename Allocator>
-class GenericRegexSearch;
-
-//! Regular expression engine with subset of ECMAscript grammar.
-/*!
- Supported regular expression syntax:
- - \c ab Concatenation
- - \c a|b Alternation
- - \c a? Zero or one
- - \c a* Zero or more
- - \c a+ One or more
- - \c a{3} Exactly 3 times
- - \c a{3,} At least 3 times
- - \c a{3,5} 3 to 5 times
- - \c (ab) Grouping
- - \c ^a At the beginning
- - \c a$ At the end
- - \c . Any character
- - \c [abc] Character classes
- - \c [a-c] Character class range
- - \c [a-z0-9_] Character class combination
- - \c [^abc] Negated character classes
- - \c [^a-c] Negated character class range
- - \c [\b] Backspace (U+0008)
- - \c \\| \\\\ ... Escape characters
- - \c \\f Form feed (U+000C)
- - \c \\n Line feed (U+000A)
- - \c \\r Carriage return (U+000D)
- - \c \\t Tab (U+0009)
- - \c \\v Vertical tab (U+000B)
-
- \note This is a Thompson NFA engine, implemented with reference to
- Cox, Russ. "Regular Expression Matching Can Be Simple And Fast (but is slow in Java, Perl, PHP, Python, Ruby,...).",
- https://swtch.com/~rsc/regexp/regexp1.html
-*/
-template <typename Encoding, typename Allocator = CrtAllocator>
-class GenericRegex {
-public:
- typedef Encoding EncodingType;
- typedef typename Encoding::Ch Ch;
- template <typename, typename> friend class GenericRegexSearch;
-
- GenericRegex(const Ch* source, Allocator* allocator = 0) :
- states_(allocator, 256), ranges_(allocator, 256), root_(kRegexInvalidState), stateCount_(), rangeCount_(),
- anchorBegin_(), anchorEnd_()
- {
- GenericStringStream<Encoding> ss(source);
- DecodedStream<GenericStringStream<Encoding>, Encoding> ds(ss);
- Parse(ds);
- }
-
- ~GenericRegex() {}
-
- bool IsValid() const {
- return root_ != kRegexInvalidState;
- }
-
-private:
- enum Operator {
- kZeroOrOne,
- kZeroOrMore,
- kOneOrMore,
- kConcatenation,
- kAlternation,
- kLeftParenthesis
- };
-
- static const unsigned kAnyCharacterClass = 0xFFFFFFFF; //!< For '.'
- static const unsigned kRangeCharacterClass = 0xFFFFFFFE;
- static const unsigned kRangeNegationFlag = 0x80000000;
-
- struct Range {
- unsigned start; //
- unsigned end;
- SizeType next;
- };
-
- struct State {
- SizeType out; //!< Equals to kInvalid for matching state
- SizeType out1; //!< Equals to non-kInvalid for split
- SizeType rangeStart;
- unsigned codepoint;
- };
-
- struct Frag {
- Frag(SizeType s, SizeType o, SizeType m) : start(s), out(o), minIndex(m) {}
- SizeType start;
- SizeType out; //!< link-list of all output states
- SizeType minIndex;
- };
-
- State& GetState(SizeType index) {
- RAPIDJSON_ASSERT(index < stateCount_);
- return states_.template Bottom<State>()[index];
- }
-
- const State& GetState(SizeType index) const {
- RAPIDJSON_ASSERT(index < stateCount_);
- return states_.template Bottom<State>()[index];
- }
-
- Range& GetRange(SizeType index) {
- RAPIDJSON_ASSERT(index < rangeCount_);
- return ranges_.template Bottom<Range>()[index];
- }
-
- const Range& GetRange(SizeType index) const {
- RAPIDJSON_ASSERT(index < rangeCount_);
- return ranges_.template Bottom<Range>()[index];
- }
-
- template <typename InputStream>
- void Parse(DecodedStream<InputStream, Encoding>& ds) {
- Allocator allocator;
- Stack<Allocator> operandStack(&allocator, 256); // Frag
- Stack<Allocator> operatorStack(&allocator, 256); // Operator
- Stack<Allocator> atomCountStack(&allocator, 256); // unsigned (Atom per parenthesis)
-
- *atomCountStack.template Push<unsigned>() = 0;
-
- unsigned codepoint;
- while (ds.Peek() != 0) {
- switch (codepoint = ds.Take()) {
- case '^':
- anchorBegin_ = true;
- break;
-
- case '$':
- anchorEnd_ = true;
- break;
-
- case '|':
- while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() < kAlternation)
- if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
- return;
- *operatorStack.template Push<Operator>() = kAlternation;
- *atomCountStack.template Top<unsigned>() = 0;
- break;
-
- case '(':
- *operatorStack.template Push<Operator>() = kLeftParenthesis;
- *atomCountStack.template Push<unsigned>() = 0;
- break;
-
- case ')':
- while (!operatorStack.Empty() && *operatorStack.template Top<Operator>() != kLeftParenthesis)
- if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
- return;
- if (operatorStack.Empty())
- return;
- operatorStack.template Pop<Operator>(1);
- atomCountStack.template Pop<unsigned>(1);
- ImplicitConcatenation(atomCountStack, operatorStack);
- break;
-
- case '?':
- if (!Eval(operandStack, kZeroOrOne))
- return;
- break;
-
- case '*':
- if (!Eval(operandStack, kZeroOrMore))
- return;
- break;
-
- case '+':
- if (!Eval(operandStack, kOneOrMore))
- return;
- break;
-
- case '{':
- {
- unsigned n, m;
- if (!ParseUnsigned(ds, &n))
- return;
-
- if (ds.Peek() == ',') {
- ds.Take();
- if (ds.Peek() == '}')
- m = kInfinityQuantifier;
- else if (!ParseUnsigned(ds, &m) || m < n)
- return;
- }
- else
- m = n;
-
- if (!EvalQuantifier(operandStack, n, m) || ds.Peek() != '}')
- return;
- ds.Take();
- }
- break;
-
- case '.':
- PushOperand(operandStack, kAnyCharacterClass);
- ImplicitConcatenation(atomCountStack, operatorStack);
- break;
-
- case '[':
- {
- SizeType range;
- if (!ParseRange(ds, &range))
- return;
- SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, kRangeCharacterClass);
- GetState(s).rangeStart = range;
- *operandStack.template Push<Frag>() = Frag(s, s, s);
- }
- ImplicitConcatenation(atomCountStack, operatorStack);
- break;
-
- case '\\': // Escape character
- if (!CharacterEscape(ds, &codepoint))
- return; // Unsupported escape character
- // fall through to default
-
- default: // Pattern character
- PushOperand(operandStack, codepoint);
- ImplicitConcatenation(atomCountStack, operatorStack);
- }
- }
-
- while (!operatorStack.Empty())
- if (!Eval(operandStack, *operatorStack.template Pop<Operator>(1)))
- return;
-
- // Link the operand to matching state.
- if (operandStack.GetSize() == sizeof(Frag)) {
- Frag* e = operandStack.template Pop<Frag>(1);
- Patch(e->out, NewState(kRegexInvalidState, kRegexInvalidState, 0));
- root_ = e->start;
-
-#if RAPIDJSON_REGEX_VERBOSE
- printf("root: %d\n", root_);
- for (SizeType i = 0; i < stateCount_ ; i++) {
- State& s = GetState(i);
- printf("[%2d] out: %2d out1: %2d c: '%c'\n", i, s.out, s.out1, (char)s.codepoint);
- }
- printf("\n");
-#endif
- }
- }
-
- SizeType NewState(SizeType out, SizeType out1, unsigned codepoint) {
- State* s = states_.template Push<State>();
- s->out = out;
- s->out1 = out1;
- s->codepoint = codepoint;
- s->rangeStart = kRegexInvalidRange;
- return stateCount_++;
- }
-
- void PushOperand(Stack<Allocator>& operandStack, unsigned codepoint) {
- SizeType s = NewState(kRegexInvalidState, kRegexInvalidState, codepoint);
- *operandStack.template Push<Frag>() = Frag(s, s, s);
- }
-
- void ImplicitConcatenation(Stack<Allocator>& atomCountStack, Stack<Allocator>& operatorStack) {
- if (*atomCountStack.template Top<unsigned>())
- *operatorStack.template Push<Operator>() = kConcatenation;
- (*atomCountStack.template Top<unsigned>())++;
- }
-
- SizeType Append(SizeType l1, SizeType l2) {
- SizeType old = l1;
- while (GetState(l1).out != kRegexInvalidState)
- l1 = GetState(l1).out;
- GetState(l1).out = l2;
- return old;
- }
-
- void Patch(SizeType l, SizeType s) {
- for (SizeType next; l != kRegexInvalidState; l = next) {
- next = GetState(l).out;
- GetState(l).out = s;
- }
- }
-
- bool Eval(Stack<Allocator>& operandStack, Operator op) {
- switch (op) {
- case kConcatenation:
- RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag) * 2);
- {
- Frag e2 = *operandStack.template Pop<Frag>(1);
- Frag e1 = *operandStack.template Pop<Frag>(1);
- Patch(e1.out, e2.start);
- *operandStack.template Push<Frag>() = Frag(e1.start, e2.out, Min(e1.minIndex, e2.minIndex));
- }
- return true;
-
- case kAlternation:
- if (operandStack.GetSize() >= sizeof(Frag) * 2) {
- Frag e2 = *operandStack.template Pop<Frag>(1);
- Frag e1 = *operandStack.template Pop<Frag>(1);
- SizeType s = NewState(e1.start, e2.start, 0);
- *operandStack.template Push<Frag>() = Frag(s, Append(e1.out, e2.out), Min(e1.minIndex, e2.minIndex));
- return true;
- }
- return false;
-
- case kZeroOrOne:
- if (operandStack.GetSize() >= sizeof(Frag)) {
- Frag e = *operandStack.template Pop<Frag>(1);
- SizeType s = NewState(kRegexInvalidState, e.start, 0);
- *operandStack.template Push<Frag>() = Frag(s, Append(e.out, s), e.minIndex);
- return true;
- }
- return false;
-
- case kZeroOrMore:
- if (operandStack.GetSize() >= sizeof(Frag)) {
- Frag e = *operandStack.template Pop<Frag>(1);
- SizeType s = NewState(kRegexInvalidState, e.start, 0);
- Patch(e.out, s);
- *operandStack.template Push<Frag>() = Frag(s, s, e.minIndex);
- return true;
- }
- return false;
-
- default:
- RAPIDJSON_ASSERT(op == kOneOrMore);
- if (operandStack.GetSize() >= sizeof(Frag)) {
- Frag e = *operandStack.template Pop<Frag>(1);
- SizeType s = NewState(kRegexInvalidState, e.start, 0);
- Patch(e.out, s);
- *operandStack.template Push<Frag>() = Frag(e.start, s, e.minIndex);
- return true;
- }
- return false;
- }
- }
-
- bool EvalQuantifier(Stack<Allocator>& operandStack, unsigned n, unsigned m) {
- RAPIDJSON_ASSERT(n <= m);
- RAPIDJSON_ASSERT(operandStack.GetSize() >= sizeof(Frag));
-
- if (n == 0) {
- if (m == 0) // a{0} not support
- return false;
- else if (m == kInfinityQuantifier)
- Eval(operandStack, kZeroOrMore); // a{0,} -> a*
- else {
- Eval(operandStack, kZeroOrOne); // a{0,5} -> a?
- for (unsigned i = 0; i < m - 1; i++)
- CloneTopOperand(operandStack); // a{0,5} -> a? a? a? a? a?
- for (unsigned i = 0; i < m - 1; i++)
- Eval(operandStack, kConcatenation); // a{0,5} -> a?a?a?a?a?
- }
- return true;
- }
-
- for (unsigned i = 0; i < n - 1; i++) // a{3} -> a a a
- CloneTopOperand(operandStack);
-
- if (m == kInfinityQuantifier)
- Eval(operandStack, kOneOrMore); // a{3,} -> a a a+
- else if (m > n) {
- CloneTopOperand(operandStack); // a{3,5} -> a a a a
- Eval(operandStack, kZeroOrOne); // a{3,5} -> a a a a?
- for (unsigned i = n; i < m - 1; i++)
- CloneTopOperand(operandStack); // a{3,5} -> a a a a? a?
- for (unsigned i = n; i < m; i++)
- Eval(operandStack, kConcatenation); // a{3,5} -> a a aa?a?
- }
-
- for (unsigned i = 0; i < n - 1; i++)
- Eval(operandStack, kConcatenation); // a{3} -> aaa, a{3,} -> aaa+, a{3.5} -> aaaa?a?
-
- return true;
- }
-
- static SizeType Min(SizeType a, SizeType b) { return a < b ? a : b; }
-
- void CloneTopOperand(Stack<Allocator>& operandStack) {
- const Frag src = *operandStack.template Top<Frag>(); // Copy constructor to prevent invalidation
- SizeType count = stateCount_ - src.minIndex; // Assumes top operand contains states in [src->minIndex, stateCount_)
- State* s = states_.template Push<State>(count);
- memcpy(s, &GetState(src.minIndex), count * sizeof(State));
- for (SizeType j = 0; j < count; j++) {
- if (s[j].out != kRegexInvalidState)
- s[j].out += count;
- if (s[j].out1 != kRegexInvalidState)
- s[j].out1 += count;
- }
- *operandStack.template Push<Frag>() = Frag(src.start + count, src.out + count, src.minIndex + count);
- stateCount_ += count;
- }
-
- template <typename InputStream>
- bool ParseUnsigned(DecodedStream<InputStream, Encoding>& ds, unsigned* u) {
- unsigned r = 0;
- if (ds.Peek() < '0' || ds.Peek() > '9')
- return false;
- while (ds.Peek() >= '0' && ds.Peek() <= '9') {
- if (r >= 429496729 && ds.Peek() > '5') // 2^32 - 1 = 4294967295
- return false; // overflow
- r = r * 10 + (ds.Take() - '0');
- }
- *u = r;
- return true;
- }
-
- template <typename InputStream>
- bool ParseRange(DecodedStream<InputStream, Encoding>& ds, SizeType* range) {
- bool isBegin = true;
- bool negate = false;
- int step = 0;
- SizeType start = kRegexInvalidRange;
- SizeType current = kRegexInvalidRange;
- unsigned codepoint;
- while ((codepoint = ds.Take()) != 0) {
- if (isBegin) {
- isBegin = false;
- if (codepoint == '^') {
- negate = true;
- continue;
- }
- }
-
- switch (codepoint) {
- case ']':
- if (start == kRegexInvalidRange)
- return false; // Error: nothing inside []
- if (step == 2) { // Add trailing '-'
- SizeType r = NewRange('-');
- RAPIDJSON_ASSERT(current != kRegexInvalidRange);
- GetRange(current).next = r;
- }
- if (negate)
- GetRange(start).start |= kRangeNegationFlag;
- *range = start;
- return true;
-
- case '\\':
- if (ds.Peek() == 'b') {
- ds.Take();
- codepoint = 0x0008; // Escape backspace character
- }
- else if (!CharacterEscape(ds, &codepoint))
- return false;
- // fall through to default
-
- default:
- switch (step) {
- case 1:
- if (codepoint == '-') {
- step++;
- break;
- }
- // fall through to step 0 for other characters
-
- case 0:
- {
- SizeType r = NewRange(codepoint);
- if (current != kRegexInvalidRange)
- GetRange(current).next = r;
- if (start == kRegexInvalidRange)
- start = r;
- current = r;
- }
- step = 1;
- break;
-
- default:
- RAPIDJSON_ASSERT(step == 2);
- GetRange(current).end = codepoint;
- step = 0;
- }
- }
- }
- return false;
- }
-
- SizeType NewRange(unsigned codepoint) {
- Range* r = ranges_.template Push<Range>();
- r->start = r->end = codepoint;
- r->next = kRegexInvalidRange;
- return rangeCount_++;
- }
-
- template <typename InputStream>
- bool CharacterEscape(DecodedStream<InputStream, Encoding>& ds, unsigned* escapedCodepoint) {
- unsigned codepoint;
- switch (codepoint = ds.Take()) {
- case '^':
- case '$':
- case '|':
- case '(':
- case ')':
- case '?':
- case '*':
- case '+':
- case '.':
- case '[':
- case ']':
- case '{':
- case '}':
- case '\\':
- *escapedCodepoint = codepoint; return true;
- case 'f': *escapedCodepoint = 0x000C; return true;
- case 'n': *escapedCodepoint = 0x000A; return true;
- case 'r': *escapedCodepoint = 0x000D; return true;
- case 't': *escapedCodepoint = 0x0009; return true;
- case 'v': *escapedCodepoint = 0x000B; return true;
- default:
- return false; // Unsupported escape character
- }
- }
-
- Stack<Allocator> states_;
- Stack<Allocator> ranges_;
- SizeType root_;
- SizeType stateCount_;
- SizeType rangeCount_;
-
- static const unsigned kInfinityQuantifier = ~0u;
-
- // For SearchWithAnchoring()
- bool anchorBegin_;
- bool anchorEnd_;
-};
-
-template <typename RegexType, typename Allocator = CrtAllocator>
-class GenericRegexSearch {
-public:
- typedef typename RegexType::EncodingType Encoding;
- typedef typename Encoding::Ch Ch;
-
- GenericRegexSearch(const RegexType& regex, Allocator* allocator = 0) :
- regex_(regex), allocator_(allocator), ownAllocator_(0),
- state0_(allocator, 0), state1_(allocator, 0), stateSet_()
- {
- RAPIDJSON_ASSERT(regex_.IsValid());
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
- stateSet_ = static_cast<unsigned*>(allocator_->Malloc(GetStateSetSize()));
- state0_.template Reserve<SizeType>(regex_.stateCount_);
- state1_.template Reserve<SizeType>(regex_.stateCount_);
- }
-
- ~GenericRegexSearch() {
- Allocator::Free(stateSet_);
- RAPIDJSON_DELETE(ownAllocator_);
- }
-
- template <typename InputStream>
- bool Match(InputStream& is) {
- return SearchWithAnchoring(is, true, true);
- }
-
- bool Match(const Ch* s) {
- GenericStringStream<Encoding> is(s);
- return Match(is);
- }
-
- template <typename InputStream>
- bool Search(InputStream& is) {
- return SearchWithAnchoring(is, regex_.anchorBegin_, regex_.anchorEnd_);
- }
-
- bool Search(const Ch* s) {
- GenericStringStream<Encoding> is(s);
- return Search(is);
- }
-
-private:
- typedef typename RegexType::State State;
- typedef typename RegexType::Range Range;
-
- template <typename InputStream>
- bool SearchWithAnchoring(InputStream& is, bool anchorBegin, bool anchorEnd) {
- DecodedStream<InputStream, Encoding> ds(is);
-
- state0_.Clear();
- Stack<Allocator> *current = &state0_, *next = &state1_;
- const size_t stateSetSize = GetStateSetSize();
- std::memset(stateSet_, 0, stateSetSize);
-
- bool matched = AddState(*current, regex_.root_);
- unsigned codepoint;
- while (!current->Empty() && (codepoint = ds.Take()) != 0) {
- std::memset(stateSet_, 0, stateSetSize);
- next->Clear();
- matched = false;
- for (const SizeType* s = current->template Bottom<SizeType>(); s != current->template End<SizeType>(); ++s) {
- const State& sr = regex_.GetState(*s);
- if (sr.codepoint == codepoint ||
- sr.codepoint == RegexType::kAnyCharacterClass ||
- (sr.codepoint == RegexType::kRangeCharacterClass && MatchRange(sr.rangeStart, codepoint)))
- {
- matched = AddState(*next, sr.out) || matched;
- if (!anchorEnd && matched)
- return true;
- }
- if (!anchorBegin)
- AddState(*next, regex_.root_);
- }
- internal::Swap(current, next);
- }
-
- return matched;
- }
-
- size_t GetStateSetSize() const {
- return (regex_.stateCount_ + 31) / 32 * 4;
- }
-
- // Return whether the added states is a match state
- bool AddState(Stack<Allocator>& l, SizeType index) {
- RAPIDJSON_ASSERT(index != kRegexInvalidState);
-
- const State& s = regex_.GetState(index);
- if (s.out1 != kRegexInvalidState) { // Split
- bool matched = AddState(l, s.out);
- return AddState(l, s.out1) || matched;
- }
- else if (!(stateSet_[index >> 5] & (1u << (index & 31)))) {
- stateSet_[index >> 5] |= (1u << (index & 31));
- *l.template PushUnsafe<SizeType>() = index;
- }
- return s.out == kRegexInvalidState; // by using PushUnsafe() above, we can ensure s is not validated due to reallocation.
- }
-
- bool MatchRange(SizeType rangeIndex, unsigned codepoint) const {
- bool yes = (regex_.GetRange(rangeIndex).start & RegexType::kRangeNegationFlag) == 0;
- while (rangeIndex != kRegexInvalidRange) {
- const Range& r = regex_.GetRange(rangeIndex);
- if (codepoint >= (r.start & ~RegexType::kRangeNegationFlag) && codepoint <= r.end)
- return yes;
- rangeIndex = r.next;
- }
- return !yes;
- }
-
- const RegexType& regex_;
- Allocator* allocator_;
- Allocator* ownAllocator_;
- Stack<Allocator> state0_;
- Stack<Allocator> state1_;
- uint32_t* stateSet_;
-};
-
-typedef GenericRegex<UTF8<> > Regex;
-typedef GenericRegexSearch<Regex> RegexSearch;
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_INTERNAL_REGEX_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/stack.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/stack.h
deleted file mode 100644
index 5c5398c35..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/stack.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_INTERNAL_STACK_H_
-#define RAPIDJSON_INTERNAL_STACK_H_
-
-#include "../allocators.h"
-#include "swap.h"
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-///////////////////////////////////////////////////////////////////////////////
-// Stack
-
-//! A type-unsafe stack for storing different types of data.
-/*! \tparam Allocator Allocator for allocating stack memory.
-*/
-template <typename Allocator>
-class Stack {
-public:
- // Optimization note: Do not allocate memory for stack_ in constructor.
- // Do it lazily when first Push() -> Expand() -> Resize().
- Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- Stack(Stack&& rhs)
- : allocator_(rhs.allocator_),
- ownAllocator_(rhs.ownAllocator_),
- stack_(rhs.stack_),
- stackTop_(rhs.stackTop_),
- stackEnd_(rhs.stackEnd_),
- initialCapacity_(rhs.initialCapacity_)
- {
- rhs.allocator_ = 0;
- rhs.ownAllocator_ = 0;
- rhs.stack_ = 0;
- rhs.stackTop_ = 0;
- rhs.stackEnd_ = 0;
- rhs.initialCapacity_ = 0;
- }
-#endif
-
- ~Stack() {
- Destroy();
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- Stack& operator=(Stack&& rhs) {
- if (&rhs != this)
- {
- Destroy();
-
- allocator_ = rhs.allocator_;
- ownAllocator_ = rhs.ownAllocator_;
- stack_ = rhs.stack_;
- stackTop_ = rhs.stackTop_;
- stackEnd_ = rhs.stackEnd_;
- initialCapacity_ = rhs.initialCapacity_;
-
- rhs.allocator_ = 0;
- rhs.ownAllocator_ = 0;
- rhs.stack_ = 0;
- rhs.stackTop_ = 0;
- rhs.stackEnd_ = 0;
- rhs.initialCapacity_ = 0;
- }
- return *this;
- }
-#endif
-
- void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
- internal::Swap(allocator_, rhs.allocator_);
- internal::Swap(ownAllocator_, rhs.ownAllocator_);
- internal::Swap(stack_, rhs.stack_);
- internal::Swap(stackTop_, rhs.stackTop_);
- internal::Swap(stackEnd_, rhs.stackEnd_);
- internal::Swap(initialCapacity_, rhs.initialCapacity_);
- }
-
- void Clear() { stackTop_ = stack_; }
-
- void ShrinkToFit() {
- if (Empty()) {
- // If the stack is empty, completely deallocate the memory.
- Allocator::Free(stack_);
- stack_ = 0;
- stackTop_ = 0;
- stackEnd_ = 0;
- }
- else
- Resize(GetSize());
- }
-
- // Optimization note: try to minimize the size of this function for force inline.
- // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
- template<typename T>
- RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
- // Expand the stack if needed
- if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
- Expand<T>(count);
- }
-
- template<typename T>
- RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
- Reserve<T>(count);
- return PushUnsafe<T>(count);
- }
-
- template<typename T>
- RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
- RAPIDJSON_ASSERT(stackTop_);
- RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
- T* ret = reinterpret_cast<T*>(stackTop_);
- stackTop_ += sizeof(T) * count;
- return ret;
- }
-
- template<typename T>
- T* Pop(size_t count) {
- RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
- stackTop_ -= count * sizeof(T);
- return reinterpret_cast<T*>(stackTop_);
- }
-
- template<typename T>
- T* Top() {
- RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
- return reinterpret_cast<T*>(stackTop_ - sizeof(T));
- }
-
- template<typename T>
- const T* Top() const {
- RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
- return reinterpret_cast<T*>(stackTop_ - sizeof(T));
- }
-
- template<typename T>
- T* End() { return reinterpret_cast<T*>(stackTop_); }
-
- template<typename T>
- const T* End() const { return reinterpret_cast<T*>(stackTop_); }
-
- template<typename T>
- T* Bottom() { return reinterpret_cast<T*>(stack_); }
-
- template<typename T>
- const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
-
- bool HasAllocator() const {
- return allocator_ != 0;
- }
-
- Allocator& GetAllocator() {
- RAPIDJSON_ASSERT(allocator_);
- return *allocator_;
- }
-
- bool Empty() const { return stackTop_ == stack_; }
- size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
- size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
-
-private:
- template<typename T>
- void Expand(size_t count) {
- // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
- size_t newCapacity;
- if (stack_ == 0) {
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
- newCapacity = initialCapacity_;
- } else {
- newCapacity = GetCapacity();
- newCapacity += (newCapacity + 1) / 2;
- }
- size_t newSize = GetSize() + sizeof(T) * count;
- if (newCapacity < newSize)
- newCapacity = newSize;
-
- Resize(newCapacity);
- }
-
- void Resize(size_t newCapacity) {
- const size_t size = GetSize(); // Backup the current size
- stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
- stackTop_ = stack_ + size;
- stackEnd_ = stack_ + newCapacity;
- }
-
- void Destroy() {
- Allocator::Free(stack_);
- RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
- }
-
- // Prohibit copy constructor & assignment operator.
- Stack(const Stack&);
- Stack& operator=(const Stack&);
-
- Allocator* allocator_;
- Allocator* ownAllocator_;
- char *stack_;
- char *stackTop_;
- char *stackEnd_;
- size_t initialCapacity_;
-};
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_STACK_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strfunc.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strfunc.h
deleted file mode 100644
index 226439a76..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strfunc.h
+++ /dev/null
@@ -1,69 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
-#define RAPIDJSON_INTERNAL_STRFUNC_H_
-
-#include "../stream.h"
-#include <cwchar>
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-//! Custom strlen() which works on different character types.
-/*! \tparam Ch Character type (e.g. char, wchar_t, short)
- \param s Null-terminated input string.
- \return Number of characters in the string.
- \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
-*/
-template <typename Ch>
-inline SizeType StrLen(const Ch* s) {
- RAPIDJSON_ASSERT(s != 0);
- const Ch* p = s;
- while (*p) ++p;
- return SizeType(p - s);
-}
-
-template <>
-inline SizeType StrLen(const char* s) {
- return SizeType(std::strlen(s));
-}
-
-template <>
-inline SizeType StrLen(const wchar_t* s) {
- return SizeType(std::wcslen(s));
-}
-
-//! Returns number of code points in a encoded string.
-template<typename Encoding>
-bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
- RAPIDJSON_ASSERT(s != 0);
- RAPIDJSON_ASSERT(outCount != 0);
- GenericStringStream<Encoding> is(s);
- const typename Encoding::Ch* end = s + length;
- SizeType count = 0;
- while (is.src_ < end) {
- unsigned codepoint;
- if (!Encoding::Decode(is, &codepoint))
- return false;
- count++;
- }
- *outCount = count;
- return true;
-}
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strtod.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strtod.h
deleted file mode 100644
index adf49e349..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/strtod.h
+++ /dev/null
@@ -1,269 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_STRTOD_
-#define RAPIDJSON_STRTOD_
-
-#include "ieee754.h"
-#include "biginteger.h"
-#include "diyfp.h"
-#include "pow10.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-inline double FastPath(double significand, int exp) {
- if (exp < -308)
- return 0.0;
- else if (exp >= 0)
- return significand * internal::Pow10(exp);
- else
- return significand / internal::Pow10(-exp);
-}
-
-inline double StrtodNormalPrecision(double d, int p) {
- if (p < -308) {
- // Prevent expSum < -308, making Pow10(p) = 0
- d = FastPath(d, -308);
- d = FastPath(d, p + 308);
- }
- else
- d = FastPath(d, p);
- return d;
-}
-
-template <typename T>
-inline T Min3(T a, T b, T c) {
- T m = a;
- if (m > b) m = b;
- if (m > c) m = c;
- return m;
-}
-
-inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
- const Double db(b);
- const uint64_t bInt = db.IntegerSignificand();
- const int bExp = db.IntegerExponent();
- const int hExp = bExp - 1;
-
- int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;
-
- // Adjust for decimal exponent
- if (dExp >= 0) {
- dS_Exp2 += dExp;
- dS_Exp5 += dExp;
- }
- else {
- bS_Exp2 -= dExp;
- bS_Exp5 -= dExp;
- hS_Exp2 -= dExp;
- hS_Exp5 -= dExp;
- }
-
- // Adjust for binary exponent
- if (bExp >= 0)
- bS_Exp2 += bExp;
- else {
- dS_Exp2 -= bExp;
- hS_Exp2 -= bExp;
- }
-
- // Adjust for half ulp exponent
- if (hExp >= 0)
- hS_Exp2 += hExp;
- else {
- dS_Exp2 -= hExp;
- bS_Exp2 -= hExp;
- }
-
- // Remove common power of two factor from all three scaled values
- int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);
- dS_Exp2 -= common_Exp2;
- bS_Exp2 -= common_Exp2;
- hS_Exp2 -= common_Exp2;
-
- BigInteger dS = d;
- dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);
-
- BigInteger bS(bInt);
- bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);
-
- BigInteger hS(1);
- hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);
-
- BigInteger delta(0);
- dS.Difference(bS, &delta);
-
- return delta.Compare(hS);
-}
-
-inline bool StrtodFast(double d, int p, double* result) {
- // Use fast path for string-to-double conversion if possible
- // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
- if (p > 22 && p < 22 + 16) {
- // Fast Path Cases In Disguise
- d *= internal::Pow10(p - 22);
- p = 22;
- }
-
- if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1
- *result = FastPath(d, p);
- return true;
- }
- else
- return false;
-}
-
-// Compute an approximation and see if it is within 1/2 ULP
-inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
- uint64_t significand = 0;
- size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
- for (; i < length; i++) {
- if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
- (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
- break;
- significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
- }
-
- if (i < length && decimals[i] >= '5') // Rounding
- significand++;
-
- size_t remaining = length - i;
- const int kUlpShift = 3;
- const int kUlp = 1 << kUlpShift;
- int64_t error = (remaining == 0) ? 0 : kUlp / 2;
-
- DiyFp v(significand, 0);
- v = v.Normalize();
- error <<= -v.e;
-
- const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
-
- int actualExp;
- DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
- if (actualExp != dExp) {
- static const DiyFp kPow10[] = {
- DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1
- DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2
- DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3
- DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4
- DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5
- DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
- DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
- };
- int adjustment = dExp - actualExp - 1;
- RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
- v = v * kPow10[adjustment];
- if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
- error += kUlp / 2;
- }
-
- v = v * cachedPower;
-
- error += kUlp + (error == 0 ? 0 : 1);
-
- const int oldExp = v.e;
- v = v.Normalize();
- error <<= oldExp - v.e;
-
- const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
- int precisionSize = 64 - effectiveSignificandSize;
- if (precisionSize + kUlpShift >= 64) {
- int scaleExp = (precisionSize + kUlpShift) - 63;
- v.f >>= scaleExp;
- v.e += scaleExp;
- error = (error >> scaleExp) + 1 + kUlp;
- precisionSize -= scaleExp;
- }
-
- DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
- const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
- const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
- if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
- rounded.f++;
- if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
- rounded.f >>= 1;
- rounded.e++;
- }
- }
-
- *result = rounded.ToDouble();
-
- return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
-}
-
-inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
- const BigInteger dInt(decimals, length);
- const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
- Double a(approx);
- int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
- if (cmp < 0)
- return a.Value(); // within half ULP
- else if (cmp == 0) {
- // Round towards even
- if (a.Significand() & 1)
- return a.NextPositiveDouble();
- else
- return a.Value();
- }
- else // adjustment
- return a.NextPositiveDouble();
-}
-
-inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
- RAPIDJSON_ASSERT(d >= 0.0);
- RAPIDJSON_ASSERT(length >= 1);
-
- double result;
- if (StrtodFast(d, p, &result))
- return result;
-
- // Trim leading zeros
- while (*decimals == '0' && length > 1) {
- length--;
- decimals++;
- decimalPosition--;
- }
-
- // Trim trailing zeros
- while (decimals[length - 1] == '0' && length > 1) {
- length--;
- decimalPosition--;
- exp++;
- }
-
- // Trim right-most digits
- const int kMaxDecimalDigit = 780;
- if (static_cast<int>(length) > kMaxDecimalDigit) {
- int delta = (static_cast<int>(length) - kMaxDecimalDigit);
- exp += delta;
- decimalPosition -= static_cast<unsigned>(delta);
- length = kMaxDecimalDigit;
- }
-
- // If too small, underflow to zero
- if (int(length) + exp < -324)
- return 0.0;
-
- if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
- return result;
-
- // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
- return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
-}
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_STRTOD_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/swap.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/swap.h
deleted file mode 100644
index 666e49f97..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/internal/swap.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_INTERNAL_SWAP_H_
-#define RAPIDJSON_INTERNAL_SWAP_H_
-
-#include "../rapidjson.h"
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-namespace internal {
-
-//! Custom swap() to avoid dependency on C++ <algorithm> header
-/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
- \note This has the same semantics as std::swap().
-*/
-template <typename T>
-inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
- T tmp = a;
- a = b;
- b = tmp;
-}
-
-} // namespace internal
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_INTERNAL_SWAP_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/istreamwrapper.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/istreamwrapper.h
deleted file mode 100644
index 8639c8c3c..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/istreamwrapper.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_ISTREAMWRAPPER_H_
-#define RAPIDJSON_ISTREAMWRAPPER_H_
-
-#include "stream.h"
-#include <iosfwd>
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept.
-/*!
- The classes can be wrapped including but not limited to:
-
- - \c std::istringstream
- - \c std::stringstream
- - \c std::wistringstream
- - \c std::wstringstream
- - \c std::ifstream
- - \c std::fstream
- - \c std::wifstream
- - \c std::wfstream
-
- \tparam StreamType Class derived from \c std::basic_istream.
-*/
-
-template <typename StreamType>
-class BasicIStreamWrapper {
-public:
- typedef typename StreamType::char_type Ch;
- BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}
-
- Ch Peek() const {
- typename StreamType::int_type c = stream_.peek();
- return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\0');
- }
-
- Ch Take() {
- typename StreamType::int_type c = stream_.get();
- if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {
- count_++;
- return static_cast<Ch>(c);
- }
- else
- return '\0';
- }
-
- // tellg() may return -1 when failed. So we count by ourself.
- size_t Tell() const { return count_; }
-
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
- // For encoding detection only.
- const Ch* Peek4() const {
- RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.
- int i;
- bool hasError = false;
- for (i = 0; i < 4; ++i) {
- typename StreamType::int_type c = stream_.get();
- if (c == StreamType::traits_type::eof()) {
- hasError = true;
- stream_.clear();
- break;
- }
- peekBuffer_[i] = static_cast<Ch>(c);
- }
- for (--i; i >= 0; --i)
- stream_.putback(peekBuffer_[i]);
- return !hasError ? peekBuffer_ : 0;
- }
-
-private:
- BasicIStreamWrapper(const BasicIStreamWrapper&);
- BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
-
- StreamType& stream_;
- size_t count_; //!< Number of characters read. Note:
- mutable Ch peekBuffer_[4];
-};
-
-typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
-typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;
-
-#if defined(__clang__) || defined(_MSC_VER)
-RAPIDJSON_DIAG_POP
-#endif
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_ISTREAMWRAPPER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorybuffer.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorybuffer.h
deleted file mode 100644
index 39bee1dec..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorybuffer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_MEMORYBUFFER_H_
-#define RAPIDJSON_MEMORYBUFFER_H_
-
-#include "stream.h"
-#include "internal/stack.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Represents an in-memory output byte stream.
-/*!
- This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
-
- It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
-
- Differences between MemoryBuffer and StringBuffer:
- 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
- 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
-
- \tparam Allocator type for allocating memory buffer.
- \note implements Stream concept
-*/
-template <typename Allocator = CrtAllocator>
-struct GenericMemoryBuffer {
- typedef char Ch; // byte
-
- GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
-
- void Put(Ch c) { *stack_.template Push<Ch>() = c; }
- void Flush() {}
-
- void Clear() { stack_.Clear(); }
- void ShrinkToFit() { stack_.ShrinkToFit(); }
- Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
- void Pop(size_t count) { stack_.template Pop<Ch>(count); }
-
- const Ch* GetBuffer() const {
- return stack_.template Bottom<Ch>();
- }
-
- size_t GetSize() const { return stack_.GetSize(); }
-
- static const size_t kDefaultCapacity = 256;
- mutable internal::Stack<Allocator> stack_;
-};
-
-typedef GenericMemoryBuffer<> MemoryBuffer;
-
-//! Implement specialized version of PutN() with memset() for better performance.
-template<>
-inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {
- std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));
-}
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_MEMORYBUFFER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorystream.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorystream.h
deleted file mode 100644
index 1d71d8a4f..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/memorystream.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_MEMORYSTREAM_H_
-#define RAPIDJSON_MEMORYSTREAM_H_
-
-#include "stream.h"
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(unreachable-code)
-RAPIDJSON_DIAG_OFF(missing-noreturn)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Represents an in-memory input byte stream.
-/*!
- This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
-
- It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
-
- Differences between MemoryStream and StringStream:
- 1. StringStream has encoding but MemoryStream is a byte stream.
- 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
- 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
- \note implements Stream concept
-*/
-struct MemoryStream {
- typedef char Ch; // byte
-
- MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
-
- Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; }
- Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
- size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
-
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
- // For encoding detection only.
- const Ch* Peek4() const {
- return Tell() + 4 <= size_ ? src_ : 0;
- }
-
- const Ch* src_; //!< Current read position.
- const Ch* begin_; //!< Original head of the string.
- const Ch* end_; //!< End of stream.
- size_t size_; //!< Size of the stream.
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_MEMORYBUFFER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/inttypes.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/inttypes.h
deleted file mode 100644
index 18111286b..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/inttypes.h
+++ /dev/null
@@ -1,316 +0,0 @@
-// ISO C9x compliant inttypes.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
-//
-// Copyright (c) 2006-2013 Alexander Chemeris
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. 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.
-//
-// 3. Neither the name of the product nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-// The above software in this distribution may have been modified by
-// THL A29 Limited ("Tencent Modifications").
-// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_INTTYPES_H_ // [
-#define _MSC_INTTYPES_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#include "stdint.h"
-
-// miloyip: VC supports inttypes.h since VC2013
-#if _MSC_VER >= 1800
-#include <inttypes.h>
-#else
-
-// 7.8 Format conversion of integer types
-
-typedef struct {
- intmax_t quot;
- intmax_t rem;
-} imaxdiv_t;
-
-// 7.8.1 Macros for format specifiers
-
-#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
-
-// The fprintf macros for signed integers are:
-#define PRId8 "d"
-#define PRIi8 "i"
-#define PRIdLEAST8 "d"
-#define PRIiLEAST8 "i"
-#define PRIdFAST8 "d"
-#define PRIiFAST8 "i"
-
-#define PRId16 "hd"
-#define PRIi16 "hi"
-#define PRIdLEAST16 "hd"
-#define PRIiLEAST16 "hi"
-#define PRIdFAST16 "hd"
-#define PRIiFAST16 "hi"
-
-#define PRId32 "I32d"
-#define PRIi32 "I32i"
-#define PRIdLEAST32 "I32d"
-#define PRIiLEAST32 "I32i"
-#define PRIdFAST32 "I32d"
-#define PRIiFAST32 "I32i"
-
-#define PRId64 "I64d"
-#define PRIi64 "I64i"
-#define PRIdLEAST64 "I64d"
-#define PRIiLEAST64 "I64i"
-#define PRIdFAST64 "I64d"
-#define PRIiFAST64 "I64i"
-
-#define PRIdMAX "I64d"
-#define PRIiMAX "I64i"
-
-#define PRIdPTR "Id"
-#define PRIiPTR "Ii"
-
-// The fprintf macros for unsigned integers are:
-#define PRIo8 "o"
-#define PRIu8 "u"
-#define PRIx8 "x"
-#define PRIX8 "X"
-#define PRIoLEAST8 "o"
-#define PRIuLEAST8 "u"
-#define PRIxLEAST8 "x"
-#define PRIXLEAST8 "X"
-#define PRIoFAST8 "o"
-#define PRIuFAST8 "u"
-#define PRIxFAST8 "x"
-#define PRIXFAST8 "X"
-
-#define PRIo16 "ho"
-#define PRIu16 "hu"
-#define PRIx16 "hx"
-#define PRIX16 "hX"
-#define PRIoLEAST16 "ho"
-#define PRIuLEAST16 "hu"
-#define PRIxLEAST16 "hx"
-#define PRIXLEAST16 "hX"
-#define PRIoFAST16 "ho"
-#define PRIuFAST16 "hu"
-#define PRIxFAST16 "hx"
-#define PRIXFAST16 "hX"
-
-#define PRIo32 "I32o"
-#define PRIu32 "I32u"
-#define PRIx32 "I32x"
-#define PRIX32 "I32X"
-#define PRIoLEAST32 "I32o"
-#define PRIuLEAST32 "I32u"
-#define PRIxLEAST32 "I32x"
-#define PRIXLEAST32 "I32X"
-#define PRIoFAST32 "I32o"
-#define PRIuFAST32 "I32u"
-#define PRIxFAST32 "I32x"
-#define PRIXFAST32 "I32X"
-
-#define PRIo64 "I64o"
-#define PRIu64 "I64u"
-#define PRIx64 "I64x"
-#define PRIX64 "I64X"
-#define PRIoLEAST64 "I64o"
-#define PRIuLEAST64 "I64u"
-#define PRIxLEAST64 "I64x"
-#define PRIXLEAST64 "I64X"
-#define PRIoFAST64 "I64o"
-#define PRIuFAST64 "I64u"
-#define PRIxFAST64 "I64x"
-#define PRIXFAST64 "I64X"
-
-#define PRIoMAX "I64o"
-#define PRIuMAX "I64u"
-#define PRIxMAX "I64x"
-#define PRIXMAX "I64X"
-
-#define PRIoPTR "Io"
-#define PRIuPTR "Iu"
-#define PRIxPTR "Ix"
-#define PRIXPTR "IX"
-
-// The fscanf macros for signed integers are:
-#define SCNd8 "d"
-#define SCNi8 "i"
-#define SCNdLEAST8 "d"
-#define SCNiLEAST8 "i"
-#define SCNdFAST8 "d"
-#define SCNiFAST8 "i"
-
-#define SCNd16 "hd"
-#define SCNi16 "hi"
-#define SCNdLEAST16 "hd"
-#define SCNiLEAST16 "hi"
-#define SCNdFAST16 "hd"
-#define SCNiFAST16 "hi"
-
-#define SCNd32 "ld"
-#define SCNi32 "li"
-#define SCNdLEAST32 "ld"
-#define SCNiLEAST32 "li"
-#define SCNdFAST32 "ld"
-#define SCNiFAST32 "li"
-
-#define SCNd64 "I64d"
-#define SCNi64 "I64i"
-#define SCNdLEAST64 "I64d"
-#define SCNiLEAST64 "I64i"
-#define SCNdFAST64 "I64d"
-#define SCNiFAST64 "I64i"
-
-#define SCNdMAX "I64d"
-#define SCNiMAX "I64i"
-
-#ifdef _WIN64 // [
-# define SCNdPTR "I64d"
-# define SCNiPTR "I64i"
-#else // _WIN64 ][
-# define SCNdPTR "ld"
-# define SCNiPTR "li"
-#endif // _WIN64 ]
-
-// The fscanf macros for unsigned integers are:
-#define SCNo8 "o"
-#define SCNu8 "u"
-#define SCNx8 "x"
-#define SCNX8 "X"
-#define SCNoLEAST8 "o"
-#define SCNuLEAST8 "u"
-#define SCNxLEAST8 "x"
-#define SCNXLEAST8 "X"
-#define SCNoFAST8 "o"
-#define SCNuFAST8 "u"
-#define SCNxFAST8 "x"
-#define SCNXFAST8 "X"
-
-#define SCNo16 "ho"
-#define SCNu16 "hu"
-#define SCNx16 "hx"
-#define SCNX16 "hX"
-#define SCNoLEAST16 "ho"
-#define SCNuLEAST16 "hu"
-#define SCNxLEAST16 "hx"
-#define SCNXLEAST16 "hX"
-#define SCNoFAST16 "ho"
-#define SCNuFAST16 "hu"
-#define SCNxFAST16 "hx"
-#define SCNXFAST16 "hX"
-
-#define SCNo32 "lo"
-#define SCNu32 "lu"
-#define SCNx32 "lx"
-#define SCNX32 "lX"
-#define SCNoLEAST32 "lo"
-#define SCNuLEAST32 "lu"
-#define SCNxLEAST32 "lx"
-#define SCNXLEAST32 "lX"
-#define SCNoFAST32 "lo"
-#define SCNuFAST32 "lu"
-#define SCNxFAST32 "lx"
-#define SCNXFAST32 "lX"
-
-#define SCNo64 "I64o"
-#define SCNu64 "I64u"
-#define SCNx64 "I64x"
-#define SCNX64 "I64X"
-#define SCNoLEAST64 "I64o"
-#define SCNuLEAST64 "I64u"
-#define SCNxLEAST64 "I64x"
-#define SCNXLEAST64 "I64X"
-#define SCNoFAST64 "I64o"
-#define SCNuFAST64 "I64u"
-#define SCNxFAST64 "I64x"
-#define SCNXFAST64 "I64X"
-
-#define SCNoMAX "I64o"
-#define SCNuMAX "I64u"
-#define SCNxMAX "I64x"
-#define SCNXMAX "I64X"
-
-#ifdef _WIN64 // [
-# define SCNoPTR "I64o"
-# define SCNuPTR "I64u"
-# define SCNxPTR "I64x"
-# define SCNXPTR "I64X"
-#else // _WIN64 ][
-# define SCNoPTR "lo"
-# define SCNuPTR "lu"
-# define SCNxPTR "lx"
-# define SCNXPTR "lX"
-#endif // _WIN64 ]
-
-#endif // __STDC_FORMAT_MACROS ]
-
-// 7.8.2 Functions for greatest-width integer types
-
-// 7.8.2.1 The imaxabs function
-#define imaxabs _abs64
-
-// 7.8.2.2 The imaxdiv function
-
-// This is modified version of div() function from Microsoft's div.c found
-// in %MSVC.NET%\crt\src\div.c
-#ifdef STATIC_IMAXDIV // [
-static
-#else // STATIC_IMAXDIV ][
-_inline
-#endif // STATIC_IMAXDIV ]
-imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
-{
- imaxdiv_t result;
-
- result.quot = numer / denom;
- result.rem = numer % denom;
-
- if (numer < 0 && result.rem > 0) {
- // did division wrong; must fix up
- ++result.quot;
- result.rem -= denom;
- }
-
- return result;
-}
-
-// 7.8.2.3 The strtoimax and strtoumax functions
-#define strtoimax _strtoi64
-#define strtoumax _strtoui64
-
-// 7.8.2.4 The wcstoimax and wcstoumax functions
-#define wcstoimax _wcstoi64
-#define wcstoumax _wcstoui64
-
-#endif // _MSC_VER >= 1800
-
-#endif // _MSC_INTTYPES_H_ ]
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/stdint.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/stdint.h
deleted file mode 100644
index 3d4477b9a..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/msinttypes/stdint.h
+++ /dev/null
@@ -1,300 +0,0 @@
-// ISO C9x compliant stdint.h for Microsoft Visual Studio
-// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
-//
-// Copyright (c) 2006-2013 Alexander Chemeris
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-//
-// 2. 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.
-//
-// 3. Neither the name of the product nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
-//
-///////////////////////////////////////////////////////////////////////////////
-
-// The above software in this distribution may have been modified by
-// THL A29 Limited ("Tencent Modifications").
-// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
-
-#ifndef _MSC_VER // [
-#error "Use this header only with Microsoft Visual C++ compilers!"
-#endif // _MSC_VER ]
-
-#ifndef _MSC_STDINT_H_ // [
-#define _MSC_STDINT_H_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
-#if _MSC_VER >= 1600 // [
-#include <stdint.h>
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
-
-#undef INT8_C
-#undef INT16_C
-#undef INT32_C
-#undef INT64_C
-#undef UINT8_C
-#undef UINT16_C
-#undef UINT32_C
-#undef UINT64_C
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val) val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val) val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C // [
-# define INTMAX_C INT64_C
-#endif // INTMAX_C ]
-#ifndef UINTMAX_C // [
-# define UINTMAX_C UINT64_C
-#endif // UINTMAX_C ]
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-#else // ] _MSC_VER >= 1700 [
-
-#include <limits.h>
-
-// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
-// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
-// or compiler would give many errors like this:
-// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
-#if defined(__cplusplus) && !defined(_M_ARM)
-extern "C" {
-#endif
-# include <wchar.h>
-#if defined(__cplusplus) && !defined(_M_ARM)
-}
-#endif
-
-// Define _W64 macros to mark types changing their size, like intptr_t.
-#ifndef _W64
-# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
-# define _W64 __w64
-# else
-# define _W64
-# endif
-#endif
-
-
-// 7.18.1 Integer types
-
-// 7.18.1.1 Exact-width integer types
-
-// Visual Studio 6 and Embedded Visual C++ 4 doesn't
-// realize that, e.g. char has the same size as __int8
-// so we give up on __intX for them.
-#if (_MSC_VER < 1300)
- typedef signed char int8_t;
- typedef signed short int16_t;
- typedef signed int int32_t;
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
- typedef unsigned int uint32_t;
-#else
- typedef signed __int8 int8_t;
- typedef signed __int16 int16_t;
- typedef signed __int32 int32_t;
- typedef unsigned __int8 uint8_t;
- typedef unsigned __int16 uint16_t;
- typedef unsigned __int32 uint32_t;
-#endif
-typedef signed __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-
-// 7.18.1.2 Minimum-width integer types
-typedef int8_t int_least8_t;
-typedef int16_t int_least16_t;
-typedef int32_t int_least32_t;
-typedef int64_t int_least64_t;
-typedef uint8_t uint_least8_t;
-typedef uint16_t uint_least16_t;
-typedef uint32_t uint_least32_t;
-typedef uint64_t uint_least64_t;
-
-// 7.18.1.3 Fastest minimum-width integer types
-typedef int8_t int_fast8_t;
-typedef int16_t int_fast16_t;
-typedef int32_t int_fast32_t;
-typedef int64_t int_fast64_t;
-typedef uint8_t uint_fast8_t;
-typedef uint16_t uint_fast16_t;
-typedef uint32_t uint_fast32_t;
-typedef uint64_t uint_fast64_t;
-
-// 7.18.1.4 Integer types capable of holding object pointers
-#ifdef _WIN64 // [
- typedef signed __int64 intptr_t;
- typedef unsigned __int64 uintptr_t;
-#else // _WIN64 ][
- typedef _W64 signed int intptr_t;
- typedef _W64 unsigned int uintptr_t;
-#endif // _WIN64 ]
-
-// 7.18.1.5 Greatest-width integer types
-typedef int64_t intmax_t;
-typedef uint64_t uintmax_t;
-
-
-// 7.18.2 Limits of specified-width integer types
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
-
-// 7.18.2.1 Limits of exact-width integer types
-#define INT8_MIN ((int8_t)_I8_MIN)
-#define INT8_MAX _I8_MAX
-#define INT16_MIN ((int16_t)_I16_MIN)
-#define INT16_MAX _I16_MAX
-#define INT32_MIN ((int32_t)_I32_MIN)
-#define INT32_MAX _I32_MAX
-#define INT64_MIN ((int64_t)_I64_MIN)
-#define INT64_MAX _I64_MAX
-#define UINT8_MAX _UI8_MAX
-#define UINT16_MAX _UI16_MAX
-#define UINT32_MAX _UI32_MAX
-#define UINT64_MAX _UI64_MAX
-
-// 7.18.2.2 Limits of minimum-width integer types
-#define INT_LEAST8_MIN INT8_MIN
-#define INT_LEAST8_MAX INT8_MAX
-#define INT_LEAST16_MIN INT16_MIN
-#define INT_LEAST16_MAX INT16_MAX
-#define INT_LEAST32_MIN INT32_MIN
-#define INT_LEAST32_MAX INT32_MAX
-#define INT_LEAST64_MIN INT64_MIN
-#define INT_LEAST64_MAX INT64_MAX
-#define UINT_LEAST8_MAX UINT8_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-
-// 7.18.2.3 Limits of fastest minimum-width integer types
-#define INT_FAST8_MIN INT8_MIN
-#define INT_FAST8_MAX INT8_MAX
-#define INT_FAST16_MIN INT16_MIN
-#define INT_FAST16_MAX INT16_MAX
-#define INT_FAST32_MIN INT32_MIN
-#define INT_FAST32_MAX INT32_MAX
-#define INT_FAST64_MIN INT64_MIN
-#define INT_FAST64_MAX INT64_MAX
-#define UINT_FAST8_MAX UINT8_MAX
-#define UINT_FAST16_MAX UINT16_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-#define UINT_FAST64_MAX UINT64_MAX
-
-// 7.18.2.4 Limits of integer types capable of holding object pointers
-#ifdef _WIN64 // [
-# define INTPTR_MIN INT64_MIN
-# define INTPTR_MAX INT64_MAX
-# define UINTPTR_MAX UINT64_MAX
-#else // _WIN64 ][
-# define INTPTR_MIN INT32_MIN
-# define INTPTR_MAX INT32_MAX
-# define UINTPTR_MAX UINT32_MAX
-#endif // _WIN64 ]
-
-// 7.18.2.5 Limits of greatest-width integer types
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
-
-// 7.18.3 Limits of other integer types
-
-#ifdef _WIN64 // [
-# define PTRDIFF_MIN _I64_MIN
-# define PTRDIFF_MAX _I64_MAX
-#else // _WIN64 ][
-# define PTRDIFF_MIN _I32_MIN
-# define PTRDIFF_MAX _I32_MAX
-#endif // _WIN64 ]
-
-#define SIG_ATOMIC_MIN INT_MIN
-#define SIG_ATOMIC_MAX INT_MAX
-
-#ifndef SIZE_MAX // [
-# ifdef _WIN64 // [
-# define SIZE_MAX _UI64_MAX
-# else // _WIN64 ][
-# define SIZE_MAX _UI32_MAX
-# endif // _WIN64 ]
-#endif // SIZE_MAX ]
-
-// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
-#ifndef WCHAR_MIN // [
-# define WCHAR_MIN 0
-#endif // WCHAR_MIN ]
-#ifndef WCHAR_MAX // [
-# define WCHAR_MAX _UI16_MAX
-#endif // WCHAR_MAX ]
-
-#define WINT_MIN 0
-#define WINT_MAX _UI16_MAX
-
-#endif // __STDC_LIMIT_MACROS ]
-
-
-// 7.18.4 Limits of other integer types
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
-
-// 7.18.4.1 Macros for minimum-width integer constants
-
-#define INT8_C(val) val##i8
-#define INT16_C(val) val##i16
-#define INT32_C(val) val##i32
-#define INT64_C(val) val##i64
-
-#define UINT8_C(val) val##ui8
-#define UINT16_C(val) val##ui16
-#define UINT32_C(val) val##ui32
-#define UINT64_C(val) val##ui64
-
-// 7.18.4.2 Macros for greatest-width integer constants
-// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
-// Check out Issue 9 for the details.
-#ifndef INTMAX_C // [
-# define INTMAX_C INT64_C
-#endif // INTMAX_C ]
-#ifndef UINTMAX_C // [
-# define UINTMAX_C UINT64_C
-#endif // UINTMAX_C ]
-
-#endif // __STDC_CONSTANT_MACROS ]
-
-#endif // _MSC_VER >= 1600 ]
-
-#endif // _MSC_STDINT_H_ ]
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/ostreamwrapper.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/ostreamwrapper.h
deleted file mode 100644
index 6f4667c08..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/ostreamwrapper.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_OSTREAMWRAPPER_H_
-#define RAPIDJSON_OSTREAMWRAPPER_H_
-
-#include "stream.h"
-#include <iosfwd>
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept.
-/*!
- The classes can be wrapped including but not limited to:
-
- - \c std::ostringstream
- - \c std::stringstream
- - \c std::wpstringstream
- - \c std::wstringstream
- - \c std::ifstream
- - \c std::fstream
- - \c std::wofstream
- - \c std::wfstream
-
- \tparam StreamType Class derived from \c std::basic_ostream.
-*/
-
-template <typename StreamType>
-class BasicOStreamWrapper {
-public:
- typedef typename StreamType::char_type Ch;
- BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}
-
- void Put(Ch c) {
- stream_.put(c);
- }
-
- void Flush() {
- stream_.flush();
- }
-
- // Not implemented
- char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
- char Take() { RAPIDJSON_ASSERT(false); return 0; }
- size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
- char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
-
-private:
- BasicOStreamWrapper(const BasicOStreamWrapper&);
- BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);
-
- StreamType& stream_;
-};
-
-typedef BasicOStreamWrapper<std::ostream> OStreamWrapper;
-typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_OSTREAMWRAPPER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/pointer.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/pointer.h
deleted file mode 100644
index 0f377efec..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/pointer.h
+++ /dev/null
@@ -1,1358 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_POINTER_H_
-#define RAPIDJSON_POINTER_H_
-
-#include "document.h"
-#include "internal/itoa.h"
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(switch-enum)
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
-
-//! Error code of parsing.
-/*! \ingroup RAPIDJSON_ERRORS
- \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
-*/
-enum PointerParseErrorCode {
- kPointerParseErrorNone = 0, //!< The parse is successful
-
- kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
- kPointerParseErrorInvalidEscape, //!< Invalid escape
- kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
- kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericPointer
-
-//! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
-/*!
- This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer"
- (https://tools.ietf.org/html/rfc6901).
-
- A JSON pointer is for identifying a specific value in a JSON document
- (GenericDocument). It can simplify coding of DOM tree manipulation, because it
- can access multiple-level depth of DOM tree with single API call.
-
- After it parses a string representation (e.g. "/foo/0" or URI fragment
- representation (e.g. "#/foo/0") into its internal representation (tokens),
- it can be used to resolve a specific value in multiple documents, or sub-tree
- of documents.
-
- Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
- Apart from assignment, a Pointer cannot be modified after construction.
-
- Although Pointer is very convenient, please aware that constructing Pointer
- involves parsing and dynamic memory allocation. A special constructor with user-
- supplied tokens eliminates these.
-
- GenericPointer depends on GenericDocument and GenericValue.
-
- \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
- \tparam Allocator The allocator type for allocating memory for internal representation.
-
- \note GenericPointer uses same encoding of ValueType.
- However, Allocator of GenericPointer is independent of Allocator of Value.
-*/
-template <typename ValueType, typename Allocator = CrtAllocator>
-class GenericPointer {
-public:
- typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
- typedef typename ValueType::Ch Ch; //!< Character type from Value
-
- //! A token is the basic units of internal representation.
- /*!
- A JSON pointer string representation "/foo/123" is parsed to two tokens:
- "foo" and 123. 123 will be represented in both numeric form and string form.
- They are resolved according to the actual value type (object or array).
-
- For token that are not numbers, or the numeric value is out of bound
- (greater than limits of SizeType), they are only treated as string form
- (i.e. the token's index will be equal to kPointerInvalidIndex).
-
- This struct is public so that user can create a Pointer without parsing and
- allocation, using a special constructor.
- */
- struct Token {
- const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character.
- SizeType length; //!< Length of the name.
- SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex.
- };
-
- //!@name Constructors and destructor.
- //@{
-
- //! Default constructor.
- GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
-
- //! Constructor that parses a string or URI fragment representation.
- /*!
- \param source A null-terminated, string or URI fragment representation of JSON pointer.
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
- */
- explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
- Parse(source, internal::StrLen(source));
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Constructor that parses a string or URI fragment representation.
- /*!
- \param source A string or URI fragment representation of JSON pointer.
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
- \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
- */
- explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
- Parse(source.c_str(), source.size());
- }
-#endif
-
- //! Constructor that parses a string or URI fragment representation, with length of the source string.
- /*!
- \param source A string or URI fragment representation of JSON pointer.
- \param length Length of source.
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
- \note Slightly faster than the overload without length.
- */
- GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
- Parse(source, length);
- }
-
- //! Constructor with user-supplied tokens.
- /*!
- This constructor let user supplies const array of tokens.
- This prevents the parsing process and eliminates allocation.
- This is preferred for memory constrained environments.
-
- \param tokens An constant array of tokens representing the JSON pointer.
- \param tokenCount Number of tokens.
-
- \b Example
- \code
- #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
- #define INDEX(i) { #i, sizeof(#i) - 1, i }
-
- static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
- static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
- // Equivalent to static const Pointer p("/foo/123");
-
- #undef NAME
- #undef INDEX
- \endcode
- */
- GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
-
- //! Copy constructor.
- GenericPointer(const GenericPointer& rhs, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
- *this = rhs;
- }
-
- //! Destructor.
- ~GenericPointer() {
- if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
- Allocator::Free(tokens_);
- RAPIDJSON_DELETE(ownAllocator_);
- }
-
- //! Assignment operator.
- GenericPointer& operator=(const GenericPointer& rhs) {
- if (this != &rhs) {
- // Do not delete ownAllcator
- if (nameBuffer_)
- Allocator::Free(tokens_);
-
- tokenCount_ = rhs.tokenCount_;
- parseErrorOffset_ = rhs.parseErrorOffset_;
- parseErrorCode_ = rhs.parseErrorCode_;
-
- if (rhs.nameBuffer_)
- CopyFromRaw(rhs); // Normally parsed tokens.
- else {
- tokens_ = rhs.tokens_; // User supplied const tokens.
- nameBuffer_ = 0;
- }
- }
- return *this;
- }
-
- //@}
-
- //!@name Append token
- //@{
-
- //! Append a token and return a new Pointer
- /*!
- \param token Token to be appended.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
- GenericPointer r;
- r.allocator_ = allocator;
- Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
- std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
- r.tokens_[tokenCount_].name = p;
- r.tokens_[tokenCount_].length = token.length;
- r.tokens_[tokenCount_].index = token.index;
- return r;
- }
-
- //! Append a name token with length, and return a new Pointer
- /*!
- \param name Name to be appended.
- \param length Length of name.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
- Token token = { name, length, kPointerInvalidIndex };
- return Append(token, allocator);
- }
-
- //! Append a name token without length, and return a new Pointer
- /*!
- \param name Name (const Ch*) to be appended.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
- Append(T* name, Allocator* allocator = 0) const {
- return Append(name, internal::StrLen(name), allocator);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Append a name token, and return a new Pointer
- /*!
- \param name Name to be appended.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
- return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
- }
-#endif
-
- //! Append a index token, and return a new Pointer
- /*!
- \param index Index to be appended.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
- char buffer[21];
- char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
- SizeType length = static_cast<SizeType>(end - buffer);
- buffer[length] = '\0';
-
- if (sizeof(Ch) == 1) {
- Token token = { reinterpret_cast<Ch*>(buffer), length, index };
- return Append(token, allocator);
- }
- else {
- Ch name[21];
- for (size_t i = 0; i <= length; i++)
- name[i] = static_cast<Ch>(buffer[i]);
- Token token = { name, length, index };
- return Append(token, allocator);
- }
- }
-
- //! Append a token by value, and return a new Pointer
- /*!
- \param token token to be appended.
- \param allocator Allocator for the newly return Pointer.
- \return A new Pointer with appended token.
- */
- GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
- if (token.IsString())
- return Append(token.GetString(), token.GetStringLength(), allocator);
- else {
- RAPIDJSON_ASSERT(token.IsUint64());
- RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
- return Append(static_cast<SizeType>(token.GetUint64()), allocator);
- }
- }
-
- //!@name Handling Parse Error
- //@{
-
- //! Check whether this is a valid pointer.
- bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
-
- //! Get the parsing error offset in code unit.
- size_t GetParseErrorOffset() const { return parseErrorOffset_; }
-
- //! Get the parsing error code.
- PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
-
- //@}
-
- //! Get the allocator of this pointer.
- Allocator& GetAllocator() { return *allocator_; }
-
- //!@name Tokens
- //@{
-
- //! Get the token array (const version only).
- const Token* GetTokens() const { return tokens_; }
-
- //! Get the number of tokens.
- size_t GetTokenCount() const { return tokenCount_; }
-
- //@}
-
- //!@name Equality/inequality operators
- //@{
-
- //! Equality operator.
- /*!
- \note When any pointers are invalid, always returns false.
- */
- bool operator==(const GenericPointer& rhs) const {
- if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
- return false;
-
- for (size_t i = 0; i < tokenCount_; i++) {
- if (tokens_[i].index != rhs.tokens_[i].index ||
- tokens_[i].length != rhs.tokens_[i].length ||
- (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
- {
- return false;
- }
- }
-
- return true;
- }
-
- //! Inequality operator.
- /*!
- \note When any pointers are invalid, always returns true.
- */
- bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
-
- //@}
-
- //!@name Stringify
- //@{
-
- //! Stringify the pointer into string representation.
- /*!
- \tparam OutputStream Type of output stream.
- \param os The output stream.
- */
- template<typename OutputStream>
- bool Stringify(OutputStream& os) const {
- return Stringify<false, OutputStream>(os);
- }
-
- //! Stringify the pointer into URI fragment representation.
- /*!
- \tparam OutputStream Type of output stream.
- \param os The output stream.
- */
- template<typename OutputStream>
- bool StringifyUriFragment(OutputStream& os) const {
- return Stringify<true, OutputStream>(os);
- }
-
- //@}
-
- //!@name Create value
- //@{
-
- //! Create a value in a subtree.
- /*!
- If the value is not exist, it creates all parent values and a JSON Null value.
- So it always succeed and return the newly created or existing value.
-
- Remind that it may change types of parents according to tokens, so it
- potentially removes previously stored values. For example, if a document
- was an array, and "/foo" is used to create a value, then the document
- will be changed to an object, and all existing array elements are lost.
-
- \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
- \param alreadyExist If non-null, it stores whether the resolved value is already exist.
- \return The resolved newly created (a JSON Null value), or already exists value.
- */
- ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
- RAPIDJSON_ASSERT(IsValid());
- ValueType* v = &root;
- bool exist = true;
- for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
- if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
- v->PushBack(ValueType().Move(), allocator);
- v = &((*v)[v->Size() - 1]);
- exist = false;
- }
- else {
- if (t->index == kPointerInvalidIndex) { // must be object name
- if (!v->IsObject())
- v->SetObject(); // Change to Object
- }
- else { // object name or array index
- if (!v->IsArray() && !v->IsObject())
- v->SetArray(); // Change to Array
- }
-
- if (v->IsArray()) {
- if (t->index >= v->Size()) {
- v->Reserve(t->index + 1, allocator);
- while (t->index >= v->Size())
- v->PushBack(ValueType().Move(), allocator);
- exist = false;
- }
- v = &((*v)[t->index]);
- }
- else {
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
- if (m == v->MemberEnd()) {
- v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
- v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
- exist = false;
- }
- else
- v = &m->value;
- }
- }
- }
-
- if (alreadyExist)
- *alreadyExist = exist;
-
- return *v;
- }
-
- //! Creates a value in a document.
- /*!
- \param document A document to be resolved.
- \param alreadyExist If non-null, it stores whether the resolved value is already exist.
- \return The resolved newly created, or already exists value.
- */
- template <typename stackAllocator>
- ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
- return Create(document, document.GetAllocator(), alreadyExist);
- }
-
- //@}
-
- //!@name Query value
- //@{
-
- //! Query a value in a subtree.
- /*!
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
- \return Pointer to the value if it can be resolved. Otherwise null.
-
- \note
- There are only 3 situations when a value cannot be resolved:
- 1. A value in the path is not an array nor object.
- 2. An object value does not contain the token.
- 3. A token is out of range of an array value.
-
- Use unresolvedTokenIndex to retrieve the token index.
- */
- ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
- RAPIDJSON_ASSERT(IsValid());
- ValueType* v = &root;
- for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
- switch (v->GetType()) {
- case kObjectType:
- {
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
- if (m == v->MemberEnd())
- break;
- v = &m->value;
- }
- continue;
- case kArrayType:
- if (t->index == kPointerInvalidIndex || t->index >= v->Size())
- break;
- v = &((*v)[t->index]);
- continue;
- default:
- break;
- }
-
- // Error: unresolved token
- if (unresolvedTokenIndex)
- *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
- return 0;
- }
- return v;
- }
-
- //! Query a const value in a const subtree.
- /*!
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \return Pointer to the value if it can be resolved. Otherwise null.
- */
- const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
- return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
- }
-
- //@}
-
- //!@name Query a value with default
- //@{
-
- //! Query a value in a subtree with default value.
- /*!
- Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.
- So that this function always succeed.
-
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \param defaultValue Default value to be cloned if the value was not exists.
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
- \see Create()
- */
- ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
- bool alreadyExist;
- Value& v = Create(root, allocator, &alreadyExist);
- return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
- }
-
- //! Query a value in a subtree with default null-terminated string.
- ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
- bool alreadyExist;
- Value& v = Create(root, allocator, &alreadyExist);
- return alreadyExist ? v : v.SetString(defaultValue, allocator);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Query a value in a subtree with default std::basic_string.
- ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
- bool alreadyExist;
- Value& v = Create(root, allocator, &alreadyExist);
- return alreadyExist ? v : v.SetString(defaultValue, allocator);
- }
-#endif
-
- //! Query a value in a subtree with default primitive value.
- /*!
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
- GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
- return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
- }
-
- //! Query a value in a document with default value.
- template <typename stackAllocator>
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
- return GetWithDefault(document, defaultValue, document.GetAllocator());
- }
-
- //! Query a value in a document with default null-terminated string.
- template <typename stackAllocator>
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
- return GetWithDefault(document, defaultValue, document.GetAllocator());
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Query a value in a document with default std::basic_string.
- template <typename stackAllocator>
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
- return GetWithDefault(document, defaultValue, document.GetAllocator());
- }
-#endif
-
- //! Query a value in a document with default primitive value.
- /*!
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
- */
- template <typename T, typename stackAllocator>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
- GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
- return GetWithDefault(document, defaultValue, document.GetAllocator());
- }
-
- //@}
-
- //!@name Set a value
- //@{
-
- //! Set a value in a subtree, with move semantics.
- /*!
- It creates all parents if they are not exist or types are different to the tokens.
- So this function always succeeds but potentially remove existing values.
-
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \param value Value to be set.
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
- \see Create()
- */
- ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator) = value;
- }
-
- //! Set a value in a subtree, with copy semantics.
- ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator).CopyFrom(value, allocator);
- }
-
- //! Set a null-terminated string in a subtree.
- ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator) = ValueType(value, allocator).Move();
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Set a std::basic_string in a subtree.
- ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator) = ValueType(value, allocator).Move();
- }
-#endif
-
- //! Set a primitive value in a subtree.
- /*!
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
- */
- template <typename T>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
- Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator) = ValueType(value).Move();
- }
-
- //! Set a value in a document, with move semantics.
- template <typename stackAllocator>
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
- return Create(document) = value;
- }
-
- //! Set a value in a document, with copy semantics.
- template <typename stackAllocator>
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
- return Create(document).CopyFrom(value, document.GetAllocator());
- }
-
- //! Set a null-terminated string in a document.
- template <typename stackAllocator>
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
- return Create(document) = ValueType(value, document.GetAllocator()).Move();
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- //! Sets a std::basic_string in a document.
- template <typename stackAllocator>
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
- return Create(document) = ValueType(value, document.GetAllocator()).Move();
- }
-#endif
-
- //! Set a primitive value in a document.
- /*!
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
- */
- template <typename T, typename stackAllocator>
- RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
- Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
- return Create(document) = value;
- }
-
- //@}
-
- //!@name Swap a value
- //@{
-
- //! Swap a value with a value in a subtree.
- /*!
- It creates all parents if they are not exist or types are different to the tokens.
- So this function always succeeds but potentially remove existing values.
-
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \param value Value to be swapped.
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
- \see Create()
- */
- ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
- return Create(root, allocator).Swap(value);
- }
-
- //! Swap a value with a value in a document.
- template <typename stackAllocator>
- ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
- return Create(document).Swap(value);
- }
-
- //@}
-
- //! Erase a value in a subtree.
- /*!
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
- \return Whether the resolved value is found and erased.
-
- \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false.
- */
- bool Erase(ValueType& root) const {
- RAPIDJSON_ASSERT(IsValid());
- if (tokenCount_ == 0) // Cannot erase the root
- return false;
-
- ValueType* v = &root;
- const Token* last = tokens_ + (tokenCount_ - 1);
- for (const Token *t = tokens_; t != last; ++t) {
- switch (v->GetType()) {
- case kObjectType:
- {
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
- if (m == v->MemberEnd())
- return false;
- v = &m->value;
- }
- break;
- case kArrayType:
- if (t->index == kPointerInvalidIndex || t->index >= v->Size())
- return false;
- v = &((*v)[t->index]);
- break;
- default:
- return false;
- }
- }
-
- switch (v->GetType()) {
- case kObjectType:
- return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
- case kArrayType:
- if (last->index == kPointerInvalidIndex || last->index >= v->Size())
- return false;
- v->Erase(v->Begin() + last->index);
- return true;
- default:
- return false;
- }
- }
-
-private:
- //! Clone the content from rhs to this.
- /*!
- \param rhs Source pointer.
- \param extraToken Extra tokens to be allocated.
- \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.
- \return Start of non-occupied name buffer, for storing extra names.
- */
- Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
- if (!allocator_) // allocator is independently owned.
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
-
- size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
- for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
- nameBufferSize += t->length;
-
- tokenCount_ = rhs.tokenCount_ + extraToken;
- tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
- nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
- if (rhs.tokenCount_ > 0) {
- std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
- }
- if (nameBufferSize > 0) {
- std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
- }
-
- // Adjust pointers to name buffer
- std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
- for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
- t->name += diff;
-
- return nameBuffer_ + nameBufferSize;
- }
-
- //! Check whether a character should be percent-encoded.
- /*!
- According to RFC 3986 2.3 Unreserved Characters.
- \param c The character (code unit) to be tested.
- */
- bool NeedPercentEncode(Ch c) const {
- return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
- }
-
- //! Parse a JSON String or its URI fragment representation into tokens.
-#ifndef __clang__ // -Wdocumentation
- /*!
- \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
- \param length Length of the source string.
- \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
- */
-#endif
- void Parse(const Ch* source, size_t length) {
- RAPIDJSON_ASSERT(source != NULL);
- RAPIDJSON_ASSERT(nameBuffer_ == 0);
- RAPIDJSON_ASSERT(tokens_ == 0);
-
- // Create own allocator if user did not supply.
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
-
- // Count number of '/' as tokenCount
- tokenCount_ = 0;
- for (const Ch* s = source; s != source + length; s++)
- if (*s == '/')
- tokenCount_++;
-
- Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
- Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
- size_t i = 0;
-
- // Detect if it is a URI fragment
- bool uriFragment = false;
- if (source[i] == '#') {
- uriFragment = true;
- i++;
- }
-
- if (i != length && source[i] != '/') {
- parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
- goto error;
- }
-
- while (i < length) {
- RAPIDJSON_ASSERT(source[i] == '/');
- i++; // consumes '/'
-
- token->name = name;
- bool isNumber = true;
-
- while (i < length && source[i] != '/') {
- Ch c = source[i];
- if (uriFragment) {
- // Decoding percent-encoding for URI fragment
- if (c == '%') {
- PercentDecodeStream is(&source[i], source + length);
- GenericInsituStringStream<EncodingType> os(name);
- Ch* begin = os.PutBegin();
- if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
- parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
- goto error;
- }
- size_t len = os.PutEnd(begin);
- i += is.Tell() - 1;
- if (len == 1)
- c = *name;
- else {
- name += len;
- isNumber = false;
- i++;
- continue;
- }
- }
- else if (NeedPercentEncode(c)) {
- parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
- goto error;
- }
- }
-
- i++;
-
- // Escaping "~0" -> '~', "~1" -> '/'
- if (c == '~') {
- if (i < length) {
- c = source[i];
- if (c == '0') c = '~';
- else if (c == '1') c = '/';
- else {
- parseErrorCode_ = kPointerParseErrorInvalidEscape;
- goto error;
- }
- i++;
- }
- else {
- parseErrorCode_ = kPointerParseErrorInvalidEscape;
- goto error;
- }
- }
-
- // First check for index: all of characters are digit
- if (c < '0' || c > '9')
- isNumber = false;
-
- *name++ = c;
- }
- token->length = static_cast<SizeType>(name - token->name);
- if (token->length == 0)
- isNumber = false;
- *name++ = '\0'; // Null terminator
-
- // Second check for index: more than one digit cannot have leading zero
- if (isNumber && token->length > 1 && token->name[0] == '0')
- isNumber = false;
-
- // String to SizeType conversion
- SizeType n = 0;
- if (isNumber) {
- for (size_t j = 0; j < token->length; j++) {
- SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
- if (m < n) { // overflow detection
- isNumber = false;
- break;
- }
- n = m;
- }
- }
-
- token->index = isNumber ? n : kPointerInvalidIndex;
- token++;
- }
-
- RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
- parseErrorCode_ = kPointerParseErrorNone;
- return;
-
- error:
- Allocator::Free(tokens_);
- nameBuffer_ = 0;
- tokens_ = 0;
- tokenCount_ = 0;
- parseErrorOffset_ = i;
- return;
- }
-
- //! Stringify to string or URI fragment representation.
- /*!
- \tparam uriFragment True for stringifying to URI fragment representation. False for string representation.
- \tparam OutputStream type of output stream.
- \param os The output stream.
- */
- template<bool uriFragment, typename OutputStream>
- bool Stringify(OutputStream& os) const {
- RAPIDJSON_ASSERT(IsValid());
-
- if (uriFragment)
- os.Put('#');
-
- for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
- os.Put('/');
- for (size_t j = 0; j < t->length; j++) {
- Ch c = t->name[j];
- if (c == '~') {
- os.Put('~');
- os.Put('0');
- }
- else if (c == '/') {
- os.Put('~');
- os.Put('1');
- }
- else if (uriFragment && NeedPercentEncode(c)) {
- // Transcode to UTF8 sequence
- GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
- PercentEncodeStream<OutputStream> target(os);
- if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
- return false;
- j += source.Tell() - 1;
- }
- else
- os.Put(c);
- }
- }
- return true;
- }
-
- //! A helper stream for decoding a percent-encoded sequence into code unit.
- /*!
- This stream decodes %XY triplet into code unit (0-255).
- If it encounters invalid characters, it sets output code unit as 0 and
- mark invalid, and to be checked by IsValid().
- */
- class PercentDecodeStream {
- public:
- typedef typename ValueType::Ch Ch;
-
- //! Constructor
- /*!
- \param source Start of the stream
- \param end Past-the-end of the stream.
- */
- PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
-
- Ch Take() {
- if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
- valid_ = false;
- return 0;
- }
- src_++;
- Ch c = 0;
- for (int j = 0; j < 2; j++) {
- c = static_cast<Ch>(c << 4);
- Ch h = *src_;
- if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
- else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
- else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
- else {
- valid_ = false;
- return 0;
- }
- src_++;
- }
- return c;
- }
-
- size_t Tell() const { return static_cast<size_t>(src_ - head_); }
- bool IsValid() const { return valid_; }
-
- private:
- const Ch* src_; //!< Current read position.
- const Ch* head_; //!< Original head of the string.
- const Ch* end_; //!< Past-the-end position.
- bool valid_; //!< Whether the parsing is valid.
- };
-
- //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
- template <typename OutputStream>
- class PercentEncodeStream {
- public:
- PercentEncodeStream(OutputStream& os) : os_(os) {}
- void Put(char c) { // UTF-8 must be byte
- unsigned char u = static_cast<unsigned char>(c);
- static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- os_.Put('%');
- os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
- os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
- }
- private:
- OutputStream& os_;
- };
-
- Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
- Allocator* ownAllocator_; //!< Allocator owned by this Pointer.
- Ch* nameBuffer_; //!< A buffer containing all names in tokens.
- Token* tokens_; //!< A list of tokens.
- size_t tokenCount_; //!< Number of tokens in tokens_.
- size_t parseErrorOffset_; //!< Offset in code unit when parsing fail.
- PointerParseErrorCode parseErrorCode_; //!< Parsing error code.
-};
-
-//! GenericPointer for Value (UTF-8, default allocator).
-typedef GenericPointer<Value> Pointer;
-
-//!@name Helper functions for GenericPointer
-//@{
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
- return pointer.Create(root, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
-}
-
-// No allocator parameter
-
-template <typename DocumentType>
-typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
- return pointer.Create(document);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
- return pointer.Get(root, unresolvedTokenIndex);
-}
-
-template <typename T>
-const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
- return pointer.Get(root, unresolvedTokenIndex);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
-}
-
-template <typename T, typename CharType, size_t N>
-const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
- return pointer.GetWithDefault(root, defaultValue, a);
-}
-
-template <typename T>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
- return pointer.GetWithDefault(root, defaultValue, a);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename T>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
- return pointer.GetWithDefault(root, defaultValue, a);
-}
-#endif
-
-template <typename T, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
-GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
- return pointer.GetWithDefault(root, defaultValue, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
-}
-#endif
-
-template <typename T, typename CharType, size_t N, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
-GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
-}
-
-// No allocator parameter
-
-template <typename DocumentType>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
- return pointer.GetWithDefault(document, defaultValue);
-}
-
-template <typename DocumentType>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
- return pointer.GetWithDefault(document, defaultValue);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename DocumentType>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
- return pointer.GetWithDefault(document, defaultValue);
-}
-#endif
-
-template <typename DocumentType, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
-GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
- return pointer.GetWithDefault(document, defaultValue);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
-}
-#endif
-
-template <typename DocumentType, typename CharType, size_t N, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
-GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
- return pointer.Set(root, value, a);
-}
-
-template <typename T>
-typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
- return pointer.Set(root, value, a);
-}
-
-template <typename T>
-typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
- return pointer.Set(root, value, a);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename T>
-typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
- return pointer.Set(root, value, a);
-}
-#endif
-
-template <typename T, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
-SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
- return pointer.Set(root, value, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
-}
-#endif
-
-template <typename T, typename CharType, size_t N, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
-SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
-}
-
-// No allocator parameter
-
-template <typename DocumentType>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
- return pointer.Set(document, value);
-}
-
-template <typename DocumentType>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
- return pointer.Set(document, value);
-}
-
-template <typename DocumentType>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
- return pointer.Set(document, value);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename DocumentType>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
- return pointer.Set(document, value);
-}
-#endif
-
-template <typename DocumentType, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
-SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
- return pointer.Set(document, value);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
-}
-
-#if RAPIDJSON_HAS_STDSTRING
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
-}
-#endif
-
-template <typename DocumentType, typename CharType, size_t N, typename T2>
-RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
-SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
- return pointer.Swap(root, value, a);
-}
-
-template <typename T, typename CharType, size_t N>
-typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
-}
-
-template <typename DocumentType>
-typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
- return pointer.Swap(document, value);
-}
-
-template <typename DocumentType, typename CharType, size_t N>
-typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-template <typename T>
-bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
- return pointer.Erase(root);
-}
-
-template <typename T, typename CharType, size_t N>
-bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
- return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
-}
-
-//@}
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_POINTER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/prettywriter.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/prettywriter.h
deleted file mode 100644
index 98dfb3060..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/prettywriter.h
+++ /dev/null
@@ -1,277 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_PRETTYWRITER_H_
-#define RAPIDJSON_PRETTYWRITER_H_
-
-#include "writer.h"
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Combination of PrettyWriter format flags.
-/*! \see PrettyWriter::SetFormatOptions
- */
-enum PrettyFormatOptions {
- kFormatDefault = 0, //!< Default pretty formatting.
- kFormatSingleLineArray = 1 //!< Format arrays on a single line.
-};
-
-//! Writer with indentation and spacing.
-/*!
- \tparam OutputStream Type of ouptut os.
- \tparam SourceEncoding Encoding of source string.
- \tparam TargetEncoding Encoding of output stream.
- \tparam StackAllocator Type of allocator for allocating memory of stack.
-*/
-template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
-class PrettyWriter : public Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> {
-public:
- typedef Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags> Base;
- typedef typename Base::Ch Ch;
-
- //! Constructor
- /*! \param os Output stream.
- \param allocator User supplied allocator. If it is null, it will create a private one.
- \param levelDepth Initial capacity of stack.
- */
- explicit PrettyWriter(OutputStream& os, StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
- Base(os, allocator, levelDepth), indentChar_(' '), indentCharCount_(4), formatOptions_(kFormatDefault) {}
-
-
- explicit PrettyWriter(StackAllocator* allocator = 0, size_t levelDepth = Base::kDefaultLevelDepth) :
- Base(allocator, levelDepth), indentChar_(' '), indentCharCount_(4) {}
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- PrettyWriter(PrettyWriter&& rhs) :
- Base(std::forward<PrettyWriter>(rhs)), indentChar_(rhs.indentChar_), indentCharCount_(rhs.indentCharCount_), formatOptions_(rhs.formatOptions_) {}
-#endif
-
- //! Set custom indentation.
- /*! \param indentChar Character for indentation. Must be whitespace character (' ', '\\t', '\\n', '\\r').
- \param indentCharCount Number of indent characters for each indentation level.
- \note The default indentation is 4 spaces.
- */
- PrettyWriter& SetIndent(Ch indentChar, unsigned indentCharCount) {
- RAPIDJSON_ASSERT(indentChar == ' ' || indentChar == '\t' || indentChar == '\n' || indentChar == '\r');
- indentChar_ = indentChar;
- indentCharCount_ = indentCharCount;
- return *this;
- }
-
- //! Set pretty writer formatting options.
- /*! \param options Formatting options.
- */
- PrettyWriter& SetFormatOptions(PrettyFormatOptions options) {
- formatOptions_ = options;
- return *this;
- }
-
- /*! @name Implementation of Handler
- \see Handler
- */
- //@{
-
- bool Null() { PrettyPrefix(kNullType); return Base::WriteNull(); }
- bool Bool(bool b) { PrettyPrefix(b ? kTrueType : kFalseType); return Base::WriteBool(b); }
- bool Int(int i) { PrettyPrefix(kNumberType); return Base::WriteInt(i); }
- bool Uint(unsigned u) { PrettyPrefix(kNumberType); return Base::WriteUint(u); }
- bool Int64(int64_t i64) { PrettyPrefix(kNumberType); return Base::WriteInt64(i64); }
- bool Uint64(uint64_t u64) { PrettyPrefix(kNumberType); return Base::WriteUint64(u64); }
- bool Double(double d) { PrettyPrefix(kNumberType); return Base::WriteDouble(d); }
-
- bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
- RAPIDJSON_ASSERT(str != 0);
- (void)copy;
- PrettyPrefix(kNumberType);
- return Base::WriteString(str, length);
- }
-
- bool String(const Ch* str, SizeType length, bool copy = false) {
- RAPIDJSON_ASSERT(str != 0);
- (void)copy;
- PrettyPrefix(kStringType);
- return Base::WriteString(str, length);
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool String(const std::basic_string<Ch>& str) {
- return String(str.data(), SizeType(str.size()));
- }
-#endif
-
- bool StartObject() {
- PrettyPrefix(kObjectType);
- new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(false);
- return Base::WriteStartObject();
- }
-
- bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool Key(const std::basic_string<Ch>& str) {
- return Key(str.data(), SizeType(str.size()));
- }
-#endif
-
- bool EndObject(SizeType memberCount = 0) {
- (void)memberCount;
- RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); // not inside an Object
- RAPIDJSON_ASSERT(!Base::level_stack_.template Top<typename Base::Level>()->inArray); // currently inside an Array, not Object
- RAPIDJSON_ASSERT(0 == Base::level_stack_.template Top<typename Base::Level>()->valueCount % 2); // Object has a Key without a Value
-
- bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
-
- if (!empty) {
- Base::os_->Put('\n');
- WriteIndent();
- }
- bool ret = Base::WriteEndObject();
- (void)ret;
- RAPIDJSON_ASSERT(ret == true);
- if (Base::level_stack_.Empty()) // end of json text
- Base::Flush();
- return true;
- }
-
- bool StartArray() {
- PrettyPrefix(kArrayType);
- new (Base::level_stack_.template Push<typename Base::Level>()) typename Base::Level(true);
- return Base::WriteStartArray();
- }
-
- bool EndArray(SizeType memberCount = 0) {
- (void)memberCount;
- RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
- RAPIDJSON_ASSERT(Base::level_stack_.template Top<typename Base::Level>()->inArray);
- bool empty = Base::level_stack_.template Pop<typename Base::Level>(1)->valueCount == 0;
-
- if (!empty && !(formatOptions_ & kFormatSingleLineArray)) {
- Base::os_->Put('\n');
- WriteIndent();
- }
- bool ret = Base::WriteEndArray();
- (void)ret;
- RAPIDJSON_ASSERT(ret == true);
- if (Base::level_stack_.Empty()) // end of json text
- Base::Flush();
- return true;
- }
-
- //@}
-
- /*! @name Convenience extensions */
- //@{
-
- //! Simpler but slower overload.
- bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
- bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
-
- //@}
-
- //! Write a raw JSON value.
- /*!
- For user to write a stringified JSON as a value.
-
- \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
- \param length Length of the json.
- \param type Type of the root of json.
- \note When using PrettyWriter::RawValue(), the result json may not be indented correctly.
- */
- bool RawValue(const Ch* json, size_t length, Type type) {
- RAPIDJSON_ASSERT(json != 0);
- PrettyPrefix(type);
- return Base::WriteRawValue(json, length);
- }
-
-protected:
- void PrettyPrefix(Type type) {
- (void)type;
- if (Base::level_stack_.GetSize() != 0) { // this value is not at root
- typename Base::Level* level = Base::level_stack_.template Top<typename Base::Level>();
-
- if (level->inArray) {
- if (level->valueCount > 0) {
- Base::os_->Put(','); // add comma if it is not the first element in array
- if (formatOptions_ & kFormatSingleLineArray)
- Base::os_->Put(' ');
- }
-
- if (!(formatOptions_ & kFormatSingleLineArray)) {
- Base::os_->Put('\n');
- WriteIndent();
- }
- }
- else { // in object
- if (level->valueCount > 0) {
- if (level->valueCount % 2 == 0) {
- Base::os_->Put(',');
- Base::os_->Put('\n');
- }
- else {
- Base::os_->Put(':');
- Base::os_->Put(' ');
- }
- }
- else
- Base::os_->Put('\n');
-
- if (level->valueCount % 2 == 0)
- WriteIndent();
- }
- if (!level->inArray && level->valueCount % 2 == 0)
- RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
- level->valueCount++;
- }
- else {
- RAPIDJSON_ASSERT(!Base::hasRoot_); // Should only has one and only one root.
- Base::hasRoot_ = true;
- }
- }
-
- void WriteIndent() {
- size_t count = (Base::level_stack_.GetSize() / sizeof(typename Base::Level)) * indentCharCount_;
- PutN(*Base::os_, static_cast<typename OutputStream::Ch>(indentChar_), count);
- }
-
- Ch indentChar_;
- unsigned indentCharCount_;
- PrettyFormatOptions formatOptions_;
-
-private:
- // Prohibit copy constructor & assignment operator.
- PrettyWriter(const PrettyWriter&);
- PrettyWriter& operator=(const PrettyWriter&);
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_RAPIDJSON_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/rapidjson.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/rapidjson.h
deleted file mode 100644
index 5716fdc06..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/rapidjson.h
+++ /dev/null
@@ -1,628 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_RAPIDJSON_H_
-#define RAPIDJSON_RAPIDJSON_H_
-
-/*!\file rapidjson.h
- \brief common definitions and configuration
-
- \see RAPIDJSON_CONFIG
- */
-
-/*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration
- \brief Configuration macros for library features
-
- Some RapidJSON features are configurable to adapt the library to a wide
- variety of platforms, environments and usage scenarios. Most of the
- features can be configured in terms of overriden or predefined
- preprocessor macros at compile-time.
-
- Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs.
-
- \note These macros should be given on the compiler command-line
- (where applicable) to avoid inconsistent values when compiling
- different translation units of a single application.
- */
-
-#include <cstdlib> // malloc(), realloc(), free(), size_t
-#include <cstring> // memset(), memcpy(), memmove(), memcmp()
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_VERSION_STRING
-//
-// ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt.
-//
-
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-// token stringification
-#define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
-#define RAPIDJSON_DO_STRINGIFY(x) #x
-
-// token concatenation
-#define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
-#define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
-#define RAPIDJSON_DO_JOIN2(X, Y) X##Y
-//!@endcond
-
-/*! \def RAPIDJSON_MAJOR_VERSION
- \ingroup RAPIDJSON_CONFIG
- \brief Major version of RapidJSON in integer.
-*/
-/*! \def RAPIDJSON_MINOR_VERSION
- \ingroup RAPIDJSON_CONFIG
- \brief Minor version of RapidJSON in integer.
-*/
-/*! \def RAPIDJSON_PATCH_VERSION
- \ingroup RAPIDJSON_CONFIG
- \brief Patch version of RapidJSON in integer.
-*/
-/*! \def RAPIDJSON_VERSION_STRING
- \ingroup RAPIDJSON_CONFIG
- \brief Version of RapidJSON in "<major>.<minor>.<patch>" string format.
-*/
-#define RAPIDJSON_MAJOR_VERSION 1
-#define RAPIDJSON_MINOR_VERSION 1
-#define RAPIDJSON_PATCH_VERSION 0
-#define RAPIDJSON_VERSION_STRING \
- RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION)
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_NAMESPACE_(BEGIN|END)
-/*! \def RAPIDJSON_NAMESPACE
- \ingroup RAPIDJSON_CONFIG
- \brief provide custom rapidjson namespace
-
- In order to avoid symbol clashes and/or "One Definition Rule" errors
- between multiple inclusions of (different versions of) RapidJSON in
- a single binary, users can customize the name of the main RapidJSON
- namespace.
-
- In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE
- to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple
- levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref
- RAPIDJSON_NAMESPACE_END need to be defined as well:
-
- \code
- // in some .cpp file
- #define RAPIDJSON_NAMESPACE my::rapidjson
- #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {
- #define RAPIDJSON_NAMESPACE_END } }
- #include "rapidjson/..."
- \endcode
-
- \see rapidjson
- */
-/*! \def RAPIDJSON_NAMESPACE_BEGIN
- \ingroup RAPIDJSON_CONFIG
- \brief provide custom rapidjson namespace (opening expression)
- \see RAPIDJSON_NAMESPACE
-*/
-/*! \def RAPIDJSON_NAMESPACE_END
- \ingroup RAPIDJSON_CONFIG
- \brief provide custom rapidjson namespace (closing expression)
- \see RAPIDJSON_NAMESPACE
-*/
-#ifndef RAPIDJSON_NAMESPACE
-#define RAPIDJSON_NAMESPACE rapidjson
-#endif
-#ifndef RAPIDJSON_NAMESPACE_BEGIN
-#define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {
-#endif
-#ifndef RAPIDJSON_NAMESPACE_END
-#define RAPIDJSON_NAMESPACE_END }
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_HAS_STDSTRING
-
-#ifndef RAPIDJSON_HAS_STDSTRING
-#ifdef RAPIDJSON_DOXYGEN_RUNNING
-#define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
-#else
-#define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
-#endif
-/*! \def RAPIDJSON_HAS_STDSTRING
- \ingroup RAPIDJSON_CONFIG
- \brief Enable RapidJSON support for \c std::string
-
- By defining this preprocessor symbol to \c 1, several convenience functions for using
- \ref rapidjson::GenericValue with \c std::string are enabled, especially
- for construction and comparison.
-
- \hideinitializer
-*/
-#endif // !defined(RAPIDJSON_HAS_STDSTRING)
-
-#if RAPIDJSON_HAS_STDSTRING
-#include <string>
-#endif // RAPIDJSON_HAS_STDSTRING
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_NO_INT64DEFINE
-
-/*! \def RAPIDJSON_NO_INT64DEFINE
- \ingroup RAPIDJSON_CONFIG
- \brief Use external 64-bit integer types.
-
- RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types
- to be available at global scope.
-
- If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to
- prevent RapidJSON from defining its own types.
-*/
-#ifndef RAPIDJSON_NO_INT64DEFINE
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013
-#include "msinttypes/stdint.h"
-#include "msinttypes/inttypes.h"
-#else
-// Other compilers should have this.
-#include <stdint.h>
-#include <inttypes.h>
-#endif
-//!@endcond
-#ifdef RAPIDJSON_DOXYGEN_RUNNING
-#define RAPIDJSON_NO_INT64DEFINE
-#endif
-#endif // RAPIDJSON_NO_INT64TYPEDEF
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_FORCEINLINE
-
-#ifndef RAPIDJSON_FORCEINLINE
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#if defined(_MSC_VER) && defined(NDEBUG)
-#define RAPIDJSON_FORCEINLINE __forceinline
-#elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG)
-#define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
-#else
-#define RAPIDJSON_FORCEINLINE
-#endif
-//!@endcond
-#endif // RAPIDJSON_FORCEINLINE
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_ENDIAN
-#define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine
-#define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine
-
-//! Endianness of the machine.
-/*!
- \def RAPIDJSON_ENDIAN
- \ingroup RAPIDJSON_CONFIG
-
- GCC 4.6 provided macro for detecting endianness of the target machine. But other
- compilers may not have this. User can define RAPIDJSON_ENDIAN to either
- \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
-
- Default detection implemented with reference to
- \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
- \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
-*/
-#ifndef RAPIDJSON_ENDIAN
-// Detect with GCC 4.6's macro
-# ifdef __BYTE_ORDER__
-# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
-# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
-# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
-# else
-# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
-# endif // __BYTE_ORDER__
-// Detect with GLIBC's endian.h
-# elif defined(__GLIBC__)
-# include <endian.h>
-# if (__BYTE_ORDER == __LITTLE_ENDIAN)
-# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-# elif (__BYTE_ORDER == __BIG_ENDIAN)
-# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
-# else
-# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
-# endif // __GLIBC__
-// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
-# elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
-# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-# elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
-# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
-// Detect with architecture macros
-# elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
-# define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
-# elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__)
-# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-# elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
-# define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
-# elif defined(RAPIDJSON_DOXYGEN_RUNNING)
-# define RAPIDJSON_ENDIAN
-# else
-# error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
-# endif
-#endif // RAPIDJSON_ENDIAN
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_64BIT
-
-//! Whether using 64-bit architecture
-#ifndef RAPIDJSON_64BIT
-#if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__)
-#define RAPIDJSON_64BIT 1
-#else
-#define RAPIDJSON_64BIT 0
-#endif
-#endif // RAPIDJSON_64BIT
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_ALIGN
-
-//! Data alignment of the machine.
-/*! \ingroup RAPIDJSON_CONFIG
- \param x pointer to align
-
- Some machines require strict data alignment. Currently the default uses 4 bytes
- alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.
- User can customize by defining the RAPIDJSON_ALIGN function macro.
-*/
-#ifndef RAPIDJSON_ALIGN
-#if RAPIDJSON_64BIT == 1
-#define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
-#else
-#define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
-#endif
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_UINT64_C2
-
-//! Construct a 64-bit literal by a pair of 32-bit integer.
-/*!
- 64-bit literal with or without ULL suffix is prone to compiler warnings.
- UINT64_C() is C macro which cause compilation problems.
- Use this macro to define 64-bit constants by a pair of 32-bit integer.
-*/
-#ifndef RAPIDJSON_UINT64_C2
-#define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_48BITPOINTER_OPTIMIZATION
-
-//! Use only lower 48-bit address for some pointers.
-/*!
- \ingroup RAPIDJSON_CONFIG
-
- This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address.
- The higher 16-bit can be used for storing other data.
- \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture.
-*/
-#ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION
-#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
-#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1
-#else
-#define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0
-#endif
-#endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION
-
-#if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1
-#if RAPIDJSON_64BIT != 1
-#error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1
-#endif
-#define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x))))
-#define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
-#else
-#define RAPIDJSON_SETPOINTER(type, p, x) (p = (x))
-#define RAPIDJSON_GETPOINTER(type, p) (p)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD
-
-/*! \def RAPIDJSON_SIMD
- \ingroup RAPIDJSON_CONFIG
- \brief Enable SSE2/SSE4.2/Neon optimization.
-
- RapidJSON supports optimized implementations for some parsing operations
- based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel
- or ARM compatible processors.
-
- To enable these optimizations, three different symbols can be defined;
- \code
- // Enable SSE2 optimization.
- #define RAPIDJSON_SSE2
-
- // Enable SSE4.2 optimization.
- #define RAPIDJSON_SSE42
- \endcode
-
- // Enable ARM Neon optimization.
- #define RAPIDJSON_NEON
- \endcode
-
- \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined.
-
- If any of these symbols is defined, RapidJSON defines the macro
- \c RAPIDJSON_SIMD to indicate the availability of the optimized code.
-*/
-#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
- || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
-#define RAPIDJSON_SIMD
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_NO_SIZETYPEDEFINE
-
-#ifndef RAPIDJSON_NO_SIZETYPEDEFINE
-/*! \def RAPIDJSON_NO_SIZETYPEDEFINE
- \ingroup RAPIDJSON_CONFIG
- \brief User-provided \c SizeType definition.
-
- In order to avoid using 32-bit size types for indexing strings and arrays,
- define this preprocessor symbol and provide the type rapidjson::SizeType
- before including RapidJSON:
- \code
- #define RAPIDJSON_NO_SIZETYPEDEFINE
- namespace rapidjson { typedef ::std::size_t SizeType; }
- #include "rapidjson/..."
- \endcode
-
- \see rapidjson::SizeType
-*/
-#ifdef RAPIDJSON_DOXYGEN_RUNNING
-#define RAPIDJSON_NO_SIZETYPEDEFINE
-#endif
-RAPIDJSON_NAMESPACE_BEGIN
-//! Size type (for string lengths, array sizes, etc.)
-/*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
- instead of using \c size_t. Users may override the SizeType by defining
- \ref RAPIDJSON_NO_SIZETYPEDEFINE.
-*/
-typedef unsigned SizeType;
-RAPIDJSON_NAMESPACE_END
-#endif
-
-// always import std::size_t to rapidjson namespace
-RAPIDJSON_NAMESPACE_BEGIN
-using std::size_t;
-RAPIDJSON_NAMESPACE_END
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_ASSERT
-
-//! Assertion.
-/*! \ingroup RAPIDJSON_CONFIG
- By default, rapidjson uses C \c assert() for internal assertions.
- User can override it by defining RAPIDJSON_ASSERT(x) macro.
-
- \note Parsing errors are handled and can be customized by the
- \ref RAPIDJSON_ERRORS APIs.
-*/
-#ifndef RAPIDJSON_ASSERT
-#include <cassert>
-#define RAPIDJSON_ASSERT(x) assert(x)
-#endif // RAPIDJSON_ASSERT
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_STATIC_ASSERT
-
-// Prefer C++11 static_assert, if available
-#ifndef RAPIDJSON_STATIC_ASSERT
-#if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
-#define RAPIDJSON_STATIC_ASSERT(x) \
- static_assert(x, RAPIDJSON_STRINGIFY(x))
-#endif // C++11
-#endif // RAPIDJSON_STATIC_ASSERT
-
-// Adopt C++03 implementation from boost
-#ifndef RAPIDJSON_STATIC_ASSERT
-#ifndef __clang__
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#endif
-RAPIDJSON_NAMESPACE_BEGIN
-template <bool x> struct STATIC_ASSERTION_FAILURE;
-template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
-template <size_t x> struct StaticAssertTest {};
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__GNUC__)
-#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
-#else
-#define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
-#endif
-#ifndef __clang__
-//!@endcond
-#endif
-
-/*! \def RAPIDJSON_STATIC_ASSERT
- \brief (Internal) macro to check for conditions at compile-time
- \param x compile-time condition
- \hideinitializer
- */
-#define RAPIDJSON_STATIC_ASSERT(x) \
- typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
- sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
- RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
-#endif // RAPIDJSON_STATIC_ASSERT
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY
-
-//! Compiler branching hint for expression with high probability to be true.
-/*!
- \ingroup RAPIDJSON_CONFIG
- \param x Boolean expression likely to be true.
-*/
-#ifndef RAPIDJSON_LIKELY
-#if defined(__GNUC__) || defined(__clang__)
-#define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
-#else
-#define RAPIDJSON_LIKELY(x) (x)
-#endif
-#endif
-
-//! Compiler branching hint for expression with low probability to be true.
-/*!
- \ingroup RAPIDJSON_CONFIG
- \param x Boolean expression unlikely to be true.
-*/
-#ifndef RAPIDJSON_UNLIKELY
-#if defined(__GNUC__) || defined(__clang__)
-#define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
-#else
-#define RAPIDJSON_UNLIKELY(x) (x)
-#endif
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Helpers
-
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-
-#define RAPIDJSON_MULTILINEMACRO_BEGIN do {
-#define RAPIDJSON_MULTILINEMACRO_END \
-} while((void)0, 0)
-
-// adopted from Boost
-#define RAPIDJSON_VERSION_CODE(x,y,z) \
- (((x)*100000) + ((y)*100) + (z))
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
-
-#if defined(__GNUC__)
-#define RAPIDJSON_GNUC \
- RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
-#endif
-
-#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))
-
-#define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
-#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
-#define RAPIDJSON_DIAG_OFF(x) \
- RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
-
-// push/pop support in Clang and GCC>=4.6
-#if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))
-#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
-#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
-#else // GCC >= 4.2, < 4.6
-#define RAPIDJSON_DIAG_PUSH /* ignored */
-#define RAPIDJSON_DIAG_POP /* ignored */
-#endif
-
-#elif defined(_MSC_VER)
-
-// pragma (MSVC specific)
-#define RAPIDJSON_PRAGMA(x) __pragma(x)
-#define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
-
-#define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
-#define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
-#define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop)
-
-#else
-
-#define RAPIDJSON_DIAG_OFF(x) /* ignored */
-#define RAPIDJSON_DIAG_PUSH /* ignored */
-#define RAPIDJSON_DIAG_POP /* ignored */
-
-#endif // RAPIDJSON_DIAG_*
-
-///////////////////////////////////////////////////////////////////////////////
-// C++11 features
-
-#ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
-#if defined(__clang__)
-#if __has_feature(cxx_rvalue_references) && \
- (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
-#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
-#else
-#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
-#endif
-#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
- (defined(_MSC_VER) && _MSC_VER >= 1600)
-
-#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
-#else
-#define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
-#endif
-#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
-
-#ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
-#if defined(__clang__)
-#define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
-#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
-// (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
-#define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
-#else
-#define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
-#endif
-#endif
-#if RAPIDJSON_HAS_CXX11_NOEXCEPT
-#define RAPIDJSON_NOEXCEPT noexcept
-#else
-#define RAPIDJSON_NOEXCEPT /* noexcept */
-#endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
-
-// no automatic detection, yet
-#ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
-#define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
-#endif
-
-#ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
-#if defined(__clang__)
-#define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
-#elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
- (defined(_MSC_VER) && _MSC_VER >= 1700)
-#define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
-#else
-#define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
-#endif
-#endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
-
-//!@endcond
-
-///////////////////////////////////////////////////////////////////////////////
-// new/delete
-
-#ifndef RAPIDJSON_NEW
-///! customization point for global \c new
-#define RAPIDJSON_NEW(TypeName) new TypeName
-#endif
-#ifndef RAPIDJSON_DELETE
-///! customization point for global \c delete
-#define RAPIDJSON_DELETE(x) delete x
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
-// Type
-
-/*! \namespace rapidjson
- \brief main RapidJSON namespace
- \see RAPIDJSON_NAMESPACE
-*/
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Type of JSON value
-enum Type {
- kNullType = 0, //!< null
- kFalseType = 1, //!< false
- kTrueType = 2, //!< true
- kObjectType = 3, //!< object
- kArrayType = 4, //!< array
- kStringType = 5, //!< string
- kNumberType = 6 //!< number
-};
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_RAPIDJSON_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/reader.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/reader.h
deleted file mode 100644
index 120c31115..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/reader.h
+++ /dev/null
@@ -1,2221 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_READER_H_
-#define RAPIDJSON_READER_H_
-
-/*! \file reader.h */
-
-#include "allocators.h"
-#include "stream.h"
-#include "encodedstream.h"
-#include "internal/meta.h"
-#include "internal/stack.h"
-#include "internal/strtod.h"
-#include <limits>
-
-#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
-#include <intrin.h>
-#pragma intrinsic(_BitScanForward)
-#endif
-#ifdef RAPIDJSON_SSE42
-#include <nmmintrin.h>
-#elif defined(RAPIDJSON_SSE2)
-#include <emmintrin.h>
-#elif defined(RAPIDJSON_NEON)
-#include <arm_neon.h>
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
-RAPIDJSON_DIAG_OFF(4702) // unreachable code
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(old-style-cast)
-RAPIDJSON_DIAG_OFF(padded)
-RAPIDJSON_DIAG_OFF(switch-enum)
-#endif
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#define RAPIDJSON_NOTHING /* deliberately empty */
-#ifndef RAPIDJSON_PARSE_ERROR_EARLY_RETURN
-#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN(value) \
- RAPIDJSON_MULTILINEMACRO_BEGIN \
- if (RAPIDJSON_UNLIKELY(HasParseError())) { return value; } \
- RAPIDJSON_MULTILINEMACRO_END
-#endif
-#define RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID \
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(RAPIDJSON_NOTHING)
-//!@endcond
-
-/*! \def RAPIDJSON_PARSE_ERROR_NORETURN
- \ingroup RAPIDJSON_ERRORS
- \brief Macro to indicate a parse error.
- \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
- \param offset position of the error in JSON input (\c size_t)
-
- This macros can be used as a customization point for the internal
- error handling mechanism of RapidJSON.
-
- A common usage model is to throw an exception instead of requiring the
- caller to explicitly check the \ref rapidjson::GenericReader::Parse's
- return value:
-
- \code
- #define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode,offset) \
- throw ParseException(parseErrorCode, #parseErrorCode, offset)
-
- #include <stdexcept> // std::runtime_error
- #include "rapidjson/error/error.h" // rapidjson::ParseResult
-
- struct ParseException : std::runtime_error, rapidjson::ParseResult {
- ParseException(rapidjson::ParseErrorCode code, const char* msg, size_t offset)
- : std::runtime_error(msg), ParseResult(code, offset) {}
- };
-
- #include "rapidjson/reader.h"
- \endcode
-
- \see RAPIDJSON_PARSE_ERROR, rapidjson::GenericReader::Parse
- */
-#ifndef RAPIDJSON_PARSE_ERROR_NORETURN
-#define RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset) \
- RAPIDJSON_MULTILINEMACRO_BEGIN \
- RAPIDJSON_ASSERT(!HasParseError()); /* Error can only be assigned once */ \
- SetParseError(parseErrorCode, offset); \
- RAPIDJSON_MULTILINEMACRO_END
-#endif
-
-/*! \def RAPIDJSON_PARSE_ERROR
- \ingroup RAPIDJSON_ERRORS
- \brief (Internal) macro to indicate and handle a parse error.
- \param parseErrorCode \ref rapidjson::ParseErrorCode of the error
- \param offset position of the error in JSON input (\c size_t)
-
- Invokes RAPIDJSON_PARSE_ERROR_NORETURN and stops the parsing.
-
- \see RAPIDJSON_PARSE_ERROR_NORETURN
- \hideinitializer
- */
-#ifndef RAPIDJSON_PARSE_ERROR
-#define RAPIDJSON_PARSE_ERROR(parseErrorCode, offset) \
- RAPIDJSON_MULTILINEMACRO_BEGIN \
- RAPIDJSON_PARSE_ERROR_NORETURN(parseErrorCode, offset); \
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; \
- RAPIDJSON_MULTILINEMACRO_END
-#endif
-
-#include "error/error.h" // ParseErrorCode, ParseResult
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// ParseFlag
-
-/*! \def RAPIDJSON_PARSE_DEFAULT_FLAGS
- \ingroup RAPIDJSON_CONFIG
- \brief User-defined kParseDefaultFlags definition.
-
- User can define this as any \c ParseFlag combinations.
-*/
-#ifndef RAPIDJSON_PARSE_DEFAULT_FLAGS
-#define RAPIDJSON_PARSE_DEFAULT_FLAGS kParseNoFlags
-#endif
-
-//! Combination of parseFlags
-/*! \see Reader::Parse, Document::Parse, Document::ParseInsitu, Document::ParseStream
- */
-enum ParseFlag {
- kParseNoFlags = 0, //!< No flags are set.
- kParseInsituFlag = 1, //!< In-situ(destructive) parsing.
- kParseValidateEncodingFlag = 2, //!< Validate encoding of JSON strings.
- kParseIterativeFlag = 4, //!< Iterative(constant complexity in terms of function call stack size) parsing.
- kParseStopWhenDoneFlag = 8, //!< After parsing a complete JSON root from stream, stop further processing the rest of stream. When this flag is used, parser will not generate kParseErrorDocumentRootNotSingular error.
- kParseFullPrecisionFlag = 16, //!< Parse number in full precision (but slower).
- kParseCommentsFlag = 32, //!< Allow one-line (//) and multi-line (/**/) comments.
- kParseNumbersAsStringsFlag = 64, //!< Parse all numbers (ints/doubles) as strings.
- kParseTrailingCommasFlag = 128, //!< Allow trailing commas at the end of objects and arrays.
- kParseNanAndInfFlag = 256, //!< Allow parsing NaN, Inf, Infinity, -Inf and -Infinity as doubles.
- kParseDefaultFlags = RAPIDJSON_PARSE_DEFAULT_FLAGS //!< Default parse flags. Can be customized by defining RAPIDJSON_PARSE_DEFAULT_FLAGS
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Handler
-
-/*! \class rapidjson::Handler
- \brief Concept for receiving events from GenericReader upon parsing.
- The functions return true if no error occurs. If they return false,
- the event publisher should terminate the process.
-\code
-concept Handler {
- typename Ch;
-
- bool Null();
- bool Bool(bool b);
- bool Int(int i);
- bool Uint(unsigned i);
- bool Int64(int64_t i);
- bool Uint64(uint64_t i);
- bool Double(double d);
- /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
- bool RawNumber(const Ch* str, SizeType length, bool copy);
- bool String(const Ch* str, SizeType length, bool copy);
- bool StartObject();
- bool Key(const Ch* str, SizeType length, bool copy);
- bool EndObject(SizeType memberCount);
- bool StartArray();
- bool EndArray(SizeType elementCount);
-};
-\endcode
-*/
-///////////////////////////////////////////////////////////////////////////////
-// BaseReaderHandler
-
-//! Default implementation of Handler.
-/*! This can be used as base class of any reader handler.
- \note implements Handler concept
-*/
-template<typename Encoding = UTF8<>, typename Derived = void>
-struct BaseReaderHandler {
- typedef typename Encoding::Ch Ch;
-
- typedef typename internal::SelectIf<internal::IsSame<Derived, void>, BaseReaderHandler, Derived>::Type Override;
-
- bool Default() { return true; }
- bool Null() { return static_cast<Override&>(*this).Default(); }
- bool Bool(bool) { return static_cast<Override&>(*this).Default(); }
- bool Int(int) { return static_cast<Override&>(*this).Default(); }
- bool Uint(unsigned) { return static_cast<Override&>(*this).Default(); }
- bool Int64(int64_t) { return static_cast<Override&>(*this).Default(); }
- bool Uint64(uint64_t) { return static_cast<Override&>(*this).Default(); }
- bool Double(double) { return static_cast<Override&>(*this).Default(); }
- /// enabled via kParseNumbersAsStringsFlag, string is not null-terminated (use length)
- bool RawNumber(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
- bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
- bool StartObject() { return static_cast<Override&>(*this).Default(); }
- bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
- bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
- bool StartArray() { return static_cast<Override&>(*this).Default(); }
- bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// StreamLocalCopy
-
-namespace internal {
-
-template<typename Stream, int = StreamTraits<Stream>::copyOptimization>
-class StreamLocalCopy;
-
-//! Do copy optimization.
-template<typename Stream>
-class StreamLocalCopy<Stream, 1> {
-public:
- StreamLocalCopy(Stream& original) : s(original), original_(original) {}
- ~StreamLocalCopy() { original_ = s; }
-
- Stream s;
-
-private:
- StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
-
- Stream& original_;
-};
-
-//! Keep reference.
-template<typename Stream>
-class StreamLocalCopy<Stream, 0> {
-public:
- StreamLocalCopy(Stream& original) : s(original) {}
-
- Stream& s;
-
-private:
- StreamLocalCopy& operator=(const StreamLocalCopy&) /* = delete */;
-};
-
-} // namespace internal
-
-///////////////////////////////////////////////////////////////////////////////
-// SkipWhitespace
-
-//! Skip the JSON white spaces in a stream.
-/*! \param is A input stream for skipping white spaces.
- \note This function has SSE2/SSE4.2 specialization.
-*/
-template<typename InputStream>
-void SkipWhitespace(InputStream& is) {
- internal::StreamLocalCopy<InputStream> copy(is);
- InputStream& s(copy.s);
-
- typename InputStream::Ch c;
- while ((c = s.Peek()) == ' ' || c == '\n' || c == '\r' || c == '\t')
- s.Take();
-}
-
-inline const char* SkipWhitespace(const char* p, const char* end) {
- while (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
- ++p;
- return p;
-}
-
-#ifdef RAPIDJSON_SSE42
-//! Skip whitespace with SSE 4.2 pcmpistrm instruction, testing 16 8-byte characters at once.
-inline const char *SkipWhitespace_SIMD(const char* p) {
- // Fast return for single non-whitespace
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- // 16-byte align to the next boundary
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- // The rest of string using SIMD
- static const char whitespace[16] = " \n\r\t";
- const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
-
- for (;; p += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
- if (r != 16) // some of characters is non-whitespace
- return p + r;
- }
-}
-
-inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
- // Fast return for single non-whitespace
- if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
- ++p;
- else
- return p;
-
- // The middle of string using SIMD
- static const char whitespace[16] = " \n\r\t";
- const __m128i w = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespace[0]));
-
- for (; p <= end - 16; p += 16) {
- const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
- const int r = _mm_cmpistri(w, s, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_LEAST_SIGNIFICANT | _SIDD_NEGATIVE_POLARITY);
- if (r != 16) // some of characters is non-whitespace
- return p + r;
- }
-
- return SkipWhitespace(p, end);
-}
-
-#elif defined(RAPIDJSON_SSE2)
-
-//! Skip whitespace with SSE2 instructions, testing 16 8-byte characters at once.
-inline const char *SkipWhitespace_SIMD(const char* p) {
- // Fast return for single non-whitespace
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- // 16-byte align to the next boundary
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- // The rest of string
- #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
- static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
- #undef C16
-
- const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
- const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
- const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
- const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
-
- for (;; p += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- __m128i x = _mm_cmpeq_epi8(s, w0);
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
- unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
- if (r != 0) { // some of characters may be non-whitespace
-#ifdef _MSC_VER // Find the index of first non-whitespace
- unsigned long offset;
- _BitScanForward(&offset, r);
- return p + offset;
-#else
- return p + __builtin_ffs(r) - 1;
-#endif
- }
- }
-}
-
-inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
- // Fast return for single non-whitespace
- if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
- ++p;
- else
- return p;
-
- // The rest of string
- #define C16(c) { c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c }
- static const char whitespaces[4][16] = { C16(' '), C16('\n'), C16('\r'), C16('\t') };
- #undef C16
-
- const __m128i w0 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[0][0]));
- const __m128i w1 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[1][0]));
- const __m128i w2 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[2][0]));
- const __m128i w3 = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&whitespaces[3][0]));
-
- for (; p <= end - 16; p += 16) {
- const __m128i s = _mm_loadu_si128(reinterpret_cast<const __m128i *>(p));
- __m128i x = _mm_cmpeq_epi8(s, w0);
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w1));
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w2));
- x = _mm_or_si128(x, _mm_cmpeq_epi8(s, w3));
- unsigned short r = static_cast<unsigned short>(~_mm_movemask_epi8(x));
- if (r != 0) { // some of characters may be non-whitespace
-#ifdef _MSC_VER // Find the index of first non-whitespace
- unsigned long offset;
- _BitScanForward(&offset, r);
- return p + offset;
-#else
- return p + __builtin_ffs(r) - 1;
-#endif
- }
- }
-
- return SkipWhitespace(p, end);
-}
-
-#elif defined(RAPIDJSON_NEON)
-
-//! Skip whitespace with ARM Neon instructions, testing 16 8-byte characters at once.
-inline const char *SkipWhitespace_SIMD(const char* p) {
- // Fast return for single non-whitespace
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- // 16-byte align to the next boundary
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')
- ++p;
- else
- return p;
-
- const uint8x16_t w0 = vmovq_n_u8(' ');
- const uint8x16_t w1 = vmovq_n_u8('\n');
- const uint8x16_t w2 = vmovq_n_u8('\r');
- const uint8x16_t w3 = vmovq_n_u8('\t');
-
- for (;; p += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, w0);
- x = vorrq_u8(x, vceqq_u8(s, w1));
- x = vorrq_u8(x, vceqq_u8(s, w2));
- x = vorrq_u8(x, vceqq_u8(s, w3));
-
- x = vmvnq_u8(x); // Negate
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- if (low == 0) {
- if (high != 0) {
- int lz =__builtin_clzll(high);;
- return p + 8 + (lz >> 3);
- }
- } else {
- int lz = __builtin_clzll(low);;
- return p + (lz >> 3);
- }
- }
-}
-
-inline const char *SkipWhitespace_SIMD(const char* p, const char* end) {
- // Fast return for single non-whitespace
- if (p != end && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t'))
- ++p;
- else
- return p;
-
- const uint8x16_t w0 = vmovq_n_u8(' ');
- const uint8x16_t w1 = vmovq_n_u8('\n');
- const uint8x16_t w2 = vmovq_n_u8('\r');
- const uint8x16_t w3 = vmovq_n_u8('\t');
-
- for (; p <= end - 16; p += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, w0);
- x = vorrq_u8(x, vceqq_u8(s, w1));
- x = vorrq_u8(x, vceqq_u8(s, w2));
- x = vorrq_u8(x, vceqq_u8(s, w3));
-
- x = vmvnq_u8(x); // Negate
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- if (low == 0) {
- if (high != 0) {
- int lz = __builtin_clzll(high);
- return p + 8 + (lz >> 3);
- }
- } else {
- int lz = __builtin_clzll(low);
- return p + (lz >> 3);
- }
- }
-
- return SkipWhitespace(p, end);
-}
-
-#endif // RAPIDJSON_NEON
-
-#ifdef RAPIDJSON_SIMD
-//! Template function specialization for InsituStringStream
-template<> inline void SkipWhitespace(InsituStringStream& is) {
- is.src_ = const_cast<char*>(SkipWhitespace_SIMD(is.src_));
-}
-
-//! Template function specialization for StringStream
-template<> inline void SkipWhitespace(StringStream& is) {
- is.src_ = SkipWhitespace_SIMD(is.src_);
-}
-
-template<> inline void SkipWhitespace(EncodedInputStream<UTF8<>, MemoryStream>& is) {
- is.is_.src_ = SkipWhitespace_SIMD(is.is_.src_, is.is_.end_);
-}
-#endif // RAPIDJSON_SIMD
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericReader
-
-//! SAX-style JSON parser. Use \ref Reader for UTF8 encoding and default allocator.
-/*! GenericReader parses JSON text from a stream, and send events synchronously to an
- object implementing Handler concept.
-
- It needs to allocate a stack for storing a single decoded string during
- non-destructive parsing.
-
- For in-situ parsing, the decoded string is directly written to the source
- text string, no temporary buffer is required.
-
- A GenericReader object can be reused for parsing multiple JSON text.
-
- \tparam SourceEncoding Encoding of the input stream.
- \tparam TargetEncoding Encoding of the parse output.
- \tparam StackAllocator Allocator type for stack.
-*/
-template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator = CrtAllocator>
-class GenericReader {
-public:
- typedef typename SourceEncoding::Ch Ch; //!< SourceEncoding character type
-
- //! Constructor.
- /*! \param stackAllocator Optional allocator for allocating stack memory. (Only use for non-destructive parsing)
- \param stackCapacity stack capacity in bytes for storing a single decoded string. (Only use for non-destructive parsing)
- */
- GenericReader(StackAllocator* stackAllocator = 0, size_t stackCapacity = kDefaultStackCapacity) : stack_(stackAllocator, stackCapacity), parseResult_() {}
-
- //! Parse JSON text.
- /*! \tparam parseFlags Combination of \ref ParseFlag.
- \tparam InputStream Type of input stream, implementing Stream concept.
- \tparam Handler Type of handler, implementing Handler concept.
- \param is Input stream to be parsed.
- \param handler The handler to receive events.
- \return Whether the parsing is successful.
- */
- template <unsigned parseFlags, typename InputStream, typename Handler>
- ParseResult Parse(InputStream& is, Handler& handler) {
- if (parseFlags & kParseIterativeFlag)
- return IterativeParse<parseFlags>(is, handler);
-
- parseResult_.Clear();
-
- ClearStackOnExit scope(*this);
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
-
- if (RAPIDJSON_UNLIKELY(is.Peek() == '\0')) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentEmpty, is.Tell());
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
- }
- else {
- ParseValue<parseFlags>(is, handler);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
-
- if (!(parseFlags & kParseStopWhenDoneFlag)) {
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
-
- if (RAPIDJSON_UNLIKELY(is.Peek() != '\0')) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorDocumentRootNotSingular, is.Tell());
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
- }
- }
- }
-
- return parseResult_;
- }
-
- //! Parse JSON text (with \ref kParseDefaultFlags)
- /*! \tparam InputStream Type of input stream, implementing Stream concept
- \tparam Handler Type of handler, implementing Handler concept.
- \param is Input stream to be parsed.
- \param handler The handler to receive events.
- \return Whether the parsing is successful.
- */
- template <typename InputStream, typename Handler>
- ParseResult Parse(InputStream& is, Handler& handler) {
- return Parse<kParseDefaultFlags>(is, handler);
- }
-
- //! Initialize JSON text token-by-token parsing
- /*!
- */
- void IterativeParseInit() {
- parseResult_.Clear();
- state_ = IterativeParsingStartState;
- }
-
- //! Parse one token from JSON text
- /*! \tparam InputStream Type of input stream, implementing Stream concept
- \tparam Handler Type of handler, implementing Handler concept.
- \param is Input stream to be parsed.
- \param handler The handler to receive events.
- \return Whether the parsing is successful.
- */
- template <unsigned parseFlags, typename InputStream, typename Handler>
- bool IterativeParseNext(InputStream& is, Handler& handler) {
- while (RAPIDJSON_LIKELY(is.Peek() != '\0')) {
- SkipWhitespaceAndComments<parseFlags>(is);
-
- Token t = Tokenize(is.Peek());
- IterativeParsingState n = Predict(state_, t);
- IterativeParsingState d = Transit<parseFlags>(state_, t, n, is, handler);
-
- // If we've finished or hit an error...
- if (RAPIDJSON_UNLIKELY(IsIterativeParsingCompleteState(d))) {
- // Report errors.
- if (d == IterativeParsingErrorState) {
- HandleError(state_, is);
- return false;
- }
-
- // Transition to the finish state.
- RAPIDJSON_ASSERT(d == IterativeParsingFinishState);
- state_ = d;
-
- // If StopWhenDone is not set...
- if (!(parseFlags & kParseStopWhenDoneFlag)) {
- // ... and extra non-whitespace data is found...
- SkipWhitespaceAndComments<parseFlags>(is);
- if (is.Peek() != '\0') {
- // ... this is considered an error.
- HandleError(state_, is);
- return false;
- }
- }
-
- // Success! We are done!
- return true;
- }
-
- // Transition to the new state.
- state_ = d;
-
- // If we parsed anything other than a delimiter, we invoked the handler, so we can return true now.
- if (!IsIterativeParsingDelimiterState(n))
- return true;
- }
-
- // We reached the end of file.
- stack_.Clear();
-
- if (state_ != IterativeParsingFinishState) {
- HandleError(state_, is);
- return false;
- }
-
- return true;
- }
-
- //! Check if token-by-token parsing JSON text is complete
- /*! \return Whether the JSON has been fully decoded.
- */
- RAPIDJSON_FORCEINLINE bool IterativeParseComplete() {
- return IsIterativeParsingCompleteState(state_);
- }
-
- //! Whether a parse error has occured in the last parsing.
- bool HasParseError() const { return parseResult_.IsError(); }
-
- //! Get the \ref ParseErrorCode of last parsing.
- ParseErrorCode GetParseErrorCode() const { return parseResult_.Code(); }
-
- //! Get the position of last parsing error in input, 0 otherwise.
- size_t GetErrorOffset() const { return parseResult_.Offset(); }
-
-protected:
- void SetParseError(ParseErrorCode code, size_t offset) { parseResult_.Set(code, offset); }
-
-private:
- // Prohibit copy constructor & assignment operator.
- GenericReader(const GenericReader&);
- GenericReader& operator=(const GenericReader&);
-
- void ClearStack() { stack_.Clear(); }
-
- // clear stack on any exit from ParseStream, e.g. due to exception
- struct ClearStackOnExit {
- explicit ClearStackOnExit(GenericReader& r) : r_(r) {}
- ~ClearStackOnExit() { r_.ClearStack(); }
- private:
- GenericReader& r_;
- ClearStackOnExit(const ClearStackOnExit&);
- ClearStackOnExit& operator=(const ClearStackOnExit&);
- };
-
- template<unsigned parseFlags, typename InputStream>
- void SkipWhitespaceAndComments(InputStream& is) {
- SkipWhitespace(is);
-
- if (parseFlags & kParseCommentsFlag) {
- while (RAPIDJSON_UNLIKELY(Consume(is, '/'))) {
- if (Consume(is, '*')) {
- while (true) {
- if (RAPIDJSON_UNLIKELY(is.Peek() == '\0'))
- RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
- else if (Consume(is, '*')) {
- if (Consume(is, '/'))
- break;
- }
- else
- is.Take();
- }
- }
- else if (RAPIDJSON_LIKELY(Consume(is, '/')))
- while (is.Peek() != '\0' && is.Take() != '\n') {}
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorUnspecificSyntaxError, is.Tell());
-
- SkipWhitespace(is);
- }
- }
- }
-
- // Parse object: { string : value, ... }
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseObject(InputStream& is, Handler& handler) {
- RAPIDJSON_ASSERT(is.Peek() == '{');
- is.Take(); // Skip '{'
-
- if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- if (Consume(is, '}')) {
- if (RAPIDJSON_UNLIKELY(!handler.EndObject(0))) // empty object
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- return;
- }
-
- for (SizeType memberCount = 0;;) {
- if (RAPIDJSON_UNLIKELY(is.Peek() != '"'))
- RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
-
- ParseString<parseFlags>(is, handler, true);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- if (RAPIDJSON_UNLIKELY(!Consume(is, ':')))
- RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell());
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- ParseValue<parseFlags>(is, handler);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- ++memberCount;
-
- switch (is.Peek()) {
- case ',':
- is.Take();
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- break;
- case '}':
- is.Take();
- if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- return;
- default:
- RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); break; // This useless break is only for making warning and coverage happy
- }
-
- if (parseFlags & kParseTrailingCommasFlag) {
- if (is.Peek() == '}') {
- if (RAPIDJSON_UNLIKELY(!handler.EndObject(memberCount)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- is.Take();
- return;
- }
- }
- }
- }
-
- // Parse array: [ value, ... ]
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseArray(InputStream& is, Handler& handler) {
- RAPIDJSON_ASSERT(is.Peek() == '[');
- is.Take(); // Skip '['
-
- if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- if (Consume(is, ']')) {
- if (RAPIDJSON_UNLIKELY(!handler.EndArray(0))) // empty array
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- return;
- }
-
- for (SizeType elementCount = 0;;) {
- ParseValue<parseFlags>(is, handler);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- ++elementCount;
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
-
- if (Consume(is, ',')) {
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- }
- else if (Consume(is, ']')) {
- if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- return;
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell());
-
- if (parseFlags & kParseTrailingCommasFlag) {
- if (is.Peek() == ']') {
- if (RAPIDJSON_UNLIKELY(!handler.EndArray(elementCount)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- is.Take();
- return;
- }
- }
- }
- }
-
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseNull(InputStream& is, Handler& handler) {
- RAPIDJSON_ASSERT(is.Peek() == 'n');
- is.Take();
-
- if (RAPIDJSON_LIKELY(Consume(is, 'u') && Consume(is, 'l') && Consume(is, 'l'))) {
- if (RAPIDJSON_UNLIKELY(!handler.Null()))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
- }
-
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseTrue(InputStream& is, Handler& handler) {
- RAPIDJSON_ASSERT(is.Peek() == 't');
- is.Take();
-
- if (RAPIDJSON_LIKELY(Consume(is, 'r') && Consume(is, 'u') && Consume(is, 'e'))) {
- if (RAPIDJSON_UNLIKELY(!handler.Bool(true)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
- }
-
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseFalse(InputStream& is, Handler& handler) {
- RAPIDJSON_ASSERT(is.Peek() == 'f');
- is.Take();
-
- if (RAPIDJSON_LIKELY(Consume(is, 'a') && Consume(is, 'l') && Consume(is, 's') && Consume(is, 'e'))) {
- if (RAPIDJSON_UNLIKELY(!handler.Bool(false)))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, is.Tell());
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell());
- }
-
- template<typename InputStream>
- RAPIDJSON_FORCEINLINE static bool Consume(InputStream& is, typename InputStream::Ch expect) {
- if (RAPIDJSON_LIKELY(is.Peek() == expect)) {
- is.Take();
- return true;
- }
- else
- return false;
- }
-
- // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
- template<typename InputStream>
- unsigned ParseHex4(InputStream& is, size_t escapeOffset) {
- unsigned codepoint = 0;
- for (int i = 0; i < 4; i++) {
- Ch c = is.Peek();
- codepoint <<= 4;
- codepoint += static_cast<unsigned>(c);
- if (c >= '0' && c <= '9')
- codepoint -= '0';
- else if (c >= 'A' && c <= 'F')
- codepoint -= 'A' - 10;
- else if (c >= 'a' && c <= 'f')
- codepoint -= 'a' - 10;
- else {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorStringUnicodeEscapeInvalidHex, escapeOffset);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(0);
- }
- is.Take();
- }
- return codepoint;
- }
-
- template <typename CharType>
- class StackStream {
- public:
- typedef CharType Ch;
-
- StackStream(internal::Stack<StackAllocator>& stack) : stack_(stack), length_(0) {}
- RAPIDJSON_FORCEINLINE void Put(Ch c) {
- *stack_.template Push<Ch>() = c;
- ++length_;
- }
-
- RAPIDJSON_FORCEINLINE void* Push(SizeType count) {
- length_ += count;
- return stack_.template Push<Ch>(count);
- }
-
- size_t Length() const { return length_; }
-
- Ch* Pop() {
- return stack_.template Pop<Ch>(length_);
- }
-
- private:
- StackStream(const StackStream&);
- StackStream& operator=(const StackStream&);
-
- internal::Stack<StackAllocator>& stack_;
- SizeType length_;
- };
-
- // Parse string and generate String event. Different code paths for kParseInsituFlag.
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
- internal::StreamLocalCopy<InputStream> copy(is);
- InputStream& s(copy.s);
-
- RAPIDJSON_ASSERT(s.Peek() == '\"');
- s.Take(); // Skip '\"'
-
- bool success = false;
- if (parseFlags & kParseInsituFlag) {
- typename InputStream::Ch *head = s.PutBegin();
- ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- size_t length = s.PutEnd(head) - 1;
- RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
- const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
- success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
- }
- else {
- StackStream<typename TargetEncoding::Ch> stackStream(stack_);
- ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- SizeType length = static_cast<SizeType>(stackStream.Length()) - 1;
- const typename TargetEncoding::Ch* const str = stackStream.Pop();
- success = (isKey ? handler.Key(str, length, true) : handler.String(str, length, true));
- }
- if (RAPIDJSON_UNLIKELY(!success))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
- }
-
- // Parse string to an output is
- // This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
- template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
- RAPIDJSON_FORCEINLINE void ParseStringToStream(InputStream& is, OutputStream& os) {
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- static const char escape[256] = {
- Z16, Z16, 0, 0,'\"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'/',
- Z16, Z16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
- 0, 0,'\b', 0, 0, 0,'\f', 0, 0, 0, 0, 0, 0, 0,'\n', 0,
- 0, 0,'\r', 0,'\t', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16
- };
-#undef Z16
-//!@endcond
-
- for (;;) {
- // Scan and copy string before "\\\"" or < 0x20. This is an optional optimzation.
- if (!(parseFlags & kParseValidateEncodingFlag))
- ScanCopyUnescapedString(is, os);
-
- Ch c = is.Peek();
- if (RAPIDJSON_UNLIKELY(c == '\\')) { // Escape
- size_t escapeOffset = is.Tell(); // For invalid escaping, report the inital '\\' as error offset
- is.Take();
- Ch e = is.Peek();
- if ((sizeof(Ch) == 1 || unsigned(e) < 256) && RAPIDJSON_LIKELY(escape[static_cast<unsigned char>(e)])) {
- is.Take();
- os.Put(static_cast<typename TEncoding::Ch>(escape[static_cast<unsigned char>(e)]));
- }
- else if (RAPIDJSON_LIKELY(e == 'u')) { // Unicode
- is.Take();
- unsigned codepoint = ParseHex4(is, escapeOffset);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- if (RAPIDJSON_UNLIKELY(codepoint >= 0xD800 && codepoint <= 0xDBFF)) {
- // Handle UTF-16 surrogate pair
- if (RAPIDJSON_UNLIKELY(!Consume(is, '\\') || !Consume(is, 'u')))
- RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
- unsigned codepoint2 = ParseHex4(is, escapeOffset);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- if (RAPIDJSON_UNLIKELY(codepoint2 < 0xDC00 || codepoint2 > 0xDFFF))
- RAPIDJSON_PARSE_ERROR(kParseErrorStringUnicodeSurrogateInvalid, escapeOffset);
- codepoint = (((codepoint - 0xD800) << 10) | (codepoint2 - 0xDC00)) + 0x10000;
- }
- TEncoding::Encode(os, codepoint);
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorStringEscapeInvalid, escapeOffset);
- }
- else if (RAPIDJSON_UNLIKELY(c == '"')) { // Closing double quote
- is.Take();
- os.Put('\0'); // null-terminate the string
- return;
- }
- else if (RAPIDJSON_UNLIKELY(static_cast<unsigned>(c) < 0x20)) { // RFC 4627: unescaped = %x20-21 / %x23-5B / %x5D-10FFFF
- if (c == '\0')
- RAPIDJSON_PARSE_ERROR(kParseErrorStringMissQuotationMark, is.Tell());
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, is.Tell());
- }
- else {
- size_t offset = is.Tell();
- if (RAPIDJSON_UNLIKELY((parseFlags & kParseValidateEncodingFlag ?
- !Transcoder<SEncoding, TEncoding>::Validate(is, os) :
- !Transcoder<SEncoding, TEncoding>::Transcode(is, os))))
- RAPIDJSON_PARSE_ERROR(kParseErrorStringInvalidEncoding, offset);
- }
- }
- }
-
- template<typename InputStream, typename OutputStream>
- static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InputStream&, OutputStream&) {
- // Do nothing for generic version
- }
-
-#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
- // StringStream -> StackStream<char>
- static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
- const char* p = is.src_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = p;
- return;
- }
- else
- os.Put(*p++);
-
- // The rest of string using SIMD
- static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
- static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
- static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
- const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
- const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
- const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
-
- for (;; p += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- const __m128i t1 = _mm_cmpeq_epi8(s, dq);
- const __m128i t2 = _mm_cmpeq_epi8(s, bs);
- const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
- const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
- unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
- if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
- SizeType length;
- #ifdef _MSC_VER // Find the index of first escaped
- unsigned long offset;
- _BitScanForward(&offset, r);
- length = offset;
- #else
- length = static_cast<SizeType>(__builtin_ffs(r) - 1);
- #endif
- if (length != 0) {
- char* q = reinterpret_cast<char*>(os.Push(length));
- for (size_t i = 0; i < length; i++)
- q[i] = p[i];
-
- p += length;
- }
- break;
- }
- _mm_storeu_si128(reinterpret_cast<__m128i *>(os.Push(16)), s);
- }
-
- is.src_ = p;
- }
-
- // InsituStringStream -> InsituStringStream
- static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
- RAPIDJSON_ASSERT(&is == &os);
- (void)os;
-
- if (is.src_ == is.dst_) {
- SkipUnescapedString(is);
- return;
- }
-
- char* p = is.src_;
- char *q = is.dst_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = p;
- is.dst_ = q;
- return;
- }
- else
- *q++ = *p++;
-
- // The rest of string using SIMD
- static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
- static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
- static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
- const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
- const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
- const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
-
- for (;; p += 16, q += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- const __m128i t1 = _mm_cmpeq_epi8(s, dq);
- const __m128i t2 = _mm_cmpeq_epi8(s, bs);
- const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
- const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
- unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
- if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
- size_t length;
-#ifdef _MSC_VER // Find the index of first escaped
- unsigned long offset;
- _BitScanForward(&offset, r);
- length = offset;
-#else
- length = static_cast<size_t>(__builtin_ffs(r) - 1);
-#endif
- for (const char* pend = p + length; p != pend; )
- *q++ = *p++;
- break;
- }
- _mm_storeu_si128(reinterpret_cast<__m128i *>(q), s);
- }
-
- is.src_ = p;
- is.dst_ = q;
- }
-
- // When read/write pointers are the same for insitu stream, just skip unescaped characters
- static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
- RAPIDJSON_ASSERT(is.src_ == is.dst_);
- char* p = is.src_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- for (; p != nextAligned; p++)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = is.dst_ = p;
- return;
- }
-
- // The rest of string using SIMD
- static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
- static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
- static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
- const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
- const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
- const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
-
- for (;; p += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- const __m128i t1 = _mm_cmpeq_epi8(s, dq);
- const __m128i t2 = _mm_cmpeq_epi8(s, bs);
- const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
- const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
- unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
- if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
- size_t length;
-#ifdef _MSC_VER // Find the index of first escaped
- unsigned long offset;
- _BitScanForward(&offset, r);
- length = offset;
-#else
- length = static_cast<size_t>(__builtin_ffs(r) - 1);
-#endif
- p += length;
- break;
- }
- }
-
- is.src_ = is.dst_ = p;
- }
-#elif defined(RAPIDJSON_NEON)
- // StringStream -> StackStream<char>
- static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(StringStream& is, StackStream<char>& os) {
- const char* p = is.src_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = p;
- return;
- }
- else
- os.Put(*p++);
-
- // The rest of string using SIMD
- const uint8x16_t s0 = vmovq_n_u8('"');
- const uint8x16_t s1 = vmovq_n_u8('\\');
- const uint8x16_t s2 = vmovq_n_u8('\b');
- const uint8x16_t s3 = vmovq_n_u8(32);
-
- for (;; p += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, s0);
- x = vorrq_u8(x, vceqq_u8(s, s1));
- x = vorrq_u8(x, vceqq_u8(s, s2));
- x = vorrq_u8(x, vcltq_u8(s, s3));
-
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- SizeType length = 0;
- bool escaped = false;
- if (low == 0) {
- if (high != 0) {
- unsigned lz = (unsigned)__builtin_clzll(high);;
- length = 8 + (lz >> 3);
- escaped = true;
- }
- } else {
- unsigned lz = (unsigned)__builtin_clzll(low);;
- length = lz >> 3;
- escaped = true;
- }
- if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
- if (length != 0) {
- char* q = reinterpret_cast<char*>(os.Push(length));
- for (size_t i = 0; i < length; i++)
- q[i] = p[i];
-
- p += length;
- }
- break;
- }
- vst1q_u8(reinterpret_cast<uint8_t *>(os.Push(16)), s);
- }
-
- is.src_ = p;
- }
-
- // InsituStringStream -> InsituStringStream
- static RAPIDJSON_FORCEINLINE void ScanCopyUnescapedString(InsituStringStream& is, InsituStringStream& os) {
- RAPIDJSON_ASSERT(&is == &os);
- (void)os;
-
- if (is.src_ == is.dst_) {
- SkipUnescapedString(is);
- return;
- }
-
- char* p = is.src_;
- char *q = is.dst_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- while (p != nextAligned)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = p;
- is.dst_ = q;
- return;
- }
- else
- *q++ = *p++;
-
- // The rest of string using SIMD
- const uint8x16_t s0 = vmovq_n_u8('"');
- const uint8x16_t s1 = vmovq_n_u8('\\');
- const uint8x16_t s2 = vmovq_n_u8('\b');
- const uint8x16_t s3 = vmovq_n_u8(32);
-
- for (;; p += 16, q += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, s0);
- x = vorrq_u8(x, vceqq_u8(s, s1));
- x = vorrq_u8(x, vceqq_u8(s, s2));
- x = vorrq_u8(x, vcltq_u8(s, s3));
-
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- SizeType length = 0;
- bool escaped = false;
- if (low == 0) {
- if (high != 0) {
- unsigned lz = (unsigned)__builtin_clzll(high);
- length = 8 + (lz >> 3);
- escaped = true;
- }
- } else {
- unsigned lz = (unsigned)__builtin_clzll(low);
- length = lz >> 3;
- escaped = true;
- }
- if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
- for (const char* pend = p + length; p != pend; ) {
- *q++ = *p++;
- }
- break;
- }
- vst1q_u8(reinterpret_cast<uint8_t *>(q), s);
- }
-
- is.src_ = p;
- is.dst_ = q;
- }
-
- // When read/write pointers are the same for insitu stream, just skip unescaped characters
- static RAPIDJSON_FORCEINLINE void SkipUnescapedString(InsituStringStream& is) {
- RAPIDJSON_ASSERT(is.src_ == is.dst_);
- char* p = is.src_;
-
- // Scan one by one until alignment (unaligned load may cross page boundary and cause crash)
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- for (; p != nextAligned; p++)
- if (RAPIDJSON_UNLIKELY(*p == '\"') || RAPIDJSON_UNLIKELY(*p == '\\') || RAPIDJSON_UNLIKELY(static_cast<unsigned>(*p) < 0x20)) {
- is.src_ = is.dst_ = p;
- return;
- }
-
- // The rest of string using SIMD
- const uint8x16_t s0 = vmovq_n_u8('"');
- const uint8x16_t s1 = vmovq_n_u8('\\');
- const uint8x16_t s2 = vmovq_n_u8('\b');
- const uint8x16_t s3 = vmovq_n_u8(32);
-
- for (;; p += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, s0);
- x = vorrq_u8(x, vceqq_u8(s, s1));
- x = vorrq_u8(x, vceqq_u8(s, s2));
- x = vorrq_u8(x, vcltq_u8(s, s3));
-
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- if (low == 0) {
- if (high != 0) {
- int lz = __builtin_clzll(high);
- p += 8 + (lz >> 3);
- break;
- }
- } else {
- int lz = __builtin_clzll(low);
- p += lz >> 3;
- break;
- }
- }
-
- is.src_ = is.dst_ = p;
- }
-#endif // RAPIDJSON_NEON
-
- template<typename InputStream, bool backup, bool pushOnTake>
- class NumberStream;
-
- template<typename InputStream>
- class NumberStream<InputStream, false, false> {
- public:
- typedef typename InputStream::Ch Ch;
-
- NumberStream(GenericReader& reader, InputStream& s) : is(s) { (void)reader; }
-
- RAPIDJSON_FORCEINLINE Ch Peek() const { return is.Peek(); }
- RAPIDJSON_FORCEINLINE Ch TakePush() { return is.Take(); }
- RAPIDJSON_FORCEINLINE Ch Take() { return is.Take(); }
- RAPIDJSON_FORCEINLINE void Push(char) {}
-
- size_t Tell() { return is.Tell(); }
- size_t Length() { return 0; }
- const char* Pop() { return 0; }
-
- protected:
- NumberStream& operator=(const NumberStream&);
-
- InputStream& is;
- };
-
- template<typename InputStream>
- class NumberStream<InputStream, true, false> : public NumberStream<InputStream, false, false> {
- typedef NumberStream<InputStream, false, false> Base;
- public:
- NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is), stackStream(reader.stack_) {}
-
- RAPIDJSON_FORCEINLINE Ch TakePush() {
- stackStream.Put(static_cast<char>(Base::is.Peek()));
- return Base::is.Take();
- }
-
- RAPIDJSON_FORCEINLINE void Push(char c) {
- stackStream.Put(c);
- }
-
- size_t Length() { return stackStream.Length(); }
-
- const char* Pop() {
- stackStream.Put('\0');
- return stackStream.Pop();
- }
-
- private:
- StackStream<char> stackStream;
- };
-
- template<typename InputStream>
- class NumberStream<InputStream, true, true> : public NumberStream<InputStream, true, false> {
- typedef NumberStream<InputStream, true, false> Base;
- public:
- NumberStream(GenericReader& reader, InputStream& is) : Base(reader, is) {}
-
- RAPIDJSON_FORCEINLINE Ch Take() { return Base::TakePush(); }
- };
-
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseNumber(InputStream& is, Handler& handler) {
- internal::StreamLocalCopy<InputStream> copy(is);
- NumberStream<InputStream,
- ((parseFlags & kParseNumbersAsStringsFlag) != 0) ?
- ((parseFlags & kParseInsituFlag) == 0) :
- ((parseFlags & kParseFullPrecisionFlag) != 0),
- (parseFlags & kParseNumbersAsStringsFlag) != 0 &&
- (parseFlags & kParseInsituFlag) == 0> s(*this, copy.s);
-
- size_t startOffset = s.Tell();
- double d = 0.0;
- bool useNanOrInf = false;
-
- // Parse minus
- bool minus = Consume(s, '-');
-
- // Parse int: zero / ( digit1-9 *DIGIT )
- unsigned i = 0;
- uint64_t i64 = 0;
- bool use64bit = false;
- int significandDigit = 0;
- if (RAPIDJSON_UNLIKELY(s.Peek() == '0')) {
- i = 0;
- s.TakePush();
- }
- else if (RAPIDJSON_LIKELY(s.Peek() >= '1' && s.Peek() <= '9')) {
- i = static_cast<unsigned>(s.TakePush() - '0');
-
- if (minus)
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (RAPIDJSON_UNLIKELY(i >= 214748364)) { // 2^31 = 2147483648
- if (RAPIDJSON_LIKELY(i != 214748364 || s.Peek() > '8')) {
- i64 = i;
- use64bit = true;
- break;
- }
- }
- i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
- significandDigit++;
- }
- else
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (RAPIDJSON_UNLIKELY(i >= 429496729)) { // 2^32 - 1 = 4294967295
- if (RAPIDJSON_LIKELY(i != 429496729 || s.Peek() > '5')) {
- i64 = i;
- use64bit = true;
- break;
- }
- }
- i = i * 10 + static_cast<unsigned>(s.TakePush() - '0');
- significandDigit++;
- }
- }
- // Parse NaN or Infinity here
- else if ((parseFlags & kParseNanAndInfFlag) && RAPIDJSON_LIKELY((s.Peek() == 'I' || s.Peek() == 'N'))) {
- if (Consume(s, 'N')) {
- if (Consume(s, 'a') && Consume(s, 'N')) {
- d = std::numeric_limits<double>::quiet_NaN();
- useNanOrInf = true;
- }
- }
- else if (RAPIDJSON_LIKELY(Consume(s, 'I'))) {
- if (Consume(s, 'n') && Consume(s, 'f')) {
- d = (minus ? -std::numeric_limits<double>::infinity() : std::numeric_limits<double>::infinity());
- useNanOrInf = true;
-
- if (RAPIDJSON_UNLIKELY(s.Peek() == 'i' && !(Consume(s, 'i') && Consume(s, 'n')
- && Consume(s, 'i') && Consume(s, 't') && Consume(s, 'y')))) {
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
- }
- }
- }
-
- if (RAPIDJSON_UNLIKELY(!useNanOrInf)) {
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
- }
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, s.Tell());
-
- // Parse 64bit int
- bool useDouble = false;
- if (use64bit) {
- if (minus)
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC))) // 2^63 = 9223372036854775808
- if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x0CCCCCCC, 0xCCCCCCCC) || s.Peek() > '8')) {
- d = static_cast<double>(i64);
- useDouble = true;
- break;
- }
- i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
- significandDigit++;
- }
- else
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (RAPIDJSON_UNLIKELY(i64 >= RAPIDJSON_UINT64_C2(0x19999999, 0x99999999))) // 2^64 - 1 = 18446744073709551615
- if (RAPIDJSON_LIKELY(i64 != RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) || s.Peek() > '5')) {
- d = static_cast<double>(i64);
- useDouble = true;
- break;
- }
- i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
- significandDigit++;
- }
- }
-
- // Force double for big integer
- if (useDouble) {
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (RAPIDJSON_UNLIKELY(d >= 1.7976931348623157e307)) // DBL_MAX / 10.0
- RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
- d = d * 10 + (s.TakePush() - '0');
- }
- }
-
- // Parse frac = decimal-point 1*DIGIT
- int expFrac = 0;
- size_t decimalPosition;
- if (Consume(s, '.')) {
- decimalPosition = s.Length();
-
- if (RAPIDJSON_UNLIKELY(!(s.Peek() >= '0' && s.Peek() <= '9')))
- RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissFraction, s.Tell());
-
- if (!useDouble) {
-#if RAPIDJSON_64BIT
- // Use i64 to store significand in 64-bit architecture
- if (!use64bit)
- i64 = i;
-
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (i64 > RAPIDJSON_UINT64_C2(0x1FFFFF, 0xFFFFFFFF)) // 2^53 - 1 for fast path
- break;
- else {
- i64 = i64 * 10 + static_cast<unsigned>(s.TakePush() - '0');
- --expFrac;
- if (i64 != 0)
- significandDigit++;
- }
- }
-
- d = static_cast<double>(i64);
-#else
- // Use double to store significand in 32-bit architecture
- d = static_cast<double>(use64bit ? i64 : i);
-#endif
- useDouble = true;
- }
-
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- if (significandDigit < 17) {
- d = d * 10.0 + (s.TakePush() - '0');
- --expFrac;
- if (RAPIDJSON_LIKELY(d > 0.0))
- significandDigit++;
- }
- else
- s.TakePush();
- }
- }
- else
- decimalPosition = s.Length(); // decimal position at the end of integer.
-
- // Parse exp = e [ minus / plus ] 1*DIGIT
- int exp = 0;
- if (Consume(s, 'e') || Consume(s, 'E')) {
- if (!useDouble) {
- d = static_cast<double>(use64bit ? i64 : i);
- useDouble = true;
- }
-
- bool expMinus = false;
- if (Consume(s, '+'))
- ;
- else if (Consume(s, '-'))
- expMinus = true;
-
- if (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- exp = static_cast<int>(s.Take() - '0');
- if (expMinus) {
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- exp = exp * 10 + static_cast<int>(s.Take() - '0');
- if (exp >= 214748364) { // Issue #313: prevent overflow exponent
- while (RAPIDJSON_UNLIKELY(s.Peek() >= '0' && s.Peek() <= '9')) // Consume the rest of exponent
- s.Take();
- }
- }
- }
- else { // positive exp
- int maxExp = 308 - expFrac;
- while (RAPIDJSON_LIKELY(s.Peek() >= '0' && s.Peek() <= '9')) {
- exp = exp * 10 + static_cast<int>(s.Take() - '0');
- if (RAPIDJSON_UNLIKELY(exp > maxExp))
- RAPIDJSON_PARSE_ERROR(kParseErrorNumberTooBig, startOffset);
- }
- }
- }
- else
- RAPIDJSON_PARSE_ERROR(kParseErrorNumberMissExponent, s.Tell());
-
- if (expMinus)
- exp = -exp;
- }
-
- // Finish parsing, call event according to the type of number.
- bool cont = true;
-
- if (parseFlags & kParseNumbersAsStringsFlag) {
- if (parseFlags & kParseInsituFlag) {
- s.Pop(); // Pop stack no matter if it will be used or not.
- typename InputStream::Ch* head = is.PutBegin();
- const size_t length = s.Tell() - startOffset;
- RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
- // unable to insert the \0 character here, it will erase the comma after this number
- const typename TargetEncoding::Ch* const str = reinterpret_cast<typename TargetEncoding::Ch*>(head);
- cont = handler.RawNumber(str, SizeType(length), false);
- }
- else {
- SizeType numCharsToCopy = static_cast<SizeType>(s.Length());
- StringStream srcStream(s.Pop());
- StackStream<typename TargetEncoding::Ch> dstStream(stack_);
- while (numCharsToCopy--) {
- Transcoder<UTF8<>, TargetEncoding>::Transcode(srcStream, dstStream);
- }
- dstStream.Put('\0');
- const typename TargetEncoding::Ch* str = dstStream.Pop();
- const SizeType length = static_cast<SizeType>(dstStream.Length()) - 1;
- cont = handler.RawNumber(str, SizeType(length), true);
- }
- }
- else {
- size_t length = s.Length();
- const char* decimal = s.Pop(); // Pop stack no matter if it will be used or not.
-
- if (useDouble) {
- int p = exp + expFrac;
- if (parseFlags & kParseFullPrecisionFlag)
- d = internal::StrtodFullPrecision(d, p, decimal, length, decimalPosition, exp);
- else
- d = internal::StrtodNormalPrecision(d, p);
-
- cont = handler.Double(minus ? -d : d);
- }
- else if (useNanOrInf) {
- cont = handler.Double(d);
- }
- else {
- if (use64bit) {
- if (minus)
- cont = handler.Int64(static_cast<int64_t>(~i64 + 1));
- else
- cont = handler.Uint64(i64);
- }
- else {
- if (minus)
- cont = handler.Int(static_cast<int32_t>(~i + 1));
- else
- cont = handler.Uint(i);
- }
- }
- }
- if (RAPIDJSON_UNLIKELY(!cont))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, startOffset);
- }
-
- // Parse any JSON value
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseValue(InputStream& is, Handler& handler) {
- switch (is.Peek()) {
- case 'n': ParseNull <parseFlags>(is, handler); break;
- case 't': ParseTrue <parseFlags>(is, handler); break;
- case 'f': ParseFalse <parseFlags>(is, handler); break;
- case '"': ParseString<parseFlags>(is, handler); break;
- case '{': ParseObject<parseFlags>(is, handler); break;
- case '[': ParseArray <parseFlags>(is, handler); break;
- default :
- ParseNumber<parseFlags>(is, handler);
- break;
-
- }
- }
-
- // Iterative Parsing
-
- // States
- enum IterativeParsingState {
- IterativeParsingFinishState = 0, // sink states at top
- IterativeParsingErrorState, // sink states at top
- IterativeParsingStartState,
-
- // Object states
- IterativeParsingObjectInitialState,
- IterativeParsingMemberKeyState,
- IterativeParsingMemberValueState,
- IterativeParsingObjectFinishState,
-
- // Array states
- IterativeParsingArrayInitialState,
- IterativeParsingElementState,
- IterativeParsingArrayFinishState,
-
- // Single value state
- IterativeParsingValueState,
-
- // Delimiter states (at bottom)
- IterativeParsingElementDelimiterState,
- IterativeParsingMemberDelimiterState,
- IterativeParsingKeyValueDelimiterState,
-
- cIterativeParsingStateCount
- };
-
- // Tokens
- enum Token {
- LeftBracketToken = 0,
- RightBracketToken,
-
- LeftCurlyBracketToken,
- RightCurlyBracketToken,
-
- CommaToken,
- ColonToken,
-
- StringToken,
- FalseToken,
- TrueToken,
- NullToken,
- NumberToken,
-
- kTokenCount
- };
-
- RAPIDJSON_FORCEINLINE Token Tokenize(Ch c) {
-
-//!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
-#define N NumberToken
-#define N16 N,N,N,N,N,N,N,N,N,N,N,N,N,N,N,N
- // Maps from ASCII to Token
- static const unsigned char tokenMap[256] = {
- N16, // 00~0F
- N16, // 10~1F
- N, N, StringToken, N, N, N, N, N, N, N, N, N, CommaToken, N, N, N, // 20~2F
- N, N, N, N, N, N, N, N, N, N, ColonToken, N, N, N, N, N, // 30~3F
- N16, // 40~4F
- N, N, N, N, N, N, N, N, N, N, N, LeftBracketToken, N, RightBracketToken, N, N, // 50~5F
- N, N, N, N, N, N, FalseToken, N, N, N, N, N, N, N, NullToken, N, // 60~6F
- N, N, N, N, TrueToken, N, N, N, N, N, N, LeftCurlyBracketToken, N, RightCurlyBracketToken, N, N, // 70~7F
- N16, N16, N16, N16, N16, N16, N16, N16 // 80~FF
- };
-#undef N
-#undef N16
-//!@endcond
-
- if (sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256)
- return static_cast<Token>(tokenMap[static_cast<unsigned char>(c)]);
- else
- return NumberToken;
- }
-
- RAPIDJSON_FORCEINLINE IterativeParsingState Predict(IterativeParsingState state, Token token) {
- // current state x one lookahead token -> new state
- static const char G[cIterativeParsingStateCount][kTokenCount] = {
- // Finish(sink state)
- {
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState
- },
- // Error(sink state)
- {
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState
- },
- // Start
- {
- IterativeParsingArrayInitialState, // Left bracket
- IterativeParsingErrorState, // Right bracket
- IterativeParsingObjectInitialState, // Left curly bracket
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingValueState, // String
- IterativeParsingValueState, // False
- IterativeParsingValueState, // True
- IterativeParsingValueState, // Null
- IterativeParsingValueState // Number
- },
- // ObjectInitial
- {
- IterativeParsingErrorState, // Left bracket
- IterativeParsingErrorState, // Right bracket
- IterativeParsingErrorState, // Left curly bracket
- IterativeParsingObjectFinishState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingMemberKeyState, // String
- IterativeParsingErrorState, // False
- IterativeParsingErrorState, // True
- IterativeParsingErrorState, // Null
- IterativeParsingErrorState // Number
- },
- // MemberKey
- {
- IterativeParsingErrorState, // Left bracket
- IterativeParsingErrorState, // Right bracket
- IterativeParsingErrorState, // Left curly bracket
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingKeyValueDelimiterState, // Colon
- IterativeParsingErrorState, // String
- IterativeParsingErrorState, // False
- IterativeParsingErrorState, // True
- IterativeParsingErrorState, // Null
- IterativeParsingErrorState // Number
- },
- // MemberValue
- {
- IterativeParsingErrorState, // Left bracket
- IterativeParsingErrorState, // Right bracket
- IterativeParsingErrorState, // Left curly bracket
- IterativeParsingObjectFinishState, // Right curly bracket
- IterativeParsingMemberDelimiterState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingErrorState, // String
- IterativeParsingErrorState, // False
- IterativeParsingErrorState, // True
- IterativeParsingErrorState, // Null
- IterativeParsingErrorState // Number
- },
- // ObjectFinish(sink state)
- {
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState
- },
- // ArrayInitial
- {
- IterativeParsingArrayInitialState, // Left bracket(push Element state)
- IterativeParsingArrayFinishState, // Right bracket
- IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingElementState, // String
- IterativeParsingElementState, // False
- IterativeParsingElementState, // True
- IterativeParsingElementState, // Null
- IterativeParsingElementState // Number
- },
- // Element
- {
- IterativeParsingErrorState, // Left bracket
- IterativeParsingArrayFinishState, // Right bracket
- IterativeParsingErrorState, // Left curly bracket
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingElementDelimiterState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingErrorState, // String
- IterativeParsingErrorState, // False
- IterativeParsingErrorState, // True
- IterativeParsingErrorState, // Null
- IterativeParsingErrorState // Number
- },
- // ArrayFinish(sink state)
- {
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState
- },
- // Single Value (sink state)
- {
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState, IterativeParsingErrorState,
- IterativeParsingErrorState
- },
- // ElementDelimiter
- {
- IterativeParsingArrayInitialState, // Left bracket(push Element state)
- IterativeParsingArrayFinishState, // Right bracket
- IterativeParsingObjectInitialState, // Left curly bracket(push Element state)
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingElementState, // String
- IterativeParsingElementState, // False
- IterativeParsingElementState, // True
- IterativeParsingElementState, // Null
- IterativeParsingElementState // Number
- },
- // MemberDelimiter
- {
- IterativeParsingErrorState, // Left bracket
- IterativeParsingErrorState, // Right bracket
- IterativeParsingErrorState, // Left curly bracket
- IterativeParsingObjectFinishState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingMemberKeyState, // String
- IterativeParsingErrorState, // False
- IterativeParsingErrorState, // True
- IterativeParsingErrorState, // Null
- IterativeParsingErrorState // Number
- },
- // KeyValueDelimiter
- {
- IterativeParsingArrayInitialState, // Left bracket(push MemberValue state)
- IterativeParsingErrorState, // Right bracket
- IterativeParsingObjectInitialState, // Left curly bracket(push MemberValue state)
- IterativeParsingErrorState, // Right curly bracket
- IterativeParsingErrorState, // Comma
- IterativeParsingErrorState, // Colon
- IterativeParsingMemberValueState, // String
- IterativeParsingMemberValueState, // False
- IterativeParsingMemberValueState, // True
- IterativeParsingMemberValueState, // Null
- IterativeParsingMemberValueState // Number
- },
- }; // End of G
-
- return static_cast<IterativeParsingState>(G[state][token]);
- }
-
- // Make an advance in the token stream and state based on the candidate destination state which was returned by Transit().
- // May return a new state on state pop.
- template <unsigned parseFlags, typename InputStream, typename Handler>
- RAPIDJSON_FORCEINLINE IterativeParsingState Transit(IterativeParsingState src, Token token, IterativeParsingState dst, InputStream& is, Handler& handler) {
- (void)token;
-
- switch (dst) {
- case IterativeParsingErrorState:
- return dst;
-
- case IterativeParsingObjectInitialState:
- case IterativeParsingArrayInitialState:
- {
- // Push the state(Element or MemeberValue) if we are nested in another array or value of member.
- // In this way we can get the correct state on ObjectFinish or ArrayFinish by frame pop.
- IterativeParsingState n = src;
- if (src == IterativeParsingArrayInitialState || src == IterativeParsingElementDelimiterState)
- n = IterativeParsingElementState;
- else if (src == IterativeParsingKeyValueDelimiterState)
- n = IterativeParsingMemberValueState;
- // Push current state.
- *stack_.template Push<SizeType>(1) = n;
- // Initialize and push the member/element count.
- *stack_.template Push<SizeType>(1) = 0;
- // Call handler
- bool hr = (dst == IterativeParsingObjectInitialState) ? handler.StartObject() : handler.StartArray();
- // On handler short circuits the parsing.
- if (!hr) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
- return IterativeParsingErrorState;
- }
- else {
- is.Take();
- return dst;
- }
- }
-
- case IterativeParsingMemberKeyState:
- ParseString<parseFlags>(is, handler, true);
- if (HasParseError())
- return IterativeParsingErrorState;
- else
- return dst;
-
- case IterativeParsingKeyValueDelimiterState:
- RAPIDJSON_ASSERT(token == ColonToken);
- is.Take();
- return dst;
-
- case IterativeParsingMemberValueState:
- // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
- ParseValue<parseFlags>(is, handler);
- if (HasParseError()) {
- return IterativeParsingErrorState;
- }
- return dst;
-
- case IterativeParsingElementState:
- // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
- ParseValue<parseFlags>(is, handler);
- if (HasParseError()) {
- return IterativeParsingErrorState;
- }
- return dst;
-
- case IterativeParsingMemberDelimiterState:
- case IterativeParsingElementDelimiterState:
- is.Take();
- // Update member/element count.
- *stack_.template Top<SizeType>() = *stack_.template Top<SizeType>() + 1;
- return dst;
-
- case IterativeParsingObjectFinishState:
- {
- // Transit from delimiter is only allowed when trailing commas are enabled
- if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingMemberDelimiterState) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorObjectMissName, is.Tell());
- return IterativeParsingErrorState;
- }
- // Get member count.
- SizeType c = *stack_.template Pop<SizeType>(1);
- // If the object is not empty, count the last member.
- if (src == IterativeParsingMemberValueState)
- ++c;
- // Restore the state.
- IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
- // Transit to Finish state if this is the topmost scope.
- if (n == IterativeParsingStartState)
- n = IterativeParsingFinishState;
- // Call handler
- bool hr = handler.EndObject(c);
- // On handler short circuits the parsing.
- if (!hr) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
- return IterativeParsingErrorState;
- }
- else {
- is.Take();
- return n;
- }
- }
-
- case IterativeParsingArrayFinishState:
- {
- // Transit from delimiter is only allowed when trailing commas are enabled
- if (!(parseFlags & kParseTrailingCommasFlag) && src == IterativeParsingElementDelimiterState) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorValueInvalid, is.Tell());
- return IterativeParsingErrorState;
- }
- // Get element count.
- SizeType c = *stack_.template Pop<SizeType>(1);
- // If the array is not empty, count the last element.
- if (src == IterativeParsingElementState)
- ++c;
- // Restore the state.
- IterativeParsingState n = static_cast<IterativeParsingState>(*stack_.template Pop<SizeType>(1));
- // Transit to Finish state if this is the topmost scope.
- if (n == IterativeParsingStartState)
- n = IterativeParsingFinishState;
- // Call handler
- bool hr = handler.EndArray(c);
- // On handler short circuits the parsing.
- if (!hr) {
- RAPIDJSON_PARSE_ERROR_NORETURN(kParseErrorTermination, is.Tell());
- return IterativeParsingErrorState;
- }
- else {
- is.Take();
- return n;
- }
- }
-
- default:
- // This branch is for IterativeParsingValueState actually.
- // Use `default:` rather than
- // `case IterativeParsingValueState:` is for code coverage.
-
- // The IterativeParsingStartState is not enumerated in this switch-case.
- // It is impossible for that case. And it can be caught by following assertion.
-
- // The IterativeParsingFinishState is not enumerated in this switch-case either.
- // It is a "derivative" state which cannot triggered from Predict() directly.
- // Therefore it cannot happen here. And it can be caught by following assertion.
- RAPIDJSON_ASSERT(dst == IterativeParsingValueState);
-
- // Must be non-compound value. Or it would be ObjectInitial or ArrayInitial state.
- ParseValue<parseFlags>(is, handler);
- if (HasParseError()) {
- return IterativeParsingErrorState;
- }
- return IterativeParsingFinishState;
- }
- }
-
- template <typename InputStream>
- void HandleError(IterativeParsingState src, InputStream& is) {
- if (HasParseError()) {
- // Error flag has been set.
- return;
- }
-
- switch (src) {
- case IterativeParsingStartState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentEmpty, is.Tell()); return;
- case IterativeParsingFinishState: RAPIDJSON_PARSE_ERROR(kParseErrorDocumentRootNotSingular, is.Tell()); return;
- case IterativeParsingObjectInitialState:
- case IterativeParsingMemberDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); return;
- case IterativeParsingMemberKeyState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissColon, is.Tell()); return;
- case IterativeParsingMemberValueState: RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, is.Tell()); return;
- case IterativeParsingKeyValueDelimiterState:
- case IterativeParsingArrayInitialState:
- case IterativeParsingElementDelimiterState: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell()); return;
- default: RAPIDJSON_ASSERT(src == IterativeParsingElementState); RAPIDJSON_PARSE_ERROR(kParseErrorArrayMissCommaOrSquareBracket, is.Tell()); return;
- }
- }
-
- RAPIDJSON_FORCEINLINE bool IsIterativeParsingDelimiterState(IterativeParsingState s) {
- return s >= IterativeParsingElementDelimiterState;
- }
-
- RAPIDJSON_FORCEINLINE bool IsIterativeParsingCompleteState(IterativeParsingState s) {
- return s <= IterativeParsingErrorState;
- }
-
- template <unsigned parseFlags, typename InputStream, typename Handler>
- ParseResult IterativeParse(InputStream& is, Handler& handler) {
- parseResult_.Clear();
- ClearStackOnExit scope(*this);
- IterativeParsingState state = IterativeParsingStartState;
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
- while (is.Peek() != '\0') {
- Token t = Tokenize(is.Peek());
- IterativeParsingState n = Predict(state, t);
- IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
-
- if (d == IterativeParsingErrorState) {
- HandleError(state, is);
- break;
- }
-
- state = d;
-
- // Do not further consume streams if a root JSON has been parsed.
- if ((parseFlags & kParseStopWhenDoneFlag) && state == IterativeParsingFinishState)
- break;
-
- SkipWhitespaceAndComments<parseFlags>(is);
- RAPIDJSON_PARSE_ERROR_EARLY_RETURN(parseResult_);
- }
-
- // Handle the end of file.
- if (state != IterativeParsingFinishState)
- HandleError(state, is);
-
- return parseResult_;
- }
-
- static const size_t kDefaultStackCapacity = 256; //!< Default stack capacity in bytes for storing a single decoded string.
- internal::Stack<StackAllocator> stack_; //!< A stack for storing decoded string temporarily during non-destructive parsing.
- ParseResult parseResult_;
- IterativeParsingState state_;
-}; // class GenericReader
-
-//! Reader with UTF8 encoding and default allocator.
-typedef GenericReader<UTF8<>, UTF8<> > Reader;
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-
-#ifdef __GNUC__
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_READER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/schema.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/schema.h
deleted file mode 100644
index abcf1a102..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/schema.h
+++ /dev/null
@@ -1,2016 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available->
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip-> All rights reserved->
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License-> You may obtain a copy of the License at
-//
-// http://opensource->org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied-> See the License for the
-// specific language governing permissions and limitations under the License->
-
-#ifndef RAPIDJSON_SCHEMA_H_
-#define RAPIDJSON_SCHEMA_H_
-
-#include "document.h"
-#include "pointer.h"
-#include <cmath> // abs, floor
-
-#if !defined(RAPIDJSON_SCHEMA_USE_INTERNALREGEX)
-#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 1
-#else
-#define RAPIDJSON_SCHEMA_USE_INTERNALREGEX 0
-#endif
-
-#if !RAPIDJSON_SCHEMA_USE_INTERNALREGEX && !defined(RAPIDJSON_SCHEMA_USE_STDREGEX) && (__cplusplus >=201103L || (defined(_MSC_VER) && _MSC_VER >= 1800))
-#define RAPIDJSON_SCHEMA_USE_STDREGEX 1
-#else
-#define RAPIDJSON_SCHEMA_USE_STDREGEX 0
-#endif
-
-#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
-#include "internal/regex.h"
-#elif RAPIDJSON_SCHEMA_USE_STDREGEX
-#include <regex>
-#endif
-
-#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX || RAPIDJSON_SCHEMA_USE_STDREGEX
-#define RAPIDJSON_SCHEMA_HAS_REGEX 1
-#else
-#define RAPIDJSON_SCHEMA_HAS_REGEX 0
-#endif
-
-#ifndef RAPIDJSON_SCHEMA_VERBOSE
-#define RAPIDJSON_SCHEMA_VERBOSE 0
-#endif
-
-#if RAPIDJSON_SCHEMA_VERBOSE
-#include "stringbuffer.h"
-#endif
-
-RAPIDJSON_DIAG_PUSH
-
-#if defined(__GNUC__)
-RAPIDJSON_DIAG_OFF(effc++)
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_OFF(weak-vtables)
-RAPIDJSON_DIAG_OFF(exit-time-destructors)
-RAPIDJSON_DIAG_OFF(c++98-compat-pedantic)
-RAPIDJSON_DIAG_OFF(variadic-macros)
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Verbose Utilities
-
-#if RAPIDJSON_SCHEMA_VERBOSE
-
-namespace internal {
-
-inline void PrintInvalidKeyword(const char* keyword) {
- printf("Fail keyword: %s\n", keyword);
-}
-
-inline void PrintInvalidKeyword(const wchar_t* keyword) {
- wprintf(L"Fail keyword: %ls\n", keyword);
-}
-
-inline void PrintInvalidDocument(const char* document) {
- printf("Fail document: %s\n\n", document);
-}
-
-inline void PrintInvalidDocument(const wchar_t* document) {
- wprintf(L"Fail document: %ls\n\n", document);
-}
-
-inline void PrintValidatorPointers(unsigned depth, const char* s, const char* d) {
- printf("S: %*s%s\nD: %*s%s\n\n", depth * 4, " ", s, depth * 4, " ", d);
-}
-
-inline void PrintValidatorPointers(unsigned depth, const wchar_t* s, const wchar_t* d) {
- wprintf(L"S: %*ls%ls\nD: %*ls%ls\n\n", depth * 4, L" ", s, depth * 4, L" ", d);
-}
-
-} // namespace internal
-
-#endif // RAPIDJSON_SCHEMA_VERBOSE
-
-///////////////////////////////////////////////////////////////////////////////
-// RAPIDJSON_INVALID_KEYWORD_RETURN
-
-#if RAPIDJSON_SCHEMA_VERBOSE
-#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword) internal::PrintInvalidKeyword(keyword)
-#else
-#define RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword)
-#endif
-
-#define RAPIDJSON_INVALID_KEYWORD_RETURN(keyword)\
-RAPIDJSON_MULTILINEMACRO_BEGIN\
- context.invalidKeyword = keyword.GetString();\
- RAPIDJSON_INVALID_KEYWORD_VERBOSE(keyword.GetString());\
- return false;\
-RAPIDJSON_MULTILINEMACRO_END
-
-///////////////////////////////////////////////////////////////////////////////
-// Forward declarations
-
-template <typename ValueType, typename Allocator>
-class GenericSchemaDocument;
-
-namespace internal {
-
-template <typename SchemaDocumentType>
-class Schema;
-
-///////////////////////////////////////////////////////////////////////////////
-// ISchemaValidator
-
-class ISchemaValidator {
-public:
- virtual ~ISchemaValidator() {}
- virtual bool IsValid() const = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// ISchemaStateFactory
-
-template <typename SchemaType>
-class ISchemaStateFactory {
-public:
- virtual ~ISchemaStateFactory() {}
- virtual ISchemaValidator* CreateSchemaValidator(const SchemaType&) = 0;
- virtual void DestroySchemaValidator(ISchemaValidator* validator) = 0;
- virtual void* CreateHasher() = 0;
- virtual uint64_t GetHashCode(void* hasher) = 0;
- virtual void DestroryHasher(void* hasher) = 0;
- virtual void* MallocState(size_t size) = 0;
- virtual void FreeState(void* p) = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Hasher
-
-// For comparison of compound value
-template<typename Encoding, typename Allocator>
-class Hasher {
-public:
- typedef typename Encoding::Ch Ch;
-
- Hasher(Allocator* allocator = 0, size_t stackCapacity = kDefaultSize) : stack_(allocator, stackCapacity) {}
-
- bool Null() { return WriteType(kNullType); }
- bool Bool(bool b) { return WriteType(b ? kTrueType : kFalseType); }
- bool Int(int i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
- bool Uint(unsigned u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
- bool Int64(int64_t i) { Number n; n.u.i = i; n.d = static_cast<double>(i); return WriteNumber(n); }
- bool Uint64(uint64_t u) { Number n; n.u.u = u; n.d = static_cast<double>(u); return WriteNumber(n); }
- bool Double(double d) {
- Number n;
- if (d < 0) n.u.i = static_cast<int64_t>(d);
- else n.u.u = static_cast<uint64_t>(d);
- n.d = d;
- return WriteNumber(n);
- }
-
- bool RawNumber(const Ch* str, SizeType len, bool) {
- WriteBuffer(kNumberType, str, len * sizeof(Ch));
- return true;
- }
-
- bool String(const Ch* str, SizeType len, bool) {
- WriteBuffer(kStringType, str, len * sizeof(Ch));
- return true;
- }
-
- bool StartObject() { return true; }
- bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }
- bool EndObject(SizeType memberCount) {
- uint64_t h = Hash(0, kObjectType);
- uint64_t* kv = stack_.template Pop<uint64_t>(memberCount * 2);
- for (SizeType i = 0; i < memberCount; i++)
- h ^= Hash(kv[i * 2], kv[i * 2 + 1]); // Use xor to achieve member order insensitive
- *stack_.template Push<uint64_t>() = h;
- return true;
- }
-
- bool StartArray() { return true; }
- bool EndArray(SizeType elementCount) {
- uint64_t h = Hash(0, kArrayType);
- uint64_t* e = stack_.template Pop<uint64_t>(elementCount);
- for (SizeType i = 0; i < elementCount; i++)
- h = Hash(h, e[i]); // Use hash to achieve element order sensitive
- *stack_.template Push<uint64_t>() = h;
- return true;
- }
-
- bool IsValid() const { return stack_.GetSize() == sizeof(uint64_t); }
-
- uint64_t GetHashCode() const {
- RAPIDJSON_ASSERT(IsValid());
- return *stack_.template Top<uint64_t>();
- }
-
-private:
- static const size_t kDefaultSize = 256;
- struct Number {
- union U {
- uint64_t u;
- int64_t i;
- }u;
- double d;
- };
-
- bool WriteType(Type type) { return WriteBuffer(type, 0, 0); }
-
- bool WriteNumber(const Number& n) { return WriteBuffer(kNumberType, &n, sizeof(n)); }
-
- bool WriteBuffer(Type type, const void* data, size_t len) {
- // FNV-1a from http://isthe.com/chongo/tech/comp/fnv/
- uint64_t h = Hash(RAPIDJSON_UINT64_C2(0x84222325, 0xcbf29ce4), type);
- const unsigned char* d = static_cast<const unsigned char*>(data);
- for (size_t i = 0; i < len; i++)
- h = Hash(h, d[i]);
- *stack_.template Push<uint64_t>() = h;
- return true;
- }
-
- static uint64_t Hash(uint64_t h, uint64_t d) {
- static const uint64_t kPrime = RAPIDJSON_UINT64_C2(0x00000100, 0x000001b3);
- h ^= d;
- h *= kPrime;
- return h;
- }
-
- Stack<Allocator> stack_;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// SchemaValidationContext
-
-template <typename SchemaDocumentType>
-struct SchemaValidationContext {
- typedef Schema<SchemaDocumentType> SchemaType;
- typedef ISchemaStateFactory<SchemaType> SchemaValidatorFactoryType;
- typedef typename SchemaType::ValueType ValueType;
- typedef typename ValueType::Ch Ch;
-
- enum PatternValidatorType {
- kPatternValidatorOnly,
- kPatternValidatorWithProperty,
- kPatternValidatorWithAdditionalProperty
- };
-
- SchemaValidationContext(SchemaValidatorFactoryType& f, const SchemaType* s) :
- factory(f),
- schema(s),
- valueSchema(),
- invalidKeyword(),
- hasher(),
- arrayElementHashCodes(),
- validators(),
- validatorCount(),
- patternPropertiesValidators(),
- patternPropertiesValidatorCount(),
- patternPropertiesSchemas(),
- patternPropertiesSchemaCount(),
- valuePatternValidatorType(kPatternValidatorOnly),
- propertyExist(),
- inArray(false),
- valueUniqueness(false),
- arrayUniqueness(false)
- {
- }
-
- ~SchemaValidationContext() {
- if (hasher)
- factory.DestroryHasher(hasher);
- if (validators) {
- for (SizeType i = 0; i < validatorCount; i++)
- factory.DestroySchemaValidator(validators[i]);
- factory.FreeState(validators);
- }
- if (patternPropertiesValidators) {
- for (SizeType i = 0; i < patternPropertiesValidatorCount; i++)
- factory.DestroySchemaValidator(patternPropertiesValidators[i]);
- factory.FreeState(patternPropertiesValidators);
- }
- if (patternPropertiesSchemas)
- factory.FreeState(patternPropertiesSchemas);
- if (propertyExist)
- factory.FreeState(propertyExist);
- }
-
- SchemaValidatorFactoryType& factory;
- const SchemaType* schema;
- const SchemaType* valueSchema;
- const Ch* invalidKeyword;
- void* hasher; // Only validator access
- void* arrayElementHashCodes; // Only validator access this
- ISchemaValidator** validators;
- SizeType validatorCount;
- ISchemaValidator** patternPropertiesValidators;
- SizeType patternPropertiesValidatorCount;
- const SchemaType** patternPropertiesSchemas;
- SizeType patternPropertiesSchemaCount;
- PatternValidatorType valuePatternValidatorType;
- PatternValidatorType objectPatternValidatorType;
- SizeType arrayElementIndex;
- bool* propertyExist;
- bool inArray;
- bool valueUniqueness;
- bool arrayUniqueness;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// Schema
-
-template <typename SchemaDocumentType>
-class Schema {
-public:
- typedef typename SchemaDocumentType::ValueType ValueType;
- typedef typename SchemaDocumentType::AllocatorType AllocatorType;
- typedef typename SchemaDocumentType::PointerType PointerType;
- typedef typename ValueType::EncodingType EncodingType;
- typedef typename EncodingType::Ch Ch;
- typedef SchemaValidationContext<SchemaDocumentType> Context;
- typedef Schema<SchemaDocumentType> SchemaType;
- typedef GenericValue<EncodingType, AllocatorType> SValue;
- friend class GenericSchemaDocument<ValueType, AllocatorType>;
-
- Schema(SchemaDocumentType* schemaDocument, const PointerType& p, const ValueType& value, const ValueType& document, AllocatorType* allocator) :
- allocator_(allocator),
- typeless_(schemaDocument->GetTypeless()),
- enum_(),
- enumCount_(),
- not_(),
- type_((1 << kTotalSchemaType) - 1), // typeless
- validatorCount_(),
- properties_(),
- additionalPropertiesSchema_(),
- patternProperties_(),
- patternPropertyCount_(),
- propertyCount_(),
- minProperties_(),
- maxProperties_(SizeType(~0)),
- additionalProperties_(true),
- hasDependencies_(),
- hasRequired_(),
- hasSchemaDependencies_(),
- additionalItemsSchema_(),
- itemsList_(),
- itemsTuple_(),
- itemsTupleCount_(),
- minItems_(),
- maxItems_(SizeType(~0)),
- additionalItems_(true),
- uniqueItems_(false),
- pattern_(),
- minLength_(0),
- maxLength_(~SizeType(0)),
- exclusiveMinimum_(false),
- exclusiveMaximum_(false)
- {
- typedef typename SchemaDocumentType::ValueType ValueType;
- typedef typename ValueType::ConstValueIterator ConstValueIterator;
- typedef typename ValueType::ConstMemberIterator ConstMemberIterator;
-
- if (!value.IsObject())
- return;
-
- if (const ValueType* v = GetMember(value, GetTypeString())) {
- type_ = 0;
- if (v->IsString())
- AddType(*v);
- else if (v->IsArray())
- for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr)
- AddType(*itr);
- }
-
- if (const ValueType* v = GetMember(value, GetEnumString()))
- if (v->IsArray() && v->Size() > 0) {
- enum_ = static_cast<uint64_t*>(allocator_->Malloc(sizeof(uint64_t) * v->Size()));
- for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr) {
- typedef Hasher<EncodingType, MemoryPoolAllocator<> > EnumHasherType;
- char buffer[256 + 24];
- MemoryPoolAllocator<> hasherAllocator(buffer, sizeof(buffer));
- EnumHasherType h(&hasherAllocator, 256);
- itr->Accept(h);
- enum_[enumCount_++] = h.GetHashCode();
- }
- }
-
- if (schemaDocument) {
- AssignIfExist(allOf_, *schemaDocument, p, value, GetAllOfString(), document);
- AssignIfExist(anyOf_, *schemaDocument, p, value, GetAnyOfString(), document);
- AssignIfExist(oneOf_, *schemaDocument, p, value, GetOneOfString(), document);
- }
-
- if (const ValueType* v = GetMember(value, GetNotString())) {
- schemaDocument->CreateSchema(&not_, p.Append(GetNotString(), allocator_), *v, document);
- notValidatorIndex_ = validatorCount_;
- validatorCount_++;
- }
-
- // Object
-
- const ValueType* properties = GetMember(value, GetPropertiesString());
- const ValueType* required = GetMember(value, GetRequiredString());
- const ValueType* dependencies = GetMember(value, GetDependenciesString());
- {
- // Gather properties from properties/required/dependencies
- SValue allProperties(kArrayType);
-
- if (properties && properties->IsObject())
- for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr)
- AddUniqueElement(allProperties, itr->name);
-
- if (required && required->IsArray())
- for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
- if (itr->IsString())
- AddUniqueElement(allProperties, *itr);
-
- if (dependencies && dependencies->IsObject())
- for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
- AddUniqueElement(allProperties, itr->name);
- if (itr->value.IsArray())
- for (ConstValueIterator i = itr->value.Begin(); i != itr->value.End(); ++i)
- if (i->IsString())
- AddUniqueElement(allProperties, *i);
- }
-
- if (allProperties.Size() > 0) {
- propertyCount_ = allProperties.Size();
- properties_ = static_cast<Property*>(allocator_->Malloc(sizeof(Property) * propertyCount_));
- for (SizeType i = 0; i < propertyCount_; i++) {
- new (&properties_[i]) Property();
- properties_[i].name = allProperties[i];
- properties_[i].schema = typeless_;
- }
- }
- }
-
- if (properties && properties->IsObject()) {
- PointerType q = p.Append(GetPropertiesString(), allocator_);
- for (ConstMemberIterator itr = properties->MemberBegin(); itr != properties->MemberEnd(); ++itr) {
- SizeType index;
- if (FindPropertyIndex(itr->name, &index))
- schemaDocument->CreateSchema(&properties_[index].schema, q.Append(itr->name, allocator_), itr->value, document);
- }
- }
-
- if (const ValueType* v = GetMember(value, GetPatternPropertiesString())) {
- PointerType q = p.Append(GetPatternPropertiesString(), allocator_);
- patternProperties_ = static_cast<PatternProperty*>(allocator_->Malloc(sizeof(PatternProperty) * v->MemberCount()));
- patternPropertyCount_ = 0;
-
- for (ConstMemberIterator itr = v->MemberBegin(); itr != v->MemberEnd(); ++itr) {
- new (&patternProperties_[patternPropertyCount_]) PatternProperty();
- patternProperties_[patternPropertyCount_].pattern = CreatePattern(itr->name);
- schemaDocument->CreateSchema(&patternProperties_[patternPropertyCount_].schema, q.Append(itr->name, allocator_), itr->value, document);
- patternPropertyCount_++;
- }
- }
-
- if (required && required->IsArray())
- for (ConstValueIterator itr = required->Begin(); itr != required->End(); ++itr)
- if (itr->IsString()) {
- SizeType index;
- if (FindPropertyIndex(*itr, &index)) {
- properties_[index].required = true;
- hasRequired_ = true;
- }
- }
-
- if (dependencies && dependencies->IsObject()) {
- PointerType q = p.Append(GetDependenciesString(), allocator_);
- hasDependencies_ = true;
- for (ConstMemberIterator itr = dependencies->MemberBegin(); itr != dependencies->MemberEnd(); ++itr) {
- SizeType sourceIndex;
- if (FindPropertyIndex(itr->name, &sourceIndex)) {
- if (itr->value.IsArray()) {
- properties_[sourceIndex].dependencies = static_cast<bool*>(allocator_->Malloc(sizeof(bool) * propertyCount_));
- std::memset(properties_[sourceIndex].dependencies, 0, sizeof(bool)* propertyCount_);
- for (ConstValueIterator targetItr = itr->value.Begin(); targetItr != itr->value.End(); ++targetItr) {
- SizeType targetIndex;
- if (FindPropertyIndex(*targetItr, &targetIndex))
- properties_[sourceIndex].dependencies[targetIndex] = true;
- }
- }
- else if (itr->value.IsObject()) {
- hasSchemaDependencies_ = true;
- schemaDocument->CreateSchema(&properties_[sourceIndex].dependenciesSchema, q.Append(itr->name, allocator_), itr->value, document);
- properties_[sourceIndex].dependenciesValidatorIndex = validatorCount_;
- validatorCount_++;
- }
- }
- }
- }
-
- if (const ValueType* v = GetMember(value, GetAdditionalPropertiesString())) {
- if (v->IsBool())
- additionalProperties_ = v->GetBool();
- else if (v->IsObject())
- schemaDocument->CreateSchema(&additionalPropertiesSchema_, p.Append(GetAdditionalPropertiesString(), allocator_), *v, document);
- }
-
- AssignIfExist(minProperties_, value, GetMinPropertiesString());
- AssignIfExist(maxProperties_, value, GetMaxPropertiesString());
-
- // Array
- if (const ValueType* v = GetMember(value, GetItemsString())) {
- PointerType q = p.Append(GetItemsString(), allocator_);
- if (v->IsObject()) // List validation
- schemaDocument->CreateSchema(&itemsList_, q, *v, document);
- else if (v->IsArray()) { // Tuple validation
- itemsTuple_ = static_cast<const Schema**>(allocator_->Malloc(sizeof(const Schema*) * v->Size()));
- SizeType index = 0;
- for (ConstValueIterator itr = v->Begin(); itr != v->End(); ++itr, index++)
- schemaDocument->CreateSchema(&itemsTuple_[itemsTupleCount_++], q.Append(index, allocator_), *itr, document);
- }
- }
-
- AssignIfExist(minItems_, value, GetMinItemsString());
- AssignIfExist(maxItems_, value, GetMaxItemsString());
-
- if (const ValueType* v = GetMember(value, GetAdditionalItemsString())) {
- if (v->IsBool())
- additionalItems_ = v->GetBool();
- else if (v->IsObject())
- schemaDocument->CreateSchema(&additionalItemsSchema_, p.Append(GetAdditionalItemsString(), allocator_), *v, document);
- }
-
- AssignIfExist(uniqueItems_, value, GetUniqueItemsString());
-
- // String
- AssignIfExist(minLength_, value, GetMinLengthString());
- AssignIfExist(maxLength_, value, GetMaxLengthString());
-
- if (const ValueType* v = GetMember(value, GetPatternString()))
- pattern_ = CreatePattern(*v);
-
- // Number
- if (const ValueType* v = GetMember(value, GetMinimumString()))
- if (v->IsNumber())
- minimum_.CopyFrom(*v, *allocator_);
-
- if (const ValueType* v = GetMember(value, GetMaximumString()))
- if (v->IsNumber())
- maximum_.CopyFrom(*v, *allocator_);
-
- AssignIfExist(exclusiveMinimum_, value, GetExclusiveMinimumString());
- AssignIfExist(exclusiveMaximum_, value, GetExclusiveMaximumString());
-
- if (const ValueType* v = GetMember(value, GetMultipleOfString()))
- if (v->IsNumber() && v->GetDouble() > 0.0)
- multipleOf_.CopyFrom(*v, *allocator_);
- }
-
- ~Schema() {
- AllocatorType::Free(enum_);
- if (properties_) {
- for (SizeType i = 0; i < propertyCount_; i++)
- properties_[i].~Property();
- AllocatorType::Free(properties_);
- }
- if (patternProperties_) {
- for (SizeType i = 0; i < patternPropertyCount_; i++)
- patternProperties_[i].~PatternProperty();
- AllocatorType::Free(patternProperties_);
- }
- AllocatorType::Free(itemsTuple_);
-#if RAPIDJSON_SCHEMA_HAS_REGEX
- if (pattern_) {
- pattern_->~RegexType();
- AllocatorType::Free(pattern_);
- }
-#endif
- }
-
- bool BeginValue(Context& context) const {
- if (context.inArray) {
- if (uniqueItems_)
- context.valueUniqueness = true;
-
- if (itemsList_)
- context.valueSchema = itemsList_;
- else if (itemsTuple_) {
- if (context.arrayElementIndex < itemsTupleCount_)
- context.valueSchema = itemsTuple_[context.arrayElementIndex];
- else if (additionalItemsSchema_)
- context.valueSchema = additionalItemsSchema_;
- else if (additionalItems_)
- context.valueSchema = typeless_;
- else
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetItemsString());
- }
- else
- context.valueSchema = typeless_;
-
- context.arrayElementIndex++;
- }
- return true;
- }
-
- RAPIDJSON_FORCEINLINE bool EndValue(Context& context) const {
- if (context.patternPropertiesValidatorCount > 0) {
- bool otherValid = false;
- SizeType count = context.patternPropertiesValidatorCount;
- if (context.objectPatternValidatorType != Context::kPatternValidatorOnly)
- otherValid = context.patternPropertiesValidators[--count]->IsValid();
-
- bool patternValid = true;
- for (SizeType i = 0; i < count; i++)
- if (!context.patternPropertiesValidators[i]->IsValid()) {
- patternValid = false;
- break;
- }
-
- if (context.objectPatternValidatorType == Context::kPatternValidatorOnly) {
- if (!patternValid)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
- }
- else if (context.objectPatternValidatorType == Context::kPatternValidatorWithProperty) {
- if (!patternValid || !otherValid)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
- }
- else if (!patternValid && !otherValid) // kPatternValidatorWithAdditionalProperty)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternPropertiesString());
- }
-
- if (enum_) {
- const uint64_t h = context.factory.GetHashCode(context.hasher);
- for (SizeType i = 0; i < enumCount_; i++)
- if (enum_[i] == h)
- goto foundEnum;
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetEnumString());
- foundEnum:;
- }
-
- if (allOf_.schemas)
- for (SizeType i = allOf_.begin; i < allOf_.begin + allOf_.count; i++)
- if (!context.validators[i]->IsValid())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetAllOfString());
-
- if (anyOf_.schemas) {
- for (SizeType i = anyOf_.begin; i < anyOf_.begin + anyOf_.count; i++)
- if (context.validators[i]->IsValid())
- goto foundAny;
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetAnyOfString());
- foundAny:;
- }
-
- if (oneOf_.schemas) {
- bool oneValid = false;
- for (SizeType i = oneOf_.begin; i < oneOf_.begin + oneOf_.count; i++)
- if (context.validators[i]->IsValid()) {
- if (oneValid)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
- else
- oneValid = true;
- }
- if (!oneValid)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetOneOfString());
- }
-
- if (not_ && context.validators[notValidatorIndex_]->IsValid())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetNotString());
-
- return true;
- }
-
- bool Null(Context& context) const {
- if (!(type_ & (1 << kNullSchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
- return CreateParallelValidator(context);
- }
-
- bool Bool(Context& context, bool) const {
- if (!(type_ & (1 << kBooleanSchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
- return CreateParallelValidator(context);
- }
-
- bool Int(Context& context, int i) const {
- if (!CheckInt(context, i))
- return false;
- return CreateParallelValidator(context);
- }
-
- bool Uint(Context& context, unsigned u) const {
- if (!CheckUint(context, u))
- return false;
- return CreateParallelValidator(context);
- }
-
- bool Int64(Context& context, int64_t i) const {
- if (!CheckInt(context, i))
- return false;
- return CreateParallelValidator(context);
- }
-
- bool Uint64(Context& context, uint64_t u) const {
- if (!CheckUint(context, u))
- return false;
- return CreateParallelValidator(context);
- }
-
- bool Double(Context& context, double d) const {
- if (!(type_ & (1 << kNumberSchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- if (!minimum_.IsNull() && !CheckDoubleMinimum(context, d))
- return false;
-
- if (!maximum_.IsNull() && !CheckDoubleMaximum(context, d))
- return false;
-
- if (!multipleOf_.IsNull() && !CheckDoubleMultipleOf(context, d))
- return false;
-
- return CreateParallelValidator(context);
- }
-
- bool String(Context& context, const Ch* str, SizeType length, bool) const {
- if (!(type_ & (1 << kStringSchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- if (minLength_ != 0 || maxLength_ != SizeType(~0)) {
- SizeType count;
- if (internal::CountStringCodePoint<EncodingType>(str, length, &count)) {
- if (count < minLength_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinLengthString());
- if (count > maxLength_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxLengthString());
- }
- }
-
- if (pattern_ && !IsPatternMatch(pattern_, str, length))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetPatternString());
-
- return CreateParallelValidator(context);
- }
-
- bool StartObject(Context& context) const {
- if (!(type_ & (1 << kObjectSchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- if (hasDependencies_ || hasRequired_) {
- context.propertyExist = static_cast<bool*>(context.factory.MallocState(sizeof(bool) * propertyCount_));
- std::memset(context.propertyExist, 0, sizeof(bool) * propertyCount_);
- }
-
- if (patternProperties_) { // pre-allocate schema array
- SizeType count = patternPropertyCount_ + 1; // extra for valuePatternValidatorType
- context.patternPropertiesSchemas = static_cast<const SchemaType**>(context.factory.MallocState(sizeof(const SchemaType*) * count));
- context.patternPropertiesSchemaCount = 0;
- std::memset(context.patternPropertiesSchemas, 0, sizeof(SchemaType*) * count);
- }
-
- return CreateParallelValidator(context);
- }
-
- bool Key(Context& context, const Ch* str, SizeType len, bool) const {
- if (patternProperties_) {
- context.patternPropertiesSchemaCount = 0;
- for (SizeType i = 0; i < patternPropertyCount_; i++)
- if (patternProperties_[i].pattern && IsPatternMatch(patternProperties_[i].pattern, str, len)) {
- context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = patternProperties_[i].schema;
- context.valueSchema = typeless_;
- }
- }
-
- SizeType index;
- if (FindPropertyIndex(ValueType(str, len).Move(), &index)) {
- if (context.patternPropertiesSchemaCount > 0) {
- context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = properties_[index].schema;
- context.valueSchema = typeless_;
- context.valuePatternValidatorType = Context::kPatternValidatorWithProperty;
- }
- else
- context.valueSchema = properties_[index].schema;
-
- if (context.propertyExist)
- context.propertyExist[index] = true;
-
- return true;
- }
-
- if (additionalPropertiesSchema_) {
- if (additionalPropertiesSchema_ && context.patternPropertiesSchemaCount > 0) {
- context.patternPropertiesSchemas[context.patternPropertiesSchemaCount++] = additionalPropertiesSchema_;
- context.valueSchema = typeless_;
- context.valuePatternValidatorType = Context::kPatternValidatorWithAdditionalProperty;
- }
- else
- context.valueSchema = additionalPropertiesSchema_;
- return true;
- }
- else if (additionalProperties_) {
- context.valueSchema = typeless_;
- return true;
- }
-
- if (context.patternPropertiesSchemaCount == 0) // patternProperties are not additional properties
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetAdditionalPropertiesString());
-
- return true;
- }
-
- bool EndObject(Context& context, SizeType memberCount) const {
- if (hasRequired_)
- for (SizeType index = 0; index < propertyCount_; index++)
- if (properties_[index].required)
- if (!context.propertyExist[index])
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetRequiredString());
-
- if (memberCount < minProperties_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinPropertiesString());
-
- if (memberCount > maxProperties_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxPropertiesString());
-
- if (hasDependencies_) {
- for (SizeType sourceIndex = 0; sourceIndex < propertyCount_; sourceIndex++)
- if (context.propertyExist[sourceIndex]) {
- if (properties_[sourceIndex].dependencies) {
- for (SizeType targetIndex = 0; targetIndex < propertyCount_; targetIndex++)
- if (properties_[sourceIndex].dependencies[targetIndex] && !context.propertyExist[targetIndex])
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
- }
- else if (properties_[sourceIndex].dependenciesSchema)
- if (!context.validators[properties_[sourceIndex].dependenciesValidatorIndex]->IsValid())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetDependenciesString());
- }
- }
-
- return true;
- }
-
- bool StartArray(Context& context) const {
- if (!(type_ & (1 << kArraySchemaType)))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- context.arrayElementIndex = 0;
- context.inArray = true;
-
- return CreateParallelValidator(context);
- }
-
- bool EndArray(Context& context, SizeType elementCount) const {
- context.inArray = false;
-
- if (elementCount < minItems_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinItemsString());
-
- if (elementCount > maxItems_)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaxItemsString());
-
- return true;
- }
-
- // Generate functions for string literal according to Ch
-#define RAPIDJSON_STRING_(name, ...) \
- static const ValueType& Get##name##String() {\
- static const Ch s[] = { __VA_ARGS__, '\0' };\
- static const ValueType v(s, static_cast<SizeType>(sizeof(s) / sizeof(Ch) - 1));\
- return v;\
- }
-
- RAPIDJSON_STRING_(Null, 'n', 'u', 'l', 'l')
- RAPIDJSON_STRING_(Boolean, 'b', 'o', 'o', 'l', 'e', 'a', 'n')
- RAPIDJSON_STRING_(Object, 'o', 'b', 'j', 'e', 'c', 't')
- RAPIDJSON_STRING_(Array, 'a', 'r', 'r', 'a', 'y')
- RAPIDJSON_STRING_(String, 's', 't', 'r', 'i', 'n', 'g')
- RAPIDJSON_STRING_(Number, 'n', 'u', 'm', 'b', 'e', 'r')
- RAPIDJSON_STRING_(Integer, 'i', 'n', 't', 'e', 'g', 'e', 'r')
- RAPIDJSON_STRING_(Type, 't', 'y', 'p', 'e')
- RAPIDJSON_STRING_(Enum, 'e', 'n', 'u', 'm')
- RAPIDJSON_STRING_(AllOf, 'a', 'l', 'l', 'O', 'f')
- RAPIDJSON_STRING_(AnyOf, 'a', 'n', 'y', 'O', 'f')
- RAPIDJSON_STRING_(OneOf, 'o', 'n', 'e', 'O', 'f')
- RAPIDJSON_STRING_(Not, 'n', 'o', 't')
- RAPIDJSON_STRING_(Properties, 'p', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
- RAPIDJSON_STRING_(Required, 'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd')
- RAPIDJSON_STRING_(Dependencies, 'd', 'e', 'p', 'e', 'n', 'd', 'e', 'n', 'c', 'i', 'e', 's')
- RAPIDJSON_STRING_(PatternProperties, 'p', 'a', 't', 't', 'e', 'r', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
- RAPIDJSON_STRING_(AdditionalProperties, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
- RAPIDJSON_STRING_(MinProperties, 'm', 'i', 'n', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
- RAPIDJSON_STRING_(MaxProperties, 'm', 'a', 'x', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'i', 'e', 's')
- RAPIDJSON_STRING_(Items, 'i', 't', 'e', 'm', 's')
- RAPIDJSON_STRING_(MinItems, 'm', 'i', 'n', 'I', 't', 'e', 'm', 's')
- RAPIDJSON_STRING_(MaxItems, 'm', 'a', 'x', 'I', 't', 'e', 'm', 's')
- RAPIDJSON_STRING_(AdditionalItems, 'a', 'd', 'd', 'i', 't', 'i', 'o', 'n', 'a', 'l', 'I', 't', 'e', 'm', 's')
- RAPIDJSON_STRING_(UniqueItems, 'u', 'n', 'i', 'q', 'u', 'e', 'I', 't', 'e', 'm', 's')
- RAPIDJSON_STRING_(MinLength, 'm', 'i', 'n', 'L', 'e', 'n', 'g', 't', 'h')
- RAPIDJSON_STRING_(MaxLength, 'm', 'a', 'x', 'L', 'e', 'n', 'g', 't', 'h')
- RAPIDJSON_STRING_(Pattern, 'p', 'a', 't', 't', 'e', 'r', 'n')
- RAPIDJSON_STRING_(Minimum, 'm', 'i', 'n', 'i', 'm', 'u', 'm')
- RAPIDJSON_STRING_(Maximum, 'm', 'a', 'x', 'i', 'm', 'u', 'm')
- RAPIDJSON_STRING_(ExclusiveMinimum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'i', 'n', 'i', 'm', 'u', 'm')
- RAPIDJSON_STRING_(ExclusiveMaximum, 'e', 'x', 'c', 'l', 'u', 's', 'i', 'v', 'e', 'M', 'a', 'x', 'i', 'm', 'u', 'm')
- RAPIDJSON_STRING_(MultipleOf, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e', 'O', 'f')
-
-#undef RAPIDJSON_STRING_
-
-private:
- enum SchemaValueType {
- kNullSchemaType,
- kBooleanSchemaType,
- kObjectSchemaType,
- kArraySchemaType,
- kStringSchemaType,
- kNumberSchemaType,
- kIntegerSchemaType,
- kTotalSchemaType
- };
-
-#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
- typedef internal::GenericRegex<EncodingType> RegexType;
-#elif RAPIDJSON_SCHEMA_USE_STDREGEX
- typedef std::basic_regex<Ch> RegexType;
-#else
- typedef char RegexType;
-#endif
-
- struct SchemaArray {
- SchemaArray() : schemas(), count() {}
- ~SchemaArray() { AllocatorType::Free(schemas); }
- const SchemaType** schemas;
- SizeType begin; // begin index of context.validators
- SizeType count;
- };
-
- template <typename V1, typename V2>
- void AddUniqueElement(V1& a, const V2& v) {
- for (typename V1::ConstValueIterator itr = a.Begin(); itr != a.End(); ++itr)
- if (*itr == v)
- return;
- V1 c(v, *allocator_);
- a.PushBack(c, *allocator_);
- }
-
- static const ValueType* GetMember(const ValueType& value, const ValueType& name) {
- typename ValueType::ConstMemberIterator itr = value.FindMember(name);
- return itr != value.MemberEnd() ? &(itr->value) : 0;
- }
-
- static void AssignIfExist(bool& out, const ValueType& value, const ValueType& name) {
- if (const ValueType* v = GetMember(value, name))
- if (v->IsBool())
- out = v->GetBool();
- }
-
- static void AssignIfExist(SizeType& out, const ValueType& value, const ValueType& name) {
- if (const ValueType* v = GetMember(value, name))
- if (v->IsUint64() && v->GetUint64() <= SizeType(~0))
- out = static_cast<SizeType>(v->GetUint64());
- }
-
- void AssignIfExist(SchemaArray& out, SchemaDocumentType& schemaDocument, const PointerType& p, const ValueType& value, const ValueType& name, const ValueType& document) {
- if (const ValueType* v = GetMember(value, name)) {
- if (v->IsArray() && v->Size() > 0) {
- PointerType q = p.Append(name, allocator_);
- out.count = v->Size();
- out.schemas = static_cast<const Schema**>(allocator_->Malloc(out.count * sizeof(const Schema*)));
- memset(out.schemas, 0, sizeof(Schema*)* out.count);
- for (SizeType i = 0; i < out.count; i++)
- schemaDocument.CreateSchema(&out.schemas[i], q.Append(i, allocator_), (*v)[i], document);
- out.begin = validatorCount_;
- validatorCount_ += out.count;
- }
- }
- }
-
-#if RAPIDJSON_SCHEMA_USE_INTERNALREGEX
- template <typename ValueType>
- RegexType* CreatePattern(const ValueType& value) {
- if (value.IsString()) {
- RegexType* r = new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString());
- if (!r->IsValid()) {
- r->~RegexType();
- AllocatorType::Free(r);
- r = 0;
- }
- return r;
- }
- return 0;
- }
-
- static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType) {
- GenericRegexSearch<RegexType> rs(*pattern);
- return rs.Search(str);
- }
-#elif RAPIDJSON_SCHEMA_USE_STDREGEX
- template <typename ValueType>
- RegexType* CreatePattern(const ValueType& value) {
- if (value.IsString())
- try {
- return new (allocator_->Malloc(sizeof(RegexType))) RegexType(value.GetString(), std::size_t(value.GetStringLength()), std::regex_constants::ECMAScript);
- }
- catch (const std::regex_error&) {
- }
- return 0;
- }
-
- static bool IsPatternMatch(const RegexType* pattern, const Ch *str, SizeType length) {
- std::match_results<const Ch*> r;
- return std::regex_search(str, str + length, r, *pattern);
- }
-#else
- template <typename ValueType>
- RegexType* CreatePattern(const ValueType&) { return 0; }
-
- static bool IsPatternMatch(const RegexType*, const Ch *, SizeType) { return true; }
-#endif // RAPIDJSON_SCHEMA_USE_STDREGEX
-
- void AddType(const ValueType& type) {
- if (type == GetNullString() ) type_ |= 1 << kNullSchemaType;
- else if (type == GetBooleanString()) type_ |= 1 << kBooleanSchemaType;
- else if (type == GetObjectString() ) type_ |= 1 << kObjectSchemaType;
- else if (type == GetArrayString() ) type_ |= 1 << kArraySchemaType;
- else if (type == GetStringString() ) type_ |= 1 << kStringSchemaType;
- else if (type == GetIntegerString()) type_ |= 1 << kIntegerSchemaType;
- else if (type == GetNumberString() ) type_ |= (1 << kNumberSchemaType) | (1 << kIntegerSchemaType);
- }
-
- bool CreateParallelValidator(Context& context) const {
- if (enum_ || context.arrayUniqueness)
- context.hasher = context.factory.CreateHasher();
-
- if (validatorCount_) {
- RAPIDJSON_ASSERT(context.validators == 0);
- context.validators = static_cast<ISchemaValidator**>(context.factory.MallocState(sizeof(ISchemaValidator*) * validatorCount_));
- context.validatorCount = validatorCount_;
-
- if (allOf_.schemas)
- CreateSchemaValidators(context, allOf_);
-
- if (anyOf_.schemas)
- CreateSchemaValidators(context, anyOf_);
-
- if (oneOf_.schemas)
- CreateSchemaValidators(context, oneOf_);
-
- if (not_)
- context.validators[notValidatorIndex_] = context.factory.CreateSchemaValidator(*not_);
-
- if (hasSchemaDependencies_) {
- for (SizeType i = 0; i < propertyCount_; i++)
- if (properties_[i].dependenciesSchema)
- context.validators[properties_[i].dependenciesValidatorIndex] = context.factory.CreateSchemaValidator(*properties_[i].dependenciesSchema);
- }
- }
-
- return true;
- }
-
- void CreateSchemaValidators(Context& context, const SchemaArray& schemas) const {
- for (SizeType i = 0; i < schemas.count; i++)
- context.validators[schemas.begin + i] = context.factory.CreateSchemaValidator(*schemas.schemas[i]);
- }
-
- // O(n)
- bool FindPropertyIndex(const ValueType& name, SizeType* outIndex) const {
- SizeType len = name.GetStringLength();
- const Ch* str = name.GetString();
- for (SizeType index = 0; index < propertyCount_; index++)
- if (properties_[index].name.GetStringLength() == len &&
- (std::memcmp(properties_[index].name.GetString(), str, sizeof(Ch) * len) == 0))
- {
- *outIndex = index;
- return true;
- }
- return false;
- }
-
- bool CheckInt(Context& context, int64_t i) const {
- if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- if (!minimum_.IsNull()) {
- if (minimum_.IsInt64()) {
- if (exclusiveMinimum_ ? i <= minimum_.GetInt64() : i < minimum_.GetInt64())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
- }
- else if (minimum_.IsUint64()) {
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString()); // i <= max(int64_t) < minimum.GetUint64()
- }
- else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
- return false;
- }
-
- if (!maximum_.IsNull()) {
- if (maximum_.IsInt64()) {
- if (exclusiveMaximum_ ? i >= maximum_.GetInt64() : i > maximum_.GetInt64())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
- }
- else if (maximum_.IsUint64()) { }
- /* do nothing */ // i <= max(int64_t) < maximum_.GetUint64()
- else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
- return false;
- }
-
- if (!multipleOf_.IsNull()) {
- if (multipleOf_.IsUint64()) {
- if (static_cast<uint64_t>(i >= 0 ? i : -i) % multipleOf_.GetUint64() != 0)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
- }
- else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
- return false;
- }
-
- return true;
- }
-
- bool CheckUint(Context& context, uint64_t i) const {
- if (!(type_ & ((1 << kIntegerSchemaType) | (1 << kNumberSchemaType))))
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetTypeString());
-
- if (!minimum_.IsNull()) {
- if (minimum_.IsUint64()) {
- if (exclusiveMinimum_ ? i <= minimum_.GetUint64() : i < minimum_.GetUint64())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
- }
- else if (minimum_.IsInt64())
- /* do nothing */; // i >= 0 > minimum.Getint64()
- else if (!CheckDoubleMinimum(context, static_cast<double>(i)))
- return false;
- }
-
- if (!maximum_.IsNull()) {
- if (maximum_.IsUint64()) {
- if (exclusiveMaximum_ ? i >= maximum_.GetUint64() : i > maximum_.GetUint64())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
- }
- else if (maximum_.IsInt64())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString()); // i >= 0 > maximum_
- else if (!CheckDoubleMaximum(context, static_cast<double>(i)))
- return false;
- }
-
- if (!multipleOf_.IsNull()) {
- if (multipleOf_.IsUint64()) {
- if (i % multipleOf_.GetUint64() != 0)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
- }
- else if (!CheckDoubleMultipleOf(context, static_cast<double>(i)))
- return false;
- }
-
- return true;
- }
-
- bool CheckDoubleMinimum(Context& context, double d) const {
- if (exclusiveMinimum_ ? d <= minimum_.GetDouble() : d < minimum_.GetDouble())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMinimumString());
- return true;
- }
-
- bool CheckDoubleMaximum(Context& context, double d) const {
- if (exclusiveMaximum_ ? d >= maximum_.GetDouble() : d > maximum_.GetDouble())
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMaximumString());
- return true;
- }
-
- bool CheckDoubleMultipleOf(Context& context, double d) const {
- double a = std::abs(d), b = std::abs(multipleOf_.GetDouble());
- double q = std::floor(a / b);
- double r = a - q * b;
- if (r > 0.0)
- RAPIDJSON_INVALID_KEYWORD_RETURN(GetMultipleOfString());
- return true;
- }
-
- struct Property {
- Property() : schema(), dependenciesSchema(), dependenciesValidatorIndex(), dependencies(), required(false) {}
- ~Property() { AllocatorType::Free(dependencies); }
- SValue name;
- const SchemaType* schema;
- const SchemaType* dependenciesSchema;
- SizeType dependenciesValidatorIndex;
- bool* dependencies;
- bool required;
- };
-
- struct PatternProperty {
- PatternProperty() : schema(), pattern() {}
- ~PatternProperty() {
- if (pattern) {
- pattern->~RegexType();
- AllocatorType::Free(pattern);
- }
- }
- const SchemaType* schema;
- RegexType* pattern;
- };
-
- AllocatorType* allocator_;
- const SchemaType* typeless_;
- uint64_t* enum_;
- SizeType enumCount_;
- SchemaArray allOf_;
- SchemaArray anyOf_;
- SchemaArray oneOf_;
- const SchemaType* not_;
- unsigned type_; // bitmask of kSchemaType
- SizeType validatorCount_;
- SizeType notValidatorIndex_;
-
- Property* properties_;
- const SchemaType* additionalPropertiesSchema_;
- PatternProperty* patternProperties_;
- SizeType patternPropertyCount_;
- SizeType propertyCount_;
- SizeType minProperties_;
- SizeType maxProperties_;
- bool additionalProperties_;
- bool hasDependencies_;
- bool hasRequired_;
- bool hasSchemaDependencies_;
-
- const SchemaType* additionalItemsSchema_;
- const SchemaType* itemsList_;
- const SchemaType** itemsTuple_;
- SizeType itemsTupleCount_;
- SizeType minItems_;
- SizeType maxItems_;
- bool additionalItems_;
- bool uniqueItems_;
-
- RegexType* pattern_;
- SizeType minLength_;
- SizeType maxLength_;
-
- SValue minimum_;
- SValue maximum_;
- SValue multipleOf_;
- bool exclusiveMinimum_;
- bool exclusiveMaximum_;
-};
-
-template<typename Stack, typename Ch>
-struct TokenHelper {
- RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
- *documentStack.template Push<Ch>() = '/';
- char buffer[21];
- size_t length = static_cast<size_t>((sizeof(SizeType) == 4 ? u32toa(index, buffer) : u64toa(index, buffer)) - buffer);
- for (size_t i = 0; i < length; i++)
- *documentStack.template Push<Ch>() = static_cast<Ch>(buffer[i]);
- }
-};
-
-// Partial specialized version for char to prevent buffer copying.
-template <typename Stack>
-struct TokenHelper<Stack, char> {
- RAPIDJSON_FORCEINLINE static void AppendIndexToken(Stack& documentStack, SizeType index) {
- if (sizeof(SizeType) == 4) {
- char *buffer = documentStack.template Push<char>(1 + 10); // '/' + uint
- *buffer++ = '/';
- const char* end = internal::u32toa(index, buffer);
- documentStack.template Pop<char>(static_cast<size_t>(10 - (end - buffer)));
- }
- else {
- char *buffer = documentStack.template Push<char>(1 + 20); // '/' + uint64
- *buffer++ = '/';
- const char* end = internal::u64toa(index, buffer);
- documentStack.template Pop<char>(static_cast<size_t>(20 - (end - buffer)));
- }
- }
-};
-
-} // namespace internal
-
-///////////////////////////////////////////////////////////////////////////////
-// IGenericRemoteSchemaDocumentProvider
-
-template <typename SchemaDocumentType>
-class IGenericRemoteSchemaDocumentProvider {
-public:
- typedef typename SchemaDocumentType::Ch Ch;
-
- virtual ~IGenericRemoteSchemaDocumentProvider() {}
- virtual const SchemaDocumentType* GetRemoteDocument(const Ch* uri, SizeType length) = 0;
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericSchemaDocument
-
-//! JSON schema document.
-/*!
- A JSON schema document is a compiled version of a JSON schema.
- It is basically a tree of internal::Schema.
-
- \note This is an immutable class (i.e. its instance cannot be modified after construction).
- \tparam ValueT Type of JSON value (e.g. \c Value ), which also determine the encoding.
- \tparam Allocator Allocator type for allocating memory of this document.
-*/
-template <typename ValueT, typename Allocator = CrtAllocator>
-class GenericSchemaDocument {
-public:
- typedef ValueT ValueType;
- typedef IGenericRemoteSchemaDocumentProvider<GenericSchemaDocument> IRemoteSchemaDocumentProviderType;
- typedef Allocator AllocatorType;
- typedef typename ValueType::EncodingType EncodingType;
- typedef typename EncodingType::Ch Ch;
- typedef internal::Schema<GenericSchemaDocument> SchemaType;
- typedef GenericPointer<ValueType, Allocator> PointerType;
- friend class internal::Schema<GenericSchemaDocument>;
- template <typename, typename, typename>
- friend class GenericSchemaValidator;
-
- //! Constructor.
- /*!
- Compile a JSON document into schema document.
-
- \param document A JSON document as source.
- \param remoteProvider An optional remote schema document provider for resolving remote reference. Can be null.
- \param allocator An optional allocator instance for allocating memory. Can be null.
- */
- explicit GenericSchemaDocument(const ValueType& document, IRemoteSchemaDocumentProviderType* remoteProvider = 0, Allocator* allocator = 0) :
- remoteProvider_(remoteProvider),
- allocator_(allocator),
- ownAllocator_(),
- root_(),
- typeless_(),
- schemaMap_(allocator, kInitialSchemaMapSize),
- schemaRef_(allocator, kInitialSchemaRefSize)
- {
- if (!allocator_)
- ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
-
- typeless_ = static_cast<SchemaType*>(allocator_->Malloc(sizeof(SchemaType)));
- new (typeless_) SchemaType(this, PointerType(), ValueType(kObjectType).Move(), ValueType(kObjectType).Move(), 0);
-
- // Generate root schema, it will call CreateSchema() to create sub-schemas,
- // And call AddRefSchema() if there are $ref.
- CreateSchemaRecursive(&root_, PointerType(), document, document);
-
- // Resolve $ref
- while (!schemaRef_.Empty()) {
- SchemaRefEntry* refEntry = schemaRef_.template Pop<SchemaRefEntry>(1);
- if (const SchemaType* s = GetSchema(refEntry->target)) {
- if (refEntry->schema)
- *refEntry->schema = s;
-
- // Create entry in map if not exist
- if (!GetSchema(refEntry->source)) {
- new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(refEntry->source, const_cast<SchemaType*>(s), false, allocator_);
- }
- }
- else if (refEntry->schema)
- *refEntry->schema = typeless_;
-
- refEntry->~SchemaRefEntry();
- }
-
- RAPIDJSON_ASSERT(root_ != 0);
-
- schemaRef_.ShrinkToFit(); // Deallocate all memory for ref
- }
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- //! Move constructor in C++11
- GenericSchemaDocument(GenericSchemaDocument&& rhs) RAPIDJSON_NOEXCEPT :
- remoteProvider_(rhs.remoteProvider_),
- allocator_(rhs.allocator_),
- ownAllocator_(rhs.ownAllocator_),
- root_(rhs.root_),
- typeless_(rhs.typeless_),
- schemaMap_(std::move(rhs.schemaMap_)),
- schemaRef_(std::move(rhs.schemaRef_))
- {
- rhs.remoteProvider_ = 0;
- rhs.allocator_ = 0;
- rhs.ownAllocator_ = 0;
- rhs.typeless_ = 0;
- }
-#endif
-
- //! Destructor
- ~GenericSchemaDocument() {
- while (!schemaMap_.Empty())
- schemaMap_.template Pop<SchemaEntry>(1)->~SchemaEntry();
-
- if (typeless_) {
- typeless_->~SchemaType();
- Allocator::Free(typeless_);
- }
-
- RAPIDJSON_DELETE(ownAllocator_);
- }
-
- //! Get the root schema.
- const SchemaType& GetRoot() const { return *root_; }
-
-private:
- //! Prohibit copying
- GenericSchemaDocument(const GenericSchemaDocument&);
- //! Prohibit assignment
- GenericSchemaDocument& operator=(const GenericSchemaDocument&);
-
- struct SchemaRefEntry {
- SchemaRefEntry(const PointerType& s, const PointerType& t, const SchemaType** outSchema, Allocator *allocator) : source(s, allocator), target(t, allocator), schema(outSchema) {}
- PointerType source;
- PointerType target;
- const SchemaType** schema;
- };
-
- struct SchemaEntry {
- SchemaEntry(const PointerType& p, SchemaType* s, bool o, Allocator* allocator) : pointer(p, allocator), schema(s), owned(o) {}
- ~SchemaEntry() {
- if (owned) {
- schema->~SchemaType();
- Allocator::Free(schema);
- }
- }
- PointerType pointer;
- SchemaType* schema;
- bool owned;
- };
-
- void CreateSchemaRecursive(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
- if (schema)
- *schema = typeless_;
-
- if (v.GetType() == kObjectType) {
- const SchemaType* s = GetSchema(pointer);
- if (!s)
- CreateSchema(schema, pointer, v, document);
-
- for (typename ValueType::ConstMemberIterator itr = v.MemberBegin(); itr != v.MemberEnd(); ++itr)
- CreateSchemaRecursive(0, pointer.Append(itr->name, allocator_), itr->value, document);
- }
- else if (v.GetType() == kArrayType)
- for (SizeType i = 0; i < v.Size(); i++)
- CreateSchemaRecursive(0, pointer.Append(i, allocator_), v[i], document);
- }
-
- void CreateSchema(const SchemaType** schema, const PointerType& pointer, const ValueType& v, const ValueType& document) {
- RAPIDJSON_ASSERT(pointer.IsValid());
- if (v.IsObject()) {
- if (!HandleRefSchema(pointer, schema, v, document)) {
- SchemaType* s = new (allocator_->Malloc(sizeof(SchemaType))) SchemaType(this, pointer, v, document, allocator_);
- new (schemaMap_.template Push<SchemaEntry>()) SchemaEntry(pointer, s, true, allocator_);
- if (schema)
- *schema = s;
- }
- }
- }
-
- bool HandleRefSchema(const PointerType& source, const SchemaType** schema, const ValueType& v, const ValueType& document) {
- static const Ch kRefString[] = { '$', 'r', 'e', 'f', '\0' };
- static const ValueType kRefValue(kRefString, 4);
-
- typename ValueType::ConstMemberIterator itr = v.FindMember(kRefValue);
- if (itr == v.MemberEnd())
- return false;
-
- if (itr->value.IsString()) {
- SizeType len = itr->value.GetStringLength();
- if (len > 0) {
- const Ch* s = itr->value.GetString();
- SizeType i = 0;
- while (i < len && s[i] != '#') // Find the first #
- i++;
-
- if (i > 0) { // Remote reference, resolve immediately
- if (remoteProvider_) {
- if (const GenericSchemaDocument* remoteDocument = remoteProvider_->GetRemoteDocument(s, i)) {
- PointerType pointer(&s[i], len - i, allocator_);
- if (pointer.IsValid()) {
- if (const SchemaType* sc = remoteDocument->GetSchema(pointer)) {
- if (schema)
- *schema = sc;
- return true;
- }
- }
- }
- }
- }
- else if (s[i] == '#') { // Local reference, defer resolution
- PointerType pointer(&s[i], len - i, allocator_);
- if (pointer.IsValid()) {
- if (const ValueType* nv = pointer.Get(document))
- if (HandleRefSchema(source, schema, *nv, document))
- return true;
-
- new (schemaRef_.template Push<SchemaRefEntry>()) SchemaRefEntry(source, pointer, schema, allocator_);
- return true;
- }
- }
- }
- }
- return false;
- }
-
- const SchemaType* GetSchema(const PointerType& pointer) const {
- for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
- if (pointer == target->pointer)
- return target->schema;
- return 0;
- }
-
- PointerType GetPointer(const SchemaType* schema) const {
- for (const SchemaEntry* target = schemaMap_.template Bottom<SchemaEntry>(); target != schemaMap_.template End<SchemaEntry>(); ++target)
- if (schema == target->schema)
- return target->pointer;
- return PointerType();
- }
-
- const SchemaType* GetTypeless() const { return typeless_; }
-
- static const size_t kInitialSchemaMapSize = 64;
- static const size_t kInitialSchemaRefSize = 64;
-
- IRemoteSchemaDocumentProviderType* remoteProvider_;
- Allocator *allocator_;
- Allocator *ownAllocator_;
- const SchemaType* root_; //!< Root schema.
- SchemaType* typeless_;
- internal::Stack<Allocator> schemaMap_; // Stores created Pointer -> Schemas
- internal::Stack<Allocator> schemaRef_; // Stores Pointer from $ref and schema which holds the $ref
-};
-
-//! GenericSchemaDocument using Value type.
-typedef GenericSchemaDocument<Value> SchemaDocument;
-//! IGenericRemoteSchemaDocumentProvider using SchemaDocument.
-typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;
-
-///////////////////////////////////////////////////////////////////////////////
-// GenericSchemaValidator
-
-//! JSON Schema Validator.
-/*!
- A SAX style JSON schema validator.
- It uses a \c GenericSchemaDocument to validate SAX events.
- It delegates the incoming SAX events to an output handler.
- The default output handler does nothing.
- It can be reused multiple times by calling \c Reset().
-
- \tparam SchemaDocumentType Type of schema document.
- \tparam OutputHandler Type of output handler. Default handler does nothing.
- \tparam StateAllocator Allocator for storing the internal validation states.
-*/
-template <
- typename SchemaDocumentType,
- typename OutputHandler = BaseReaderHandler<typename SchemaDocumentType::SchemaType::EncodingType>,
- typename StateAllocator = CrtAllocator>
-class GenericSchemaValidator :
- public internal::ISchemaStateFactory<typename SchemaDocumentType::SchemaType>,
- public internal::ISchemaValidator
-{
-public:
- typedef typename SchemaDocumentType::SchemaType SchemaType;
- typedef typename SchemaDocumentType::PointerType PointerType;
- typedef typename SchemaType::EncodingType EncodingType;
- typedef typename EncodingType::Ch Ch;
-
- //! Constructor without output handler.
- /*!
- \param schemaDocument The schema document to conform to.
- \param allocator Optional allocator for storing internal validation states.
- \param schemaStackCapacity Optional initial capacity of schema path stack.
- \param documentStackCapacity Optional initial capacity of document path stack.
- */
- GenericSchemaValidator(
- const SchemaDocumentType& schemaDocument,
- StateAllocator* allocator = 0,
- size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
- size_t documentStackCapacity = kDefaultDocumentStackCapacity)
- :
- schemaDocument_(&schemaDocument),
- root_(schemaDocument.GetRoot()),
- stateAllocator_(allocator),
- ownStateAllocator_(0),
- schemaStack_(allocator, schemaStackCapacity),
- documentStack_(allocator, documentStackCapacity),
- outputHandler_(0),
- valid_(true)
-#if RAPIDJSON_SCHEMA_VERBOSE
- , depth_(0)
-#endif
- {
- }
-
- //! Constructor with output handler.
- /*!
- \param schemaDocument The schema document to conform to.
- \param allocator Optional allocator for storing internal validation states.
- \param schemaStackCapacity Optional initial capacity of schema path stack.
- \param documentStackCapacity Optional initial capacity of document path stack.
- */
- GenericSchemaValidator(
- const SchemaDocumentType& schemaDocument,
- OutputHandler& outputHandler,
- StateAllocator* allocator = 0,
- size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
- size_t documentStackCapacity = kDefaultDocumentStackCapacity)
- :
- schemaDocument_(&schemaDocument),
- root_(schemaDocument.GetRoot()),
- stateAllocator_(allocator),
- ownStateAllocator_(0),
- schemaStack_(allocator, schemaStackCapacity),
- documentStack_(allocator, documentStackCapacity),
- outputHandler_(&outputHandler),
- valid_(true)
-#if RAPIDJSON_SCHEMA_VERBOSE
- , depth_(0)
-#endif
- {
- }
-
- //! Destructor.
- ~GenericSchemaValidator() {
- Reset();
- RAPIDJSON_DELETE(ownStateAllocator_);
- }
-
- //! Reset the internal states.
- void Reset() {
- while (!schemaStack_.Empty())
- PopSchema();
- documentStack_.Clear();
- valid_ = true;
- }
-
- //! Checks whether the current state is valid.
- // Implementation of ISchemaValidator
- virtual bool IsValid() const { return valid_; }
-
- //! Gets the JSON pointer pointed to the invalid schema.
- PointerType GetInvalidSchemaPointer() const {
- return schemaStack_.Empty() ? PointerType() : schemaDocument_->GetPointer(&CurrentSchema());
- }
-
- //! Gets the keyword of invalid schema.
- const Ch* GetInvalidSchemaKeyword() const {
- return schemaStack_.Empty() ? 0 : CurrentContext().invalidKeyword;
- }
-
- //! Gets the JSON pointer pointed to the invalid value.
- PointerType GetInvalidDocumentPointer() const {
- return documentStack_.Empty() ? PointerType() : PointerType(documentStack_.template Bottom<Ch>(), documentStack_.GetSize() / sizeof(Ch));
- }
-
-#if RAPIDJSON_SCHEMA_VERBOSE
-#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_() \
-RAPIDJSON_MULTILINEMACRO_BEGIN\
- *documentStack_.template Push<Ch>() = '\0';\
- documentStack_.template Pop<Ch>(1);\
- internal::PrintInvalidDocument(documentStack_.template Bottom<Ch>());\
-RAPIDJSON_MULTILINEMACRO_END
-#else
-#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_()
-#endif
-
-#define RAPIDJSON_SCHEMA_HANDLE_BEGIN_(method, arg1)\
- if (!valid_) return false; \
- if (!BeginValue() || !CurrentSchema().method arg1) {\
- RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_();\
- return valid_ = false;\
- }
-
-#define RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2)\
- for (Context* context = schemaStack_.template Bottom<Context>(); context != schemaStack_.template End<Context>(); context++) {\
- if (context->hasher)\
- static_cast<HasherType*>(context->hasher)->method arg2;\
- if (context->validators)\
- for (SizeType i_ = 0; i_ < context->validatorCount; i_++)\
- static_cast<GenericSchemaValidator*>(context->validators[i_])->method arg2;\
- if (context->patternPropertiesValidators)\
- for (SizeType i_ = 0; i_ < context->patternPropertiesValidatorCount; i_++)\
- static_cast<GenericSchemaValidator*>(context->patternPropertiesValidators[i_])->method arg2;\
- }
-
-#define RAPIDJSON_SCHEMA_HANDLE_END_(method, arg2)\
- return valid_ = EndValue() && (!outputHandler_ || outputHandler_->method arg2)
-
-#define RAPIDJSON_SCHEMA_HANDLE_VALUE_(method, arg1, arg2) \
- RAPIDJSON_SCHEMA_HANDLE_BEGIN_ (method, arg1);\
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(method, arg2);\
- RAPIDJSON_SCHEMA_HANDLE_END_ (method, arg2)
-
- bool Null() { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Null, (CurrentContext() ), ( )); }
- bool Bool(bool b) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Bool, (CurrentContext(), b), (b)); }
- bool Int(int i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int, (CurrentContext(), i), (i)); }
- bool Uint(unsigned u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint, (CurrentContext(), u), (u)); }
- bool Int64(int64_t i) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Int64, (CurrentContext(), i), (i)); }
- bool Uint64(uint64_t u) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Uint64, (CurrentContext(), u), (u)); }
- bool Double(double d) { RAPIDJSON_SCHEMA_HANDLE_VALUE_(Double, (CurrentContext(), d), (d)); }
- bool RawNumber(const Ch* str, SizeType length, bool copy)
- { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
- bool String(const Ch* str, SizeType length, bool copy)
- { RAPIDJSON_SCHEMA_HANDLE_VALUE_(String, (CurrentContext(), str, length, copy), (str, length, copy)); }
-
- bool StartObject() {
- RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartObject, (CurrentContext()));
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartObject, ());
- return valid_ = !outputHandler_ || outputHandler_->StartObject();
- }
-
- bool Key(const Ch* str, SizeType len, bool copy) {
- if (!valid_) return false;
- AppendToken(str, len);
- if (!CurrentSchema().Key(CurrentContext(), str, len, copy)) return valid_ = false;
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(Key, (str, len, copy));
- return valid_ = !outputHandler_ || outputHandler_->Key(str, len, copy);
- }
-
- bool EndObject(SizeType memberCount) {
- if (!valid_) return false;
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndObject, (memberCount));
- if (!CurrentSchema().EndObject(CurrentContext(), memberCount)) return valid_ = false;
- RAPIDJSON_SCHEMA_HANDLE_END_(EndObject, (memberCount));
- }
-
- bool StartArray() {
- RAPIDJSON_SCHEMA_HANDLE_BEGIN_(StartArray, (CurrentContext()));
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(StartArray, ());
- return valid_ = !outputHandler_ || outputHandler_->StartArray();
- }
-
- bool EndArray(SizeType elementCount) {
- if (!valid_) return false;
- RAPIDJSON_SCHEMA_HANDLE_PARALLEL_(EndArray, (elementCount));
- if (!CurrentSchema().EndArray(CurrentContext(), elementCount)) return valid_ = false;
- RAPIDJSON_SCHEMA_HANDLE_END_(EndArray, (elementCount));
- }
-
-#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_VERBOSE_
-#undef RAPIDJSON_SCHEMA_HANDLE_BEGIN_
-#undef RAPIDJSON_SCHEMA_HANDLE_PARALLEL_
-#undef RAPIDJSON_SCHEMA_HANDLE_VALUE_
-
- // Implementation of ISchemaStateFactory<SchemaType>
- virtual ISchemaValidator* CreateSchemaValidator(const SchemaType& root) {
- return new (GetStateAllocator().Malloc(sizeof(GenericSchemaValidator))) GenericSchemaValidator(*schemaDocument_, root,
-#if RAPIDJSON_SCHEMA_VERBOSE
- depth_ + 1,
-#endif
- &GetStateAllocator());
- }
-
- virtual void DestroySchemaValidator(ISchemaValidator* validator) {
- GenericSchemaValidator* v = static_cast<GenericSchemaValidator*>(validator);
- v->~GenericSchemaValidator();
- StateAllocator::Free(v);
- }
-
- virtual void* CreateHasher() {
- return new (GetStateAllocator().Malloc(sizeof(HasherType))) HasherType(&GetStateAllocator());
- }
-
- virtual uint64_t GetHashCode(void* hasher) {
- return static_cast<HasherType*>(hasher)->GetHashCode();
- }
-
- virtual void DestroryHasher(void* hasher) {
- HasherType* h = static_cast<HasherType*>(hasher);
- h->~HasherType();
- StateAllocator::Free(h);
- }
-
- virtual void* MallocState(size_t size) {
- return GetStateAllocator().Malloc(size);
- }
-
- virtual void FreeState(void* p) {
- StateAllocator::Free(p);
- }
-
-private:
- typedef typename SchemaType::Context Context;
- typedef GenericValue<UTF8<>, StateAllocator> HashCodeArray;
- typedef internal::Hasher<EncodingType, StateAllocator> HasherType;
-
- GenericSchemaValidator(
- const SchemaDocumentType& schemaDocument,
- const SchemaType& root,
-#if RAPIDJSON_SCHEMA_VERBOSE
- unsigned depth,
-#endif
- StateAllocator* allocator = 0,
- size_t schemaStackCapacity = kDefaultSchemaStackCapacity,
- size_t documentStackCapacity = kDefaultDocumentStackCapacity)
- :
- schemaDocument_(&schemaDocument),
- root_(root),
- stateAllocator_(allocator),
- ownStateAllocator_(0),
- schemaStack_(allocator, schemaStackCapacity),
- documentStack_(allocator, documentStackCapacity),
- outputHandler_(0),
- valid_(true)
-#if RAPIDJSON_SCHEMA_VERBOSE
- , depth_(depth)
-#endif
- {
- }
-
- StateAllocator& GetStateAllocator() {
- if (!stateAllocator_)
- stateAllocator_ = ownStateAllocator_ = RAPIDJSON_NEW(StateAllocator)();
- return *stateAllocator_;
- }
-
- bool BeginValue() {
- if (schemaStack_.Empty())
- PushSchema(root_);
- else {
- if (CurrentContext().inArray)
- internal::TokenHelper<internal::Stack<StateAllocator>, Ch>::AppendIndexToken(documentStack_, CurrentContext().arrayElementIndex);
-
- if (!CurrentSchema().BeginValue(CurrentContext()))
- return false;
-
- SizeType count = CurrentContext().patternPropertiesSchemaCount;
- const SchemaType** sa = CurrentContext().patternPropertiesSchemas;
- typename Context::PatternValidatorType patternValidatorType = CurrentContext().valuePatternValidatorType;
- bool valueUniqueness = CurrentContext().valueUniqueness;
- RAPIDJSON_ASSERT(CurrentContext().valueSchema);
- PushSchema(*CurrentContext().valueSchema);
-
- if (count > 0) {
- CurrentContext().objectPatternValidatorType = patternValidatorType;
- ISchemaValidator**& va = CurrentContext().patternPropertiesValidators;
- SizeType& validatorCount = CurrentContext().patternPropertiesValidatorCount;
- va = static_cast<ISchemaValidator**>(MallocState(sizeof(ISchemaValidator*) * count));
- for (SizeType i = 0; i < count; i++)
- va[validatorCount++] = CreateSchemaValidator(*sa[i]);
- }
-
- CurrentContext().arrayUniqueness = valueUniqueness;
- }
- return true;
- }
-
- bool EndValue() {
- if (!CurrentSchema().EndValue(CurrentContext()))
- return false;
-
-#if RAPIDJSON_SCHEMA_VERBOSE
- GenericStringBuffer<EncodingType> sb;
- schemaDocument_->GetPointer(&CurrentSchema()).Stringify(sb);
-
- *documentStack_.template Push<Ch>() = '\0';
- documentStack_.template Pop<Ch>(1);
- internal::PrintValidatorPointers(depth_, sb.GetString(), documentStack_.template Bottom<Ch>());
-#endif
-
- uint64_t h = CurrentContext().arrayUniqueness ? static_cast<HasherType*>(CurrentContext().hasher)->GetHashCode() : 0;
-
- PopSchema();
-
- if (!schemaStack_.Empty()) {
- Context& context = CurrentContext();
- if (context.valueUniqueness) {
- HashCodeArray* a = static_cast<HashCodeArray*>(context.arrayElementHashCodes);
- if (!a)
- CurrentContext().arrayElementHashCodes = a = new (GetStateAllocator().Malloc(sizeof(HashCodeArray))) HashCodeArray(kArrayType);
- for (typename HashCodeArray::ConstValueIterator itr = a->Begin(); itr != a->End(); ++itr)
- if (itr->GetUint64() == h)
- RAPIDJSON_INVALID_KEYWORD_RETURN(SchemaType::GetUniqueItemsString());
- a->PushBack(h, GetStateAllocator());
- }
- }
-
- // Remove the last token of document pointer
- while (!documentStack_.Empty() && *documentStack_.template Pop<Ch>(1) != '/')
- ;
-
- return true;
- }
-
- void AppendToken(const Ch* str, SizeType len) {
- documentStack_.template Reserve<Ch>(1 + len * 2); // worst case all characters are escaped as two characters
- *documentStack_.template PushUnsafe<Ch>() = '/';
- for (SizeType i = 0; i < len; i++) {
- if (str[i] == '~') {
- *documentStack_.template PushUnsafe<Ch>() = '~';
- *documentStack_.template PushUnsafe<Ch>() = '0';
- }
- else if (str[i] == '/') {
- *documentStack_.template PushUnsafe<Ch>() = '~';
- *documentStack_.template PushUnsafe<Ch>() = '1';
- }
- else
- *documentStack_.template PushUnsafe<Ch>() = str[i];
- }
- }
-
- RAPIDJSON_FORCEINLINE void PushSchema(const SchemaType& schema) { new (schemaStack_.template Push<Context>()) Context(*this, &schema); }
-
- RAPIDJSON_FORCEINLINE void PopSchema() {
- Context* c = schemaStack_.template Pop<Context>(1);
- if (HashCodeArray* a = static_cast<HashCodeArray*>(c->arrayElementHashCodes)) {
- a->~HashCodeArray();
- StateAllocator::Free(a);
- }
- c->~Context();
- }
-
- const SchemaType& CurrentSchema() const { return *schemaStack_.template Top<Context>()->schema; }
- Context& CurrentContext() { return *schemaStack_.template Top<Context>(); }
- const Context& CurrentContext() const { return *schemaStack_.template Top<Context>(); }
-
- static const size_t kDefaultSchemaStackCapacity = 1024;
- static const size_t kDefaultDocumentStackCapacity = 256;
- const SchemaDocumentType* schemaDocument_;
- const SchemaType& root_;
- StateAllocator* stateAllocator_;
- StateAllocator* ownStateAllocator_;
- internal::Stack<StateAllocator> schemaStack_; //!< stack to store the current path of schema (BaseSchemaType *)
- internal::Stack<StateAllocator> documentStack_; //!< stack to store the current path of validating document (Ch)
- OutputHandler* outputHandler_;
- bool valid_;
-#if RAPIDJSON_SCHEMA_VERBOSE
- unsigned depth_;
-#endif
-};
-
-typedef GenericSchemaValidator<SchemaDocument> SchemaValidator;
-
-///////////////////////////////////////////////////////////////////////////////
-// SchemaValidatingReader
-
-//! A helper class for parsing with validation.
-/*!
- This helper class is a functor, designed as a parameter of \ref GenericDocument::Populate().
-
- \tparam parseFlags Combination of \ref ParseFlag.
- \tparam InputStream Type of input stream, implementing Stream concept.
- \tparam SourceEncoding Encoding of the input stream.
- \tparam SchemaDocumentType Type of schema document.
- \tparam StackAllocator Allocator type for stack.
-*/
-template <
- unsigned parseFlags,
- typename InputStream,
- typename SourceEncoding,
- typename SchemaDocumentType = SchemaDocument,
- typename StackAllocator = CrtAllocator>
-class SchemaValidatingReader {
-public:
- typedef typename SchemaDocumentType::PointerType PointerType;
- typedef typename InputStream::Ch Ch;
-
- //! Constructor
- /*!
- \param is Input stream.
- \param sd Schema document.
- */
- SchemaValidatingReader(InputStream& is, const SchemaDocumentType& sd) : is_(is), sd_(sd), invalidSchemaKeyword_(), isValid_(true) {}
-
- template <typename Handler>
- bool operator()(Handler& handler) {
- GenericReader<SourceEncoding, typename SchemaDocumentType::EncodingType, StackAllocator> reader;
- GenericSchemaValidator<SchemaDocumentType, Handler> validator(sd_, handler);
- parseResult_ = reader.template Parse<parseFlags>(is_, validator);
-
- isValid_ = validator.IsValid();
- if (isValid_) {
- invalidSchemaPointer_ = PointerType();
- invalidSchemaKeyword_ = 0;
- invalidDocumentPointer_ = PointerType();
- }
- else {
- invalidSchemaPointer_ = validator.GetInvalidSchemaPointer();
- invalidSchemaKeyword_ = validator.GetInvalidSchemaKeyword();
- invalidDocumentPointer_ = validator.GetInvalidDocumentPointer();
- }
-
- return parseResult_;
- }
-
- const ParseResult& GetParseResult() const { return parseResult_; }
- bool IsValid() const { return isValid_; }
- const PointerType& GetInvalidSchemaPointer() const { return invalidSchemaPointer_; }
- const Ch* GetInvalidSchemaKeyword() const { return invalidSchemaKeyword_; }
- const PointerType& GetInvalidDocumentPointer() const { return invalidDocumentPointer_; }
-
-private:
- InputStream& is_;
- const SchemaDocumentType& sd_;
-
- ParseResult parseResult_;
- PointerType invalidSchemaPointer_;
- const Ch* invalidSchemaKeyword_;
- PointerType invalidDocumentPointer_;
- bool isValid_;
-};
-
-RAPIDJSON_NAMESPACE_END
-RAPIDJSON_DIAG_POP
-
-#endif // RAPIDJSON_SCHEMA_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stream.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stream.h
deleted file mode 100644
index fef82c252..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stream.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#include "rapidjson.h"
-
-#ifndef RAPIDJSON_STREAM_H_
-#define RAPIDJSON_STREAM_H_
-
-#include "encodings.h"
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// Stream
-
-/*! \class rapidjson::Stream
- \brief Concept for reading and writing characters.
-
- For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
-
- For write-only stream, only need to implement Put() and Flush().
-
-\code
-concept Stream {
- typename Ch; //!< Character type of the stream.
-
- //! Read the current character from stream without moving the read cursor.
- Ch Peek() const;
-
- //! Read the current character from stream and moving the read cursor to next character.
- Ch Take();
-
- //! Get the current read cursor.
- //! \return Number of characters read from start.
- size_t Tell();
-
- //! Begin writing operation at the current read pointer.
- //! \return The begin writer pointer.
- Ch* PutBegin();
-
- //! Write a character.
- void Put(Ch c);
-
- //! Flush the buffer.
- void Flush();
-
- //! End the writing operation.
- //! \param begin The begin write pointer returned by PutBegin().
- //! \return Number of characters written.
- size_t PutEnd(Ch* begin);
-}
-\endcode
-*/
-
-//! Provides additional information for stream.
-/*!
- By using traits pattern, this type provides a default configuration for stream.
- For custom stream, this type can be specialized for other configuration.
- See TEST(Reader, CustomStringStream) in readertest.cpp for example.
-*/
-template<typename Stream>
-struct StreamTraits {
- //! Whether to make local copy of stream for optimization during parsing.
- /*!
- By default, for safety, streams do not use local copy optimization.
- Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
- */
- enum { copyOptimization = 0 };
-};
-
-//! Reserve n characters for writing to a stream.
-template<typename Stream>
-inline void PutReserve(Stream& stream, size_t count) {
- (void)stream;
- (void)count;
-}
-
-//! Write character to a stream, presuming buffer is reserved.
-template<typename Stream>
-inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
- stream.Put(c);
-}
-
-//! Put N copies of a character to a stream.
-template<typename Stream, typename Ch>
-inline void PutN(Stream& stream, Ch c, size_t n) {
- PutReserve(stream, n);
- for (size_t i = 0; i < n; i++)
- PutUnsafe(stream, c);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// StringStream
-
-//! Read-only string stream.
-/*! \note implements Stream concept
-*/
-template <typename Encoding>
-struct GenericStringStream {
- typedef typename Encoding::Ch Ch;
-
- GenericStringStream(const Ch *src) : src_(src), head_(src) {}
-
- Ch Peek() const { return *src_; }
- Ch Take() { return *src_++; }
- size_t Tell() const { return static_cast<size_t>(src_ - head_); }
-
- Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
- void Put(Ch) { RAPIDJSON_ASSERT(false); }
- void Flush() { RAPIDJSON_ASSERT(false); }
- size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
-
- const Ch* src_; //!< Current read position.
- const Ch* head_; //!< Original head of the string.
-};
-
-template <typename Encoding>
-struct StreamTraits<GenericStringStream<Encoding> > {
- enum { copyOptimization = 1 };
-};
-
-//! String stream with UTF8 encoding.
-typedef GenericStringStream<UTF8<> > StringStream;
-
-///////////////////////////////////////////////////////////////////////////////
-// InsituStringStream
-
-//! A read-write string stream.
-/*! This string stream is particularly designed for in-situ parsing.
- \note implements Stream concept
-*/
-template <typename Encoding>
-struct GenericInsituStringStream {
- typedef typename Encoding::Ch Ch;
-
- GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
-
- // Read
- Ch Peek() { return *src_; }
- Ch Take() { return *src_++; }
- size_t Tell() { return static_cast<size_t>(src_ - head_); }
-
- // Write
- void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
-
- Ch* PutBegin() { return dst_ = src_; }
- size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
- void Flush() {}
-
- Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
- void Pop(size_t count) { dst_ -= count; }
-
- Ch* src_;
- Ch* dst_;
- Ch* head_;
-};
-
-template <typename Encoding>
-struct StreamTraits<GenericInsituStringStream<Encoding> > {
- enum { copyOptimization = 1 };
-};
-
-//! Insitu string stream with UTF8 encoding.
-typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
-
-RAPIDJSON_NAMESPACE_END
-
-#endif // RAPIDJSON_STREAM_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stringbuffer.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stringbuffer.h
deleted file mode 100644
index 4e38b82c3..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/stringbuffer.h
+++ /dev/null
@@ -1,121 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_STRINGBUFFER_H_
-#define RAPIDJSON_STRINGBUFFER_H_
-
-#include "stream.h"
-#include "internal/stack.h"
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
-#include <utility> // std::move
-#endif
-
-#include "internal/stack.h"
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-//! Represents an in-memory output stream.
-/*!
- \tparam Encoding Encoding of the stream.
- \tparam Allocator type for allocating memory buffer.
- \note implements Stream concept
-*/
-template <typename Encoding, typename Allocator = CrtAllocator>
-class GenericStringBuffer {
-public:
- typedef typename Encoding::Ch Ch;
-
- GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
- GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
- if (&rhs != this)
- stack_ = std::move(rhs.stack_);
- return *this;
- }
-#endif
-
- void Put(Ch c) { *stack_.template Push<Ch>() = c; }
- void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
- void Flush() {}
-
- void Clear() { stack_.Clear(); }
- void ShrinkToFit() {
- // Push and pop a null terminator. This is safe.
- *stack_.template Push<Ch>() = '\0';
- stack_.ShrinkToFit();
- stack_.template Pop<Ch>(1);
- }
-
- void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
- Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
- Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }
- void Pop(size_t count) { stack_.template Pop<Ch>(count); }
-
- const Ch* GetString() const {
- // Push and pop a null terminator. This is safe.
- *stack_.template Push<Ch>() = '\0';
- stack_.template Pop<Ch>(1);
-
- return stack_.template Bottom<Ch>();
- }
-
- //! Get the size of string in bytes in the string buffer.
- size_t GetSize() const { return stack_.GetSize(); }
-
- //! Get the length of string in Ch in the string buffer.
- size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }
-
- static const size_t kDefaultCapacity = 256;
- mutable internal::Stack<Allocator> stack_;
-
-private:
- // Prohibit copy constructor & assignment operator.
- GenericStringBuffer(const GenericStringBuffer&);
- GenericStringBuffer& operator=(const GenericStringBuffer&);
-};
-
-//! String buffer with UTF8 encoding
-typedef GenericStringBuffer<UTF8<> > StringBuffer;
-
-template<typename Encoding, typename Allocator>
-inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
- stream.Reserve(count);
-}
-
-template<typename Encoding, typename Allocator>
-inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
- stream.PutUnsafe(c);
-}
-
-//! Implement specialized version of PutN() with memset() for better performance.
-template<>
-inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
- std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
-}
-
-RAPIDJSON_NAMESPACE_END
-
-#if defined(__clang__)
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_STRINGBUFFER_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/writer.h b/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/writer.h
deleted file mode 100644
index e610ebb60..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/include/rapidjson/writer.h
+++ /dev/null
@@ -1,711 +0,0 @@
-// Tencent is pleased to support the open source community by making RapidJSON available.
-//
-// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-//
-// Licensed under the MIT License (the "License"); you may not use this file except
-// in compliance with the License. You may obtain a copy of the License at
-//
-// http://opensource.org/licenses/MIT
-//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations under the License.
-
-#ifndef RAPIDJSON_WRITER_H_
-#define RAPIDJSON_WRITER_H_
-
-#include "stream.h"
-#include "internal/meta.h"
-#include "internal/stack.h"
-#include "internal/strfunc.h"
-#include "internal/dtoa.h"
-#include "internal/itoa.h"
-#include "stringbuffer.h"
-#include <new> // placement new
-
-#if defined(RAPIDJSON_SIMD) && defined(_MSC_VER)
-#include <intrin.h>
-#pragma intrinsic(_BitScanForward)
-#endif
-#ifdef RAPIDJSON_SSE42
-#include <nmmintrin.h>
-#elif defined(RAPIDJSON_SSE2)
-#include <emmintrin.h>
-#elif defined(RAPIDJSON_NEON)
-#include <arm_neon.h>
-#endif
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_PUSH
-RAPIDJSON_DIAG_OFF(padded)
-RAPIDJSON_DIAG_OFF(unreachable-code)
-RAPIDJSON_DIAG_OFF(c++98-compat)
-#endif
-
-RAPIDJSON_NAMESPACE_BEGIN
-
-///////////////////////////////////////////////////////////////////////////////
-// WriteFlag
-
-/*! \def RAPIDJSON_WRITE_DEFAULT_FLAGS
- \ingroup RAPIDJSON_CONFIG
- \brief User-defined kWriteDefaultFlags definition.
-
- User can define this as any \c WriteFlag combinations.
-*/
-#ifndef RAPIDJSON_WRITE_DEFAULT_FLAGS
-#define RAPIDJSON_WRITE_DEFAULT_FLAGS kWriteNoFlags
-#endif
-
-//! Combination of writeFlags
-enum WriteFlag {
- kWriteNoFlags = 0, //!< No flags are set.
- kWriteValidateEncodingFlag = 1, //!< Validate encoding of JSON strings.
- kWriteNanAndInfFlag = 2, //!< Allow writing of Infinity, -Infinity and NaN.
- kWriteDefaultFlags = RAPIDJSON_WRITE_DEFAULT_FLAGS //!< Default write flags. Can be customized by defining RAPIDJSON_WRITE_DEFAULT_FLAGS
-};
-
-//! JSON writer
-/*! Writer implements the concept Handler.
- It generates JSON text by events to an output os.
-
- User may programmatically calls the functions of a writer to generate JSON text.
-
- On the other side, a writer can also be passed to objects that generates events,
-
- for example Reader::Parse() and Document::Accept().
-
- \tparam OutputStream Type of output stream.
- \tparam SourceEncoding Encoding of source string.
- \tparam TargetEncoding Encoding of output stream.
- \tparam StackAllocator Type of allocator for allocating memory of stack.
- \note implements Handler concept
-*/
-template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator, unsigned writeFlags = kWriteDefaultFlags>
-class Writer {
-public:
- typedef typename SourceEncoding::Ch Ch;
-
- static const int kDefaultMaxDecimalPlaces = 324;
-
- //! Constructor
- /*! \param os Output stream.
- \param stackAllocator User supplied allocator. If it is null, it will create a private one.
- \param levelDepth Initial capacity of stack.
- */
- explicit
- Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
- os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
-
- explicit
- Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) :
- os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), maxDecimalPlaces_(kDefaultMaxDecimalPlaces), hasRoot_(false) {}
-
-#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
- Writer(Writer&& rhs) :
- os_(rhs.os_), level_stack_(std::move(rhs.level_stack_)), maxDecimalPlaces_(rhs.maxDecimalPlaces_), hasRoot_(rhs.hasRoot_) {
- rhs.os_ = 0;
- }
-#endif
-
- //! Reset the writer with a new stream.
- /*!
- This function reset the writer with a new stream and default settings,
- in order to make a Writer object reusable for output multiple JSONs.
-
- \param os New output stream.
- \code
- Writer<OutputStream> writer(os1);
- writer.StartObject();
- // ...
- writer.EndObject();
-
- writer.Reset(os2);
- writer.StartObject();
- // ...
- writer.EndObject();
- \endcode
- */
- void Reset(OutputStream& os) {
- os_ = &os;
- hasRoot_ = false;
- level_stack_.Clear();
- }
-
- //! Checks whether the output is a complete JSON.
- /*!
- A complete JSON has a complete root object or array.
- */
- bool IsComplete() const {
- return hasRoot_ && level_stack_.Empty();
- }
-
- int GetMaxDecimalPlaces() const {
- return maxDecimalPlaces_;
- }
-
- //! Sets the maximum number of decimal places for double output.
- /*!
- This setting truncates the output with specified number of decimal places.
-
- For example,
-
- \code
- writer.SetMaxDecimalPlaces(3);
- writer.StartArray();
- writer.Double(0.12345); // "0.123"
- writer.Double(0.0001); // "0.0"
- writer.Double(1.234567890123456e30); // "1.234567890123456e30" (do not truncate significand for positive exponent)
- writer.Double(1.23e-4); // "0.0" (do truncate significand for negative exponent)
- writer.EndArray();
- \endcode
-
- The default setting does not truncate any decimal places. You can restore to this setting by calling
- \code
- writer.SetMaxDecimalPlaces(Writer::kDefaultMaxDecimalPlaces);
- \endcode
- */
- void SetMaxDecimalPlaces(int maxDecimalPlaces) {
- maxDecimalPlaces_ = maxDecimalPlaces;
- }
-
- /*!@name Implementation of Handler
- \see Handler
- */
- //@{
-
- bool Null() { Prefix(kNullType); return EndValue(WriteNull()); }
- bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return EndValue(WriteBool(b)); }
- bool Int(int i) { Prefix(kNumberType); return EndValue(WriteInt(i)); }
- bool Uint(unsigned u) { Prefix(kNumberType); return EndValue(WriteUint(u)); }
- bool Int64(int64_t i64) { Prefix(kNumberType); return EndValue(WriteInt64(i64)); }
- bool Uint64(uint64_t u64) { Prefix(kNumberType); return EndValue(WriteUint64(u64)); }
-
- //! Writes the given \c double value to the stream
- /*!
- \param d The value to be written.
- \return Whether it is succeed.
- */
- bool Double(double d) { Prefix(kNumberType); return EndValue(WriteDouble(d)); }
-
- bool RawNumber(const Ch* str, SizeType length, bool copy = false) {
- RAPIDJSON_ASSERT(str != 0);
- (void)copy;
- Prefix(kNumberType);
- return EndValue(WriteString(str, length));
- }
-
- bool String(const Ch* str, SizeType length, bool copy = false) {
- RAPIDJSON_ASSERT(str != 0);
- (void)copy;
- Prefix(kStringType);
- return EndValue(WriteString(str, length));
- }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool String(const std::basic_string<Ch>& str) {
- return String(str.data(), SizeType(str.size()));
- }
-#endif
-
- bool StartObject() {
- Prefix(kObjectType);
- new (level_stack_.template Push<Level>()) Level(false);
- return WriteStartObject();
- }
-
- bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
-
-#if RAPIDJSON_HAS_STDSTRING
- bool Key(const std::basic_string<Ch>& str)
- {
- return Key(str.data(), SizeType(str.size()));
- }
-#endif
-
- bool EndObject(SizeType memberCount = 0) {
- (void)memberCount;
- RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); // not inside an Object
- RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); // currently inside an Array, not Object
- RAPIDJSON_ASSERT(0 == level_stack_.template Top<Level>()->valueCount % 2); // Object has a Key without a Value
- level_stack_.template Pop<Level>(1);
- return EndValue(WriteEndObject());
- }
-
- bool StartArray() {
- Prefix(kArrayType);
- new (level_stack_.template Push<Level>()) Level(true);
- return WriteStartArray();
- }
-
- bool EndArray(SizeType elementCount = 0) {
- (void)elementCount;
- RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
- RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray);
- level_stack_.template Pop<Level>(1);
- return EndValue(WriteEndArray());
- }
- //@}
-
- /*! @name Convenience extensions */
- //@{
-
- //! Simpler but slower overload.
- bool String(const Ch* const& str) { return String(str, internal::StrLen(str)); }
- bool Key(const Ch* const& str) { return Key(str, internal::StrLen(str)); }
-
- //@}
-
- //! Write a raw JSON value.
- /*!
- For user to write a stringified JSON as a value.
-
- \param json A well-formed JSON value. It should not contain null character within [0, length - 1] range.
- \param length Length of the json.
- \param type Type of the root of json.
- */
- bool RawValue(const Ch* json, size_t length, Type type) {
- RAPIDJSON_ASSERT(json != 0);
- Prefix(type);
- return EndValue(WriteRawValue(json, length));
- }
-
- //! Flush the output stream.
- /*!
- Allows the user to flush the output stream immediately.
- */
- void Flush() {
- os_->Flush();
- }
-
-protected:
- //! Information for each nested level
- struct Level {
- Level(bool inArray_) : valueCount(0), inArray(inArray_) {}
- size_t valueCount; //!< number of values in this level
- bool inArray; //!< true if in array, otherwise in object
- };
-
- static const size_t kDefaultLevelDepth = 32;
-
- bool WriteNull() {
- PutReserve(*os_, 4);
- PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 'l'); return true;
- }
-
- bool WriteBool(bool b) {
- if (b) {
- PutReserve(*os_, 4);
- PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'r'); PutUnsafe(*os_, 'u'); PutUnsafe(*os_, 'e');
- }
- else {
- PutReserve(*os_, 5);
- PutUnsafe(*os_, 'f'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'l'); PutUnsafe(*os_, 's'); PutUnsafe(*os_, 'e');
- }
- return true;
- }
-
- bool WriteInt(int i) {
- char buffer[11];
- const char* end = internal::i32toa(i, buffer);
- PutReserve(*os_, static_cast<size_t>(end - buffer));
- for (const char* p = buffer; p != end; ++p)
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
- return true;
- }
-
- bool WriteUint(unsigned u) {
- char buffer[10];
- const char* end = internal::u32toa(u, buffer);
- PutReserve(*os_, static_cast<size_t>(end - buffer));
- for (const char* p = buffer; p != end; ++p)
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
- return true;
- }
-
- bool WriteInt64(int64_t i64) {
- char buffer[21];
- const char* end = internal::i64toa(i64, buffer);
- PutReserve(*os_, static_cast<size_t>(end - buffer));
- for (const char* p = buffer; p != end; ++p)
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
- return true;
- }
-
- bool WriteUint64(uint64_t u64) {
- char buffer[20];
- char* end = internal::u64toa(u64, buffer);
- PutReserve(*os_, static_cast<size_t>(end - buffer));
- for (char* p = buffer; p != end; ++p)
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
- return true;
- }
-
- bool WriteDouble(double d) {
- if (internal::Double(d).IsNanOrInf()) {
- if (!(writeFlags & kWriteNanAndInfFlag))
- return false;
- if (internal::Double(d).IsNan()) {
- PutReserve(*os_, 3);
- PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
- return true;
- }
- if (internal::Double(d).Sign()) {
- PutReserve(*os_, 9);
- PutUnsafe(*os_, '-');
- }
- else
- PutReserve(*os_, 8);
- PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
- PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
- return true;
- }
-
- char buffer[25];
- char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
- PutReserve(*os_, static_cast<size_t>(end - buffer));
- for (char* p = buffer; p != end; ++p)
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(*p));
- return true;
- }
-
- bool WriteString(const Ch* str, SizeType length) {
- static const typename OutputStream::Ch hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
- static const char escape[256] = {
-#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- //0 1 2 3 4 5 6 7 8 9 A B C D E F
- 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
- 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
- 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
- Z16, Z16, // 30~4F
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
- Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
-#undef Z16
- };
-
- if (TargetEncoding::supportUnicode)
- PutReserve(*os_, 2 + length * 6); // "\uxxxx..."
- else
- PutReserve(*os_, 2 + length * 12); // "\uxxxx\uyyyy..."
-
- PutUnsafe(*os_, '\"');
- GenericStringStream<SourceEncoding> is(str);
- while (ScanWriteUnescapedString(is, length)) {
- const Ch c = is.Peek();
- if (!TargetEncoding::supportUnicode && static_cast<unsigned>(c) >= 0x80) {
- // Unicode escaping
- unsigned codepoint;
- if (RAPIDJSON_UNLIKELY(!SourceEncoding::Decode(is, &codepoint)))
- return false;
- PutUnsafe(*os_, '\\');
- PutUnsafe(*os_, 'u');
- if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) {
- PutUnsafe(*os_, hexDigits[(codepoint >> 12) & 15]);
- PutUnsafe(*os_, hexDigits[(codepoint >> 8) & 15]);
- PutUnsafe(*os_, hexDigits[(codepoint >> 4) & 15]);
- PutUnsafe(*os_, hexDigits[(codepoint ) & 15]);
- }
- else {
- RAPIDJSON_ASSERT(codepoint >= 0x010000 && codepoint <= 0x10FFFF);
- // Surrogate pair
- unsigned s = codepoint - 0x010000;
- unsigned lead = (s >> 10) + 0xD800;
- unsigned trail = (s & 0x3FF) + 0xDC00;
- PutUnsafe(*os_, hexDigits[(lead >> 12) & 15]);
- PutUnsafe(*os_, hexDigits[(lead >> 8) & 15]);
- PutUnsafe(*os_, hexDigits[(lead >> 4) & 15]);
- PutUnsafe(*os_, hexDigits[(lead ) & 15]);
- PutUnsafe(*os_, '\\');
- PutUnsafe(*os_, 'u');
- PutUnsafe(*os_, hexDigits[(trail >> 12) & 15]);
- PutUnsafe(*os_, hexDigits[(trail >> 8) & 15]);
- PutUnsafe(*os_, hexDigits[(trail >> 4) & 15]);
- PutUnsafe(*os_, hexDigits[(trail ) & 15]);
- }
- }
- else if ((sizeof(Ch) == 1 || static_cast<unsigned>(c) < 256) && RAPIDJSON_UNLIKELY(escape[static_cast<unsigned char>(c)])) {
- is.Take();
- PutUnsafe(*os_, '\\');
- PutUnsafe(*os_, static_cast<typename OutputStream::Ch>(escape[static_cast<unsigned char>(c)]));
- if (escape[static_cast<unsigned char>(c)] == 'u') {
- PutUnsafe(*os_, '0');
- PutUnsafe(*os_, '0');
- PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) >> 4]);
- PutUnsafe(*os_, hexDigits[static_cast<unsigned char>(c) & 0xF]);
- }
- }
- else if (RAPIDJSON_UNLIKELY(!(writeFlags & kWriteValidateEncodingFlag ?
- Transcoder<SourceEncoding, TargetEncoding>::Validate(is, *os_) :
- Transcoder<SourceEncoding, TargetEncoding>::TranscodeUnsafe(is, *os_))))
- return false;
- }
- PutUnsafe(*os_, '\"');
- return true;
- }
-
- bool ScanWriteUnescapedString(GenericStringStream<SourceEncoding>& is, size_t length) {
- return RAPIDJSON_LIKELY(is.Tell() < length);
- }
-
- bool WriteStartObject() { os_->Put('{'); return true; }
- bool WriteEndObject() { os_->Put('}'); return true; }
- bool WriteStartArray() { os_->Put('['); return true; }
- bool WriteEndArray() { os_->Put(']'); return true; }
-
- bool WriteRawValue(const Ch* json, size_t length) {
- PutReserve(*os_, length);
- for (size_t i = 0; i < length; i++) {
- RAPIDJSON_ASSERT(json[i] != '\0');
- PutUnsafe(*os_, json[i]);
- }
- return true;
- }
-
- void Prefix(Type type) {
- (void)type;
- if (RAPIDJSON_LIKELY(level_stack_.GetSize() != 0)) { // this value is not at root
- Level* level = level_stack_.template Top<Level>();
- if (level->valueCount > 0) {
- if (level->inArray)
- os_->Put(','); // add comma if it is not the first element in array
- else // in object
- os_->Put((level->valueCount % 2 == 0) ? ',' : ':');
- }
- if (!level->inArray && level->valueCount % 2 == 0)
- RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
- level->valueCount++;
- }
- else {
- RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
- hasRoot_ = true;
- }
- }
-
- // Flush the value if it is the top level one.
- bool EndValue(bool ret) {
- if (RAPIDJSON_UNLIKELY(level_stack_.Empty())) // end of json text
- Flush();
- return ret;
- }
-
- OutputStream* os_;
- internal::Stack<StackAllocator> level_stack_;
- int maxDecimalPlaces_;
- bool hasRoot_;
-
-private:
- // Prohibit copy constructor & assignment operator.
- Writer(const Writer&);
- Writer& operator=(const Writer&);
-};
-
-// Full specialization for StringStream to prevent memory copying
-
-template<>
-inline bool Writer<StringBuffer>::WriteInt(int i) {
- char *buffer = os_->Push(11);
- const char* end = internal::i32toa(i, buffer);
- os_->Pop(static_cast<size_t>(11 - (end - buffer)));
- return true;
-}
-
-template<>
-inline bool Writer<StringBuffer>::WriteUint(unsigned u) {
- char *buffer = os_->Push(10);
- const char* end = internal::u32toa(u, buffer);
- os_->Pop(static_cast<size_t>(10 - (end - buffer)));
- return true;
-}
-
-template<>
-inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) {
- char *buffer = os_->Push(21);
- const char* end = internal::i64toa(i64, buffer);
- os_->Pop(static_cast<size_t>(21 - (end - buffer)));
- return true;
-}
-
-template<>
-inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) {
- char *buffer = os_->Push(20);
- const char* end = internal::u64toa(u, buffer);
- os_->Pop(static_cast<size_t>(20 - (end - buffer)));
- return true;
-}
-
-template<>
-inline bool Writer<StringBuffer>::WriteDouble(double d) {
- if (internal::Double(d).IsNanOrInf()) {
- // Note: This code path can only be reached if (RAPIDJSON_WRITE_DEFAULT_FLAGS & kWriteNanAndInfFlag).
- if (!(kWriteDefaultFlags & kWriteNanAndInfFlag))
- return false;
- if (internal::Double(d).IsNan()) {
- PutReserve(*os_, 3);
- PutUnsafe(*os_, 'N'); PutUnsafe(*os_, 'a'); PutUnsafe(*os_, 'N');
- return true;
- }
- if (internal::Double(d).Sign()) {
- PutReserve(*os_, 9);
- PutUnsafe(*os_, '-');
- }
- else
- PutReserve(*os_, 8);
- PutUnsafe(*os_, 'I'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'f');
- PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 'n'); PutUnsafe(*os_, 'i'); PutUnsafe(*os_, 't'); PutUnsafe(*os_, 'y');
- return true;
- }
-
- char *buffer = os_->Push(25);
- char* end = internal::dtoa(d, buffer, maxDecimalPlaces_);
- os_->Pop(static_cast<size_t>(25 - (end - buffer)));
- return true;
-}
-
-#if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42)
-template<>
-inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
- if (length < 16)
- return RAPIDJSON_LIKELY(is.Tell() < length);
-
- if (!RAPIDJSON_LIKELY(is.Tell() < length))
- return false;
-
- const char* p = is.src_;
- const char* end = is.head_ + length;
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
- if (nextAligned > end)
- return true;
-
- while (p != nextAligned)
- if (*p < 0x20 || *p == '\"' || *p == '\\') {
- is.src_ = p;
- return RAPIDJSON_LIKELY(is.Tell() < length);
- }
- else
- os_->PutUnsafe(*p++);
-
- // The rest of string using SIMD
- static const char dquote[16] = { '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"', '\"' };
- static const char bslash[16] = { '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\', '\\' };
- static const char space[16] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F };
- const __m128i dq = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&dquote[0]));
- const __m128i bs = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&bslash[0]));
- const __m128i sp = _mm_loadu_si128(reinterpret_cast<const __m128i *>(&space[0]));
-
- for (; p != endAligned; p += 16) {
- const __m128i s = _mm_load_si128(reinterpret_cast<const __m128i *>(p));
- const __m128i t1 = _mm_cmpeq_epi8(s, dq);
- const __m128i t2 = _mm_cmpeq_epi8(s, bs);
- const __m128i t3 = _mm_cmpeq_epi8(_mm_max_epu8(s, sp), sp); // s < 0x20 <=> max(s, 0x1F) == 0x1F
- const __m128i x = _mm_or_si128(_mm_or_si128(t1, t2), t3);
- unsigned short r = static_cast<unsigned short>(_mm_movemask_epi8(x));
- if (RAPIDJSON_UNLIKELY(r != 0)) { // some of characters is escaped
- SizeType len;
-#ifdef _MSC_VER // Find the index of first escaped
- unsigned long offset;
- _BitScanForward(&offset, r);
- len = offset;
-#else
- len = static_cast<SizeType>(__builtin_ffs(r) - 1);
-#endif
- char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
- for (size_t i = 0; i < len; i++)
- q[i] = p[i];
-
- p += len;
- break;
- }
- _mm_storeu_si128(reinterpret_cast<__m128i *>(os_->PushUnsafe(16)), s);
- }
-
- is.src_ = p;
- return RAPIDJSON_LIKELY(is.Tell() < length);
-}
-#elif defined(RAPIDJSON_NEON)
-template<>
-inline bool Writer<StringBuffer>::ScanWriteUnescapedString(StringStream& is, size_t length) {
- if (length < 16)
- return RAPIDJSON_LIKELY(is.Tell() < length);
-
- if (!RAPIDJSON_LIKELY(is.Tell() < length))
- return false;
-
- const char* p = is.src_;
- const char* end = is.head_ + length;
- const char* nextAligned = reinterpret_cast<const char*>((reinterpret_cast<size_t>(p) + 15) & static_cast<size_t>(~15));
- const char* endAligned = reinterpret_cast<const char*>(reinterpret_cast<size_t>(end) & static_cast<size_t>(~15));
- if (nextAligned > end)
- return true;
-
- while (p != nextAligned)
- if (*p < 0x20 || *p == '\"' || *p == '\\') {
- is.src_ = p;
- return RAPIDJSON_LIKELY(is.Tell() < length);
- }
- else
- os_->PutUnsafe(*p++);
-
- // The rest of string using SIMD
- const uint8x16_t s0 = vmovq_n_u8('"');
- const uint8x16_t s1 = vmovq_n_u8('\\');
- const uint8x16_t s2 = vmovq_n_u8('\b');
- const uint8x16_t s3 = vmovq_n_u8(32);
-
- for (; p != endAligned; p += 16) {
- const uint8x16_t s = vld1q_u8(reinterpret_cast<const uint8_t *>(p));
- uint8x16_t x = vceqq_u8(s, s0);
- x = vorrq_u8(x, vceqq_u8(s, s1));
- x = vorrq_u8(x, vceqq_u8(s, s2));
- x = vorrq_u8(x, vcltq_u8(s, s3));
-
- x = vrev64q_u8(x); // Rev in 64
- uint64_t low = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 0); // extract
- uint64_t high = vgetq_lane_u64(reinterpret_cast<uint64x2_t>(x), 1); // extract
-
- SizeType len = 0;
- bool escaped = false;
- if (low == 0) {
- if (high != 0) {
- unsigned lz = (unsigned)__builtin_clzll(high);
- len = 8 + (lz >> 3);
- escaped = true;
- }
- } else {
- unsigned lz = (unsigned)__builtin_clzll(low);
- len = lz >> 3;
- escaped = true;
- }
- if (RAPIDJSON_UNLIKELY(escaped)) { // some of characters is escaped
- char* q = reinterpret_cast<char*>(os_->PushUnsafe(len));
- for (size_t i = 0; i < len; i++)
- q[i] = p[i];
-
- p += len;
- break;
- }
- vst1q_u8(reinterpret_cast<uint8_t *>(os_->PushUnsafe(16)), s);
- }
-
- is.src_ = p;
- return RAPIDJSON_LIKELY(is.Tell() < length);
-}
-#endif // RAPIDJSON_NEON
-
-RAPIDJSON_NAMESPACE_END
-
-#ifdef _MSC_VER
-RAPIDJSON_DIAG_POP
-#endif
-
-#ifdef __clang__
-RAPIDJSON_DIAG_POP
-#endif
-
-#endif // RAPIDJSON_RAPIDJSON_H_
diff --git a/src/3rdparty/assimp/contrib/rapidjson/license.txt b/src/3rdparty/assimp/contrib/rapidjson/license.txt
deleted file mode 100644
index 7ccc161c8..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/license.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-Tencent is pleased to support the open source community by making RapidJSON available.
-
-Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-
-If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License.
-If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license.
-A copy of the MIT License is included in this file.
-
-Other dependencies and licenses:
-
-Open Source Software Licensed Under the BSD License:
---------------------------------------------------------------------
-
-The msinttypes r29
-Copyright (c) 2006-2013 Alexander Chemeris
-All rights reserved.
-
-Redistribution and use 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 copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS AND 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.
-
-Open Source Software Licensed Under the JSON License:
---------------------------------------------------------------------
-
-json.org
-Copyright (c) 2002 JSON.org
-All Rights Reserved.
-
-JSON_checker
-Copyright (c) 2002 JSON.org
-All Rights Reserved.
-
-
-Terms of the JSON License:
----------------------------------------------------
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-Terms of the MIT License:
---------------------------------------------------------------------
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/3rdparty/assimp/contrib/rapidjson/readme.md b/src/3rdparty/assimp/contrib/rapidjson/readme.md
deleted file mode 100644
index b833a98e8..000000000
--- a/src/3rdparty/assimp/contrib/rapidjson/readme.md
+++ /dev/null
@@ -1,160 +0,0 @@
-![RapidJSON logo](doc/logo/rapidjson.png)
-
-![Release version](https://img.shields.io/badge/release-v1.1.0-blue.svg)
-
-## A fast JSON parser/generator for C++ with both SAX/DOM style API
-
-Tencent is pleased to support the open source community by making RapidJSON available.
-
-Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
-
-* [RapidJSON GitHub](https://github.com/Tencent/rapidjson/)
-* RapidJSON Documentation
- * [English](http://rapidjson.org/)
- * [简体中文](http://rapidjson.org/zh-cn/)
- * [GitBook](https://www.gitbook.com/book/miloyip/rapidjson/) with downloadable PDF/EPUB/MOBI, without API reference.
-
-## Build status
-
-| [Linux][lin-link] | [Windows][win-link] | [Coveralls][cov-link] |
-| :---------------: | :-----------------: | :-------------------: |
-| ![lin-badge] | ![win-badge] | ![cov-badge] |
-
-[lin-badge]: https://travis-ci.org/Tencent/rapidjson.svg?branch=master "Travis build status"
-[lin-link]: https://travis-ci.org/Tencent/rapidjson "Travis build status"
-[win-badge]: https://ci.appveyor.com/api/projects/status/l6qulgqahcayidrf/branch/master?svg=true "AppVeyor build status"
-[win-link]: https://ci.appveyor.com/project/miloyip/rapidjson-0fdqj/branch/master "AppVeyor build status"
-[cov-badge]: https://coveralls.io/repos/Tencent/rapidjson/badge.svg?branch=master "Coveralls coverage"
-[cov-link]: https://coveralls.io/r/Tencent/rapidjson?branch=master "Coveralls coverage"
-
-## Introduction
-
-RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](http://rapidxml.sourceforge.net/).
-
-* RapidJSON is **small** but **complete**. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code.
-
-* RapidJSON is **fast**. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration.
-
-* RapidJSON is **self-contained** and **header-only**. It does not depend on external libraries such as BOOST. It even does not depend on STL.
-
-* RapidJSON is **memory-friendly**. Each JSON value occupies exactly 16 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing.
-
-* RapidJSON is **Unicode-friendly**. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character).
-
-More features can be read [here](doc/features.md).
-
-JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in fully compliance with RFC7159/ECMA-404, with optional support of relaxed syntax. More information about JSON can be obtained at
-* [Introducing JSON](http://json.org/)
-* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159)
-* [Standard ECMA-404: The JSON Data Interchange Format](https://www.ecma-international.org/publications/standards/Ecma-404.htm)
-
-## Highlights in v1.1 (2016-8-25)
-
-* Added [JSON Pointer](doc/pointer.md)
-* Added [JSON Schema](doc/schema.md)
-* Added [relaxed JSON syntax](doc/dom.md) (comment, trailing comma, NaN/Infinity)
-* Iterating array/object with [C++11 Range-based for loop](doc/tutorial.md)
-* Reduce memory overhead of each `Value` from 24 bytes to 16 bytes in x86-64 architecture.
-
-For other changes please refer to [change log](CHANGELOG.md).
-
-## Compatibility
-
-RapidJSON is cross-platform. Some platform/compiler combinations which have been tested are shown as follows.
-* Visual C++ 2008/2010/2013 on Windows (32/64-bit)
-* GNU C++ 3.8.x on Cygwin
-* Clang 3.4 on Mac OS X (32/64-bit) and iOS
-* Clang 3.4 on Android NDK
-
-Users can build and run the unit tests on their platform/compiler.
-
-## Installation
-
-RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path.
-
-RapidJSON uses following software as its dependencies:
-* [CMake](https://cmake.org/) as a general build tool
-* (optional) [Doxygen](http://www.doxygen.org) to build documentation
-* (optional) [googletest](https://github.com/google/googletest) for unit and performance testing
-
-To generate user documentation and run tests please proceed with the steps below:
-
-1. Execute `git submodule update --init` to get the files of thirdparty submodules (google test).
-2. Create directory called `build` in rapidjson source directory.
-3. Change to `build` directory and run `cmake ..` command to configure your build. Windows users can do the same with cmake-gui application.
-4. On Windows, build the solution found in the build directory. On Linux, run `make` from the build directory.
-
-On successful build you will find compiled test and example binaries in `bin`
-directory. The generated documentation will be available in `doc/html`
-directory of the build tree. To run tests after finished build please run `make
-test` or `ctest` from your build tree. You can get detailed output using `ctest
--V` command.
-
-It is possible to install library system-wide by running `make install` command
-from the build tree with administrative privileges. This will install all files
-according to system preferences. Once RapidJSON is installed, it is possible
-to use it from other CMake projects by adding `find_package(RapidJSON)` line to
-your CMakeLists.txt.
-
-## Usage at a glance
-
-This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string.
-
-~~~~~~~~~~cpp
-// rapidjson/example/simpledom/simpledom.cpp`
-#include "rapidjson/document.h"
-#include "rapidjson/writer.h"
-#include "rapidjson/stringbuffer.h"
-#include <iostream>
-
-using namespace rapidjson;
-
-int main() {
- // 1. Parse a JSON string into DOM.
- const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
- Document d;
- d.Parse(json);
-
- // 2. Modify it by DOM.
- Value& s = d["stars"];
- s.SetInt(s.GetInt() + 1);
-
- // 3. Stringify the DOM
- StringBuffer buffer;
- Writer<StringBuffer> writer(buffer);
- d.Accept(writer);
-
- // Output {"project":"rapidjson","stars":11}
- std::cout << buffer.GetString() << std::endl;
- return 0;
-}
-~~~~~~~~~~
-
-Note that this example did not handle potential errors.
-
-The following diagram shows the process.
-
-![simpledom](doc/diagram/simpledom.png)
-
-More [examples](https://github.com/Tencent/rapidjson/tree/master/example) are available:
-
-* DOM API
- * [tutorial](https://github.com/Tencent/rapidjson/blob/master/example/tutorial/tutorial.cpp): Basic usage of DOM API.
-
-* SAX API
- * [simplereader](https://github.com/Tencent/rapidjson/blob/master/example/simplereader/simplereader.cpp): Dumps all SAX events while parsing a JSON by `Reader`.
- * [condense](https://github.com/Tencent/rapidjson/blob/master/example/condense/condense.cpp): A command line tool to rewrite a JSON, with all whitespaces removed.
- * [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp): A command line tool to rewrite a JSON with indents and newlines by `PrettyWriter`.
- * [capitalize](https://github.com/Tencent/rapidjson/blob/master/example/capitalize/capitalize.cpp): A command line tool to capitalize strings in JSON.
- * [messagereader](https://github.com/Tencent/rapidjson/blob/master/example/messagereader/messagereader.cpp): Parse a JSON message with SAX API.
- * [serialize](https://github.com/Tencent/rapidjson/blob/master/example/serialize/serialize.cpp): Serialize a C++ object into JSON with SAX API.
- * [jsonx](https://github.com/Tencent/rapidjson/blob/master/example/jsonx/jsonx.cpp): Implements a `JsonxWriter` which stringify SAX events into [JSONx](https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html) (a kind of XML) format. The example is a command line tool which converts input JSON into JSONx format.
-
-* Schema
- * [schemavalidator](https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp) : A command line tool to validate a JSON with a JSON schema.
-
-* Advanced
- * [prettyauto](https://github.com/Tencent/rapidjson/blob/master/example/prettyauto/prettyauto.cpp): A modified version of [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp) to automatically handle JSON with any UTF encodings.
- * [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread.
- * [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key.
- * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`.
diff --git a/src/3rdparty/assimp/contrib/unzip/crypt.h b/src/3rdparty/assimp/contrib/unzip/crypt.h
deleted file mode 100644
index 2aa99c284..000000000
--- a/src/3rdparty/assimp/contrib/unzip/crypt.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* crypt.h -- base code for crypt/uncrypt ZIPfile
-
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- This code is a modified version of crypting code in Infozip distribution
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
-
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
-
- If you don't need crypting in your application, just define symbols
- NOCRYPT and NOUNCRYPT.
-
- This code support the "Traditional PKWARE Encryption".
-
- The new AES encryption added on Zip format by Winzip (see the page
- http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
- Encryption is not supported.
-*/
-
-#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
-
-/***********************************************************************
- * Return the next byte in the pseudo-random sequence
- */
-static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
-{
- unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
- * unpredictable manner on 16-bit systems; not a problem
- * with any known compiler so far, though */
-
- temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
- return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
-}
-
-/***********************************************************************
- * Update the encryption keys with the next byte of plain text
- */
-static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
-{
- (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
- (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
- (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
- {
- register int keyshift = (int)((*(pkeys+1)) >> 24);
- (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
- }
- return c;
-}
-
-
-/***********************************************************************
- * Initialize the encryption keys and the random header according to
- * the given password.
- */
-static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
-{
- *(pkeys+0) = 305419896L;
- *(pkeys+1) = 591751049L;
- *(pkeys+2) = 878082192L;
- while (*passwd != '\0') {
- update_keys(pkeys,pcrc_32_tab,(int)*passwd);
- passwd++;
- }
-}
-
-#define zdecode(pkeys,pcrc_32_tab,c) \
- (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
-
-#define zencode(pkeys,pcrc_32_tab,c,t) \
- (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
-
-#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
-
-#define RAND_HEAD_LEN 12
- /* "last resort" source for second part of crypt seed pattern */
-# ifndef ZCR_SEED2
-# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
-# endif
-
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
- const char *passwd; /* password string */
- unsigned char *buf; /* where to write header */
- int bufSize;
- unsigned long* pkeys;
- const unsigned long* pcrc_32_tab;
- unsigned long crcForCrypting;
-{
- int n; /* index in random header */
- int t; /* temporary */
- int c; /* random byte */
- unsigned char header[RAND_HEAD_LEN-2]; /* random header */
- static unsigned calls = 0; /* ensure different random header each time */
-
- if (bufSize<RAND_HEAD_LEN)
- return 0;
-
- /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
- * output of rand() to get less predictability, since rand() is
- * often poorly implemented.
- */
- if (++calls == 1)
- {
- srand((unsigned)(time(NULL) ^ ZCR_SEED2));
- }
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- c = (rand() >> 7) & 0xff;
- header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
- }
- /* Encrypt random header (last two bytes is high word of crc) */
- init_keys(passwd, pkeys, pcrc_32_tab);
- for (n = 0; n < RAND_HEAD_LEN-2; n++)
- {
- buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
- }
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
- buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
- return n;
-}
-
-#endif
diff --git a/src/3rdparty/assimp/contrib/unzip/ioapi.c b/src/3rdparty/assimp/contrib/unzip/ioapi.c
deleted file mode 100644
index f1bee23e6..000000000
--- a/src/3rdparty/assimp/contrib/unzip/ioapi.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* ioapi.c -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "zlib.h"
-#include "ioapi.h"
-
-
-
-/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-voidpf ZCALLBACK fopen_file_func OF((
- voidpf opaque,
- const char* filename,
- int mode));
-
-uLong ZCALLBACK fread_file_func OF((
- voidpf opaque,
- voidpf stream,
- void* buf,
- uLong size));
-
-uLong ZCALLBACK fwrite_file_func OF((
- voidpf opaque,
- voidpf stream,
- const void* buf,
- uLong size));
-
-long ZCALLBACK ftell_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-long ZCALLBACK fseek_file_func OF((
- voidpf opaque,
- voidpf stream,
- uLong offset,
- int origin));
-
-int ZCALLBACK fclose_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-int ZCALLBACK ferror_file_func OF((
- voidpf opaque,
- voidpf stream));
-
-
-voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
- voidpf opaque;
- const char* filename;
- int mode;
-{
- FILE* file = NULL;
- 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";
-
- if ((filename!=NULL) && (mode_fopen != NULL))
- file = fopen(filename, mode_fopen);
- return file;
-}
-
-
-uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-
-uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
- voidpf opaque;
- voidpf stream;
- const void* buf;
- uLong size;
-{
- uLong ret;
- ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK ftell_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- long ret;
- ret = ftell((FILE *)stream);
- return ret;
-}
-
-long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
- voidpf opaque;
- voidpf stream;
- uLong offset;
- int origin;
-{
- int fseek_origin=0;
- long ret;
- switch (origin)
- {
- case ZLIB_FILEFUNC_SEEK_CUR :
- fseek_origin = SEEK_CUR;
- break;
- case ZLIB_FILEFUNC_SEEK_END :
- fseek_origin = SEEK_END;
- break;
- case ZLIB_FILEFUNC_SEEK_SET :
- fseek_origin = SEEK_SET;
- break;
- default: return -1;
- }
- ret = 0;
- fseek((FILE *)stream, offset, fseek_origin);
- return ret;
-}
-
-int ZCALLBACK fclose_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = fclose((FILE *)stream);
- return ret;
-}
-
-int ZCALLBACK ferror_file_func (opaque, stream)
- voidpf opaque;
- voidpf stream;
-{
- int ret;
- ret = ferror((FILE *)stream);
- return ret;
-}
-
-void fill_fopen_filefunc (pzlib_filefunc_def)
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- pzlib_filefunc_def->zopen_file = fopen_file_func;
- pzlib_filefunc_def->zread_file = fread_file_func;
- pzlib_filefunc_def->zwrite_file = fwrite_file_func;
- pzlib_filefunc_def->ztell_file = ftell_file_func;
- pzlib_filefunc_def->zseek_file = fseek_file_func;
- pzlib_filefunc_def->zclose_file = fclose_file_func;
- pzlib_filefunc_def->zerror_file = ferror_file_func;
- pzlib_filefunc_def->opaque = NULL;
-}
diff --git a/src/3rdparty/assimp/contrib/unzip/ioapi.h b/src/3rdparty/assimp/contrib/unzip/ioapi.h
deleted file mode 100644
index 7d457baab..000000000
--- a/src/3rdparty/assimp/contrib/unzip/ioapi.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* ioapi.h -- IO base function header for compress/uncompress .zip
- files using zlib + zip or unzip API
-
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-*/
-
-#ifndef _ZLIBIOAPI_H
-#define _ZLIBIOAPI_H
-
-
-#define ZLIB_FILEFUNC_SEEK_CUR (1)
-#define ZLIB_FILEFUNC_SEEK_END (2)
-#define ZLIB_FILEFUNC_SEEK_SET (0)
-
-#define ZLIB_FILEFUNC_MODE_READ (1)
-#define ZLIB_FILEFUNC_MODE_WRITE (2)
-#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
-
-#define ZLIB_FILEFUNC_MODE_EXISTING (4)
-#define ZLIB_FILEFUNC_MODE_CREATE (8)
-
-
-#ifndef ZCALLBACK
-
-#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
-#define ZCALLBACK CALLBACK
-#else
-#define ZCALLBACK
-#endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
-typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
-typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
-typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
-typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
-typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
-typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
-
-typedef struct zlib_filefunc_def_s
-{
- open_file_func zopen_file;
- read_file_func zread_file;
- write_file_func zwrite_file;
- tell_file_func ztell_file;
- seek_file_func zseek_file;
- close_file_func zclose_file;
- testerror_file_func zerror_file;
- voidpf opaque;
-} zlib_filefunc_def;
-
-
-
-void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
-
-#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
-#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
-#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
-#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
-#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
-#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/src/3rdparty/assimp/contrib/unzip/unzip.c b/src/3rdparty/assimp/contrib/unzip/unzip.c
deleted file mode 100644
index e8b62e763..000000000
--- a/src/3rdparty/assimp/contrib/unzip/unzip.c
+++ /dev/null
@@ -1,1611 +0,0 @@
-/* unzip.c -- IO for uncompress .zip files using zlib
- Version 1.01e, February 12th, 2005
-
- Copyright (C) 1998-2005 Gilles Vollant
-
- Read unzip.h for more info
-*/
-
-/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
-compatibility with older software. The following is from the original crypt.c. Code
-woven in by Terry Thorsen 1/2003.
-*/
-/*
- Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
-
- See the accompanying file LICENSE, version 2000-Apr-09 or later
- (the contents of which are also included in zip.h) for terms of use.
- If, for some reason, all these files are missing, the Info-ZIP license
- also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
-*/
-/*
- crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h]
-
- The encryption/decryption parts of this source code (as opposed to the
- non-echoing password parts) were originally written in Europe. The
- whole source package can be freely distributed, including from the USA.
- (Prior to January 2000, re-export from the US was a violation of US law.)
- */
-
-/*
- This encryption code is a direct transcription of the algorithm from
- Roger Schlafly, described by Phil Katz in the file appnote.txt. This
- file (appnote.txt) is distributed with the PKZIP program (even in the
- version without encryption capabilities).
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "zlib.h"
-#include "unzip.h"
-
-#ifdef STDC
-# include <stddef.h>
-# include <string.h>
-# include <stdlib.h>
-#endif
-#ifdef NO_ERRNO_H
- extern int errno;
-#else
-# include <errno.h>
-#endif
-
-
-#ifndef local
-# define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-
-#ifndef CASESENSITIVITYDEFAULT_NO
-# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
-# define CASESENSITIVITYDEFAULT_NO
-# endif
-#endif
-
-
-#ifndef UNZ_BUFSIZE
-#define UNZ_BUFSIZE (16384)
-#endif
-
-#ifndef UNZ_MAXFILENAMEINZIP
-#define UNZ_MAXFILENAMEINZIP (256)
-#endif
-
-#ifndef ALLOC
-# define ALLOC(size) (malloc(size))
-#endif
-#ifndef TRYFREE
-# define TRYFREE(p) {if (p) free(p);}
-#endif
-
-#define SIZECENTRALDIRITEM (0x2e)
-#define SIZEZIPLOCALHEADER (0x1e)
-
-
-
-
-const char unz_copyright[] =
- " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
-
-/* unz_file_info_interntal contain internal info about a file in zipfile*/
-typedef struct unz_file_info_internal_s
-{
- uLong offset_curfile;/* relative offset of local header 4 bytes */
-} unz_file_info_internal;
-
-
-/* file_in_zip_read_info_s contain internal information about a file in zipfile,
- when reading and decompress it */
-typedef struct
-{
- char *read_buffer; /* internal buffer for compressed data */
- z_stream stream; /* zLib stream structure for inflate */
-
- uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/
- uLong stream_initialised; /* flag set if stream structure is initialised*/
-
- uLong offset_local_extrafield;/* offset of the local extra field */
- uInt size_local_extrafield;/* size of the local extra field */
- uLong pos_local_extrafield; /* position in the local extra field in read*/
-
- uLong crc32; /* crc32 of all data uncompressed */
- uLong crc32_wait; /* crc32 we must obtain after decompress all */
- uLong rest_read_compressed; /* number of byte to be decompressed */
- uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- uLong compression_method; /* compression method (0==store) */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- int raw;
-} file_in_zip_read_info_s;
-
-
-/* unz_s contain internal information about the zipfile
-*/
-typedef struct
-{
- zlib_filefunc_def z_filefunc;
- voidpf filestream; /* io structore of the zipfile */
- unz_global_info gi; /* public global information */
- uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
- uLong num_file; /* number of the current file in the zipfile*/
- uLong pos_in_central_dir; /* pos of the current file in the central dir*/
- uLong current_file_ok; /* flag about the usability of the current file*/
- uLong central_pos; /* position of the beginning of the central dir*/
-
- uLong size_central_dir; /* size of the central directory */
- uLong offset_central_dir; /* offset of start of central directory with
- respect to the starting disk number */
-
- unz_file_info cur_file_info; /* public info about the current file in zip*/
- unz_file_info_internal cur_file_info_internal; /* private info about it*/
- file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
- file if we are decompressing it */
- int encrypted;
-# ifndef NOUNCRYPT
- unsigned long keys[3]; /* keys defining the pseudo-random sequence */
- const z_crc_t* pcrc_32_tab;
-# endif
-} unz_s;
-
-
-#ifndef NOUNCRYPT
-#include "crypt.h"
-#endif
-
-/* ===========================================================================
- Read a byte from a gz_stream; update next_in and avail_in. Return EOF
- for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
-*/
-
-
-local int unzlocal_getByte OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- int *pi));
-
-local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- int *pi;
-{
- unsigned char c;
- int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1);
- if (err==1)
- {
- *pi = (int)c;
- return UNZ_OK;
- }
- else
- {
- if (ZERROR(*pzlib_filefunc_def,filestream))
- return UNZ_ERRNO;
- else
- return UNZ_EOF;
- }
-}
-
-
-/* ===========================================================================
- Reads a long in LSB order from the given gz_stream. Sets
-*/
-local int unzlocal_getShort OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i = 0;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-local int unzlocal_getLong OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream,
- uLong *pX));
-
-local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
- uLong *pX;
-{
- uLong x ;
- int i = 0;
- int err;
-
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x = (uLong)i;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<8;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<16;
-
- if (err==UNZ_OK)
- err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
- x += ((uLong)i)<<24;
-
- if (err==UNZ_OK)
- *pX = x;
- else
- *pX = 0;
- return err;
-}
-
-
-/* My own strcmpi / strcasecmp */
-local int strcmpcasenosensitive_internal (fileName1,fileName2)
- const char* fileName1;
- const char* fileName2;
-{
- for (;;)
- {
- char c1=*(fileName1++);
- char c2=*(fileName2++);
- if ((c1>='a') && (c1<='z'))
- c1 -= 0x20;
- if ((c2>='a') && (c2<='z'))
- c2 -= 0x20;
- if (c1=='\0')
- return ((c2=='\0') ? 0 : -1);
- if (c2=='\0')
- return 1;
- if (c1<c2)
- return -1;
- if (c1>c2)
- return 1;
- }
-}
-
-
-#ifdef CASESENSITIVITYDEFAULT_NO
-#define CASESENSITIVITYDEFAULTVALUE 2
-#else
-#define CASESENSITIVITYDEFAULTVALUE 1
-#endif
-
-#ifndef STRCMPCASENOSENTIVEFUNCTION
-#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
-#endif
-
-/*
- Compare two filename (fileName1,fileName2).
- If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
- If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
- or strcasecmp)
- If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
- (like 1 on Unix, 2 on Windows)
-
-*/
-extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
- const char* fileName1;
- const char* fileName2;
- int iCaseSensitivity;
-{
- if (iCaseSensitivity==0)
- iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
-
- if (iCaseSensitivity==1)
- return strcmp(fileName1,fileName2);
-
- return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
-}
-
-#ifndef BUFREADCOMMENT
-#define BUFREADCOMMENT (0x400)
-#endif
-
-/*
- Locate the Central directory of a zipfile (at the end, just before
- the global comment)
-*/
-local uLong unzlocal_SearchCentralDir OF((
- const zlib_filefunc_def* pzlib_filefunc_def,
- voidpf filestream));
-
-local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream)
- const zlib_filefunc_def* pzlib_filefunc_def;
- voidpf filestream;
-{
- unsigned char* buf;
- uLong uSizeFile;
- uLong uBackRead;
- uLong uMaxBack=0xffff; /* maximum size of global comment */
- uLong uPosFound=0;
-
- if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
- return 0;
-
-
- uSizeFile = ZTELL(*pzlib_filefunc_def,filestream);
-
- if (uMaxBack>uSizeFile)
- uMaxBack = uSizeFile;
-
- buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
- if (buf==NULL)
- return 0;
-
- uBackRead = 4;
- while (uBackRead<uMaxBack)
- {
- uLong uReadSize,uReadPos ;
- int i;
- if (uBackRead+BUFREADCOMMENT>uMaxBack)
- uBackRead = uMaxBack;
- else
- uBackRead+=BUFREADCOMMENT;
- uReadPos = uSizeFile-uBackRead ;
-
- uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
- (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
- if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- break;
-
- if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
- break;
-
- for (i=(int)uReadSize-3; (i--)>0;)
- if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
- ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
- {
- uPosFound = uReadPos+i;
- break;
- }
-
- if (uPosFound!=0)
- break;
- }
- TRYFREE(buf);
- return uPosFound;
-}
-
-/*
- Open a Zip file. path contain the full pathname (by example,
- on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
- "zlib/zlib114.zip".
- If the zipfile cannot be opened (file doesn't exist or in not valid), the
- return value is NULL.
- Else, the return value is a unzFile Handle, usable with other function
- of this unzip package.
-*/
-extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def)
- const char *path;
- zlib_filefunc_def* pzlib_filefunc_def;
-{
- unz_s us;
- unz_s *s;
- uLong central_pos,uL;
-
- uLong number_disk; /* number of the current dist, used for
- spaning ZIP, unsupported, always 0*/
- uLong number_disk_with_CD; /* number the the disk with central dir, used
- for spaning ZIP, unsupported, always 0*/
- uLong number_entry_CD; /* total number of entries in
- the central dir
- (same than number_entry on nospan) */
-
- int err=UNZ_OK;
-
- if (unz_copyright[0]!=' ')
- return NULL;
-
- if (pzlib_filefunc_def==NULL)
- fill_fopen_filefunc(&us.z_filefunc);
- else
- us.z_filefunc = *pzlib_filefunc_def;
-
- us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque,
- path,
- ZLIB_FILEFUNC_MODE_READ |
- ZLIB_FILEFUNC_MODE_EXISTING);
- if (us.filestream==NULL)
- return NULL;
-
- central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream);
- if (central_pos==0)
- err=UNZ_ERRNO;
-
- if (ZSEEK(us.z_filefunc, us.filestream,
- central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
- /* the signature, already checked */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* number of the disk with the start of the central directory */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir on this disk */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* total number of entries in the central dir */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((number_entry_CD!=us.gi.number_entry) ||
- (number_disk_with_CD!=0) ||
- (number_disk!=0))
- err=UNZ_BADZIPFILE;
-
- /* size of the central directory */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* offset of start of central directory with respect to the
- starting disk number */
- if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- /* zipfile comment length */
- if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
- err=UNZ_ERRNO;
-
- if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
- (err==UNZ_OK))
- err=UNZ_BADZIPFILE;
-
- if (err!=UNZ_OK)
- {
- ZCLOSE(us.z_filefunc, us.filestream);
- return NULL;
- }
-
- us.byte_before_the_zipfile = central_pos -
- (us.offset_central_dir+us.size_central_dir);
- us.central_pos = central_pos;
- us.pfile_in_zip_read = NULL;
- us.encrypted = 0;
-
-
- s=(unz_s*)ALLOC(sizeof(unz_s));
- *s=us;
- unzGoToFirstFile((unzFile)s);
- return (unzFile)s;
-}
-
-
-extern unzFile ZEXPORT unzOpen (path)
- const char *path;
-{
- return unzOpen2(path, NULL);
-}
-
-/*
- Close a ZipFile opened with unzipOpen.
- If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
- these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzClose (file)
- unzFile file;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- if (s->pfile_in_zip_read!=NULL)
- unzCloseCurrentFile(file);
-
- ZCLOSE(s->z_filefunc, s->filestream);
- TRYFREE(s);
- return UNZ_OK;
-}
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem. */
-extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
- unzFile file;
- unz_global_info *pglobal_info;
-{
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- *pglobal_info=s->gi;
- return UNZ_OK;
-}
-
-
-/*
- Translate date/time from Dos format to tm_unz (readable more easilty)
-*/
-local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
- uLong ulDosDate;
- tm_unz* ptm;
-{
- uLong uDate;
- uDate = (uLong)(ulDosDate>>16);
- ptm->tm_mday = (uInt)(uDate&0x1f) ;
- ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ;
- ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
-
- ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
- ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ;
- ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ;
-}
-
-/*
- Get Info about the current file in the zipfile, with internal only info
-*/
-local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
- unz_file_info *pfile_info,
- unz_file_info_internal
- *pfile_info_internal,
- char *szFileName,
- uLong fileNameBufferSize,
- void *extraField,
- uLong extraFieldBufferSize,
- char *szComment,
- uLong commentBufferSize));
-
-local int unzlocal_GetCurrentFileInfoInternal (file,
- pfile_info,
- pfile_info_internal,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- unz_file_info_internal *pfile_info_internal;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- unz_s* s;
- unz_file_info file_info;
- unz_file_info_internal file_info_internal;
- int err=UNZ_OK;
- uLong uMagic;
- long lSeek=0;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pos_in_central_dir+s->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- err=UNZ_ERRNO;
-
-
- /* we check the magic */
- if (err==UNZ_OK)
- {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- {
- err=UNZ_ERRNO;
- }
- else if (uMagic!=0x02014b50)
- {
- err=UNZ_BADZIPFILE;
- }
- }
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
- err=UNZ_ERRNO;
-
- unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
- err=UNZ_ERRNO;
-
- lSeek+=file_info.size_filename;
- if ((err==UNZ_OK) && (szFileName!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_filename<fileNameBufferSize)
- {
- *(szFileName+file_info.size_filename)='\0';
- uSizeRead = file_info.size_filename;
- }
- else
- uSizeRead = fileNameBufferSize;
-
- if ((file_info.size_filename>0) && (fileNameBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek -= uSizeRead;
- }
-
-
- if ((err==UNZ_OK) && (extraField!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_extra<extraFieldBufferSize)
- uSizeRead = file_info.size_file_extra;
- else
- uSizeRead = extraFieldBufferSize;
-
- if (lSeek!=0)
- {
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
- lSeek=0;
- else
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- lSeek += file_info.size_file_extra - uSizeRead;
- }
- else
- {
- lSeek+=file_info.size_file_extra;
- }
-
- if ((err==UNZ_OK) && (szComment!=NULL))
- {
- uLong uSizeRead ;
- if (file_info.size_file_comment<commentBufferSize)
- {
- *(szComment+file_info.size_file_comment)='\0';
- uSizeRead = file_info.size_file_comment;
- }
- else
- {
- uSizeRead = commentBufferSize;
- }
-
- if (lSeek!=0)
- {
- if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)!=0)
- err=UNZ_ERRNO;
- }
- if ((file_info.size_file_comment>0) && (commentBufferSize>0))
- if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
- err=UNZ_ERRNO;
- }
- else
- {
- }
-
- if ((err==UNZ_OK) && (pfile_info!=NULL))
- *pfile_info=file_info;
-
- if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
- *pfile_info_internal=file_info_internal;
-
- return err;
-}
-
-
-
-/*
- Write info about the ZipFile in the *pglobal_info structure.
- No preparation of the structure is needed
- return UNZ_OK if there is no problem.
-*/
-extern int ZEXPORT unzGetCurrentFileInfo (file,
- pfile_info,
- szFileName, fileNameBufferSize,
- extraField, extraFieldBufferSize,
- szComment, commentBufferSize)
- unzFile file;
- unz_file_info *pfile_info;
- char *szFileName;
- uLong fileNameBufferSize;
- void *extraField;
- uLong extraFieldBufferSize;
- char *szComment;
- uLong commentBufferSize;
-{
- return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
- szFileName,fileNameBufferSize,
- extraField,extraFieldBufferSize,
- szComment,commentBufferSize);
-}
-
-/*
- Set the current file of the zipfile to the first file.
- return UNZ_OK if there is no problem
-*/
-extern int ZEXPORT unzGoToFirstFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
- unz_s* s;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- s->pos_in_central_dir=s->offset_central_dir;
- s->num_file=0;
- err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
- Set the current file of the zipfile to the next file.
- return UNZ_OK if there is no problem
- return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
-*/
-extern int ZEXPORT unzGoToNextFile (file)
- unzFile file;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
- if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */
- if (s->num_file+1==s->gi.number_entry)
- return UNZ_END_OF_LIST_OF_FILE;
-
- s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
- s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
- s->num_file++;
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-
-/*
- Try locate the file szFileName in the zipfile.
- For the iCaseSensitivity signification, see unzipStringFileNameCompare
-
- return value :
- UNZ_OK if the file is found. It becomes the current file.
- UNZ_END_OF_LIST_OF_FILE if the file is not found
-*/
-extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
- unzFile file;
- const char *szFileName;
- int iCaseSensitivity;
-{
- unz_s* s;
- int err;
-
- /* We remember the 'current' position in the file so that we can jump
- * back there if we fail.
- */
- unz_file_info cur_file_infoSaved;
- unz_file_info_internal cur_file_info_internalSaved;
- uLong num_fileSaved;
- uLong pos_in_central_dirSaved;
-
-
- if (file==NULL)
- return UNZ_PARAMERROR;
-
- if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
- return UNZ_PARAMERROR;
-
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- /* Save the current state */
- num_fileSaved = s->num_file;
- pos_in_central_dirSaved = s->pos_in_central_dir;
- cur_file_infoSaved = s->cur_file_info;
- cur_file_info_internalSaved = s->cur_file_info_internal;
-
- err = unzGoToFirstFile(file);
-
- while (err == UNZ_OK)
- {
- char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
- err = unzGetCurrentFileInfo(file,NULL,
- szCurrentFileName,sizeof(szCurrentFileName)-1,
- NULL,0,NULL,0);
- if (err == UNZ_OK)
- {
- if (unzStringFileNameCompare(szCurrentFileName,
- szFileName,iCaseSensitivity)==0)
- return UNZ_OK;
- err = unzGoToNextFile(file);
- }
- }
-
- /* We failed, so restore the state of the 'current file' to where we
- * were.
- */
- s->num_file = num_fileSaved ;
- s->pos_in_central_dir = pos_in_central_dirSaved ;
- s->cur_file_info = cur_file_infoSaved;
- s->cur_file_info_internal = cur_file_info_internalSaved;
- return err;
-}
-
-
-/*
-///////////////////////////////////////////
-// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
-// I need random access
-//
-// Further optimization could be realized by adding an ability
-// to cache the directory in memory. The goal being a single
-// comprehensive file read to put the file I need in a memory.
-*/
-
-/*
-typedef struct unz_file_pos_s
-{
- uLong pos_in_zip_directory; // offset in file
- uLong num_of_file; // # of file
-} unz_file_pos;
-*/
-
-extern int ZEXPORT unzGetFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_END_OF_LIST_OF_FILE;
-
- file_pos->pos_in_zip_directory = s->pos_in_central_dir;
- file_pos->num_of_file = s->num_file;
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzGoToFilePos(file, file_pos)
- unzFile file;
- unz_file_pos* file_pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL || file_pos==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- /* jump to the right spot */
- s->pos_in_central_dir = file_pos->pos_in_zip_directory;
- s->num_file = file_pos->num_of_file;
-
- /* set the current file */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- /* return results */
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
-
-/*
-// Unzip Helper Functions - should be here?
-///////////////////////////////////////////
-*/
-
-/*
- Read the local header of the current zipfile
- Check the coherency of the local header and info in the end of central
- directory about this file
- store in *piSizeVar the size of extra info in local header
- (filename and size of extra field data)
-*/
-local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
- poffset_local_extrafield,
- psize_local_extrafield)
- unz_s* s;
- uInt* piSizeVar;
- uLong *poffset_local_extrafield;
- uInt *psize_local_extrafield;
-{
- uLong uMagic,uData,uFlags;
- uLong size_filename;
- uLong size_extra_field;
- int err=UNZ_OK;
-
- *piSizeVar = 0;
- *poffset_local_extrafield = 0;
- *psize_local_extrafield = 0;
-
- if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
- s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
-
- if (err==UNZ_OK)
- {
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
- err=UNZ_ERRNO;
- else if (uMagic!=0x04034b50)
- err=UNZ_BADZIPFILE;
- }
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
-/*
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
- err=UNZ_BADZIPFILE;
-*/
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
- err=UNZ_ERRNO;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
- err=UNZ_BADZIPFILE;
-
- if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
- err=UNZ_ERRNO;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
- if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) &&
- ((uFlags & 8)==0))
- err=UNZ_BADZIPFILE;
-
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
- err=UNZ_ERRNO;
- else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
- err=UNZ_BADZIPFILE;
-
- *piSizeVar += (uInt)size_filename;
-
- if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
- err=UNZ_ERRNO;
- *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
- SIZEZIPLOCALHEADER + size_filename;
- *psize_local_extrafield = (uInt)size_extra_field;
-
- *piSizeVar += (uInt)size_extra_field;
-
- return err;
-}
-
-/*
- Open for reading data the current file in the zipfile.
- If there is no error and the file is opened, the return value is UNZ_OK.
-*/
-extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
- unzFile file;
- int* method;
- int* level;
- int raw;
- const char* password;
-{
- int err=UNZ_OK;
- uInt iSizeVar;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uLong offset_local_extrafield; /* offset of the local extra field */
- uInt size_local_extrafield; /* size of the local extra field */
-# ifndef NOUNCRYPT
- char source[12];
-# else
- if (password != NULL)
- return UNZ_PARAMERROR;
-# endif
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return UNZ_PARAMERROR;
-
- if (s->pfile_in_zip_read != NULL)
- unzCloseCurrentFile(file);
-
- if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
- &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info = (file_in_zip_read_info_s*)
- ALLOC(sizeof(file_in_zip_read_info_s));
- if (pfile_in_zip_read_info==NULL)
- return UNZ_INTERNALERROR;
-
- pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
- pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
- pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
- pfile_in_zip_read_info->pos_local_extrafield=0;
- pfile_in_zip_read_info->raw=raw;
-
- if (pfile_in_zip_read_info->read_buffer==NULL)
- {
- TRYFREE(pfile_in_zip_read_info);
- return UNZ_INTERNALERROR;
- }
-
- pfile_in_zip_read_info->stream_initialised=0;
-
- if (method!=NULL)
- *method = (int)s->cur_file_info.compression_method;
-
- if (level!=NULL)
- {
- *level = 6;
- switch (s->cur_file_info.flag & 0x06)
- {
- case 6 : *level = 1; break;
- case 4 : *level = 2; break;
- case 2 : *level = 9; break;
- }
- }
-
- if ((s->cur_file_info.compression_method!=0) &&
- (s->cur_file_info.compression_method!=Z_DEFLATED))
- return UNZ_BADZIPFILE;
-
- pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
- pfile_in_zip_read_info->crc32=0;
- pfile_in_zip_read_info->compression_method =
- s->cur_file_info.compression_method;
- pfile_in_zip_read_info->filestream=s->filestream;
- pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
- pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
-
- pfile_in_zip_read_info->stream.total_out = 0;
-
- if ((s->cur_file_info.compression_method==Z_DEFLATED) &&
- (!raw))
- {
- pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
- pfile_in_zip_read_info->stream.zfree = (free_func)0;
- pfile_in_zip_read_info->stream.opaque = (voidpf)0;
- pfile_in_zip_read_info->stream.next_in = (voidpf)0;
- pfile_in_zip_read_info->stream.avail_in = 0;
-
- err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
- if (err == Z_OK)
- pfile_in_zip_read_info->stream_initialised=1;
- else
- {
- TRYFREE(pfile_in_zip_read_info);
- return err;
- }
- /* windowBits is passed < 0 to tell that there is no zlib header.
- * Note that in this case inflate *requires* an extra "dummy" byte
- * after the compressed stream in order to complete decompression and
- * return Z_STREAM_END.
- * In unzip, i don't wait absolutely Z_STREAM_END because I known the
- * size of both compressed and uncompressed data
- */
- }
- pfile_in_zip_read_info->rest_read_compressed =
- s->cur_file_info.compressed_size ;
- pfile_in_zip_read_info->rest_read_uncompressed =
- s->cur_file_info.uncompressed_size ;
-
-
- pfile_in_zip_read_info->pos_in_zipfile =
- s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
- iSizeVar;
-
- pfile_in_zip_read_info->stream.avail_in = (uInt)0;
-
- s->pfile_in_zip_read = pfile_in_zip_read_info;
-
-# ifndef NOUNCRYPT
- if (password != NULL)
- {
- int i;
- s->pcrc_32_tab = get_crc_table();
- init_keys(password,s->keys,s->pcrc_32_tab);
- if (ZSEEK(s->z_filefunc, s->filestream,
- s->pfile_in_zip_read->pos_in_zipfile +
- s->pfile_in_zip_read->byte_before_the_zipfile,
- SEEK_SET)!=0)
- return UNZ_INTERNALERROR;
- if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12)
- return UNZ_INTERNALERROR;
-
- for (i = 0; i<12; i++)
- zdecode(s->keys,s->pcrc_32_tab,source[i]);
-
- s->pfile_in_zip_read->pos_in_zipfile+=12;
- s->encrypted=1;
- }
-# endif
-
-
- return UNZ_OK;
-}
-
-extern int ZEXPORT unzOpenCurrentFile (file)
- unzFile file;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
-}
-
-extern int ZEXPORT unzOpenCurrentFilePassword (file, password)
- unzFile file;
- const char* password;
-{
- return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
-}
-
-extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw)
- unzFile file;
- int* method;
- int* level;
- int raw;
-{
- return unzOpenCurrentFile3(file, method, level, raw, NULL);
-}
-
-/*
- Read bytes from the current file.
- buf contain buffer where data must be copied
- len the size of buf.
-
- return the number of byte copied if somes bytes are copied
- return 0 if the end of file was reached
- return <0 with error code if there is an error
- (UNZ_ERRNO for IO error, or zLib error for uncompress error)
-*/
-extern int ZEXPORT unzReadCurrentFile (file, buf, len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- int err=UNZ_OK;
- uInt iRead = 0;
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if (pfile_in_zip_read_info->read_buffer == NULL)
- return UNZ_END_OF_LIST_OF_FILE;
- if (len==0)
- return 0;
-
- pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
-
- pfile_in_zip_read_info->stream.avail_out = (uInt)len;
-
- if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
- (!(pfile_in_zip_read_info->raw)))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
-
- if ((len>pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in) &&
- (pfile_in_zip_read_info->raw))
- pfile_in_zip_read_info->stream.avail_out =
- (uInt)pfile_in_zip_read_info->rest_read_compressed+
- pfile_in_zip_read_info->stream.avail_in;
-
- while (pfile_in_zip_read_info->stream.avail_out>0)
- {
- if ((pfile_in_zip_read_info->stream.avail_in==0) &&
- (pfile_in_zip_read_info->rest_read_compressed>0))
- {
- uInt uReadThis = UNZ_BUFSIZE;
- if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
- uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
- if (uReadThis == 0)
- return UNZ_EOF;
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->pos_in_zipfile +
- pfile_in_zip_read_info->byte_before_the_zipfile,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->read_buffer,
- uReadThis)!=uReadThis)
- return UNZ_ERRNO;
-
-
-# ifndef NOUNCRYPT
- if(s->encrypted)
- {
- uInt i;
- for(i=0;i<uReadThis;i++)
- pfile_in_zip_read_info->read_buffer[i] =
- zdecode(s->keys,s->pcrc_32_tab,
- pfile_in_zip_read_info->read_buffer[i]);
- }
-# endif
-
-
- pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
-
- pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
-
- pfile_in_zip_read_info->stream.next_in =
- (Bytef*)pfile_in_zip_read_info->read_buffer;
- pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
- }
-
- if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
- {
- uInt uDoCopy,i ;
-
- if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- return (iRead==0) ? UNZ_EOF : iRead;
-
- if (pfile_in_zip_read_info->stream.avail_out <
- pfile_in_zip_read_info->stream.avail_in)
- uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
- else
- uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
-
- for (i=0;i<uDoCopy;i++)
- *(pfile_in_zip_read_info->stream.next_out+i) =
- *(pfile_in_zip_read_info->stream.next_in+i);
-
- pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
- pfile_in_zip_read_info->stream.next_out,
- uDoCopy);
- pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
- pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
- pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
- pfile_in_zip_read_info->stream.next_out += uDoCopy;
- pfile_in_zip_read_info->stream.next_in += uDoCopy;
- pfile_in_zip_read_info->stream.total_out += uDoCopy;
- iRead += uDoCopy;
- }
- else
- {
- uLong uTotalOutBefore,uTotalOutAfter;
- const Bytef *bufBefore;
- uLong uOutThis;
- int flush=Z_SYNC_FLUSH;
-
- uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
- bufBefore = pfile_in_zip_read_info->stream.next_out;
-
- /*
- if ((pfile_in_zip_read_info->rest_read_uncompressed ==
- pfile_in_zip_read_info->stream.avail_out) &&
- (pfile_in_zip_read_info->rest_read_compressed == 0))
- flush = Z_FINISH;
- */
- err=inflate(&pfile_in_zip_read_info->stream,flush);
-
- if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
- err = Z_DATA_ERROR;
-
- uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
- uOutThis = uTotalOutAfter-uTotalOutBefore;
-
- pfile_in_zip_read_info->crc32 =
- crc32(pfile_in_zip_read_info->crc32,bufBefore,
- (uInt)(uOutThis));
-
- pfile_in_zip_read_info->rest_read_uncompressed -=
- uOutThis;
-
- iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
-
- if (err==Z_STREAM_END)
- return (iRead==0) ? UNZ_EOF : iRead;
- if (err!=Z_OK)
- break;
- }
- }
-
- if (err==Z_OK)
- return iRead;
- return err;
-}
-
-
-/*
- Give the current position in uncompressed data
-*/
-extern z_off_t ZEXPORT unztell (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- return (z_off_t)pfile_in_zip_read_info->stream.total_out;
-}
-
-
-/*
- return 1 if the end of file was reached, 0 elsewhere
-*/
-extern int ZEXPORT unzeof (file)
- unzFile file;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
- return 1;
- else
- return 0;
-}
-
-
-
-/*
- Read extra field from the current file (opened by unzOpenCurrentFile)
- This is the local-header version of the extra field (sometimes, there is
- more info in the local-header version than in the central-header)
-
- if buf==NULL, it return the size of the local extra field that can be read
-
- if buf!=NULL, len is the size of the buffer, the extra header is copied in
- buf.
- the return value is the number of bytes copied in buf, or (if <0)
- the error code
-*/
-extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
- unzFile file;
- voidp buf;
- unsigned len;
-{
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- uInt read_now;
- uLong size_to_read;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
- size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
- pfile_in_zip_read_info->pos_local_extrafield);
-
- if (buf==NULL)
- return (int)size_to_read;
-
- if (len>size_to_read)
- read_now = (uInt)size_to_read;
- else
- read_now = (uInt)len ;
-
- if (read_now==0)
- return 0;
-
- if (ZSEEK(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- pfile_in_zip_read_info->offset_local_extrafield +
- pfile_in_zip_read_info->pos_local_extrafield,
- ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (ZREAD(pfile_in_zip_read_info->z_filefunc,
- pfile_in_zip_read_info->filestream,
- buf,read_now)!=read_now)
- return UNZ_ERRNO;
-
- return (int)read_now;
-}
-
-/*
- Close the file in zip opened with unzipOpenCurrentFile
- Return UNZ_CRCERROR if all the file was read but the CRC is not good
-*/
-extern int ZEXPORT unzCloseCurrentFile (file)
- unzFile file;
-{
- int err=UNZ_OK;
-
- unz_s* s;
- file_in_zip_read_info_s* pfile_in_zip_read_info;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- pfile_in_zip_read_info=s->pfile_in_zip_read;
-
- if (pfile_in_zip_read_info==NULL)
- return UNZ_PARAMERROR;
-
-
- if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
- (!pfile_in_zip_read_info->raw))
- {
- if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
- err=UNZ_CRCERROR;
- }
-
-
- TRYFREE(pfile_in_zip_read_info->read_buffer);
- pfile_in_zip_read_info->read_buffer = NULL;
- if (pfile_in_zip_read_info->stream_initialised)
- inflateEnd(&pfile_in_zip_read_info->stream);
-
- pfile_in_zip_read_info->stream_initialised = 0;
- TRYFREE(pfile_in_zip_read_info);
-
- s->pfile_in_zip_read=NULL;
-
- return err;
-}
-
-
-/*
- Get the global comment string of the ZipFile, in the szComment buffer.
- uSizeBuf is the size of the szComment buffer.
- return the number of byte copied or an error code <0
-*/
-extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
- unzFile file;
- char *szComment;
- uLong uSizeBuf;
-{
- int err=UNZ_OK;
- unz_s* s;
- uLong uReadThis ;
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- uReadThis = uSizeBuf;
- if (uReadThis>s->gi.size_comment)
- uReadThis = s->gi.size_comment;
-
- if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
- return UNZ_ERRNO;
-
- if (uReadThis>0)
- {
- *szComment='\0';
- if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
- return UNZ_ERRNO;
- }
-
- if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
- *(szComment+s->gi.size_comment)='\0';
- return (int)uReadThis;
-}
-
-/* Additions by RX '2004 */
-extern uLong ZEXPORT unzGetOffset (file)
- unzFile file;
-{
- unz_s* s;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
- if (!s->current_file_ok)
- return 0;
- if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
- if (s->num_file==s->gi.number_entry)
- return 0;
- return s->pos_in_central_dir;
-}
-
-extern int ZEXPORT unzSetOffset (file, pos)
- unzFile file;
- uLong pos;
-{
- unz_s* s;
- int err;
-
- if (file==NULL)
- return UNZ_PARAMERROR;
- s=(unz_s*)file;
-
- s->pos_in_central_dir = pos;
- s->num_file = s->gi.number_entry; /* hack */
- err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
- &s->cur_file_info_internal,
- NULL,0,NULL,0,NULL,0);
- s->current_file_ok = (err == UNZ_OK);
- return err;
-}
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes b/src/3rdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
deleted file mode 100644
index 364411a23..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/doc/ReleaseNotes
+++ /dev/null
@@ -1,12 +0,0 @@
-utf8 cpp library
-Release 2.3.4
-
-A minor bug fix release. Thanks to all who reported bugs.
-
-Note: Version 2.3.3 contained a regression, and therefore was removed.
-
-Changes from version 2.3.2
-- Bug fix [39]: checked.h Line 273 and unchecked.h Line 182 have an extra ';'
-- Bug fix [36]: replace_invalid() only works with back_inserter
-
-Files included in the release: utf8.h, core.h, checked.h, unchecked.h, utf8cpp.html, ReleaseNotes
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html b/src/3rdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
deleted file mode 100644
index 6f2aacbe7..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/doc/utf8cpp.html
+++ /dev/null
@@ -1,1789 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
- <head>
- <meta name="generator" content=
- "HTML Tidy for Linux/x86 (vers 1st November 2002), see www.w3.org">
- <meta name="description" content=
- "A simple, portable and lightweigt C++ library for easy handling of UTF-8 encoded strings">
- <meta name="keywords" content="UTF-8 C++ portable utf8 unicode generic templates">
- <meta name="author" content="Nemanja Trifunovic">
- <title>
- UTF8-CPP: UTF-8 with C++ in a Portable Way
- </title>
- <style type="text/css">
- <!--
- span.return_value {
- color: brown;
- }
- span.keyword {
- color: blue;
- }
- span.preprocessor {
- color: navy;
- }
- span.literal {
- color: olive;
- }
- span.comment {
- color: green;
- }
- code {
- font-weight: bold;
- }
- ul.toc {
- list-style-type: none;
- }
- p.version {
- font-size: small;
- font-style: italic;
- }
- -->
- </style>
- </head>
- <body>
- <h1>
- UTF8-CPP: UTF-8 with C++ in a Portable Way
- </h1>
- <p>
- <a href="https://sourceforge.net/projects/utfcpp">The Sourceforge project page</a>
- </p>
- <div id="toc">
- <h2>
- Table of Contents
- </h2>
- <ul class="toc">
- <li>
- <a href="#introduction">Introduction</a>
- </li>
- <li>
- <a href="#examples">Examples of Use</a>
- <ul class="toc">
- <li>
- <a href=#introsample>Introductionary Sample </a>
- </li>
- <li>
- <a href=#validfile>Checking if a file contains valid UTF-8 text</a>
- </li>
- <li>
- <a href=#fixinvalid>Ensure that a string contains valid UTF-8 text</a>
- </li>
- </ul>
- <li>
- <a href="#reference">Reference</a>
- <ul class="toc">
- <li>
- <a href="#funutf8">Functions From utf8 Namespace </a>
- </li>
- <li>
- <a href="#typesutf8">Types From utf8 Namespace </a>
- </li>
- <li>
- <a href="#fununchecked">Functions From utf8::unchecked Namespace </a>
- </li>
- <li>
- <a href="#typesunchecked">Types From utf8::unchecked Namespace </a>
- </li>
- </ul>
- </li>
- <li>
- <a href="#points">Points of Interest</a>
- </li>
- <li>
- <a href="#links">Links</a>
- </li>
- </ul>
- </div>
- <h2 id="introduction">
- Introduction
- </h2>
- <p>
- Many C++ developers miss an easy and portable way of handling Unicode encoded
- strings. The original C++ Standard (known as C++98 or C++03) is Unicode agnostic.
- C++11 provides some support for Unicode on core language and library level:
- u8, u, and U character and string literals, char16_t and char32_t character types,
- u16string and u32string library classes, and codecvt support for conversions
- between Unicode encoding forms.
- In the meantime, developers use third party libraries like ICU, OS specific capabilities, or simply
- roll out their own solutions.
- </p>
- <p>
- In order to easily handle UTF-8 encoded Unicode strings, I came up with a small
- generic library. For anybody used to work with STL algorithms and iterators, it should be
- easy and natural to use. The code is freely available for any purpose - check out
- the license at the beginning of the utf8.h file. If you run into
- bugs or performance issues, please let me know and I'll do my best to address them.
- </p>
- <p>
- The purpose of this article is not to offer an introduction to Unicode in general,
- and UTF-8 in particular. If you are not familiar with Unicode, be sure to check out
- <a href="http://www.unicode.org/">Unicode Home Page</a> or some other source of
- information for Unicode. Also, it is not my aim to advocate the use of UTF-8
- encoded strings in C++ programs; if you want to handle UTF-8 encoded strings from
- C++, I am sure you have good reasons for it.
- </p>
- <h2 id="examples">
- Examples of use
- </h2>
- <h3 id="introsample">
- Introductionary Sample
- </h3>
- <p>
- To illustrate the use of the library, let's start with a small but complete program
- that opens a file containing UTF-8 encoded text, reads it line by line, checks each line
- for invalid UTF-8 byte sequences, and converts it to UTF-16 encoding and back to UTF-8:
- </p>
-<pre>
-<span class="preprocessor">#include &lt;fstream&gt;</span>
-<span class="preprocessor">#include &lt;iostream&gt;</span>
-<span class="preprocessor">#include &lt;string&gt;</span>
-<span class="preprocessor">#include &lt;vector&gt;</span>
-<span class="preprocessor">#include "utf8.h"</span>
-<span class="keyword">using namespace</span> std;
-<span class="keyword">int</span> main(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)
-{
- <span class="keyword">if</span> (argc != <span class="literal">2</span>) {
- cout &lt;&lt; <span class="literal">"\nUsage: docsample filename\n"</span>;
- <span class="keyword">return</span> <span class="literal">0</span>;
- }
-
- <span class="keyword">const char</span>* test_file_path = argv[1];
- <span class="comment">// Open the test file (contains UTF-8 encoded text)</span>
- ifstream fs8(test_file_path);
- <span class="keyword">if</span> (!fs8.is_open()) {
- cout &lt;&lt; <span class=
-"literal">"Could not open "</span> &lt;&lt; test_file_path &lt;&lt; endl;
- <span class="keyword">return</span> <span class="literal">0</span>;
- }
-
- <span class="keyword">unsigned</span> line_count = <span class="literal">1</span>;
- string line;
- <span class="comment">// Play with all the lines in the file</span>
- <span class="keyword">while</span> (getline(fs8, line)) {
- <span class="comment">// check for invalid utf-8 (for a simple yes/no check, there is also utf8::is_valid function)</span>
- string::iterator end_it = utf8::find_invalid(line.begin(), line.end());
- <span class="keyword">if</span> (end_it != line.end()) {
- cout &lt;&lt; <span class=
-"literal">"Invalid UTF-8 encoding detected at line "</span> &lt;&lt; line_count &lt;&lt; <span
- class="literal">"\n"</span>;
- cout &lt;&lt; <span class=
-"literal">"This part is fine: "</span> &lt;&lt; string(line.begin(), end_it) &lt;&lt; <span
- class="literal">"\n"</span>;
- }
-
- <span class="comment">// Get the line length (at least for the valid part)</span>
- <span class="keyword">int</span> length = utf8::distance(line.begin(), end_it);
- cout &lt;&lt; <span class=
-"literal">"Length of line "</span> &lt;&lt; line_count &lt;&lt; <span class=
-"literal">" is "</span> &lt;&lt; length &lt;&lt; <span class="literal">"\n"</span>;
-
- <span class="comment">// Convert it to utf-16</span>
- vector&lt;unsigned short&gt; utf16line;
- utf8::utf8to16(line.begin(), end_it, back_inserter(utf16line));
-
- <span class="comment">// And back to utf-8</span>
- string utf8line;
- utf8::utf16to8(utf16line.begin(), utf16line.end(), back_inserter(utf8line));
-
- <span class="comment">// Confirm that the conversion went OK:</span>
- <span class="keyword">if</span> (utf8line != string(line.begin(), end_it))
- cout &lt;&lt; <span class=
-"literal">"Error in UTF-16 conversion at line: "</span> &lt;&lt; line_count &lt;&lt; <span
- class="literal">"\n"</span>;
-
- line_count++;
- }
- <span class="keyword">return</span> <span class="literal">0</span>;
-}
-</pre>
- <p>
- In the previous code sample, for each line we performed
- a detection of invalid UTF-8 sequences with <code>find_invalid</code>; the number
- of characters (more precisely - the number of Unicode code points, including the end
- of line and even BOM if there is one) in each line was
- determined with a use of <code>utf8::distance</code>; finally, we have converted
- each line to UTF-16 encoding with <code>utf8to16</code> and back to UTF-8 with
- <code>utf16to8</code>.
- </p>
- <h3 id="validfile">Checking if a file contains valid UTF-8 text</h3>
-<p>
-Here is a function that checks whether the content of a file is valid UTF-8 encoded text without
-reading the content into the memory:
-</p>
-<pre>
-<span class="keyword">bool</span> valid_utf8_file(i<span class="keyword">const char</span>* file_name)
-{
- ifstream ifs(file_name);
- <span class="keyword">if</span> (!ifs)
- <span class="keyword">return false</span>; <span class="comment">// even better, throw here</span>
-
- istreambuf_iterator&lt;<span class="keyword">char</span>&gt; it(ifs.rdbuf());
- istreambuf_iterator&lt;<span class="keyword">char</span>&gt; eos;
-
- <span class="keyword">return</span> utf8::is_valid(it, eos);
-}
-</pre>
-<p>
-Because the function <code>utf8::is_valid()</code> works with input iterators, we were able
-to pass an <code>istreambuf_iterator</code> to it and read the content of the file directly
-without loading it to the memory first.</p>
-<p>
-Note that other functions that take input iterator arguments can be used in a similar way. For
-instance, to read the content of a UTF-8 encoded text file and convert the text to UTF-16, just
-do something like:
-</p>
-<pre>
- utf8::utf8to16(it, eos, back_inserter(u16string));
-</pre>
- <h3 id="fixinvalid">Ensure that a string contains valid UTF-8 text</h3>
-<p>
-If we have some text that "probably" contains UTF-8 encoded text and we want to
-replace any invalid UTF-8 sequence with a replacement character, something like
-the following function may be used:
-</p>
-<pre>
-<span class="keyword">void</span> fix_utf8_string(std::string&amp; str)
-{
- std::string temp;
- utf8::replace_invalid(str.begin(), str.end(), back_inserter(temp));
- str = temp;
-}
-</pre>
-<p>The function will replace any invalid UTF-8 sequence with a Unicode replacement character.
-There is an overloaded function that enables the caller to supply their own replacement character.
-</p>
- <h2 id="reference">
- Reference
- </h2>
- <h3 id="funutf8">
- Functions From utf8 Namespace
- </h3>
- <h4>
- utf8::append
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
- to a UTF-8 string.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-octet_iterator append(uint32_t cp, octet_iterator result);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an output iterator.<br>
- <code>cp</code>: a 32 bit integer representing a code point to append to the
- sequence.<br>
- <code>result</code>: an output iterator to the place in the sequence where to
- append the code point.<br>
- <span class="return_value">Return value</span>: an iterator pointing to the place
- after the newly appended sequence.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
-class="literal">0</span>,<span class="literal">0</span>,<span class=
-"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
-<span class="keyword">unsigned char</span>* end = append(<span class=
-"literal">0x0448</span>, u);
-assert (u[<span class="literal">0</span>] == <span class=
-"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
-"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
-"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
-"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
-"literal">0</span>);
-</pre>
- <p>
- Note that <code>append</code> does not allocate any memory - it is the burden of
- the caller to make sure there is enough memory allocated for the operation. To make
- things more interesting, <code>append</code> can add anywhere between 1 and 4
- octets to the sequence. In practice, you would most often want to use
- <code>std::back_inserter</code> to ensure that the necessary memory is allocated.
- </p>
- <p>
- In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
- is thrown.
- </p>
- <h4>
- utf8::next
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Given the iterator to the beginning of the UTF-8 sequence, it returns the code
- point and moves the iterator to the next position.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t next(octet_iterator&amp; it, octet_iterator end);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
- encoded code point. After the function returns, it is incremented to point to the
- beginning of the next code point.<br>
- <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
- gets equal to <code>end</code> during the extraction of a code point, an
- <code>utf8::not_enough_room</code> exception is thrown.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- processed UTF-8 code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars;
-<span class="keyword">int</span> cp = next(w, twochars + <span class="literal">6</span>);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars + <span class="literal">3</span>);
-</pre>
- <p>
- This function is typically used to iterate through a UTF-8 encoded string.
- </p>
- <p>
- In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
- thrown.
- </p>
- <h4>
- utf8::peek_next
- </h4>
- <p class="version">
- Available in version 2.1 and later.
- </p>
- <p>
- Given the iterator to the beginning of the UTF-8 sequence, it returns the code
- point for the following sequence without changing the value of the iterator.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t peek_next(octet_iterator it, octet_iterator end);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>it</code>: an iterator pointing to the beginning of an UTF-8
- encoded code point.<br>
- <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
- gets equal to <code>end</code> during the extraction of a code point, an
- <code>utf8::not_enough_room</code> exception is thrown.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- processed UTF-8 code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars;
-<span class="keyword">int</span> cp = peek_next(w, twochars + <span class="literal">6</span>);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
- thrown.
- </p>
- <h4>
- utf8::prior
- </h4>
- <p class="version">
- Available in version 1.02 and later.
- </p>
- <p>
- Given a reference to an iterator pointing to an octet in a UTF-8 sequence, it
- decreases the iterator until it hits the beginning of the previous UTF-8 encoded
- code point and returns the 32 bits representation of the code point.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t prior(octet_iterator&amp; it, octet_iterator start);
-
-</pre>
- <p>
- <code>octet_iterator</code>: a bidirectional iterator.<br>
- <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
- After the function returns, it is decremented to point to the beginning of the
- previous code point.<br>
- <code>start</code>: an iterator to the beginning of the sequence where the search
- for the beginning of a code point is performed. It is a
- safety measure to prevent passing the beginning of the string in the search for a
- UTF-8 lead octet.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- previous code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">unsigned char</span>* w = twochars + <span class=
-"literal">3</span>;
-<span class="keyword">int</span> cp = prior (w, twochars);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- This function has two purposes: one is two iterate backwards through a UTF-8
- encoded string. Note that it is usually a better idea to iterate forward instead,
- since <code>utf8::next</code> is faster. The second purpose is to find a beginning
- of a UTF-8 sequence if we have a random position within a string. Note that in that
- case <code>utf8::prior</code> may not detect an invalid UTF-8 sequence in some scenarios:
- for instance if there are superfluous trail octets, it will just skip them.
- </p>
- <p>
- <code>it</code> will typically point to the beginning of
- a code point, and <code>start</code> will point to the
- beginning of the string to ensure we don't go backwards too far. <code>it</code> is
- decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
- beginning with that octet is decoded to a 32 bit representation and returned.
- </p>
- <p>
- In case <code>start</code> is reached before a UTF-8 lead octet is hit, or if an
- invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
- exception is thrown.
- </p>
- <p>In case <code>start</code> equals <code>it</code>, a <code>not_enough_room</code>
- exception is thrown.
- <h4>
- utf8::previous
- </h4>
- <p class="version">
- Deprecated in version 1.02 and later.
- </p>
- <p>
- Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
- decreases the iterator until it hits the beginning of the previous UTF-8 encoded
- code point and returns the 32 bits representation of the code point.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t previous(octet_iterator&amp; it, octet_iterator pass_start);
-
-</pre>
- <p>
- <code>octet_iterator</code>: a random access iterator.<br>
- <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
- After the function returns, it is decremented to point to the beginning of the
- previous code point.<br>
- <code>pass_start</code>: an iterator to the point in the sequence where the search
- for the beginning of a code point is aborted if no result was reached. It is a
- safety measure to prevent passing the beginning of the string in the search for a
- UTF-8 lead octet.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- previous code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">unsigned char</span>* w = twochars + <span class=
-"literal">3</span>;
-<span class="keyword">int</span> cp = previous (w, twochars - <span class=
-"literal">1</span>);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- <code>utf8::previous</code> is deprecated, and <code>utf8::prior</code> should
- be used instead, although the existing code can continue using this function.
- The problem is the parameter <code>pass_start</code> that points to the position
- just before the beginning of the sequence. Standard containers don't have the
- concept of "pass start" and the function can not be used with their iterators.
- </p>
- <p>
- <code>it</code> will typically point to the beginning of
- a code point, and <code>pass_start</code> will point to the octet just before the
- beginning of the string to ensure we don't go backwards too far. <code>it</code> is
- decreased until it points to a lead UTF-8 octet, and then the UTF-8 sequence
- beginning with that octet is decoded to a 32 bit representation and returned.
- </p>
- <p>
- In case <code>pass_start</code> is reached before a UTF-8 lead octet is hit, or if an
- invalid UTF-8 sequence is started by the lead octet, an <code>invalid_utf8</code>
- exception is thrown
- </p>
- <h4>
- utf8::advance
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Advances an iterator by the specified number of code points within an UTF-8
- sequence.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, typename distance_type&gt;
-<span class=
-"keyword">void</span> advance (octet_iterator&amp; it, distance_type n, octet_iterator end);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>distance_type</code>: an integral type convertible to <code>octet_iterator</code>'s difference type.<br>
- <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
- encoded code point. After the function returns, it is incremented to point to the
- nth following code point.<br>
- <code>n</code>: a positive integer that shows how many code points we want to
- advance.<br>
- <code>end</code>: end of the UTF-8 sequence to be processed. If <code>it</code>
- gets equal to <code>end</code> during the extraction of a code point, an
- <code>utf8::not_enough_room</code> exception is thrown.<br>
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">unsigned char</span>* w = twochars;
-advance (w, <span class="literal">2</span>, twochars + <span class="literal">6</span>);
-assert (w == twochars + <span class="literal">5</span>);
-</pre>
- <p>
- This function works only "forward". In case of a negative <code>n</code>, there is
- no effect.
- </p>
- <p>
- In case of an invalid code point, a <code>utf8::invalid_code_point</code> exception
- is thrown.
- </p>
- <h4>
- utf8::distance
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Given the iterators to two UTF-8 encoded code points in a seqence, returns the
- number of code points between them.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-<span class=
-"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
- <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
- point in the sequence we are trying to determine the length. It can be the
- beginning of a new code point, or not.<br>
- <span class="return_value">Return value</span> the distance between the iterators,
- in code points.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-size_t dist = utf8::distance(twochars, twochars + <span class="literal">5</span>);
-assert (dist == <span class="literal">2</span>);
-</pre>
- <p>
- This function is used to find the length (in code points) of a UTF-8 encoded
- string. The reason it is called <em>distance</em>, rather than, say,
- <em>length</em> is mainly because developers are used that <em>length</em> is an
- O(1) function. Computing the length of an UTF-8 string is a linear operation, and
- it looked better to model it after <code>std::distance</code> algorithm.
- </p>
- <p>
- In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
- thrown. If <code>last</code> does not point to the past-of-end of a UTF-8 seqence,
- a <code>utf8::not_enough_room</code> exception is thrown.
- </p>
- <h4>
- utf8::utf16to8
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-16 encoded string to UTF-8.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> u16bit_iterator, <span class=
-"keyword">typename</span> octet_iterator&gt;
-octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
-
-</pre>
- <p>
- <code>u16bit_iterator</code>: an input iterator.<br>
- <code>octet_iterator</code>: an output iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
- string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-8 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-8 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned short</span> utf16string[] = {<span class=
-"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
-"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
-"literal">0xdd1e</span>};
-vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
-utf16to8(utf16string, utf16string + <span class=
-"literal">5</span>, back_inserter(utf8result));
-assert (utf8result.size() == <span class="literal">10</span>);
-</pre>
- <p>
- In case of invalid UTF-16 sequence, a <code>utf8::invalid_utf16</code> exception is
- thrown.
- </p>
- <h4>
- utf8::utf8to16
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts an UTF-8 encoded string to UTF-16
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
-u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>u16bit_iterator</code>: an output iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
- string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
- pass-the-end of the UTF-8 encoded string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-16 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-16 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
-vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
-utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
-"literal">9</span>, back_inserter(utf16result));
-assert (utf16result.size() == <span class="literal">4</span>);
-assert (utf16result[<span class="literal">2</span>] == <span class=
-"literal">0xd834</span>);
-assert (utf16result[<span class="literal">3</span>] == <span class=
-"literal">0xdd1e</span>);
-</pre>
- <p>
- In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
- thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
- <code>utf8::not_enough_room</code> exception is thrown.
- </p>
- <h4>
- utf8::utf32to8
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-32 encoded string to UTF-8.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
-octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an output iterator.<br>
- <code>u32bit_iterator</code>: an input iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
- string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-8 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-8 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">int</span> utf32string[] = {<span class=
-"literal">0x448</span>, <span class="literal">0x65E5</span>, <span class=
-"literal">0x10346</span>, <span class="literal">0</span>};
-vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
-utf32to8(utf32string, utf32string + <span class=
-"literal">3</span>, back_inserter(utf8result));
-assert (utf8result.size() == <span class="literal">9</span>);
-</pre>
- <p>
- In case of invalid UTF-32 string, a <code>utf8::invalid_code_point</code> exception
- is thrown.
- </p>
- <h4>
- utf8::utf8to32
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-8 encoded string to UTF-32.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, <span class=
-"keyword">typename</span> u32bit_iterator&gt;
-u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>u32bit_iterator</code>: an output iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
- to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-32 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-32 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-vector&lt;<span class="keyword">int</span>&gt; utf32result;
-utf8to32(twochars, twochars + <span class=
-"literal">5</span>, back_inserter(utf32result));
-assert (utf32result.size() == <span class="literal">2</span>);
-</pre>
- <p>
- In case of an invalid UTF-8 seqence, a <code>utf8::invalid_utf8</code> exception is
- thrown. If <code>end</code> does not point to the past-of-end of a UTF-8 seqence, a
- <code>utf8::not_enough_room</code> exception is thrown.
- </p>
- <h4>
- utf8::find_invalid
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Detects an invalid sequence within a UTF-8 string.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-octet_iterator find_invalid(octet_iterator start, octet_iterator end);
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
- test for validity.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
- for validity.<br>
- <span class="return_value">Return value</span>: an iterator pointing to the first
- invalid octet in the UTF-8 string. In case none were found, equals
- <code>end</code>.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span> utf_invalid[] = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
-<span class=
-"keyword">char</span>* invalid = find_invalid(utf_invalid, utf_invalid + <span class=
-"literal">6</span>);
-assert (invalid == utf_invalid + <span class="literal">5</span>);
-</pre>
- <p>
- This function is typically used to make sure a UTF-8 string is valid before
- processing it with other functions. It is especially important to call it if before
- doing any of the <em>unchecked</em> operations on it.
- </p>
- <h4>
- utf8::is_valid
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Checks whether a sequence of octets is a valid UTF-8 string.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-<span class="keyword">bool</span> is_valid(octet_iterator start, octet_iterator end);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
- test for validity.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to test
- for validity.<br>
- <span class="return_value">Return value</span>: <code>true</code> if the sequence
- is a valid UTF-8 string; <code>false</code> if not.
- </p>
- Example of use:
-<pre>
-<span class="keyword">char</span> utf_invalid[] = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88\xfa"</span>;
-<span class="keyword">bool</span> bvalid = is_valid(utf_invalid, utf_invalid + <span
-class="literal">6</span>);
-assert (bvalid == false);
-</pre>
- <p>
- <code>is_valid</code> is a shorthand for <code>find_invalid(start, end) ==
- end;</code>. You may want to use it to make sure that a byte seqence is a valid
- UTF-8 string without the need to know where it fails if it is not valid.
- </p>
- <h4>
- utf8::replace_invalid
- </h4>
- <p class="version">
- Available in version 2.0 and later.
- </p>
- <p>
- Replaces all invalid UTF-8 sequences within a string with a replacement marker.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, <span class=
-"keyword">typename</span> output_iterator&gt;
-output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement);
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, <span class=
-"keyword">typename</span> output_iterator&gt;
-output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out);
-
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>output_iterator</code>: an output iterator.<br>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 string to
- look for invalid UTF-8 sequences.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 string to look
- for invalid UTF-8 sequences.<br>
- <code>out</code>: An output iterator to the range where the result of replacement
- is stored.<br>
- <code>replacement</code>: A Unicode code point for the replacement marker. The
- version without this parameter assumes the value <code>0xfffd</code><br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the UTF-8 string with replaced invalid sequences.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span> invalid_sequence[] = <span class=
-"literal">"a\x80\xe0\xa0\xc0\xaf\xed\xa0\x80z"</span>;
-vector&lt;<span class="keyword">char</span>&gt; replace_invalid_result;
-replace_invalid (invalid_sequence, invalid_sequence + sizeof(invalid_sequence), back_inserter(replace_invalid_result), <span
- class="literal">'?'</span>);
-bvalid = is_valid(replace_invalid_result.begin(), replace_invalid_result.end());
-assert (bvalid);
-<span class="keyword">char</span>* fixed_invalid_sequence = <span class=
-"literal">"a????z"</span>;
-assert (std::equal(replace_invalid_result.begin(), replace_invalid_result.end(), fixed_invalid_sequence));
-</pre>
- <p>
- <code>replace_invalid</code> does not perform in-place replacement of invalid
- sequences. Rather, it produces a copy of the original string with the invalid
- sequences replaced with a replacement marker. Therefore, <code>out</code> must not
- be in the <code>[start, end]</code> range.
- </p>
- <p>
- If <code>end</code> does not point to the past-of-end of a UTF-8 sequence, a
- <code>utf8::not_enough_room</code> exception is thrown.
- </p>
- <h4>
- utf8::starts_with_bom
- </h4>
- <p class="version">
- Available in version 2.3 and later. Relaces deprecated <code>is_bom()</code> function.
- </p>
- <p>
- Checks whether an octet sequence starts with a UTF-8 byte order mark (BOM)
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-<span class="keyword">bool</span> starts_with_bom (octet_iterator it, octet_iterator end);
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>it</code>: beginning of the octet sequence to check<br>
- <code>end</code>: pass-end of the sequence to check<br>
- <span class="return_value">Return value</span>: <code>true</code> if the sequence
- starts with a UTF-8 byte order mark; <code>false</code> if not.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
-"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
-"literal">0xbf</span>};
-<span class="keyword">bool</span> bbom = starts_with_bom(byte_order_mark, byte_order_mark + <span class="keyword">sizeof</span>(byte_order_mark));
-assert (bbom == <span class="literal">true</span>);
-</pre>
- <p>
- The typical use of this function is to check the first three bytes of a file. If
- they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
- encoded text.
- </p>
- <h4>
- utf8::is_bom
- </h4>
- <p class="version">
- Available in version 1.0 and later. Deprecated in version 2.3. <code>starts_with_bom()</code> should be used
- instead.
- </p>
- <p>
- Checks whether a sequence of three octets is a UTF-8 byte order mark (BOM)
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-<span class="keyword">bool</span> is_bom (octet_iterator it); <span class="comment"> // Deprecated</span>
-</pre>
- <p>
- <code>octet_iterator</code>: an input iterator.<br>
- <code>it</code>: beginning of the 3-octet sequence to check<br>
- <span class="return_value">Return value</span>: <code>true</code> if the sequence
- is UTF-8 byte order mark; <code>false</code> if not.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned char</span> byte_order_mark[] = {<span class=
-"literal">0xef</span>, <span class="literal">0xbb</span>, <span class=
-"literal">0xbf</span>};
-<span class="keyword">bool</span> bbom = is_bom(byte_order_mark);
-assert (bbom == <span class="literal">true</span>);
-</pre>
- <p>
- The typical use of this function is to check the first three bytes of a file. If
- they form the UTF-8 BOM, we want to skip them before processing the actual UTF-8
- encoded text.
- </p>
- <p>
- If a sequence is
- shorter than three bytes, an invalid iterator will be dereferenced. Therefore, this function is deprecated
- in favor of <code>starts_with_bom()</code>that takes the end of sequence as an argument.
- </p>
- <h3 id="typesutf8">
- Types From utf8 Namespace
- </h3>
- <h4>utf8::exception
- </h4>
- <p class="version">
- Available in version 2.3 and later.
- </p>
- <p>
- Base class for the exceptions thrown by UTF CPP library functions.
- </p>
-<pre>
-<span class="keyword">class</span> exception : <span class="keyword">public</span> std::exception {};
-</pre>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">try</span> {
- code_that_uses_utf_cpp_library();
-}
-<span class="keyword">catch</span>(<span class="keyword">const</span> utf8::exception&amp; utfcpp_ex) {
- cerr &lt;&lt; utfcpp_ex.what();
-}
-</pre>
-
- <h4>utf8::invalid_code_point
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Thrown by UTF8 CPP functions such as <code>advance</code> and <code>next</code> if an UTF-8 sequence represents and invalid code point.
- </p>
-
-<pre>
-<span class="keyword">class</span> invalid_code_point : <span class="keyword">public</span> exception {
-<span class="keyword">public</span>:
- uint32_t code_point() <span class="keyword">const</span>;
-};
-
-</pre>
- <p>
- Member function <code>code_point()</code> can be used to determine the invalid code point that
- caused the exception to be thrown.
- </p>
- <h4>utf8::invalid_utf8
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Thrown by UTF8 CPP functions such as <code>next</code> and <code>prior</code> if an invalid UTF-8 sequence
- is detected during decoding.
- </p>
-
-<pre>
-<span class="keyword">class</span> invalid_utf8 : <span class="keyword">public</span> exception {
-<span class="keyword">public</span>:
- uint8_t utf8_octet() <span class="keyword">const</span>;
-};
-</pre>
-
- <p>
- Member function <code>utf8_octet()</code> can be used to determine the beginning of the byte
- sequence that caused the exception to be thrown.
- </p>
-</pre>
- <h4>utf8::invalid_utf16
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Thrown by UTF8 CPP function <code>utf16to8</code> if an invalid UTF-16 sequence
- is detected during decoding.
- </p>
-
-<pre>
-<span class="keyword">class</span> invalid_utf16 : <span class="keyword">public</span> exception {
-<span class="keyword">public</span>:
- uint16_t utf16_word() <span class="keyword">const</span>;
-};
-</pre>
-
- <p>
- Member function <code>utf16_word()</code> can be used to determine the UTF-16 code unit
- that caused the exception to be thrown.
- </p>
- <h4>utf8::not_enough_room
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Thrown by UTF8 CPP functions such as <code>next</code> if the end of the decoded UTF-8 sequence
- was reached before the code point was decoded.
- </p>
-
-<pre>
-<span class="keyword">class</span> not_enough_room : <span class="keyword">public</span> exception {};
-</pre>
- <h4>
- utf8::iterator
- </h4>
- <p class="version">
- Available in version 2.0 and later.
- </p>
- <p>
- Adapts the underlying octet iterator to iterate over the sequence of code points,
- rather than raw octets.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
-<span class="keyword">class</span> iterator;
-</pre>
-
- <h5>Member functions</h5>
- <dl>
- <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
- constructed with its default constructor.
- <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it,
- const octet_iterator&amp; range_start,
- const octet_iterator&amp; range_end);</code> <dd> a constructor
- that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
- and sets the range in which the iterator is considered valid.
- <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
- underlying <code>octet_iterator</code>.
- <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
- the underlying <code>octet_iterator</code> is pointing to and returns the code point.
- <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
- <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
- if the two underlaying iterators are equal.
- <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
- <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
- if the two underlaying iterators are not equal.
- <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
- the iterator to the next UTF-8 encoded code point.
- <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
- the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
- <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
- the iterator to the previous UTF-8 encoded code point.
- <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
- the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
- </dl>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
-utf8::iterator&lt;<span class="keyword">char</span>*&gt; it(threechars, threechars, threechars + <span class="literal">9</span>);
-utf8::iterator&lt;<span class="keyword">char</span>*&gt; it2 = it;
-assert (it2 == it);
-assert (*it == <span class="literal">0x10346</span>);
-assert (*(++it) == <span class="literal">0x65e5</span>);
-assert ((*it++) == <span class="literal">0x65e5</span>);
-assert (*it == <span class="literal">0x0448</span>);
-assert (it != it2);
-utf8::iterator&lt;<span class="keyword">char</span>*&gt; endit (threechars + <span class="literal">9</span>, threechars, threechars + <span class="literal">9</span>);
-assert (++it == endit);
-assert (*(--it) == <span class="literal">0x0448</span>);
-assert ((*it--) == <span class="literal">0x0448</span>);
-assert (*it == <span class="literal">0x65e5</span>);
-assert (--it == utf8::iterator&lt;<span class="keyword">char</span>*&gt;(threechars, threechars, threechars + <span class="literal">9</span>));
-assert (*it == <span class="literal">0x10346</span>);
-</pre>
- <p>
- The purpose of <code>utf8::iterator</code> adapter is to enable easy iteration as well as the use of STL
- algorithms with UTF-8 encoded strings. Increment and decrement operators are implemented in terms of
- <code>utf8::next()</code> and <code>utf8::prior()</code> functions.
- </p>
- <p>
- Note that <code>utf8::iterator</code> adapter is a checked iterator. It operates on the range specified in
- the constructor; any attempt to go out of that range will result in an exception. Even the comparison operators
- require both iterator object to be constructed against the same range - otherwise an exception is thrown. Typically,
- the range will be determined by sequence container functions <code>begin</code> and <code>end</code>, i.e.:
- </p>
-<pre>
-std::string s = <span class="literal">"example"</span>;
-utf8::iterator i (s.begin(), s.begin(), s.end());
-</pre>
- <h3 id="fununchecked">
- Functions From utf8::unchecked Namespace
- </h3>
- <h4>
- utf8::unchecked::append
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Encodes a 32 bit code point as a UTF-8 sequence of octets and appends the sequence
- to a UTF-8 string.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-octet_iterator append(uint32_t cp, octet_iterator result);
-
-</pre>
- <p>
- <code>cp</code>: A 32 bit integer representing a code point to append to the
- sequence.<br>
- <code>result</code>: An output iterator to the place in the sequence where to
- append the code point.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the newly appended sequence.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned char</span> u[<span class="literal">5</span>] = {<span
-class="literal">0</span>,<span class="literal">0</span>,<span class=
-"literal">0</span>,<span class="literal">0</span>,<span class="literal">0</span>};
-<span class="keyword">unsigned char</span>* end = unchecked::append(<span class=
-"literal">0x0448</span>, u);
-assert (u[<span class="literal">0</span>] == <span class=
-"literal">0xd1</span> &amp;&amp; u[<span class="literal">1</span>] == <span class=
-"literal">0x88</span> &amp;&amp; u[<span class="literal">2</span>] == <span class=
-"literal">0</span> &amp;&amp; u[<span class="literal">3</span>] == <span class=
-"literal">0</span> &amp;&amp; u[<span class="literal">4</span>] == <span class=
-"literal">0</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::append</code>. It does not
- check for validity of the supplied code point, and may produce an invalid UTF-8
- sequence.
- </p>
- <h4>
- utf8::unchecked::next
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Given the iterator to the beginning of a UTF-8 sequence, it returns the code point
- and moves the iterator to the next position.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t next(octet_iterator&amp; it);
-
-</pre>
- <p>
- <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
- encoded code point. After the function returns, it is incremented to point to the
- beginning of the next code point.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- processed UTF-8 code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars;
-<span class="keyword">int</span> cp = unchecked::next(w);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars + <span class="literal">3</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::next</code>. It does not
- check for validity of the supplied UTF-8 sequence.
- </p>
- <h4>
- utf8::unchecked::peek_next
- </h4>
- <p class="version">
- Available in version 2.1 and later.
- </p>
- <p>
- Given the iterator to the beginning of a UTF-8 sequence, it returns the code point.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t peek_next(octet_iterator it);
-
-</pre>
- <p>
- <code>it</code>: an iterator pointing to the beginning of an UTF-8
- encoded code point.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- processed UTF-8 code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars;
-<span class="keyword">int</span> cp = unchecked::peek_next(w);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::peek_next</code>. It does not
- check for validity of the supplied UTF-8 sequence.
- </p>
- <h4>
- utf8::unchecked::prior
- </h4>
- <p class="version">
- Available in version 1.02 and later.
- </p>
- <p>
- Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
- decreases the iterator until it hits the beginning of the previous UTF-8 encoded
- code point and returns the 32 bits representation of the code point.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t prior(octet_iterator&amp; it);
-
-</pre>
- <p>
- <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
- After the function returns, it is decremented to point to the beginning of the
- previous code point.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- previous code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
-<span class="keyword">int</span> cp = unchecked::prior (w);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::prior</code>. It does not
- check for validity of the supplied UTF-8 sequence and offers no boundary checking.
- </p>
- <h4>
- utf8::unchecked::previous (deprecated, see utf8::unchecked::prior)
- </h4>
- <p class="version">
- Deprecated in version 1.02 and later.
- </p>
- <p>
- Given a reference to an iterator pointing to an octet in a UTF-8 seqence, it
- decreases the iterator until it hits the beginning of the previous UTF-8 encoded
- code point and returns the 32 bits representation of the code point.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-uint32_t previous(octet_iterator&amp; it);
-
-</pre>
- <p>
- <code>it</code>: a reference pointing to an octet within a UTF-8 encoded string.
- After the function returns, it is decremented to point to the beginning of the
- previous code point.<br>
- <span class="return_value">Return value</span>: the 32 bit representation of the
- previous code point.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars + <span class="literal">3</span>;
-<span class="keyword">int</span> cp = unchecked::previous (w);
-assert (cp == <span class="literal">0x65e5</span>);
-assert (w == twochars);
-</pre>
- <p>
- The reason this function is deprecated is just the consistency with the "checked"
- versions, where <code>prior</code> should be used instead of <code>previous</code>.
- In fact, <code>unchecked::previous</code> behaves exactly the same as <code>
- unchecked::prior</code>
- </p>
- <p>
- This is a faster but less safe version of <code>utf8::previous</code>. It does not
- check for validity of the supplied UTF-8 sequence and offers no boundary checking.
- </p>
- <h4>
- utf8::unchecked::advance
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Advances an iterator by the specified number of code points within an UTF-8
- sequence.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, typename distance_type&gt;
-<span class="keyword">void</span> advance (octet_iterator&amp; it, distance_type n);
-
-</pre>
- <p>
- <code>it</code>: a reference to an iterator pointing to the beginning of an UTF-8
- encoded code point. After the function returns, it is incremented to point to the
- nth following code point.<br>
- <code>n</code>: a positive integer that shows how many code points we want to
- advance.<br>
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-<span class="keyword">char</span>* w = twochars;
-unchecked::advance (w, <span class="literal">2</span>);
-assert (w == twochars + <span class="literal">5</span>);
-</pre>
- <p>
- This function works only "forward". In case of a negative <code>n</code>, there is
- no effect.
- </p>
- <p>
- This is a faster but less safe version of <code>utf8::advance</code>. It does not
- check for validity of the supplied UTF-8 sequence and offers no boundary checking.
- </p>
- <h4>
- utf8::unchecked::distance
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Given the iterators to two UTF-8 encoded code points in a seqence, returns the
- number of code points between them.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator&gt;
-<span class=
-"keyword">typename</span> std::iterator_traits&lt;octet_iterator&gt;::difference_type distance (octet_iterator first, octet_iterator last);
-</pre>
- <p>
- <code>first</code>: an iterator to a beginning of a UTF-8 encoded code point.<br>
- <code>last</code>: an iterator to a "post-end" of the last UTF-8 encoded code
- point in the sequence we are trying to determine the length. It can be the
- beginning of a new code point, or not.<br>
- <span class="return_value">Return value</span> the distance between the iterators,
- in code points.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-size_t dist = utf8::unchecked::distance(twochars, twochars + <span class=
-"literal">5</span>);
-assert (dist == <span class="literal">2</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::distance</code>. It does not
- check for validity of the supplied UTF-8 sequence.
- </p>
- <h4>
- utf8::unchecked::utf16to8
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-16 encoded string to UTF-8.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> u16bit_iterator, <span class=
-"keyword">typename</span> octet_iterator&gt;
-octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result);
-
-</pre>
- <p>
- <code>start</code>: an iterator pointing to the beginning of the UTF-16 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-16 encoded
- string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-8 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-8 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">unsigned short</span> utf16string[] = {<span class=
-"literal">0x41</span>, <span class="literal">0x0448</span>, <span class=
-"literal">0x65e5</span>, <span class="literal">0xd834</span>, <span class=
-"literal">0xdd1e</span>};
-vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
-unchecked::utf16to8(utf16string, utf16string + <span class=
-"literal">5</span>, back_inserter(utf8result));
-assert (utf8result.size() == <span class="literal">10</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::utf16to8</code>. It does not
- check for validity of the supplied UTF-16 sequence.
- </p>
- <h4>
- utf8::unchecked::utf8to16
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts an UTF-8 encoded string to UTF-16
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> u16bit_iterator, typename octet_iterator&gt;
-u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result);
-
-</pre>
- <p>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
- string to convert. &lt; br /&gt; <code>end</code>: an iterator pointing to
- pass-the-end of the UTF-8 encoded string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-16 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-16 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span> utf8_with_surrogates[] = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88\xf0\x9d\x84\x9e"</span>;
-vector &lt;<span class="keyword">unsigned short</span>&gt; utf16result;
-unchecked::utf8to16(utf8_with_surrogates, utf8_with_surrogates + <span class=
-"literal">9</span>, back_inserter(utf16result));
-assert (utf16result.size() == <span class="literal">4</span>);
-assert (utf16result[<span class="literal">2</span>] == <span class=
-"literal">0xd834</span>);
-assert (utf16result[<span class="literal">3</span>] == <span class=
-"literal">0xdd1e</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::utf8to16</code>. It does not
- check for validity of the supplied UTF-8 sequence.
- </p>
- <h4>
- utf8::unchecked::utf32to8
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-32 encoded string to UTF-8.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, <span class=
-"keyword">typename</span> u32bit_iterator&gt;
-octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result);
-
-</pre>
- <p>
- <code>start</code>: an iterator pointing to the beginning of the UTF-32 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-32 encoded
- string to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-8 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-8 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">int</span> utf32string[] = {<span class=
-"literal">0x448</span>, <span class="literal">0x65e5</span>, <span class=
-"literal">0x10346</span>, <span class="literal">0</span>};
-vector&lt;<span class="keyword">unsigned char</span>&gt; utf8result;
-utf32to8(utf32string, utf32string + <span class=
-"literal">3</span>, back_inserter(utf8result));
-assert (utf8result.size() == <span class="literal">9</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::utf32to8</code>. It does not
- check for validity of the supplied UTF-32 sequence.
- </p>
- <h4>
- utf8::unchecked::utf8to32
- </h4>
- <p class="version">
- Available in version 1.0 and later.
- </p>
- <p>
- Converts a UTF-8 encoded string to UTF-32.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class=
-"keyword">typename</span> octet_iterator, typename u32bit_iterator&gt;
-u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result);
-
-</pre>
- <p>
- <code>start</code>: an iterator pointing to the beginning of the UTF-8 encoded
- string to convert.<br>
- <code>end</code>: an iterator pointing to pass-the-end of the UTF-8 encoded string
- to convert.<br>
- <code>result</code>: an output iterator to the place in the UTF-32 string where to
- append the result of conversion.<br>
- <span class="return_value">Return value</span>: An iterator pointing to the place
- after the appended UTF-32 string.
- </p>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* twochars = <span class=
-"literal">"\xe6\x97\xa5\xd1\x88"</span>;
-vector&lt;<span class="keyword">int</span>&gt; utf32result;
-unchecked::utf8to32(twochars, twochars + <span class=
-"literal">5</span>, back_inserter(utf32result));
-assert (utf32result.size() == <span class="literal">2</span>);
-</pre>
- <p>
- This is a faster but less safe version of <code>utf8::utf8to32</code>. It does not
- check for validity of the supplied UTF-8 sequence.
- </p>
- <h3 id="typesunchecked">
- Types From utf8::unchecked Namespace
- </h3>
- <h4>
- utf8::iterator
- </h4>
- <p class="version">
- Available in version 2.0 and later.
- </p>
- <p>
- Adapts the underlying octet iterator to iterate over the sequence of code points,
- rather than raw octets.
- </p>
-<pre>
-<span class="keyword">template</span> &lt;<span class="keyword">typename</span> octet_iterator&gt;
-<span class="keyword">class</span> iterator;
-</pre>
-
- <h5>Member functions</h5>
- <dl>
- <dt><code>iterator();</code> <dd> the deafult constructor; the underlying <code>octet_iterator</code> is
- constructed with its default constructor.
- <dt><code><span class="keyword">explicit</span> iterator (const octet_iterator&amp; octet_it);
- </code> <dd> a constructor
- that initializes the underlying <code>octet_iterator</code> with <code>octet_it</code>
- <dt><code>octet_iterator base () <span class="keyword">const</span>;</code> <dd> returns the
- underlying <code>octet_iterator</code>.
- <dt><code>uint32_t operator * () <span class="keyword">const</span>;</code> <dd> decodes the utf-8 sequence
- the underlying <code>octet_iterator</code> is pointing to and returns the code point.
- <dt><code><span class="keyword">bool operator</span> == (const iterator&amp; rhs)
- <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
- if the two underlaying iterators are equal.
- <dt><code><span class="keyword">bool operator</span> != (const iterator&amp; rhs)
- <span class="keyword">const</span>;</code> <dd> returns <span class="keyword">true</span>
- if the two underlaying iterators are not equal.
- <dt><code>iterator&amp; <span class="keyword">operator</span> ++ (); </code> <dd> the prefix increment - moves
- the iterator to the next UTF-8 encoded code point.
- <dt><code>iterator <span class="keyword">operator</span> ++ (<span class="keyword">int</span>); </code> <dd>
- the postfix increment - moves the iterator to the next UTF-8 encoded code point and returns the current one.
- <dt><code>iterator&amp; <span class="keyword">operator</span> -- (); </code> <dd> the prefix decrement - moves
- the iterator to the previous UTF-8 encoded code point.
- <dt><code>iterator <span class="keyword">operator</span> -- (<span class="keyword">int</span>); </code> <dd>
- the postfix decrement - moves the iterator to the previous UTF-8 encoded code point and returns the current one.
- </dl>
- <p>
- Example of use:
- </p>
-<pre>
-<span class="keyword">char</span>* threechars = <span class="literal">"\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88"</span>;
-utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it(threechars);
-utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_it2 = un_it;
-assert (un_it2 == un_it);
-assert (*un_it == <span class="literal">0x10346</span>);
-assert (*(++un_it) == <span class="literal">0x65e5</span>);
-assert ((*un_it++) == <span class="literal">0x65e5</span>);
-assert (*un_it == <span class="literal">0x0448</span>);
-assert (un_it != un_it2);
-utf8::::unchecked::iterator&lt;<span class="keyword">char</span>*&gt; un_endit (threechars + <span class="literal">9</span>);
-assert (++un_it == un_endit);
-assert (*(--un_it) == <span class="literal">0x0448</span>);
-assert ((*un_it--) == <span class="literal">0x0448</span>);
-assert (*un_it == <span class="literal">0x65e5</span>);
-assert (--un_it == utf8::unchecked::iterator&lt;<span class="keyword">char</span>*&gt;(threechars));
-assert (*un_it == <span class="literal">0x10346</span>);
-</pre>
- <p>
- This is an unchecked version of <code>utf8::iterator</code>. It is faster in many cases, but offers
- no validity or range checks.
- </p>
- <h2 id="points">
- Points of interest
- </h2>
- <h4>
- Design goals and decisions
- </h4>
- <p>
- The library was designed to be:
- </p>
- <ol>
- <li>
- Generic: for better or worse, there are many C++ string classes out there, and
- the library should work with as many of them as possible.
- </li>
- <li>
- Portable: the library should be portable both accross different platforms and
- compilers. The only non-portable code is a small section that declares unsigned
- integers of different sizes: three typedefs. They can be changed by the users of
- the library if they don't match their platform. The default setting should work
- for Windows (both 32 and 64 bit), and most 32 bit and 64 bit Unix derivatives.
- </li>
- <li>
- Lightweight: follow the "pay only for what you use" guideline.
- </li>
- <li>
- Unintrusive: avoid forcing any particular design or even programming style on the
- user. This is a library, not a framework.
- </li>
- </ol>
- <h4>
- Alternatives
- </h4>
- <p>
- In case you want to look into other means of working with UTF-8 strings from C++,
- here is the list of solutions I am aware of:
- </p>
- <ol>
- <li>
- <a href="http://icu.sourceforge.net/">ICU Library</a>. It is very powerful,
- complete, feature-rich, mature, and widely used. Also big, intrusive,
- non-generic, and doesn't play well with the Standard Library. I definitelly
- recommend looking at ICU even if you don't plan to use it.
- </li>
- <li>
- C++11 language and library features. Still far from complete, and not widely
- supported by compiler vendors.
- </li>
- <li>
- <a href=
- "http://www.gtkmm.org/gtkmm2/docs/tutorial/html/ch03s04.html">Glib::ustring</a>.
- A class specifically made to work with UTF-8 strings, and also feel like
- <code>std::string</code>. If you prefer to have yet another string class in your
- code, it may be worth a look. Be aware of the licensing issues, though.
- </li>
- <li>
- Platform dependent solutions: Windows and POSIX have functions to convert strings
- from one encoding to another. That is only a subset of what my library offers,
- but if that is all you need it may be good enough.
- </li>
- </ol>
- <h2 id="links">
- Links
- </h2>
- <ol>
- <li>
- <a href="http://www.unicode.org/">The Unicode Consortium</a>.
- </li>
- <li>
- <a href="http://icu.sourceforge.net/">ICU Library</a>.
- </li>
- <li>
- <a href="http://en.wikipedia.org/wiki/UTF-8">UTF-8 at Wikipedia</a>
- </li>
- <li>
- <a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html">UTF-8 and Unicode FAQ for
- Unix/Linux</a>
- </li>
- </ol>
- </body>
-</html>
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8.h b/src/3rdparty/assimp/contrib/utf8cpp/source/utf8.h
deleted file mode 100644
index 82b13f59f..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2006 Nemanja Trifunovic
-
-/*
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-
-#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
-#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
-
-#include "utf8/checked.h"
-#include "utf8/unchecked.h"
-
-#endif // header guard
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/checked.h b/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/checked.h
deleted file mode 100644
index 133115513..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/checked.h
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2006 Nemanja Trifunovic
-
-/*
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-
-#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-
-#include "core.h"
-#include <stdexcept>
-
-namespace utf8
-{
- // Base for the exceptions that may be thrown from the library
- class exception : public ::std::exception {
- };
-
- // Exceptions that may be thrown from the library functions.
- class invalid_code_point : public exception {
- uint32_t cp;
- public:
- invalid_code_point(uint32_t cp) : cp(cp) {}
- virtual const char* what() const throw() { return "Invalid code point"; }
- uint32_t code_point() const {return cp;}
- };
-
- class invalid_utf8 : public exception {
- uint8_t u8;
- public:
- invalid_utf8 (uint8_t u) : u8(u) {}
- virtual const char* what() const throw() { return "Invalid UTF-8"; }
- uint8_t utf8_octet() const {return u8;}
- };
-
- class invalid_utf16 : public exception {
- uint16_t u16;
- public:
- invalid_utf16 (uint16_t u) : u16(u) {}
- virtual const char* what() const throw() { return "Invalid UTF-16"; }
- uint16_t utf16_word() const {return u16;}
- };
-
- class not_enough_room : public exception {
- public:
- virtual const char* what() const throw() { return "Not enough space"; }
- };
-
- /// The library API - functions intended to be called by the users
-
- template <typename octet_iterator>
- octet_iterator append(uint32_t cp, octet_iterator result)
- {
- if (!utf8::internal::is_code_point_valid(cp))
- throw invalid_code_point(cp);
-
- if (cp < 0x80) // one octet
- *(result++) = static_cast<uint8_t>(cp);
- else if (cp < 0x800) { // two octets
- *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- else if (cp < 0x10000) { // three octets
- *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
- *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- else { // four octets
- *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
- *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
- *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- return result;
- }
-
- template <typename octet_iterator, typename output_iterator>
- output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
- {
- while (start != end) {
- octet_iterator sequence_start = start;
- internal::utf_error err_code = utf8::internal::validate_next(start, end);
- switch (err_code) {
- case internal::UTF8_OK :
- for (octet_iterator it = sequence_start; it != start; ++it)
- *out++ = *it;
- break;
- case internal::NOT_ENOUGH_ROOM:
- throw not_enough_room();
- case internal::INVALID_LEAD:
- out = utf8::append (replacement, out);
- ++start;
- break;
- case internal::INCOMPLETE_SEQUENCE:
- case internal::OVERLONG_SEQUENCE:
- case internal::INVALID_CODE_POINT:
- out = utf8::append (replacement, out);
- ++start;
- // just one replacement mark for the sequence
- while (start != end && utf8::internal::is_trail(*start))
- ++start;
- break;
- }
- }
- return out;
- }
-
- template <typename octet_iterator, typename output_iterator>
- inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
- {
- static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
- return utf8::replace_invalid(start, end, out, replacement_marker);
- }
-
- template <typename octet_iterator>
- uint32_t next(octet_iterator& it, octet_iterator end)
- {
- uint32_t cp = 0;
- internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
- switch (err_code) {
- case internal::UTF8_OK :
- break;
- case internal::NOT_ENOUGH_ROOM :
- throw not_enough_room();
- case internal::INVALID_LEAD :
- case internal::INCOMPLETE_SEQUENCE :
- case internal::OVERLONG_SEQUENCE :
- throw invalid_utf8(*it);
- case internal::INVALID_CODE_POINT :
- throw invalid_code_point(cp);
- }
- return cp;
- }
-
- template <typename octet_iterator>
- uint32_t peek_next(octet_iterator it, octet_iterator end)
- {
- return utf8::next(it, end);
- }
-
- template <typename octet_iterator>
- uint32_t prior(octet_iterator& it, octet_iterator start)
- {
- // can't do much if it == start
- if (it == start)
- throw not_enough_room();
-
- octet_iterator end = it;
- // Go back until we hit either a lead octet or start
- while (utf8::internal::is_trail(*(--it)))
- if (it == start)
- throw invalid_utf8(*it); // error - no lead byte in the sequence
- return utf8::peek_next(it, end);
- }
-
- /// Deprecated in versions that include "prior"
- template <typename octet_iterator>
- uint32_t previous(octet_iterator& it, octet_iterator pass_start)
- {
- octet_iterator end = it;
- while (utf8::internal::is_trail(*(--it)))
- if (it == pass_start)
- throw invalid_utf8(*it); // error - no lead byte in the sequence
- octet_iterator temp = it;
- return utf8::next(temp, end);
- }
-
- template <typename octet_iterator, typename distance_type>
- void advance (octet_iterator& it, distance_type n, octet_iterator end)
- {
- for (distance_type i = 0; i < n; ++i)
- utf8::next(it, end);
- }
-
- template <typename octet_iterator>
- typename std::iterator_traits<octet_iterator>::difference_type
- distance (octet_iterator first, octet_iterator last)
- {
- typename std::iterator_traits<octet_iterator>::difference_type dist;
- for (dist = 0; first < last; ++dist)
- utf8::next(first, last);
- return dist;
- }
-
- template <typename u16bit_iterator, typename octet_iterator>
- octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
- {
- while (start != end) {
- uint32_t cp = utf8::internal::mask16(*start++);
- // Take care of surrogate pairs first
- if (utf8::internal::is_lead_surrogate(cp)) {
- if (start != end) {
- uint32_t trail_surrogate = utf8::internal::mask16(*start++);
- if (utf8::internal::is_trail_surrogate(trail_surrogate))
- cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
- else
- throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
- }
- else
- throw invalid_utf16(static_cast<uint16_t>(cp));
-
- }
- // Lone trail surrogate
- else if (utf8::internal::is_trail_surrogate(cp))
- throw invalid_utf16(static_cast<uint16_t>(cp));
-
- result = utf8::append(cp, result);
- }
- return result;
- }
-
- template <typename u16bit_iterator, typename octet_iterator>
- u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
- {
- while (start != end) {
- uint32_t cp = utf8::next(start, end);
- if (cp > 0xffff) { //make a surrogate pair
- *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
- *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
- }
- else
- *result++ = static_cast<uint16_t>(cp);
- }
- return result;
- }
-
- template <typename octet_iterator, typename u32bit_iterator>
- octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
- {
- while (start != end)
- result = utf8::append(*(start++), result);
-
- return result;
- }
-
- template <typename octet_iterator, typename u32bit_iterator>
- u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
- {
- while (start != end)
- (*result++) = utf8::next(start, end);
-
- return result;
- }
-
- // The iterator class
- template <typename octet_iterator>
- class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
- octet_iterator it;
- octet_iterator range_start;
- octet_iterator range_end;
- public:
- iterator () {}
- explicit iterator (const octet_iterator& octet_it,
- const octet_iterator& range_start,
- const octet_iterator& range_end) :
- it(octet_it), range_start(range_start), range_end(range_end)
- {
- if (it < range_start || it > range_end)
- throw std::out_of_range("Invalid utf-8 iterator position");
- }
- // the default "big three" are OK
- octet_iterator base () const { return it; }
- uint32_t operator * () const
- {
- octet_iterator temp = it;
- return utf8::next(temp, range_end);
- }
- bool operator == (const iterator& rhs) const
- {
- if (range_start != rhs.range_start || range_end != rhs.range_end)
- throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
- return (it == rhs.it);
- }
- bool operator != (const iterator& rhs) const
- {
- return !(operator == (rhs));
- }
- iterator& operator ++ ()
- {
- utf8::next(it, range_end);
- return *this;
- }
- iterator operator ++ (int)
- {
- iterator temp = *this;
- utf8::next(it, range_end);
- return temp;
- }
- iterator& operator -- ()
- {
- utf8::prior(it, range_start);
- return *this;
- }
- iterator operator -- (int)
- {
- iterator temp = *this;
- utf8::prior(it, range_start);
- return temp;
- }
- }; // class iterator
-
-} // namespace utf8
-
-#endif //header guard
-
-
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/core.h b/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/core.h
deleted file mode 100644
index 693d388c0..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/core.h
+++ /dev/null
@@ -1,329 +0,0 @@
-// Copyright 2006 Nemanja Trifunovic
-
-/*
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-
-#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-
-#include <iterator>
-
-namespace utf8
-{
- // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
- // You may need to change them to match your system.
- // These typedefs have the same names as ones from cstdint, or boost/cstdint
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
- typedef unsigned int uint32_t;
-
-// Helper code - not intended to be directly called by the library users. May be changed at any time
-namespace internal
-{
- // Unicode constants
- // Leading (high) surrogates: 0xd800 - 0xdbff
- // Trailing (low) surrogates: 0xdc00 - 0xdfff
- const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
- const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
- const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
- const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
- const uint16_t LEAD_OFFSET = LEAD_SURROGATE_MIN - (0x10000 >> 10);
- const uint32_t SURROGATE_OFFSET = 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN;
-
- // Maximum valid value for a Unicode code point
- const uint32_t CODE_POINT_MAX = 0x0010ffffu;
-
- template<typename octet_type>
- inline uint8_t mask8(octet_type oc)
- {
- return static_cast<uint8_t>(0xff & oc);
- }
- template<typename u16_type>
- inline uint16_t mask16(u16_type oc)
- {
- return static_cast<uint16_t>(0xffff & oc);
- }
- template<typename octet_type>
- inline bool is_trail(octet_type oc)
- {
- return ((utf8::internal::mask8(oc) >> 6) == 0x2);
- }
-
- template <typename u16>
- inline bool is_lead_surrogate(u16 cp)
- {
- return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
- }
-
- template <typename u16>
- inline bool is_trail_surrogate(u16 cp)
- {
- return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
- }
-
- template <typename u16>
- inline bool is_surrogate(u16 cp)
- {
- return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
- }
-
- template <typename u32>
- inline bool is_code_point_valid(u32 cp)
- {
- return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
- }
-
- template <typename octet_iterator>
- inline typename std::iterator_traits<octet_iterator>::difference_type
- sequence_length(octet_iterator lead_it)
- {
- uint8_t lead = utf8::internal::mask8(*lead_it);
- if (lead < 0x80)
- return 1;
- else if ((lead >> 5) == 0x6)
- return 2;
- else if ((lead >> 4) == 0xe)
- return 3;
- else if ((lead >> 3) == 0x1e)
- return 4;
- else
- return 0;
- }
-
- template <typename octet_difference_type>
- inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
- {
- if (cp < 0x80) {
- if (length != 1)
- return true;
- }
- else if (cp < 0x800) {
- if (length != 2)
- return true;
- }
- else if (cp < 0x10000) {
- if (length != 3)
- return true;
- }
-
- return false;
- }
-
- enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
-
- /// Helper for get_sequence_x
- template <typename octet_iterator>
- utf_error increase_safely(octet_iterator& it, octet_iterator end)
- {
- if (++it == end)
- return NOT_ENOUGH_ROOM;
-
- if (!utf8::internal::is_trail(*it))
- return INCOMPLETE_SEQUENCE;
-
- return UTF8_OK;
- }
-
- #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
-
- /// get_sequence_x functions decode utf-8 sequences of the length x
- template <typename octet_iterator>
- utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
- {
- if (it == end)
- return NOT_ENOUGH_ROOM;
-
- code_point = utf8::internal::mask8(*it);
-
- return UTF8_OK;
- }
-
- template <typename octet_iterator>
- utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
- {
- if (it == end)
- return NOT_ENOUGH_ROOM;
-
- code_point = utf8::internal::mask8(*it);
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
-
- return UTF8_OK;
- }
-
- template <typename octet_iterator>
- utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
- {
- if (it == end)
- return NOT_ENOUGH_ROOM;
-
- code_point = utf8::internal::mask8(*it);
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point += (*it) & 0x3f;
-
- return UTF8_OK;
- }
-
- template <typename octet_iterator>
- utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
- {
- if (it == end)
- return NOT_ENOUGH_ROOM;
-
- code_point = utf8::internal::mask8(*it);
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
-
- UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
-
- code_point += (*it) & 0x3f;
-
- return UTF8_OK;
- }
-
- #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
-
- template <typename octet_iterator>
- utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
- {
- // Save the original value of it so we can go back in case of failure
- // Of course, it does not make much sense with i.e. stream iterators
- octet_iterator original_it = it;
-
- uint32_t cp = 0;
- // Determine the sequence length based on the lead octet
- typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
- const octet_difference_type length = utf8::internal::sequence_length(it);
-
- // Get trail octets and calculate the code point
- utf_error err = UTF8_OK;
- switch (length) {
- case 0:
- return INVALID_LEAD;
- case 1:
- err = utf8::internal::get_sequence_1(it, end, cp);
- break;
- case 2:
- err = utf8::internal::get_sequence_2(it, end, cp);
- break;
- case 3:
- err = utf8::internal::get_sequence_3(it, end, cp);
- break;
- case 4:
- err = utf8::internal::get_sequence_4(it, end, cp);
- break;
- }
-
- if (err == UTF8_OK) {
- // Decoding succeeded. Now, security checks...
- if (utf8::internal::is_code_point_valid(cp)) {
- if (!utf8::internal::is_overlong_sequence(cp, length)){
- // Passed! Return here.
- code_point = cp;
- ++it;
- return UTF8_OK;
- }
- else
- err = OVERLONG_SEQUENCE;
- }
- else
- err = INVALID_CODE_POINT;
- }
-
- // Failure branch - restore the original value of the iterator
- it = original_it;
- return err;
- }
-
- template <typename octet_iterator>
- inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
- uint32_t ignored;
- return utf8::internal::validate_next(it, end, ignored);
- }
-
-} // namespace internal
-
- /// The library API - functions intended to be called by the users
-
- // Byte order mark
- const uint8_t bom[] = {0xef, 0xbb, 0xbf};
-
- template <typename octet_iterator>
- octet_iterator find_invalid(octet_iterator start, octet_iterator end)
- {
- octet_iterator result = start;
- while (result != end) {
- utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
- if (err_code != internal::UTF8_OK)
- return result;
- }
- return result;
- }
-
- template <typename octet_iterator>
- inline bool is_valid(octet_iterator start, octet_iterator end)
- {
- return (utf8::find_invalid(start, end) == end);
- }
-
- template <typename octet_iterator>
- inline bool starts_with_bom (octet_iterator it, octet_iterator end)
- {
- return (
- ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
- ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
- ((it != end) && (utf8::internal::mask8(*it)) == bom[2])
- );
- }
-
- //Deprecated in release 2.3
- template <typename octet_iterator>
- inline bool is_bom (octet_iterator it)
- {
- return (
- (utf8::internal::mask8(*it++)) == bom[0] &&
- (utf8::internal::mask8(*it++)) == bom[1] &&
- (utf8::internal::mask8(*it)) == bom[2]
- );
- }
-} // namespace utf8
-
-#endif // header guard
-
-
diff --git a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h b/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h
deleted file mode 100644
index cb2427166..000000000
--- a/src/3rdparty/assimp/contrib/utf8cpp/source/utf8/unchecked.h
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2006 Nemanja Trifunovic
-
-/*
-Permission is hereby granted, free of charge, to any person or organization
-obtaining a copy of the software and accompanying documentation covered by
-this license (the "Software") to use, reproduce, display, distribute,
-execute, and transmit the Software, and to prepare derivative works of the
-Software, and to permit third-parties to whom the Software is furnished to
-do so, all subject to the following:
-
-The copyright notices in the Software and this entire statement, including
-the above license grant, this restriction and the following disclaimer,
-must be included in all copies of the Software, in whole or in part, and
-all derivative works of the Software, unless such copies or derivative
-works are solely in the form of machine-executable object code generated by
-a source language processor.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
-SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
-FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
-*/
-
-
-#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
-
-#include "core.h"
-
-namespace utf8
-{
- namespace unchecked
- {
- template <typename octet_iterator>
- octet_iterator append(uint32_t cp, octet_iterator result)
- {
- if (cp < 0x80) // one octet
- *(result++) = static_cast<uint8_t>(cp);
- else if (cp < 0x800) { // two octets
- *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- else if (cp < 0x10000) { // three octets
- *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
- *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- else { // four octets
- *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
- *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
- *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
- *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
- }
- return result;
- }
-
- template <typename octet_iterator>
- uint32_t next(octet_iterator& it)
- {
- uint32_t cp = utf8::internal::mask8(*it);
- typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
- switch (length) {
- case 1:
- break;
- case 2:
- it++;
- cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
- break;
- case 3:
- ++it;
- cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
- ++it;
- cp += (*it) & 0x3f;
- break;
- case 4:
- ++it;
- cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
- ++it;
- cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
- ++it;
- cp += (*it) & 0x3f;
- break;
- }
- ++it;
- return cp;
- }
-
- template <typename octet_iterator>
- uint32_t peek_next(octet_iterator it)
- {
- return utf8::unchecked::next(it);
- }
-
- template <typename octet_iterator>
- uint32_t prior(octet_iterator& it)
- {
- while (utf8::internal::is_trail(*(--it))) ;
- octet_iterator temp = it;
- return utf8::unchecked::next(temp);
- }
-
- // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
- template <typename octet_iterator>
- inline uint32_t previous(octet_iterator& it)
- {
- return utf8::unchecked::prior(it);
- }
-
- template <typename octet_iterator, typename distance_type>
- void advance (octet_iterator& it, distance_type n)
- {
- for (distance_type i = 0; i < n; ++i)
- utf8::unchecked::next(it);
- }
-
- template <typename octet_iterator>
- typename std::iterator_traits<octet_iterator>::difference_type
- distance (octet_iterator first, octet_iterator last)
- {
- typename std::iterator_traits<octet_iterator>::difference_type dist;
- for (dist = 0; first < last; ++dist)
- utf8::unchecked::next(first);
- return dist;
- }
-
- template <typename u16bit_iterator, typename octet_iterator>
- octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
- {
- while (start != end) {
- uint32_t cp = utf8::internal::mask16(*start++);
- // Take care of surrogate pairs first
- if (utf8::internal::is_lead_surrogate(cp)) {
- uint32_t trail_surrogate = utf8::internal::mask16(*start++);
- cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
- }
- result = utf8::unchecked::append(cp, result);
- }
- return result;
- }
-
- template <typename u16bit_iterator, typename octet_iterator>
- u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
- {
- while (start < end) {
- uint32_t cp = utf8::unchecked::next(start);
- if (cp > 0xffff) { //make a surrogate pair
- *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
- *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
- }
- else
- *result++ = static_cast<uint16_t>(cp);
- }
- return result;
- }
-
- template <typename octet_iterator, typename u32bit_iterator>
- octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
- {
- while (start != end)
- result = utf8::unchecked::append(*(start++), result);
-
- return result;
- }
-
- template <typename octet_iterator, typename u32bit_iterator>
- u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
- {
- while (start < end)
- (*result++) = utf8::unchecked::next(start);
-
- return result;
- }
-
- // The iterator class
- template <typename octet_iterator>
- class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
- octet_iterator it;
- public:
- iterator () {}
- explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
- // the default "big three" are OK
- octet_iterator base () const { return it; }
- uint32_t operator * () const
- {
- octet_iterator temp = it;
- return utf8::unchecked::next(temp);
- }
- bool operator == (const iterator& rhs) const
- {
- return (it == rhs.it);
- }
- bool operator != (const iterator& rhs) const
- {
- return !(operator == (rhs));
- }
- iterator& operator ++ ()
- {
- ::std::advance(it, utf8::internal::sequence_length(it));
- return *this;
- }
- iterator operator ++ (int)
- {
- iterator temp = *this;
- ::std::advance(it, utf8::internal::sequence_length(it));
- return temp;
- }
- iterator& operator -- ()
- {
- utf8::unchecked::prior(it);
- return *this;
- }
- iterator operator -- (int)
- {
- iterator temp = *this;
- utf8::unchecked::prior(it);
- return temp;
- }
- }; // class iterator
-
- } // namespace utf8::unchecked
-} // namespace utf8
-
-
-#endif // header guard
-
diff --git a/src/3rdparty/assimp/contrib/zip/README.md b/src/3rdparty/assimp/contrib/zip/README.md
deleted file mode 100644
index 24de5e61a..000000000
--- a/src/3rdparty/assimp/contrib/zip/README.md
+++ /dev/null
@@ -1,139 +0,0 @@
-### A portable (OSX/Linux/Windows), simple zip library written in C
-This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
-
-[![Windows][win-badge]][win-link] [![OS X][osx-linux-badge]][osx-linux-link]
-
-[win-badge]: https://img.shields.io/appveyor/ci/kuba--/zip/master.svg?label=windows "AppVeyor build status"
-[win-link]: https://ci.appveyor.com/project/kuba--/zip "AppVeyor build status"
-[osx-linux-badge]: https://img.shields.io/travis/kuba--/zip/master.svg?label=linux/osx "Travis CI build status"
-[osx-linux-link]: https://travis-ci.org/kuba--/zip "Travis CI build status"
-
-# The Idea
-<img src="zip.png" name="zip" />
-... Some day, I was looking for zip library written in C for my project, but I could not find anything simple enough and lightweight.
-Everything what I tried required 'crazy mental gymnastics' to integrate or had some limitations or was too heavy.
-I hate frameworks, factories and adding new dependencies. If I must to install all those dependencies and link new library, I'm getting almost sick.
-I wanted something powerfull and small enough, so I could add just a few files and compile them into my project.
-And finally I found miniz.
-Miniz is a lossless, high performance data compression library in a single source file. I only needed simple interface to append buffers or files to the current zip-entry. Thanks to this feature I'm able to merge many files/buffers and compress them on-the-fly.
-
-It was the reason, why I decided to write zip module on top of the miniz. It required a little bit hacking and wrapping some functions, but I kept simplicity. So, you can grab these 3 files and compile them into your project. I hope that interface is also extremely simple, so you will not have any problems to understand it.
-
-# Examples
-
-* Create a new zip archive with default compression level.
-```c
- struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
- {
- zip_entry_open(zip, "foo-1.txt");
- {
- char *buf = "Some data here...";
- zip_entry_write(zip, buf, strlen(buf));
- }
- zip_entry_close(zip);
-
- zip_entry_open(zip, "foo-2.txt");
- {
- // merge 3 files into one entry and compress them on-the-fly.
- zip_entry_fwrite(zip, "foo-2.1.txt");
- zip_entry_fwrite(zip, "foo-2.2.txt");
- zip_entry_fwrite(zip, "foo-2.3.txt");
- }
- zip_entry_close(zip);
- }
- zip_close(zip);
-```
-
-* Append to the existing zip archive.
-```c
- struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
- {
- zip_entry_open(zip, "foo-3.txt");
- {
- char *buf = "Append some data here...";
- zip_entry_write(zip, buf, strlen(buf));
- }
- zip_entry_close(zip);
- }
- zip_close(zip);
-```
-
-* Extract a zip archive into a folder.
-```c
- int on_extract_entry(const char *filename, void *arg) {
- static int i = 0;
- int n = *(int *)arg;
- printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
-
- return 0;
- }
-
- int arg = 2;
- zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);
-```
-
-* Extract a zip entry into memory.
-```c
- void *buf = NULL;
- size_t bufsize;
-
- struct zip_t *zip = zip_open("foo.zip", 0, 'r');
- {
- zip_entry_open(zip, "foo-1.txt");
- {
- zip_entry_read(zip, &buf, &bufsize);
- }
- zip_entry_close(zip);
- }
- zip_close(zip);
-
- free(buf);
-```
-
-* Extract a zip entry into memory using callback.
-```c
- struct buffer_t {
- char *data;
- size_t size;
- };
-
- static size_t on_extract(void *arg, unsigned long long offset, const void *data, size_t size) {
- struct buffer_t *buf = (struct buffer_t *)arg;
- buf->data = realloc(buf->data, buf->size + size + 1);
- assert(NULL != buf->data);
-
- memcpy(&(buf->data[buf->size]), data, size);
- buf->size += size;
- buf->data[buf->size] = 0;
-
- return size;
- }
-
- struct buffer_t buf = {0};
- struct zip_t *zip = zip_open("foo.zip", 0, 'r');
- {
- zip_entry_open(zip, "foo-1.txt");
- {
- zip_entry_extract(zip, on_extract, &buf);
- }
- zip_entry_close(zip);
- }
- zip_close(zip);
-
- free(buf.data);
-```
-
-
-* Extract a zip entry into a file.
-```c
- struct zip_t *zip = zip_open("foo.zip", 0, 'r');
- {
- zip_entry_open(zip, "foo-2.txt");
- {
- zip_entry_fread(zip, "foo-2.txt");
- }
- zip_entry_close(zip);
- }
- zip_close(zip);
-```
-
diff --git a/src/3rdparty/assimp/contrib/zip/UNLICENSE b/src/3rdparty/assimp/contrib/zip/UNLICENSE
deleted file mode 100644
index ed7cccdf2..000000000
--- a/src/3rdparty/assimp/contrib/zip/UNLICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- This is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to <http://unlicense.org/>
-*/
diff --git a/src/3rdparty/assimp/contrib/zip/src/miniz.h b/src/3rdparty/assimp/contrib/zip/src/miniz.h
deleted file mode 100644
index 2e4e223da..000000000
--- a/src/3rdparty/assimp/contrib/zip/src/miniz.h
+++ /dev/null
@@ -1,4928 +0,0 @@
-/*
- miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
- See "unlicense" statement at the end of this file.
- Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
- Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
-
- Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
- MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
-
- * Change History
- 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
- - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
- would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
- (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
- - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
- - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
- Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
- - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
- - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
- - Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
- - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
- - Merged MZ_FORCEINLINE fix from hdeanclark
- - Fix <time.h> include before config #ifdef, thanks emil.brink
- - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
- set it to 1 for real-time compression).
- - Merged in some compiler fixes from paulharris's github repro.
- - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
- - Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
- - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
- - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
-  - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
- 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
- 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
- - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
- - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
- - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
- "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
- - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
- - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
- - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
- - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
- - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
- 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
- level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
- 5/28/11 v1.11 - Added statement from unlicense.org
- 5/27/11 v1.10 - Substantial compressor optimizations:
- - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
- - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
- - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
- - Refactored the compression code for better readability and maintainability.
- - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
- drop in throughput on some files).
- 5/15/11 v1.09 - Initial stable release.
-
- * Low-level Deflate/Inflate implementation notes:
-
- Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
- greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
- approximately as well as zlib.
-
- Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
- coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
- block large enough to hold the entire file.
-
- The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
-
- * zlib-style API notes:
-
- miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
- zlib replacement in many apps:
- The z_stream struct, optional memory allocation callbacks
- deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
- inflateInit/inflateInit2/inflate/inflateEnd
- compress, compress2, compressBound, uncompress
- CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
- Supports raw deflate streams or standard zlib streams with adler-32 checking.
-
- Limitations:
- The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
- I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
- there are no guarantees that miniz.c pulls this off perfectly.
-
- * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
- Alex Evans. Supports 1-4 bytes/pixel images.
-
- * ZIP archive API notes:
-
- The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
- get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
- existing archives, create new archives, append new files to existing archives, or clone archive data from
- one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
- or you can specify custom file read/write callbacks.
-
- - Archive reading: Just call this function to read a single file from a disk archive:
-
- void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
- size_t *pSize, mz_uint zip_flags);
-
- For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
- directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
-
- - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
-
- int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
-
- The locate operation can optionally check file comments too, which (as one example) can be used to identify
- multiple versions of the same file in an archive. This function uses a simple linear search through the central
- directory, so it's not very fast.
-
- Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
- retrieve detailed info on each file by calling mz_zip_reader_file_stat().
-
- - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
- to disk and builds an exact image of the central directory in memory. The central directory image is written
- all at once at the end of the archive file when the archive is finalized.
-
- The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
- which can be useful when the archive will be read from optical media. Also, the writer supports placing
- arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
- readable by any ZIP tool.
-
- - Archive appending: The simple way to add a single file to an archive is to call this function:
-
- mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
- const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
-
- The archive will be created if it doesn't already exist, otherwise it'll be appended to.
- Note the appending is done in-place and is not an atomic operation, so if something goes wrong
- during the operation it's possible the archive could be left without a central directory (although the local
- file headers and file data will be fine, so the archive will be recoverable).
-
- For more complex archive modification scenarios:
- 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
- preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
- compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
- you're done. This is safe but requires a bunch of temporary disk space or heap memory.
-
- 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
- append new files as needed, then finalize the archive which will write an updated central directory to the
- original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
- possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
-
- - ZIP archive support limitations:
- No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
- Requires streams capable of seeking.
-
- * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
- below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
-
- * Important: For best perf. be sure to customize the below macros for your target platform:
- #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
- #define MINIZ_LITTLE_ENDIAN 1
- #define MINIZ_HAS_64BIT_REGISTERS 1
-
- * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
- uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
- (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
-*/
-
-#ifndef MINIZ_HEADER_INCLUDED
-#define MINIZ_HEADER_INCLUDED
-
-#include <stdlib.h>
-
-// Defines to completely disable specific portions of miniz.c:
-// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
-
-// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
-//#define MINIZ_NO_STDIO
-
-// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
-// get/set file times, and the C run-time funcs that get/set times won't be called.
-// The current downside is the times written to your archives will be from 1979.
-//#define MINIZ_NO_TIME
-
-// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
-//#define MINIZ_NO_ARCHIVE_APIS
-
-// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
-//#define MINIZ_NO_ARCHIVE_WRITING_APIS
-
-// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
-//#define MINIZ_NO_ZLIB_APIS
-
-// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
-//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
-
-// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
-// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
-// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
-// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
-//#define MINIZ_NO_MALLOC
-
-#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
- // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux
- #define MINIZ_NO_TIME
-#endif
-
-#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
- #include <time.h>
-#endif
-
-#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
-// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
-#define MINIZ_X86_OR_X64_CPU 1
-#endif
-
-#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
-// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
-#define MINIZ_LITTLE_ENDIAN 1
-#endif
-
-#if MINIZ_X86_OR_X64_CPU
-// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
-#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
-#endif
-
-#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
-// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).
-#define MINIZ_HAS_64BIT_REGISTERS 1
-#endif
-
-#ifdef __APPLE__
-#define ftello64 ftello
-#define fseeko64 fseeko
-#define fopen64 fopen
-#define freopen64 freopen
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ------------------- zlib-style API Definitions.
-
-// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
-typedef unsigned long mz_ulong;
-
-// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap.
-void mz_free(void *p);
-
-#define MZ_ADLER32_INIT (1)
-// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
-mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
-
-#define MZ_CRC32_INIT (0)
-// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
-mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
-
-// Compression strategies.
-enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
-
-// Method
-#define MZ_DEFLATED 8
-
-#ifndef MINIZ_NO_ZLIB_APIS
-
-// Heap allocation callbacks.
-// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
-typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
-typedef void (*mz_free_func)(void *opaque, void *address);
-typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
-
-#define MZ_VERSION "9.1.15"
-#define MZ_VERNUM 0x91F0
-#define MZ_VER_MAJOR 9
-#define MZ_VER_MINOR 1
-#define MZ_VER_REVISION 15
-#define MZ_VER_SUBREVISION 0
-
-// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
-enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
-
-// Return status codes. MZ_PARAM_ERROR is non-standard.
-enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 };
-
-// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
-enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
-
-// Window bits
-#define MZ_DEFAULT_WINDOW_BITS 15
-
-struct mz_internal_state;
-
-// Compression/decompression stream struct.
-typedef struct mz_stream_s
-{
- const unsigned char *next_in; // pointer to next byte to read
- unsigned int avail_in; // number of bytes available at next_in
- mz_ulong total_in; // total number of bytes consumed so far
-
- unsigned char *next_out; // pointer to next byte to write
- unsigned int avail_out; // number of bytes that can be written to next_out
- mz_ulong total_out; // total number of bytes produced so far
-
- char *msg; // error msg (unused)
- struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
-
- mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
- mz_free_func zfree; // optional heap free function (defaults to free)
- void *opaque; // heap alloc function user pointer
-
- int data_type; // data_type (unused)
- mz_ulong adler; // adler32 of the source or uncompressed data
- mz_ulong reserved; // not used
-} mz_stream;
-
-typedef mz_stream *mz_streamp;
-
-// Returns the version string of miniz.c.
-const char *mz_version(void);
-
-// mz_deflateInit() initializes a compressor with default options:
-// Parameters:
-// pStream must point to an initialized mz_stream struct.
-// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
-// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
-// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
-// Return values:
-// MZ_OK on success.
-// MZ_STREAM_ERROR if the stream is bogus.
-// MZ_PARAM_ERROR if the input parameters are bogus.
-// MZ_MEM_ERROR on out of memory.
-int mz_deflateInit(mz_streamp pStream, int level);
-
-// mz_deflateInit2() is like mz_deflate(), except with more control:
-// Additional parameters:
-// method must be MZ_DEFLATED
-// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
-// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
-int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
-
-// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
-int mz_deflateReset(mz_streamp pStream);
-
-// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
-// Parameters:
-// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
-// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
-// Return values:
-// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
-// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore.
-// MZ_STREAM_ERROR if the stream is bogus.
-// MZ_PARAM_ERROR if one of the parameters is invalid.
-// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
-int mz_deflate(mz_streamp pStream, int flush);
-
-// mz_deflateEnd() deinitializes a compressor:
-// Return values:
-// MZ_OK on success.
-// MZ_STREAM_ERROR if the stream is bogus.
-int mz_deflateEnd(mz_streamp pStream);
-
-// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH.
-mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
-
-// Single-call compression functions mz_compress() and mz_compress2():
-// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
-int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
-int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
-
-// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
-mz_ulong mz_compressBound(mz_ulong source_len);
-
-// Initializes a decompressor.
-int mz_inflateInit(mz_streamp pStream);
-
-// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
-// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
-int mz_inflateInit2(mz_streamp pStream, int window_bits);
-
-// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
-// Parameters:
-// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
-// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
-// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
-// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
-// Return values:
-// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
-// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
-// MZ_STREAM_ERROR if the stream is bogus.
-// MZ_DATA_ERROR if the deflate stream is invalid.
-// MZ_PARAM_ERROR if one of the parameters is invalid.
-// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again
-// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
-int mz_inflate(mz_streamp pStream, int flush);
-
-// Deinitializes a decompressor.
-int mz_inflateEnd(mz_streamp pStream);
-
-// Single-call decompression.
-// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
-int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
-
-// Returns a string description of the specified error code, or NULL if the error code is invalid.
-const char *mz_error(int err);
-
-// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports.
-// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
-#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
- typedef unsigned char Byte;
- typedef unsigned int uInt;
- typedef mz_ulong uLong;
- typedef Byte Bytef;
- typedef uInt uIntf;
- typedef char charf;
- typedef int intf;
- typedef void *voidpf;
- typedef uLong uLongf;
- typedef void *voidp;
- typedef void *const voidpc;
- #define Z_NULL 0
- #define Z_NO_FLUSH MZ_NO_FLUSH
- #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
- #define Z_SYNC_FLUSH MZ_SYNC_FLUSH
- #define Z_FULL_FLUSH MZ_FULL_FLUSH
- #define Z_FINISH MZ_FINISH
- #define Z_BLOCK MZ_BLOCK
- #define Z_OK MZ_OK
- #define Z_STREAM_END MZ_STREAM_END
- #define Z_NEED_DICT MZ_NEED_DICT
- #define Z_ERRNO MZ_ERRNO
- #define Z_STREAM_ERROR MZ_STREAM_ERROR
- #define Z_DATA_ERROR MZ_DATA_ERROR
- #define Z_MEM_ERROR MZ_MEM_ERROR
- #define Z_BUF_ERROR MZ_BUF_ERROR
- #define Z_VERSION_ERROR MZ_VERSION_ERROR
- #define Z_PARAM_ERROR MZ_PARAM_ERROR
- #define Z_NO_COMPRESSION MZ_NO_COMPRESSION
- #define Z_BEST_SPEED MZ_BEST_SPEED
- #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
- #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
- #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
- #define Z_FILTERED MZ_FILTERED
- #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
- #define Z_RLE MZ_RLE
- #define Z_FIXED MZ_FIXED
- #define Z_DEFLATED MZ_DEFLATED
- #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
- #define alloc_func mz_alloc_func
- #define free_func mz_free_func
- #define internal_state mz_internal_state
- #define z_stream mz_stream
- #define deflateInit mz_deflateInit
- #define deflateInit2 mz_deflateInit2
- #define deflateReset mz_deflateReset
- #define deflate mz_deflate
- #define deflateEnd mz_deflateEnd
- #define deflateBound mz_deflateBound
- #define compress mz_compress
- #define compress2 mz_compress2
- #define compressBound mz_compressBound
- #define inflateInit mz_inflateInit
- #define inflateInit2 mz_inflateInit2
- #define inflate mz_inflate
- #define inflateEnd mz_inflateEnd
- #define uncompress mz_uncompress
- #define crc32 mz_crc32
- #define adler32 mz_adler32
- #define MAX_WBITS 15
- #define MAX_MEM_LEVEL 9
- #define zError mz_error
- #define ZLIB_VERSION MZ_VERSION
- #define ZLIB_VERNUM MZ_VERNUM
- #define ZLIB_VER_MAJOR MZ_VER_MAJOR
- #define ZLIB_VER_MINOR MZ_VER_MINOR
- #define ZLIB_VER_REVISION MZ_VER_REVISION
- #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
- #define zlibVersion mz_version
- #define zlib_version mz_version()
-#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
-
-#endif // MINIZ_NO_ZLIB_APIS
-
-// ------------------- Types and macros
-
-typedef unsigned char mz_uint8;
-typedef signed short mz_int16;
-typedef unsigned short mz_uint16;
-typedef unsigned int mz_uint32;
-typedef unsigned int mz_uint;
-typedef long long mz_int64;
-typedef unsigned long long mz_uint64;
-typedef int mz_bool;
-
-#define MZ_FALSE (0)
-#define MZ_TRUE (1)
-
-// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
-#ifdef _MSC_VER
- #define MZ_MACRO_END while (0, 0)
-#else
- #define MZ_MACRO_END while (0)
-#endif
-
-// ------------------- ZIP archive reading/writing
-
-#ifndef MINIZ_NO_ARCHIVE_APIS
-
-enum
-{
- MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024,
- MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
- MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
-};
-
-typedef struct
-{
- mz_uint32 m_file_index;
- mz_uint32 m_central_dir_ofs;
- mz_uint16 m_version_made_by;
- mz_uint16 m_version_needed;
- mz_uint16 m_bit_flag;
- mz_uint16 m_method;
-#ifndef MINIZ_NO_TIME
- time_t m_time;
-#endif
- mz_uint32 m_crc32;
- mz_uint64 m_comp_size;
- mz_uint64 m_uncomp_size;
- mz_uint16 m_internal_attr;
- mz_uint32 m_external_attr;
- mz_uint64 m_local_header_ofs;
- mz_uint32 m_comment_size;
- char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
- char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
-} mz_zip_archive_file_stat;
-
-typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
-typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
-
-struct mz_zip_internal_state_tag;
-typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
-
-typedef enum
-{
- MZ_ZIP_MODE_INVALID = 0,
- MZ_ZIP_MODE_READING = 1,
- MZ_ZIP_MODE_WRITING = 2,
- MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
-} mz_zip_mode;
-
-typedef struct mz_zip_archive_tag
-{
- mz_uint64 m_archive_size;
- mz_uint64 m_central_directory_file_ofs;
- mz_uint m_total_files;
- mz_zip_mode m_zip_mode;
-
- mz_uint m_file_offset_alignment;
-
- mz_alloc_func m_pAlloc;
- mz_free_func m_pFree;
- mz_realloc_func m_pRealloc;
- void *m_pAlloc_opaque;
-
- mz_file_read_func m_pRead;
- mz_file_write_func m_pWrite;
- void *m_pIO_opaque;
-
- mz_zip_internal_state *m_pState;
-
-} mz_zip_archive;
-
-typedef enum
-{
- MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
- MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
- MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
- MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
-} mz_zip_flags;
-
-// ZIP archive reading
-
-// Inits a ZIP archive reader.
-// These functions read and validate the archive's central directory.
-mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
-mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
-
-#ifndef MINIZ_NO_STDIO
-mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
-#endif
-
-// Returns the total number of files in the archive.
-mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
-
-// Returns detailed information about an archive file entry.
-mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
-
-// Determines if an archive file entry is a directory entry.
-mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
-mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
-
-// Retrieves the filename of an archive file entry.
-// Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
-mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
-
-// Attempts to locates a file in the archive's central directory.
-// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
-// Returns -1 if the file cannot be found.
-int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
-
-// Extracts a archive file to a memory buffer using no memory allocation.
-mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
-mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
-
-// Extracts a archive file to a memory buffer.
-mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
-mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
-
-// Extracts a archive file to a dynamically allocated heap buffer.
-void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
-void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
-
-// Extracts a archive file using a callback function to output the file's data.
-mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
-mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
-
-#ifndef MINIZ_NO_STDIO
-// Extracts a archive file to a disk file and sets its last accessed and modified times.
-// This function only extracts files, not archive directory records.
-mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
-mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
-#endif
-
-// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
-mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
-
-// ZIP archive writing
-
-#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
-
-// Inits a ZIP archive writer.
-mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
-mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
-
-#ifndef MINIZ_NO_STDIO
-mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
-#endif
-
-// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
-// For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called.
-// For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it).
-// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
-// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
-// the archive is finalized the file's central directory will be hosed.
-mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
-
-// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
-// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
-// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
-mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
-mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
-
-#ifndef MINIZ_NO_STDIO
-// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
-// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
-mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
-#endif
-
-// Adds a file to an archive by fully cloning the data from another archive.
-// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
-mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
-
-// Finalizes the archive by writing the central directory records followed by the end of central directory record.
-// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
-// An archive must be manually finalized by calling this function for it to be valid.
-mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
-mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
-
-// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
-// Note for the archive to be valid, it must have been finalized before ending.
-mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
-
-// Misc. high-level helper functions:
-
-// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
-// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
-mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
-
-// Reads a single file from an archive into a heap block.
-// Returns NULL on failure.
-void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
-
-#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
-
-#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
-
-// ------------------- Low-level Decompression API Definitions
-
-// Decompression flags used by tinfl_decompress().
-// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
-// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
-// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
-// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
-enum
-{
- TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
- TINFL_FLAG_HAS_MORE_INPUT = 2,
- TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
- TINFL_FLAG_COMPUTE_ADLER32 = 8
-};
-
-// High level decompression functions:
-// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
-// On entry:
-// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
-// On return:
-// Function returns a pointer to the decompressed data, or NULL on failure.
-// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
-// The caller must call mz_free() on the returned block when it's no longer needed.
-void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
-
-// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
-// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
-#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
-size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
-
-// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
-// Returns 1 on success or 0 on failure.
-typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
-int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
-
-struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
-
-// Max size of LZ dictionary.
-#define TINFL_LZ_DICT_SIZE 32768
-
-// Return status.
-typedef enum
-{
- TINFL_STATUS_BAD_PARAM = -3,
- TINFL_STATUS_ADLER32_MISMATCH = -2,
- TINFL_STATUS_FAILED = -1,
- TINFL_STATUS_DONE = 0,
- TINFL_STATUS_NEEDS_MORE_INPUT = 1,
- TINFL_STATUS_HAS_MORE_OUTPUT = 2
-} tinfl_status;
-
-// Initializes the decompressor to its initial state.
-#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
-#define tinfl_get_adler32(r) (r)->m_check_adler32
-
-// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
-// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
-tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
-
-// Internal/private bits follow.
-enum
-{
- TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
- TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
-};
-
-typedef struct
-{
- mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
- mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
-} tinfl_huff_table;
-
-#if MINIZ_HAS_64BIT_REGISTERS
- #define TINFL_USE_64BIT_BITBUF 1
-#endif
-
-#if TINFL_USE_64BIT_BITBUF
- typedef mz_uint64 tinfl_bit_buf_t;
- #define TINFL_BITBUF_SIZE (64)
-#else
- typedef mz_uint32 tinfl_bit_buf_t;
- #define TINFL_BITBUF_SIZE (32)
-#endif
-
-struct tinfl_decompressor_tag
-{
- mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
- tinfl_bit_buf_t m_bit_buf;
- size_t m_dist_from_out_buf_start;
- tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
- mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
-};
-
-// ------------------- Low-level Compression API Definitions
-
-// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
-#define TDEFL_LESS_MEMORY 0
-
-// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
-// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
-enum
-{
- TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
-};
-
-// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
-// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
-// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
-// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
-// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
-// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
-// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
-// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
-// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
-enum
-{
- TDEFL_WRITE_ZLIB_HEADER = 0x01000,
- TDEFL_COMPUTE_ADLER32 = 0x02000,
- TDEFL_GREEDY_PARSING_FLAG = 0x04000,
- TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
- TDEFL_RLE_MATCHES = 0x10000,
- TDEFL_FILTER_MATCHES = 0x20000,
- TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
- TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
-};
-
-// High level compression functions:
-// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
-// On entry:
-// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
-// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
-// On return:
-// Function returns a pointer to the compressed data, or NULL on failure.
-// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
-// The caller must free() the returned block when it's no longer needed.
-void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
-
-// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
-// Returns 0 on failure.
-size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
-
-// Compresses an image to a compressed PNG file in memory.
-// On entry:
-// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
-// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
-// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
-// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
-// On return:
-// Function returns a pointer to the compressed data, or NULL on failure.
-// *pLen_out will be set to the size of the PNG image file.
-// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
-void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
-void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
-
-// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
-typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
-
-// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
-mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
-
-enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 };
-
-// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
-#if TDEFL_LESS_MEMORY
-enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
-#else
-enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS };
-#endif
-
-// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
-typedef enum
-{
- TDEFL_STATUS_BAD_PARAM = -2,
- TDEFL_STATUS_PUT_BUF_FAILED = -1,
- TDEFL_STATUS_OKAY = 0,
- TDEFL_STATUS_DONE = 1,
-} tdefl_status;
-
-// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
-typedef enum
-{
- TDEFL_NO_FLUSH = 0,
- TDEFL_SYNC_FLUSH = 2,
- TDEFL_FULL_FLUSH = 3,
- TDEFL_FINISH = 4
-} tdefl_flush;
-
-// tdefl's compression state structure.
-typedef struct
-{
- tdefl_put_buf_func_ptr m_pPut_buf_func;
- void *m_pPut_buf_user;
- mz_uint m_flags, m_max_probes[2];
- int m_greedy_parsing;
- mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
- mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
- mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
- mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
- tdefl_status m_prev_return_status;
- const void *m_pIn_buf;
- void *m_pOut_buf;
- size_t *m_pIn_buf_size, *m_pOut_buf_size;
- tdefl_flush m_flush;
- const mz_uint8 *m_pSrc;
- size_t m_src_buf_left, m_out_buf_ofs;
- mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
- mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
- mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
- mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
- mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
- mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
- mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
- mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
-} tdefl_compressor;
-
-// Initializes the compressor.
-// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
-// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
-// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
-// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
-tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
-
-// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
-tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
-
-// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
-// tdefl_compress_buffer() always consumes the entire input buffer.
-tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
-
-tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
-mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
-
-// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
-#ifndef MINIZ_NO_ZLIB_APIS
-// Create tdefl_compress() flags given zlib-style compression parameters.
-// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
-// window_bits may be -15 (raw deflate) or 15 (zlib)
-// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
-mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
-#endif // #ifndef MINIZ_NO_ZLIB_APIS
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // MINIZ_HEADER_INCLUDED
-
-// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
-
-#ifndef MINIZ_HEADER_FILE_ONLY
-
-typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1];
-typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1];
-typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1];
-
-#include <string.h>
-#include <assert.h>
-
-#define MZ_ASSERT(x) assert(x)
-
-#ifdef MINIZ_NO_MALLOC
- #define MZ_MALLOC(x) NULL
- #define MZ_FREE(x) (void)x, ((void)0)
- #define MZ_REALLOC(p, x) NULL
-#else
- #define MZ_MALLOC(x) malloc(x)
- #define MZ_FREE(x) free(x)
- #define MZ_REALLOC(p, x) realloc(p, x)
-#endif
-
-#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
-#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
-#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
-
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
- #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
- #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
-#else
- #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
- #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
-#endif
-
-#ifdef _MSC_VER
- #define MZ_FORCEINLINE __forceinline
-#elif defined(__GNUC__)
- #define MZ_FORCEINLINE inline __attribute__((__always_inline__))
-#else
- #define MZ_FORCEINLINE inline
-#endif
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-// ------------------- zlib-style API's
-
-mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
-{
- mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
- if (!ptr) return MZ_ADLER32_INIT;
- while (buf_len) {
- for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
- s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
- s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
- }
- for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
- s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
- }
- return (s2 << 16) + s1;
-}
-
-// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/
-mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
-{
- static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
- 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
- mz_uint32 crcu32 = (mz_uint32)crc;
- if (!ptr) return MZ_CRC32_INIT;
- crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
- return ~crcu32;
-}
-
-void mz_free(void *p)
-{
- MZ_FREE(p);
-}
-
-#ifndef MINIZ_NO_ZLIB_APIS
-
-static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
-static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
-static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); }
-
-const char *mz_version(void)
-{
- return MZ_VERSION;
-}
-
-int mz_deflateInit(mz_streamp pStream, int level)
-{
- return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
-}
-
-int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
-{
- tdefl_compressor *pComp;
- mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
-
- if (!pStream) return MZ_STREAM_ERROR;
- if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR;
-
- pStream->data_type = 0;
- pStream->adler = MZ_ADLER32_INIT;
- pStream->msg = NULL;
- pStream->reserved = 0;
- pStream->total_in = 0;
- pStream->total_out = 0;
- if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
- if (!pStream->zfree) pStream->zfree = def_free_func;
-
- pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
- if (!pComp)
- return MZ_MEM_ERROR;
-
- pStream->state = (struct mz_internal_state *)pComp;
-
- if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
- {
- mz_deflateEnd(pStream);
- return MZ_PARAM_ERROR;
- }
-
- return MZ_OK;
-}
-
-int mz_deflateReset(mz_streamp pStream)
-{
- if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
- pStream->total_in = pStream->total_out = 0;
- tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
- return MZ_OK;
-}
-
-int mz_deflate(mz_streamp pStream, int flush)
-{
- size_t in_bytes, out_bytes;
- mz_ulong orig_total_in, orig_total_out;
- int mz_status = MZ_OK;
-
- if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
- if (!pStream->avail_out) return MZ_BUF_ERROR;
-
- if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
-
- if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
- return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
-
- orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
- for ( ; ; )
- {
- tdefl_status defl_status;
- in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
-
- defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
- pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
- pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
-
- pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
- pStream->total_out += (mz_uint)out_bytes;
-
- if (defl_status < 0)
- {
- mz_status = MZ_STREAM_ERROR;
- break;
- }
- else if (defl_status == TDEFL_STATUS_DONE)
- {
- mz_status = MZ_STREAM_END;
- break;
- }
- else if (!pStream->avail_out)
- break;
- else if ((!pStream->avail_in) && (flush != MZ_FINISH))
- {
- if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
- break;
- return MZ_BUF_ERROR; // Can't make forward progress without some input.
- }
- }
- return mz_status;
-}
-
-int mz_deflateEnd(mz_streamp pStream)
-{
- if (!pStream) return MZ_STREAM_ERROR;
- if (pStream->state)
- {
- pStream->zfree(pStream->opaque, pStream->state);
- pStream->state = NULL;
- }
- return MZ_OK;
-}
-
-mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
-{
- (void)pStream;
- // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.)
- return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
-}
-
-int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
-{
- int status;
- mz_stream stream;
- memset(&stream, 0, sizeof(stream));
-
- // In case mz_ulong is 64-bits (argh I hate longs).
- if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
-
- stream.next_in = pSource;
- stream.avail_in = (mz_uint32)source_len;
- stream.next_out = pDest;
- stream.avail_out = (mz_uint32)*pDest_len;
-
- status = mz_deflateInit(&stream, level);
- if (status != MZ_OK) return status;
-
- status = mz_deflate(&stream, MZ_FINISH);
- if (status != MZ_STREAM_END)
- {
- mz_deflateEnd(&stream);
- return (status == MZ_OK) ? MZ_BUF_ERROR : status;
- }
-
- *pDest_len = stream.total_out;
- return mz_deflateEnd(&stream);
-}
-
-int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
-{
- return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
-}
-
-mz_ulong mz_compressBound(mz_ulong source_len)
-{
- return mz_deflateBound(NULL, source_len);
-}
-
-typedef struct
-{
- tinfl_decompressor m_decomp;
- mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
- mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
- tinfl_status m_last_status;
-} inflate_state;
-
-int mz_inflateInit2(mz_streamp pStream, int window_bits)
-{
- inflate_state *pDecomp;
- if (!pStream) return MZ_STREAM_ERROR;
- if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
-
- pStream->data_type = 0;
- pStream->adler = 0;
- pStream->msg = NULL;
- pStream->total_in = 0;
- pStream->total_out = 0;
- pStream->reserved = 0;
- if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
- if (!pStream->zfree) pStream->zfree = def_free_func;
-
- pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
- if (!pDecomp) return MZ_MEM_ERROR;
-
- pStream->state = (struct mz_internal_state *)pDecomp;
-
- tinfl_init(&pDecomp->m_decomp);
- pDecomp->m_dict_ofs = 0;
- pDecomp->m_dict_avail = 0;
- pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
- pDecomp->m_first_call = 1;
- pDecomp->m_has_flushed = 0;
- pDecomp->m_window_bits = window_bits;
-
- return MZ_OK;
-}
-
-int mz_inflateInit(mz_streamp pStream)
-{
- return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
-}
-
-int mz_inflate(mz_streamp pStream, int flush)
-{
- inflate_state* pState;
- mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
- size_t in_bytes, out_bytes, orig_avail_in;
- tinfl_status status;
-
- if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
- if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
- if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
-
- pState = (inflate_state*)pStream->state;
- if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
- orig_avail_in = pStream->avail_in;
-
- first_call = pState->m_first_call; pState->m_first_call = 0;
- if (pState->m_last_status < 0) return MZ_DATA_ERROR;
-
- if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
- pState->m_has_flushed |= (flush == MZ_FINISH);
-
- if ((flush == MZ_FINISH) && (first_call))
- {
- // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
- decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
- in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
- status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
- pState->m_last_status = status;
- pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
- pStream->adler = tinfl_get_adler32(&pState->m_decomp);
- pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
-
- if (status < 0)
- return MZ_DATA_ERROR;
- else if (status != TINFL_STATUS_DONE)
- {
- pState->m_last_status = TINFL_STATUS_FAILED;
- return MZ_BUF_ERROR;
- }
- return MZ_STREAM_END;
- }
- // flush != MZ_FINISH then we must assume there's more input.
- if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
-
- if (pState->m_dict_avail)
- {
- n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
- memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
- pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
- pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
- return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
- }
-
- for ( ; ; )
- {
- in_bytes = pStream->avail_in;
- out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
-
- status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
- pState->m_last_status = status;
-
- pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
- pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
-
- pState->m_dict_avail = (mz_uint)out_bytes;
-
- n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
- memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
- pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
- pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
-
- if (status < 0)
- return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
- else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
- return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
- else if (flush == MZ_FINISH)
- {
- // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
- if (status == TINFL_STATUS_DONE)
- return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
- // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong.
- else if (!pStream->avail_out)
- return MZ_BUF_ERROR;
- }
- else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
- break;
- }
-
- return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
-}
-
-int mz_inflateEnd(mz_streamp pStream)
-{
- if (!pStream)
- return MZ_STREAM_ERROR;
- if (pStream->state)
- {
- pStream->zfree(pStream->opaque, pStream->state);
- pStream->state = NULL;
- }
- return MZ_OK;
-}
-
-int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
-{
- mz_stream stream;
- int status;
- memset(&stream, 0, sizeof(stream));
-
- // In case mz_ulong is 64-bits (argh I hate longs).
- if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
-
- stream.next_in = pSource;
- stream.avail_in = (mz_uint32)source_len;
- stream.next_out = pDest;
- stream.avail_out = (mz_uint32)*pDest_len;
-
- status = mz_inflateInit(&stream);
- if (status != MZ_OK)
- return status;
-
- status = mz_inflate(&stream, MZ_FINISH);
- if (status != MZ_STREAM_END)
- {
- mz_inflateEnd(&stream);
- return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
- }
- *pDest_len = stream.total_out;
-
- return mz_inflateEnd(&stream);
-}
-
-const char *mz_error(int err)
-{
- static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
- {
- { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
- { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
- };
- mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc;
- return NULL;
-}
-
-#endif //MINIZ_NO_ZLIB_APIS
-
-// ------------------- Low-level Decompression (completely independent from all compression API's)
-
-#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
-#define TINFL_MEMSET(p, c, l) memset(p, c, l)
-
-#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
-#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
-#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
-#define TINFL_CR_FINISH }
-
-// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
-// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
-#define TINFL_GET_BYTE(state_index, c) do { \
- if (pIn_buf_cur >= pIn_buf_end) { \
- for ( ; ; ) { \
- if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
- TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
- if (pIn_buf_cur < pIn_buf_end) { \
- c = *pIn_buf_cur++; \
- break; \
- } \
- } else { \
- c = 0; \
- break; \
- } \
- } \
- } else c = *pIn_buf_cur++; } MZ_MACRO_END
-
-#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
-#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
-#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
-
-// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
-// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
-// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
-// bit buffer contains >=15 bits (deflate's max. Huffman code size).
-#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
- do { \
- temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
- if (temp >= 0) { \
- code_len = temp >> 9; \
- if ((code_len) && (num_bits >= code_len)) \
- break; \
- } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
- code_len = TINFL_FAST_LOOKUP_BITS; \
- do { \
- temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
- } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
- } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
- } while (num_bits < 15);
-
-// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
-// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
-// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
-// The slow path is only executed at the very end of the input buffer.
-#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
- int temp; mz_uint code_len, c; \
- if (num_bits < 15) { \
- if ((pIn_buf_end - pIn_buf_cur) < 2) { \
- TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
- } else { \
- bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
- } \
- } \
- if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
- code_len = temp >> 9, temp &= 511; \
- else { \
- code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
- } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
-
-tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
-{
- static const int s_length_base[31] = { 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 int s_length_extra[31]= { 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,0,0 };
- static const int s_dist_base[32] = { 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 int s_dist_extra[32] = { 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};
- static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
- static const int s_min_table_sizes[3] = { 257, 1, 4 };
-
- tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
- const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
- mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
- size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
-
- // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
- if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
-
- num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
- TINFL_CR_BEGIN
-
- bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
- if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
- {
- TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
- counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
- if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
- if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
- }
-
- do
- {
- TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
- if (r->m_type == 0)
- {
- TINFL_SKIP_BITS(5, num_bits & 7);
- for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
- if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
- while ((counter) && (num_bits))
- {
- TINFL_GET_BITS(51, dist, 8);
- while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
- *pOut_buf_cur++ = (mz_uint8)dist;
- counter--;
- }
- while (counter)
- {
- size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
- while (pIn_buf_cur >= pIn_buf_end)
- {
- if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
- {
- TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
- }
- else
- {
- TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
- }
- }
- n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
- TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
- }
- }
- else if (r->m_type == 3)
- {
- TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
- }
- else
- {
- if (r->m_type == 1)
- {
- mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
- r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
- for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
- }
- else
- {
- for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
- MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
- r->m_table_sizes[2] = 19;
- }
- for ( ; (int)r->m_type >= 0; r->m_type--)
- {
- int tree_next, tree_cur; tinfl_huff_table *pTable;
- mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
- for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
- used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
- for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
- if ((65536 != total) && (used_syms > 1))
- {
- TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
- }
- for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
- {
- mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
- cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
- if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
- if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
- rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
- for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
- {
- tree_cur -= ((rev_code >>= 1) & 1);
- if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
- }
- tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
- }
- if (r->m_type == 2)
- {
- for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
- {
- mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
- if ((dist == 16) && (!counter))
- {
- TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
- }
- num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
- TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
- }
- if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
- {
- TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
- }
- TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
- }
- }
- for ( ; ; )
- {
- mz_uint8 *pSrc;
- for ( ; ; )
- {
- if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
- {
- TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
- if (counter >= 256)
- break;
- while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
- *pOut_buf_cur++ = (mz_uint8)counter;
- }
- else
- {
- int sym2; mz_uint code_len;
-#if TINFL_USE_64BIT_BITBUF
- if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
-#else
- if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
-#endif
- if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
- code_len = sym2 >> 9;
- else
- {
- code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
- }
- counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
- if (counter & 256)
- break;
-
-#if !TINFL_USE_64BIT_BITBUF
- if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
-#endif
- if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
- code_len = sym2 >> 9;
- else
- {
- code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
- }
- bit_buf >>= code_len; num_bits -= code_len;
-
- pOut_buf_cur[0] = (mz_uint8)counter;
- if (sym2 & 256)
- {
- pOut_buf_cur++;
- counter = sym2;
- break;
- }
- pOut_buf_cur[1] = (mz_uint8)sym2;
- pOut_buf_cur += 2;
- }
- }
- if ((counter &= 511) == 256) break;
-
- num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
- if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
-
- TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
- num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
- if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
-
- dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
- if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
- {
- TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
- }
-
- pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
-
- if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
- {
- while (counter--)
- {
- while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
- *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
- }
- continue;
- }
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
- else if ((counter >= 9) && (counter <= dist))
- {
- const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
- do
- {
- ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
- ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
- pOut_buf_cur += 8;
- } while ((pSrc += 8) < pSrc_end);
- if ((counter &= 7) < 3)
- {
- if (counter)
- {
- pOut_buf_cur[0] = pSrc[0];
- if (counter > 1)
- pOut_buf_cur[1] = pSrc[1];
- pOut_buf_cur += counter;
- }
- continue;
- }
- }
-#endif
- do
- {
- pOut_buf_cur[0] = pSrc[0];
- pOut_buf_cur[1] = pSrc[1];
- pOut_buf_cur[2] = pSrc[2];
- pOut_buf_cur += 3; pSrc += 3;
- } while ((int)(counter -= 3) > 2);
- if ((int)counter > 0)
- {
- pOut_buf_cur[0] = pSrc[0];
- if ((int)counter > 1)
- pOut_buf_cur[1] = pSrc[1];
- pOut_buf_cur += counter;
- }
- }
- }
- } while (!(r->m_final & 1));
- if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
- {
- TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
- }
- TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
- TINFL_CR_FINISH
-
-common_exit:
- r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
- *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
- if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
- {
- const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
- mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
- while (buf_len)
- {
- for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
- {
- s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
- s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
- }
- for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
- s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
- }
- r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
- }
- return status;
-}
-
-// Higher level helper functions.
-void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
-{
- tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
- *pOut_len = 0;
- tinfl_init(&decomp);
- for ( ; ; )
- {
- size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
- tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size,
- (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
- if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
- {
- MZ_FREE(pBuf); *pOut_len = 0; return NULL;
- }
- src_buf_ofs += src_buf_size;
- *pOut_len += dst_buf_size;
- if (status == TINFL_STATUS_DONE) break;
- new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
- pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
- if (!pNew_buf)
- {
- MZ_FREE(pBuf); *pOut_len = 0; return NULL;
- }
- pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
- }
- return pBuf;
-}
-
-size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
-{
- tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
- status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
- return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
-}
-
-int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
-{
- int result = 0;
- tinfl_decompressor decomp;
- mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
- if (!pDict)
- return TINFL_STATUS_FAILED;
- tinfl_init(&decomp);
- for ( ; ; )
- {
- size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
- tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
- (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
- in_buf_ofs += in_buf_size;
- if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
- break;
- if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
- {
- result = (status == TINFL_STATUS_DONE);
- break;
- }
- dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
- }
- MZ_FREE(pDict);
- *pIn_buf_size = in_buf_ofs;
- return result;
-}
-
-// ------------------- Low-level Compression (independent from all decompression API's)
-
-// Purposely making these tables static for faster init and thread safety.
-static const mz_uint16 s_tdefl_len_sym[256] = {
- 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272,
- 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276,
- 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,
- 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,
- 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,
- 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,
- 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,
- 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 };
-
-static const mz_uint8 s_tdefl_len_extra[256] = {
- 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 };
-
-static const mz_uint8 s_tdefl_small_dist_sym[512] = {
- 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,16,16,16,16,16,16,16,16,16,16,16,16,16,
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
- 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
- 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 };
-
-static const mz_uint8 s_tdefl_small_dist_extra[512] = {
- 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,
- 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
- 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
- 7,7,7,7,7,7,7,7 };
-
-static const mz_uint8 s_tdefl_large_dist_sym[128] = {
- 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,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,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 };
-
-static const mz_uint8 s_tdefl_large_dist_extra[128] = {
- 0,0,8,8,9,9,9,9,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,
- 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 };
-
-// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
-typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
-static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
-{
- mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist);
- for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
- while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
- for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
- {
- const mz_uint32* pHist = &hist[pass << 8];
- mz_uint offsets[256], cur_ofs = 0;
- for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
- for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
- { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
- }
- return pCur_syms;
-}
-
-// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
-static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
-{
- int root, leaf, next, avbl, used, dpth;
- if (n==0) return; else if (n==1) { A[0].m_key = 1; return; }
- A[0].m_key += A[1].m_key; root = 0; leaf = 2;
- for (next=1; next < n-1; next++)
- {
- if (leaf>=n || A[root].m_key<A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; } else A[next].m_key = A[leaf++].m_key;
- if (leaf>=n || (root<next && A[root].m_key<A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; } else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
- }
- A[n-2].m_key = 0; for (next=n-3; next>=0; next--) A[next].m_key = A[A[next].m_key].m_key+1;
- avbl = 1; used = dpth = 0; root = n-2; next = n-1;
- while (avbl>0)
- {
- while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; }
- while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
- avbl = 2*used; dpth++; used = 0;
- }
-}
-
-// Limits canonical Huffman code table's max code size.
-enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
-static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
-{
- int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
- for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
- for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
- while (total != (1UL << max_code_size))
- {
- pNum_codes[max_code_size]--;
- for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
- total--;
- }
-}
-
-static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
-{
- int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes);
- if (static_table)
- {
- for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
- }
- else
- {
- tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
- int num_used_syms = 0;
- const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
- for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; }
-
- pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
-
- for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
-
- tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
-
- MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
- for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
- for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
- }
-
- next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
-
- for (i = 0; i < table_len; i++)
- {
- mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
- code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
- d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
- }
-}
-
-#define TDEFL_PUT_BITS(b, l) do { \
- mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
- d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
- while (d->m_bits_in >= 8) { \
- if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
- *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
- d->m_bit_buffer >>= 8; \
- d->m_bits_in -= 8; \
- } \
-} MZ_MACRO_END
-
-#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
- if (rle_repeat_count < 3) { \
- d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
- while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
- } else { \
- d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
-} rle_repeat_count = 0; } }
-
-#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
- if (rle_z_count < 3) { \
- d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
- } else if (rle_z_count <= 10) { \
- d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
- } else { \
- d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
-} rle_z_count = 0; } }
-
-static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
-
-static void tdefl_start_dynamic_block(tdefl_compressor *d)
-{
- int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
- mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
-
- d->m_huff_count[0][256] = 1;
-
- tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
- tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
-
- for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
- for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
-
- memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
- memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
- total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
-
- memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
- for (i = 0; i < total_code_sizes_to_pack; i++)
- {
- mz_uint8 code_size = code_sizes_to_pack[i];
- if (!code_size)
- {
- TDEFL_RLE_PREV_CODE_SIZE();
- if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
- }
- else
- {
- TDEFL_RLE_ZERO_CODE_SIZE();
- if (code_size != prev_code_size)
- {
- TDEFL_RLE_PREV_CODE_SIZE();
- d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size;
- }
- else if (++rle_repeat_count == 6)
- {
- TDEFL_RLE_PREV_CODE_SIZE();
- }
- }
- prev_code_size = code_size;
- }
- if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
-
- tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
-
- TDEFL_PUT_BITS(2, 2);
-
- TDEFL_PUT_BITS(num_lit_codes - 257, 5);
- TDEFL_PUT_BITS(num_dist_codes - 1, 5);
-
- for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break;
- num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
- for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
-
- for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
- {
- mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
- TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
- if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
- }
-}
-
-static void tdefl_start_static_block(tdefl_compressor *d)
-{
- mz_uint i;
- mz_uint8 *p = &d->m_huff_code_sizes[0][0];
-
- for (i = 0; i <= 143; ++i) *p++ = 8;
- for ( ; i <= 255; ++i) *p++ = 9;
- for ( ; i <= 279; ++i) *p++ = 7;
- for ( ; i <= 287; ++i) *p++ = 8;
-
- memset(d->m_huff_code_sizes[1], 5, 32);
-
- tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
- tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
-
- TDEFL_PUT_BITS(1, 2);
-}
-
-static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
-
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
-static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
-{
- mz_uint flags;
- mz_uint8 *pLZ_codes;
- mz_uint8 *pOutput_buf = d->m_pOutput_buf;
- mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
- mz_uint64 bit_buffer = d->m_bit_buffer;
- mz_uint bits_in = d->m_bits_in;
-
-#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
-
- flags = 1;
- for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
- {
- if (flags == 1)
- flags = *pLZ_codes++ | 0x100;
-
- if (flags & 1)
- {
- mz_uint s0, s1, n0, n1, sym, num_extra_bits;
- mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
-
- MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
- TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
- TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
-
- // This sequence coaxes MSVC into using cmov's vs. jmp's.
- s0 = s_tdefl_small_dist_sym[match_dist & 511];
- n0 = s_tdefl_small_dist_extra[match_dist & 511];
- s1 = s_tdefl_large_dist_sym[match_dist >> 8];
- n1 = s_tdefl_large_dist_extra[match_dist >> 8];
- sym = (match_dist < 512) ? s0 : s1;
- num_extra_bits = (match_dist < 512) ? n0 : n1;
-
- MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
- TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
- TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
- }
- else
- {
- mz_uint lit = *pLZ_codes++;
- MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
- TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
-
- if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
- {
- flags >>= 1;
- lit = *pLZ_codes++;
- MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
- TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
-
- if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
- {
- flags >>= 1;
- lit = *pLZ_codes++;
- MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
- TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
- }
- }
- }
-
- if (pOutput_buf >= d->m_pOutput_buf_end)
- return MZ_FALSE;
-
- *(mz_uint64*)pOutput_buf = bit_buffer;
- pOutput_buf += (bits_in >> 3);
- bit_buffer >>= (bits_in & ~7);
- bits_in &= 7;
- }
-
-#undef TDEFL_PUT_BITS_FAST
-
- d->m_pOutput_buf = pOutput_buf;
- d->m_bits_in = 0;
- d->m_bit_buffer = 0;
-
- while (bits_in)
- {
- mz_uint32 n = MZ_MIN(bits_in, 16);
- TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
- bit_buffer >>= n;
- bits_in -= n;
- }
-
- TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
-
- return (d->m_pOutput_buf < d->m_pOutput_buf_end);
-}
-#else
-static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
-{
- mz_uint flags;
- mz_uint8 *pLZ_codes;
-
- flags = 1;
- for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
- {
- if (flags == 1)
- flags = *pLZ_codes++ | 0x100;
- if (flags & 1)
- {
- mz_uint sym, num_extra_bits;
- mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
-
- MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
- TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
- TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
-
- if (match_dist < 512)
- {
- sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
- }
- else
- {
- sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
- }
- MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
- TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
- TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
- }
- else
- {
- mz_uint lit = *pLZ_codes++;
- MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
- TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
- }
- }
-
- TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
-
- return (d->m_pOutput_buf < d->m_pOutput_buf_end);
-}
-#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
-
-static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
-{
- if (static_block)
- tdefl_start_static_block(d);
- else
- tdefl_start_dynamic_block(d);
- return tdefl_compress_lz_codes(d);
-}
-
-static int tdefl_flush_block(tdefl_compressor *d, int flush)
-{
- mz_uint saved_bit_buf, saved_bits_in;
- mz_uint8 *pSaved_output_buf;
- mz_bool comp_block_succeeded = MZ_FALSE;
- int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
- mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
-
- d->m_pOutput_buf = pOutput_buf_start;
- d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
-
- MZ_ASSERT(!d->m_output_flush_remaining);
- d->m_output_flush_ofs = 0;
- d->m_output_flush_remaining = 0;
-
- *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
- d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
-
- if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
- {
- TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
- }
-
- TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
-
- pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
-
- if (!use_raw_block)
- comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
-
- // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
- if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
- ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) )
- {
- mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
- TDEFL_PUT_BITS(0, 2);
- if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
- for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
- {
- TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
- }
- for (i = 0; i < d->m_total_lz_bytes; ++i)
- {
- TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
- }
- }
- // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
- else if (!comp_block_succeeded)
- {
- d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
- tdefl_compress_block(d, MZ_TRUE);
- }
-
- if (flush)
- {
- if (flush == TDEFL_FINISH)
- {
- if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
- if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } }
- }
- else
- {
- mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); }
- }
- }
-
- MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
-
- memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
- memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
-
- d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++;
-
- if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
- {
- if (d->m_pPut_buf_func)
- {
- *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
- if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
- return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
- }
- else if (pOutput_buf_start == d->m_output_buf)
- {
- int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
- memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
- d->m_out_buf_ofs += bytes_to_copy;
- if ((n -= bytes_to_copy) != 0)
- {
- d->m_output_flush_ofs = bytes_to_copy;
- d->m_output_flush_remaining = n;
- }
- }
- else
- {
- d->m_out_buf_ofs += n;
- }
- }
-
- return d->m_output_flush_remaining;
-}
-
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
-#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
-static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
-{
- mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
- mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
- const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
- mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
- MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
- for ( ; ; )
- {
- for ( ; ; )
- {
- if (--num_probes_left == 0) return;
- #define TDEFL_PROBE \
- next_probe_pos = d->m_next[probe_pos]; \
- if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
- probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
- if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
- TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
- }
- if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32;
- do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
- (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
- if (!probe_len)
- {
- *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
- }
- else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
- {
- *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
- c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
- }
- }
-}
-#else
-static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
-{
- mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
- mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
- const mz_uint8 *s = d->m_dict + pos, *p, *q;
- mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
- MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
- for ( ; ; )
- {
- for ( ; ; )
- {
- if (--num_probes_left == 0) return;
- #define TDEFL_PROBE \
- next_probe_pos = d->m_next[probe_pos]; \
- if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
- probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
- if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
- TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
- }
- if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break;
- if (probe_len > match_len)
- {
- *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
- c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
- }
- }
-}
-#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
-
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
-static mz_bool tdefl_compress_fast(tdefl_compressor *d)
-{
- // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
- mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
- mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
- mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
-
- while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
- {
- const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
- mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
- mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
- d->m_src_buf_left -= num_bytes_to_process;
- lookahead_size += num_bytes_to_process;
-
- while (num_bytes_to_process)
- {
- mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
- memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
- if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
- memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
- d->m_pSrc += n;
- dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
- num_bytes_to_process -= n;
- }
-
- dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
- if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
-
- while (lookahead_size >= 4)
- {
- mz_uint cur_match_dist, cur_match_len = 1;
- mz_uint8 *pCur_dict = d->m_dict + cur_pos;
- mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
- mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
- mz_uint probe_pos = d->m_hash[hash];
- d->m_hash[hash] = (mz_uint16)lookahead_pos;
-
- if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
- {
- const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
- const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
- mz_uint32 probe_len = 32;
- do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
- (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
- cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
- if (!probe_len)
- cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
-
- if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)))
- {
- cur_match_len = 1;
- *pLZ_code_buf++ = (mz_uint8)first_trigram;
- *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
- d->m_huff_count[0][(mz_uint8)first_trigram]++;
- }
- else
- {
- mz_uint32 s0, s1;
- cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
-
- MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
-
- cur_match_dist--;
-
- pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
- *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
- pLZ_code_buf += 3;
- *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
-
- s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
- s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
- d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
-
- d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
- }
- }
- else
- {
- *pLZ_code_buf++ = (mz_uint8)first_trigram;
- *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
- d->m_huff_count[0][(mz_uint8)first_trigram]++;
- }
-
- if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
-
- total_lz_bytes += cur_match_len;
- lookahead_pos += cur_match_len;
- dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
- cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
- MZ_ASSERT(lookahead_size >= cur_match_len);
- lookahead_size -= cur_match_len;
-
- if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
- {
- int n;
- d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
- d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
- if ((n = tdefl_flush_block(d, 0)) != 0)
- return (n < 0) ? MZ_FALSE : MZ_TRUE;
- total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
- }
- }
-
- while (lookahead_size)
- {
- mz_uint8 lit = d->m_dict[cur_pos];
-
- total_lz_bytes++;
- *pLZ_code_buf++ = lit;
- *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
- if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
-
- d->m_huff_count[0][lit]++;
-
- lookahead_pos++;
- dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
- cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
- lookahead_size--;
-
- if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
- {
- int n;
- d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
- d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
- if ((n = tdefl_flush_block(d, 0)) != 0)
- return (n < 0) ? MZ_FALSE : MZ_TRUE;
- total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
- }
- }
- }
-
- d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
- d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
- return MZ_TRUE;
-}
-#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
-
-static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
-{
- d->m_total_lz_bytes++;
- *d->m_pLZ_code_buf++ = lit;
- *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
- d->m_huff_count[0][lit]++;
-}
-
-static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
-{
- mz_uint32 s0, s1;
-
- MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
-
- d->m_total_lz_bytes += match_len;
-
- d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
-
- match_dist -= 1;
- d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
- d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3;
-
- *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
-
- s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
- d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
-
- if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
-}
-
-static mz_bool tdefl_compress_normal(tdefl_compressor *d)
-{
- const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left;
- tdefl_flush flush = d->m_flush;
-
- while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
- {
- mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
- // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
- if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
- {
- mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
- mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
- mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
- const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
- src_buf_left -= num_bytes_to_process;
- d->m_lookahead_size += num_bytes_to_process;
- while (pSrc != pSrc_end)
- {
- mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
- hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
- d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
- dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++;
- }
- }
- else
- {
- while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
- {
- mz_uint8 c = *pSrc++;
- mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
- src_buf_left--;
- d->m_dict[dst_pos] = c;
- if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
- d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
- if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
- {
- mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
- mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
- d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
- }
- }
- }
- d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
- if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
- break;
-
- // Simple lazy/greedy parsing state machine.
- len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
- if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
- {
- if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
- {
- mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
- cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; }
- if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1;
- }
- }
- else
- {
- tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
- }
- if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
- {
- cur_match_dist = cur_match_len = 0;
- }
- if (d->m_saved_match_len)
- {
- if (cur_match_len > d->m_saved_match_len)
- {
- tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
- if (cur_match_len >= 128)
- {
- tdefl_record_match(d, cur_match_len, cur_match_dist);
- d->m_saved_match_len = 0; len_to_move = cur_match_len;
- }
- else
- {
- d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
- }
- }
- else
- {
- tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
- len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0;
- }
- }
- else if (!cur_match_dist)
- tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
- else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
- {
- tdefl_record_match(d, cur_match_len, cur_match_dist);
- len_to_move = cur_match_len;
- }
- else
- {
- d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
- }
- // Move the lookahead forward by len_to_move bytes.
- d->m_lookahead_pos += len_to_move;
- MZ_ASSERT(d->m_lookahead_size >= len_to_move);
- d->m_lookahead_size -= len_to_move;
- d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
- // Check if it's time to flush the current LZ codes to the internal output buffer.
- if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
- ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) )
- {
- int n;
- d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
- if ((n = tdefl_flush_block(d, 0)) != 0)
- return (n < 0) ? MZ_FALSE : MZ_TRUE;
- }
- }
-
- d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
- return MZ_TRUE;
-}
-
-static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
-{
- if (d->m_pIn_buf_size)
- {
- *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
- }
-
- if (d->m_pOut_buf_size)
- {
- size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
- memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
- d->m_output_flush_ofs += (mz_uint)n;
- d->m_output_flush_remaining -= (mz_uint)n;
- d->m_out_buf_ofs += n;
-
- *d->m_pOut_buf_size = d->m_out_buf_ofs;
- }
-
- return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
-}
-
-tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
-{
- if (!d)
- {
- if (pIn_buf_size) *pIn_buf_size = 0;
- if (pOut_buf_size) *pOut_buf_size = 0;
- return TDEFL_STATUS_BAD_PARAM;
- }
-
- d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size;
- d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size;
- d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
- d->m_out_buf_ofs = 0;
- d->m_flush = flush;
-
- if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
- (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) )
- {
- if (pIn_buf_size) *pIn_buf_size = 0;
- if (pOut_buf_size) *pOut_buf_size = 0;
- return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
- }
- d->m_wants_to_finish |= (flush == TDEFL_FINISH);
-
- if ((d->m_output_flush_remaining) || (d->m_finished))
- return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
-
-#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
- if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
- ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
- ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
- {
- if (!tdefl_compress_fast(d))
- return d->m_prev_return_status;
- }
- else
-#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
- {
- if (!tdefl_compress_normal(d))
- return d->m_prev_return_status;
- }
-
- if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
- d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
-
- if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
- {
- if (tdefl_flush_block(d, flush) < 0)
- return d->m_prev_return_status;
- d->m_finished = (flush == TDEFL_FINISH);
- if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; }
- }
-
- return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
-}
-
-tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
-{
- MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
-}
-
-tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
-{
- d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user;
- d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
- d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
- if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash);
- d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
- d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
- d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8;
- d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY;
- d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1;
- d->m_pIn_buf = NULL; d->m_pOut_buf = NULL;
- d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL;
- d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0;
- memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
- memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
- return TDEFL_STATUS_OKAY;
-}
-
-tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
-{
- return d->m_prev_return_status;
-}
-
-mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
-{
- return d->m_adler32;
-}
-
-mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
-{
- tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
- pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE;
- succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
- succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
- MZ_FREE(pComp); return succeeded;
-}
-
-typedef struct
-{
- size_t m_size, m_capacity;
- mz_uint8 *m_pBuf;
- mz_bool m_expandable;
-} tdefl_output_buffer;
-
-static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
-{
- tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
- size_t new_size = p->m_size + len;
- if (new_size > p->m_capacity)
- {
- size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE;
- do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity);
- pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE;
- p->m_pBuf = pNew_buf; p->m_capacity = new_capacity;
- }
- memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size;
- return MZ_TRUE;
-}
-
-void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
-{
- tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
- if (!pOut_len) return MZ_FALSE; else *pOut_len = 0;
- out_buf.m_expandable = MZ_TRUE;
- if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL;
- *pOut_len = out_buf.m_size; return out_buf.m_pBuf;
-}
-
-size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
-{
- tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
- if (!pOut_buf) return 0;
- out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len;
- if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0;
- return out_buf.m_size;
-}
-
-#ifndef MINIZ_NO_ZLIB_APIS
-static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
-
-// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
-mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
-{
- mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
- if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
-
- if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
- else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES;
- else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK;
- else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
- else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES;
-
- return comp_flags;
-}
-#endif //MINIZ_NO_ZLIB_APIS
-
-#ifdef _MSC_VER
-#pragma warning (push)
-#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
-#endif
-
-// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
-// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
-// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck.
-void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
-{
- // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined.
- static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
- tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0;
- if (!pComp) return NULL;
- MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; }
- // write dummy header
- for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
- // compress image data
- tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
- for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); }
- if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
- // write real header
- *pLen_out = out_buf.m_size-41;
- {
- static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
- mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
- 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0,
- (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54};
- c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24);
- memcpy(out_buf.m_pBuf, pnghdr, 41);
- }
- // write footer (IDAT CRC-32, followed by IEND chunk)
- if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
- c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24);
- // compute final size of file, grab compressed data buffer and return
- *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
-}
-void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
-{
- // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
- return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
-}
-
-#ifdef _MSC_VER
-#pragma warning (pop)
-#endif
-
-// ------------------- .ZIP archive reading
-
-#ifndef MINIZ_NO_ARCHIVE_APIS
-
-#ifdef MINIZ_NO_STDIO
- #define MZ_FILE void *
-#else
- #include <stdio.h>
- #include <sys/stat.h>
-
- #if defined(_MSC_VER) || defined(__MINGW64__)
- static FILE *mz_fopen(const char *pFilename, const char *pMode)
- {
- FILE* pFile = NULL;
- fopen_s(&pFile, pFilename, pMode);
- return pFile;
- }
- static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
- {
- FILE* pFile = NULL;
- if (freopen_s(&pFile, pPath, pMode, pStream))
- return NULL;
- return pFile;
- }
- #ifndef MINIZ_NO_TIME
- #include <sys/utime.h>
- #endif
- #define MZ_FILE FILE
- #define MZ_FOPEN mz_fopen
- #define MZ_FCLOSE fclose
- #define MZ_FREAD fread
- #define MZ_FWRITE fwrite
- #define MZ_FTELL64 _ftelli64
- #define MZ_FSEEK64 _fseeki64
- #define MZ_FILE_STAT_STRUCT _stat
- #define MZ_FILE_STAT _stat
- #define MZ_FFLUSH fflush
- #define MZ_FREOPEN mz_freopen
- #define MZ_DELETE_FILE remove
- #elif defined(__MINGW32__)
- #ifndef MINIZ_NO_TIME
- #include <sys/utime.h>
- #endif
- #define MZ_FILE FILE
- #define MZ_FOPEN(f, m) fopen(f, m)
- #define MZ_FCLOSE fclose
- #define MZ_FREAD fread
- #define MZ_FWRITE fwrite
- #define MZ_FTELL64 ftello64
- #define MZ_FSEEK64 fseeko64
- #define MZ_FILE_STAT_STRUCT _stat
- #define MZ_FILE_STAT _stat
- #define MZ_FFLUSH fflush
- #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
- #define MZ_DELETE_FILE remove
- #elif defined(__TINYC__)
- #ifndef MINIZ_NO_TIME
- #include <sys/utime.h>
- #endif
- #define MZ_FILE FILE
- #define MZ_FOPEN(f, m) fopen(f, m)
- #define MZ_FCLOSE fclose
- #define MZ_FREAD fread
- #define MZ_FWRITE fwrite
- #define MZ_FTELL64 ftell
- #define MZ_FSEEK64 fseek
- #define MZ_FILE_STAT_STRUCT stat
- #define MZ_FILE_STAT stat
- #define MZ_FFLUSH fflush
- #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
- #define MZ_DELETE_FILE remove
- #elif defined(__GNUC__) && _LARGEFILE64_SOURCE
- #ifndef MINIZ_NO_TIME
- #include <utime.h>
- #endif
- #define MZ_FILE FILE
- #define MZ_FOPEN(f, m) fopen64(f, m)
- #define MZ_FCLOSE fclose
- #define MZ_FREAD fread
- #define MZ_FWRITE fwrite
- #define MZ_FTELL64 ftello64
- #define MZ_FSEEK64 fseeko64
- #define MZ_FILE_STAT_STRUCT stat64
- #define MZ_FILE_STAT stat64
- #define MZ_FFLUSH fflush
- #define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
- #define MZ_DELETE_FILE remove
- #else
- #ifndef MINIZ_NO_TIME
- #include <utime.h>
- #endif
- #define MZ_FILE FILE
- #define MZ_FOPEN(f, m) fopen(f, m)
- #define MZ_FCLOSE fclose
- #define MZ_FREAD fread
- #define MZ_FWRITE fwrite
- #define MZ_FTELL64 ftello
- #define MZ_FSEEK64 fseeko
- #define MZ_FILE_STAT_STRUCT stat
- #define MZ_FILE_STAT stat
- #define MZ_FFLUSH fflush
- #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
- #define MZ_DELETE_FILE remove
- #endif // #ifdef _MSC_VER
-#endif // #ifdef MINIZ_NO_STDIO
-
-#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
-
-// Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff.
-enum
-{
- // ZIP archive identifiers and record sizes
- MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
- MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
- // Central directory header record offsets
- MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
- MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16,
- MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
- MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
- // Local directory header offsets
- MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10,
- MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
- MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
- // End of central directory offsets
- MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
- MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
-};
-
-typedef struct
-{
- void *m_p;
- size_t m_size, m_capacity;
- mz_uint m_element_size;
-} mz_zip_array;
-
-struct mz_zip_internal_state_tag
-{
- mz_zip_array m_central_dir;
- mz_zip_array m_central_dir_offsets;
- mz_zip_array m_sorted_central_dir_offsets;
- MZ_FILE *m_pFile;
- void *m_pMem;
- size_t m_mem_size;
- size_t m_mem_capacity;
-};
-
-#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
-#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
-
-static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
-{
- pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
- memset(pArray, 0, sizeof(mz_zip_array));
-}
-
-static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
-{
- void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE;
- if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; }
- if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE;
- pArray->m_p = pNew_p; pArray->m_capacity = new_capacity;
- return MZ_TRUE;
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
-{
- if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; }
- return MZ_TRUE;
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
-{
- if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; }
- pArray->m_size = new_size;
- return MZ_TRUE;
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
-{
- return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
-{
- if (n==0) return MZ_TRUE;
- assert(NULL!=pElements);
- size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE;
- memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_TIME
-static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date)
-{
- struct tm tm;
- memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1;
- tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31;
- tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62;
- return mktime(&tm);
-}
-
-static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
-{
-#ifdef _MSC_VER
- struct tm tm_struct;
- struct tm *tm = &tm_struct;
- errno_t err = localtime_s(tm, &time);
- if (err)
- {
- *pDOS_date = 0; *pDOS_time = 0;
- return;
- }
-#else
- struct tm *tm = localtime(&time);
-#endif
- *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
- *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
-}
-#endif
-
-#ifndef MINIZ_NO_STDIO
-static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
-{
-#ifdef MINIZ_NO_TIME
- (void)pFilename; *pDOS_date = *pDOS_time = 0;
-#else
- struct MZ_FILE_STAT_STRUCT file_stat;
- // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh.
- if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
- return MZ_FALSE;
- mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date);
-#endif // #ifdef MINIZ_NO_TIME
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_TIME
-static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time)
-{
- struct utimbuf t; t.actime = access_time; t.modtime = modified_time;
- return !utime(pFilename, &t);
-}
-#endif // #ifndef MINIZ_NO_TIME
-#endif // #ifndef MINIZ_NO_STDIO
-
-static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags)
-{
- (void)flags;
- if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
- return MZ_FALSE;
-
- if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
- if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
- if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
-
- pZip->m_zip_mode = MZ_ZIP_MODE_READING;
- pZip->m_archive_size = 0;
- pZip->m_central_directory_file_ofs = 0;
- pZip->m_total_files = 0;
-
- if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
- return MZ_FALSE;
- memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
- return MZ_TRUE;
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
-{
- const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
- const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
- mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
- mz_uint8 l = 0, r = 0;
- pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
- pE = pL + MZ_MIN(l_len, r_len);
- while (pL < pE)
- {
- if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
- break;
- pL++; pR++;
- }
- return (pL == pE) ? (l_len < r_len) : (l < r);
-}
-
-#define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END
-
-// Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.)
-static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
-{
- mz_zip_internal_state *pState = pZip->m_pState;
- const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
- const mz_zip_array *pCentral_dir = &pState->m_central_dir;
- mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
- const int size = pZip->m_total_files;
- int start = (size - 2) >> 1, end;
- while (start >= 0)
- {
- int child, root = start;
- for ( ; ; )
- {
- if ((child = (root << 1) + 1) >= size)
- break;
- child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])));
- if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
- break;
- MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
- }
- start--;
- }
-
- end = size - 1;
- while (end > 0)
- {
- int child, root = 0;
- MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
- for ( ; ; )
- {
- if ((child = (root << 1) + 1) >= end)
- break;
- child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]));
- if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
- break;
- MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
- }
- end--;
- }
-}
-
-static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags)
-{
- mz_uint cdir_size, num_this_disk, cdir_disk_index;
- mz_uint64 cdir_ofs;
- mz_int64 cur_file_ofs;
- const mz_uint8 *p;
- mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
- mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
- // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there.
- if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- // Find the end of central directory record by scanning the file from the end towards the beginning.
- cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
- for ( ; ; )
- {
- int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
- return MZ_FALSE;
- for (i = n - 4; i >= 0; --i)
- if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
- break;
- if (i >= 0)
- {
- cur_file_ofs += i;
- break;
- }
- if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
- return MZ_FALSE;
- cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
- }
- // Read and verify the end of central directory record.
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
- ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
- return MZ_FALSE;
-
- num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
- cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
- if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
- return MZ_FALSE;
-
- if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
-
- cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
- if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
- return MZ_FALSE;
-
- pZip->m_central_directory_file_ofs = cdir_ofs;
-
- if (pZip->m_total_files)
- {
- mz_uint i, n;
-
- // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices.
- if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
- (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
- return MZ_FALSE;
-
- if (sort_central_dir)
- {
- if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
- return MZ_FALSE;
- }
-
- if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
- return MZ_FALSE;
-
- // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported).
- p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
- for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
- {
- mz_uint total_header_size, comp_size, decomp_size, disk_index;
- if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
- return MZ_FALSE;
- MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
- if (sort_central_dir)
- MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
- comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
- decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
- if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF))
- return MZ_FALSE;
- disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
- if ((disk_index != num_this_disk) && (disk_index != 1))
- return MZ_FALSE;
- if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
- return MZ_FALSE;
- if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
- return MZ_FALSE;
- n -= total_header_size; p += total_header_size;
- }
- }
-
- if (sort_central_dir)
- mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
-
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags)
-{
- if ((!pZip) || (!pZip->m_pRead))
- return MZ_FALSE;
- if (!mz_zip_reader_init_internal(pZip, flags))
- return MZ_FALSE;
- pZip->m_archive_size = size;
- if (!mz_zip_reader_read_central_dir(pZip, flags))
- {
- mz_zip_reader_end(pZip);
- return MZ_FALSE;
- }
- return MZ_TRUE;
-}
-
-static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
-{
- mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
- size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
- memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
- return s;
-}
-
-mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags)
-{
- if (!mz_zip_reader_init_internal(pZip, flags))
- return MZ_FALSE;
- pZip->m_archive_size = size;
- pZip->m_pRead = mz_zip_mem_read_func;
- pZip->m_pIO_opaque = pZip;
-#ifdef __cplusplus
- pZip->m_pState->m_pMem = const_cast<void *>(pMem);
-#else
- pZip->m_pState->m_pMem = (void *)pMem;
-#endif
- pZip->m_pState->m_mem_size = size;
- if (!mz_zip_reader_read_central_dir(pZip, flags))
- {
- mz_zip_reader_end(pZip);
- return MZ_FALSE;
- }
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_STDIO
-static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
-{
- mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
- mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
- if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
- return 0;
- return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
-}
-
-mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
-{
- mz_uint64 file_size;
- MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb");
- if (!pFile)
- return MZ_FALSE;
- if (MZ_FSEEK64(pFile, 0, SEEK_END))
- {
- MZ_FCLOSE(pFile);
- return MZ_FALSE;
- }
- file_size = MZ_FTELL64(pFile);
- if (!mz_zip_reader_init_internal(pZip, flags))
- {
- MZ_FCLOSE(pFile);
- return MZ_FALSE;
- }
- pZip->m_pRead = mz_zip_file_read_func;
- pZip->m_pIO_opaque = pZip;
- pZip->m_pState->m_pFile = pFile;
- pZip->m_archive_size = file_size;
- if (!mz_zip_reader_read_central_dir(pZip, flags))
- {
- mz_zip_reader_end(pZip);
- return MZ_FALSE;
- }
- return MZ_TRUE;
-}
-#endif // #ifndef MINIZ_NO_STDIO
-
-mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
-{
- return pZip ? pZip->m_total_files : 0;
-}
-
-static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
-{
- if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
- return NULL;
- return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
-}
-
-mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
-{
- mz_uint m_bit_flag;
- const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
- if (!p)
- return MZ_FALSE;
- m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
- return (m_bit_flag & 1);
-}
-
-mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
-{
- mz_uint filename_len, external_attr;
- const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
- if (!p)
- return MZ_FALSE;
-
- // First see if the filename ends with a '/' character.
- filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
- if (filename_len)
- {
- if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
- return MZ_TRUE;
- }
-
- // Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct.
- // Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field.
- // FIXME: Remove this check? Is it necessary - we already check the filename.
- external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
- if ((external_attr & 0x10) != 0)
- return MZ_TRUE;
-
- return MZ_FALSE;
-}
-
-mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
-{
- mz_uint n;
- const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
- if ((!p) || (!pStat))
- return MZ_FALSE;
-
- // Unpack the central directory record.
- pStat->m_file_index = file_index;
- pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
- pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
- pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
- pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
- pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
-#ifndef MINIZ_NO_TIME
- pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
-#endif
- pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
- pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
- pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
- pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
- pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
- pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
-
- // Copy as much of the filename and comment as possible.
- n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
- memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0';
-
- n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
- pStat->m_comment_size = n;
- memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0';
-
- return MZ_TRUE;
-}
-
-mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
-{
- mz_uint n;
- const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
- if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; }
- n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
- if (filename_buf_size)
- {
- n = MZ_MIN(n, filename_buf_size - 1);
- memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
- pFilename[n] = '\0';
- }
- return n + 1;
-}
-
-static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
-{
- mz_uint i;
- if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
- return 0 == memcmp(pA, pB, len);
- for (i = 0; i < len; ++i)
- if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
- return MZ_FALSE;
- return MZ_TRUE;
-}
-
-static MZ_FORCEINLINE int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
-{
- const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
- mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
- mz_uint8 l = 0, r = 0;
- pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
- pE = pL + MZ_MIN(l_len, r_len);
- while (pL < pE)
- {
- if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
- break;
- pL++; pR++;
- }
- return (pL == pE) ? (int)(l_len - r_len) : (l - r);
-}
-
-static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename)
-{
- mz_zip_internal_state *pState = pZip->m_pState;
- const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
- const mz_zip_array *pCentral_dir = &pState->m_central_dir;
- mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
- const int size = pZip->m_total_files;
- const mz_uint filename_len = (mz_uint)strlen(pFilename);
- int l = 0, h = size - 1;
- while (l <= h)
- {
- int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
- if (!comp)
- return file_index;
- else if (comp < 0)
- l = m + 1;
- else
- h = m - 1;
- }
- return -1;
-}
-
-int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
-{
- mz_uint file_index; size_t name_len, comment_len;
- if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
- return -1;
- if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
- return mz_zip_reader_locate_file_binary_search(pZip, pName);
- name_len = strlen(pName); if (name_len > 0xFFFF) return -1;
- comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1;
- for (file_index = 0; file_index < pZip->m_total_files; file_index++)
- {
- const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
- mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
- const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
- if (filename_len < name_len)
- continue;
- if (comment_len)
- {
- mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
- const char *pFile_comment = pFilename + filename_len + file_extra_len;
- if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags)))
- continue;
- }
- if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
- {
- int ofs = filename_len - 1;
- do
- {
- if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
- break;
- } while (--ofs >= 0);
- ofs++;
- pFilename += ofs; filename_len -= ofs;
- }
- if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
- return file_index;
- }
- return -1;
-}
-
-mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
-{
- int status = TINFL_STATUS_DONE;
- mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
- mz_zip_archive_file_stat file_stat;
- void *pRead_buf;
- mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
- tinfl_decompressor inflator;
-
- if ((buf_size) && (!pBuf))
- return MZ_FALSE;
-
- if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
- return MZ_FALSE;
-
- // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
- if (!file_stat.m_comp_size)
- return MZ_TRUE;
-
- // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
- // I'm torn how to handle this case - should it fail instead?
- if (mz_zip_reader_is_file_a_directory(pZip, file_index))
- return MZ_TRUE;
-
- // Encryption and patch files are not supported.
- if (file_stat.m_bit_flag & (1 | 32))
- return MZ_FALSE;
-
- // This function only supports stored and deflate.
- if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
- return MZ_FALSE;
-
- // Ensure supplied output buffer is large enough.
- needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
- if (buf_size < needed_size)
- return MZ_FALSE;
-
- // Read and parse the local directory entry.
- cur_file_ofs = file_stat.m_local_header_ofs;
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
- return MZ_FALSE;
-
- cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
- if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
- return MZ_FALSE;
-
- if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
- {
- // The file is stored or the caller has requested the compressed data.
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
- return MZ_FALSE;
- return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
- }
-
- // Decompress the file either directly from memory or from a file input buffer.
- tinfl_init(&inflator);
-
- if (pZip->m_pState->m_pMem)
- {
- // Read directly from the archive in memory.
- pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
- read_buf_size = read_buf_avail = file_stat.m_comp_size;
- comp_remaining = 0;
- }
- else if (pUser_read_buf)
- {
- // Use a user provided read buffer.
- if (!user_read_buf_size)
- return MZ_FALSE;
- pRead_buf = (mz_uint8 *)pUser_read_buf;
- read_buf_size = user_read_buf_size;
- read_buf_avail = 0;
- comp_remaining = file_stat.m_comp_size;
- }
- else
- {
- // Temporarily allocate a read buffer.
- read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
-#ifdef _MSC_VER
- if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
-#else
- if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
-#endif
- return MZ_FALSE;
- if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
- return MZ_FALSE;
- read_buf_avail = 0;
- comp_remaining = file_stat.m_comp_size;
- }
-
- do
- {
- size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
- if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
- {
- read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
- cur_file_ofs += read_buf_avail;
- comp_remaining -= read_buf_avail;
- read_buf_ofs = 0;
- }
- in_buf_size = (size_t)read_buf_avail;
- status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
- read_buf_avail -= in_buf_size;
- read_buf_ofs += in_buf_size;
- out_buf_ofs += out_buf_size;
- } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
-
- if (status == TINFL_STATUS_DONE)
- {
- // Make sure the entire file was decompressed, and check its CRC.
- if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
- status = TINFL_STATUS_FAILED;
- }
-
- if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
-
- return status == TINFL_STATUS_DONE;
-}
-
-mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
-{
- int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
- if (file_index < 0)
- return MZ_FALSE;
- return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
-}
-
-mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
-{
- return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
-}
-
-mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
-{
- return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
-}
-
-void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
-{
- mz_uint64 comp_size, uncomp_size, alloc_size;
- const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
- void *pBuf;
-
- if (pSize)
- *pSize = 0;
- if (!p)
- return NULL;
-
- comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
- uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
-
- alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
-#ifdef _MSC_VER
- if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
-#else
- if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
-#endif
- return NULL;
- if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
- return NULL;
-
- if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
- return NULL;
- }
-
- if (pSize) *pSize = (size_t)alloc_size;
- return pBuf;
-}
-
-void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
-{
- int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
- if (file_index < 0)
- {
- if (pSize) *pSize = 0;
- return MZ_FALSE;
- }
- return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
-}
-
-mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
-{
- int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT;
- mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
- mz_zip_archive_file_stat file_stat;
- void *pRead_buf = NULL; void *pWrite_buf = NULL;
- mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
-
- if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
- return MZ_FALSE;
-
- // Empty file, or a directory (but not always a directory - I've seen odd zips with directories that have compressed data which inflates to 0 bytes)
- if (!file_stat.m_comp_size)
- return MZ_TRUE;
-
- // Entry is a subdirectory (I've seen old zips with dir entries which have compressed deflate data which inflates to 0 bytes, but these entries claim to uncompress to 512 bytes in the headers).
- // I'm torn how to handle this case - should it fail instead?
- if (mz_zip_reader_is_file_a_directory(pZip, file_index))
- return MZ_TRUE;
-
- // Encryption and patch files are not supported.
- if (file_stat.m_bit_flag & (1 | 32))
- return MZ_FALSE;
-
- // This function only supports stored and deflate.
- if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
- return MZ_FALSE;
-
- // Read and parse the local directory entry.
- cur_file_ofs = file_stat.m_local_header_ofs;
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
- return MZ_FALSE;
-
- cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
- if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
- return MZ_FALSE;
-
- // Decompress the file either directly from memory or from a file input buffer.
- if (pZip->m_pState->m_pMem)
- {
- pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
- read_buf_size = read_buf_avail = file_stat.m_comp_size;
- comp_remaining = 0;
- }
- else
- {
- read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
- if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
- return MZ_FALSE;
- read_buf_avail = 0;
- comp_remaining = file_stat.m_comp_size;
- }
-
- if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
- {
- // The file is stored or the caller has requested the compressed data.
- if (pZip->m_pState->m_pMem)
- {
-#ifdef _MSC_VER
- if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
-#else
- if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
-#endif
- return MZ_FALSE;
- if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
- status = TINFL_STATUS_FAILED;
- else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
- file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
- out_buf_ofs += file_stat.m_comp_size;
- }
- else
- {
- while (comp_remaining)
- {
- read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
-
- if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
- file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
-
- if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
- cur_file_ofs += read_buf_avail;
- out_buf_ofs += read_buf_avail;
- comp_remaining -= read_buf_avail;
- }
- }
- }
- else
- {
- tinfl_decompressor inflator;
- tinfl_init(&inflator);
-
- if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
- status = TINFL_STATUS_FAILED;
- else
- {
- do
- {
- mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
- size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
- if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
- {
- read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
- if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
- cur_file_ofs += read_buf_avail;
- comp_remaining -= read_buf_avail;
- read_buf_ofs = 0;
- }
-
- in_buf_size = (size_t)read_buf_avail;
- status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
- read_buf_avail -= in_buf_size;
- read_buf_ofs += in_buf_size;
-
- if (out_buf_size)
- {
- if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
- file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
- if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
- {
- status = TINFL_STATUS_FAILED;
- break;
- }
- }
- } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
- }
- }
-
- if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
- {
- // Make sure the entire file was decompressed, and check its CRC.
- if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32))
- status = TINFL_STATUS_FAILED;
- }
-
- if (!pZip->m_pState->m_pMem)
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- if (pWrite_buf)
- pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
-
- return status == TINFL_STATUS_DONE;
-}
-
-mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
-{
- int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
- if (file_index < 0)
- return MZ_FALSE;
- return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
-}
-
-#ifndef MINIZ_NO_STDIO
-static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
-{
- (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque);
-}
-
-mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
-{
- mz_bool status;
- mz_zip_archive_file_stat file_stat;
- MZ_FILE *pFile;
- if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
- return MZ_FALSE;
- pFile = MZ_FOPEN(pDst_filename, "wb");
- if (!pFile)
- return MZ_FALSE;
- status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
- if (MZ_FCLOSE(pFile) == EOF)
- return MZ_FALSE;
-#ifndef MINIZ_NO_TIME
- if (status)
- mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
-#endif
- return status;
-}
-#endif // #ifndef MINIZ_NO_STDIO
-
-mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
-{
- if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
- return MZ_FALSE;
-
- if (pZip->m_pState)
- {
- mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL;
- mz_zip_array_clear(pZip, &pState->m_central_dir);
- mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
- mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
-
-#ifndef MINIZ_NO_STDIO
- if (pState->m_pFile)
- {
- MZ_FCLOSE(pState->m_pFile);
- pState->m_pFile = NULL;
- }
-#endif // #ifndef MINIZ_NO_STDIO
-
- pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
- }
- pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
-
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_STDIO
-mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
-{
- int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
- if (file_index < 0)
- return MZ_FALSE;
- return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
-}
-#endif
-
-// ------------------- .ZIP archive writing
-
-#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
-
-static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); }
-static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); }
-#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
-#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
-
-mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
-{
- if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
- return MZ_FALSE;
-
- if (pZip->m_file_offset_alignment)
- {
- // Ensure user specified file offset alignment is a power of 2.
- if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
- return MZ_FALSE;
- }
-
- if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
- if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
- if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
-
- pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
- pZip->m_archive_size = existing_size;
- pZip->m_central_directory_file_ofs = 0;
- pZip->m_total_files = 0;
-
- if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
- return MZ_FALSE;
- memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
- MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32));
- return MZ_TRUE;
-}
-
-static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
-{
- mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
- mz_zip_internal_state *pState = pZip->m_pState;
- mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
-#ifdef _MSC_VER
- if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
-#else
- if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
-#endif
- return 0;
- if (new_size > pState->m_mem_capacity)
- {
- void *pNew_block;
- size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2;
- if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
- return 0;
- pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity;
- }
- memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
- pState->m_mem_size = (size_t)new_size;
- return n;
-}
-
-mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
-{
- pZip->m_pWrite = mz_zip_heap_write_func;
- pZip->m_pIO_opaque = pZip;
- if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
- return MZ_FALSE;
- if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
- {
- if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
- {
- mz_zip_writer_end(pZip);
- return MZ_FALSE;
- }
- pZip->m_pState->m_mem_capacity = initial_allocation_size;
- }
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_STDIO
-static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
-{
- mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
- mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
- if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
- return 0;
- return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
-}
-
-mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
-{
- MZ_FILE *pFile;
- pZip->m_pWrite = mz_zip_file_write_func;
- pZip->m_pIO_opaque = pZip;
- if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
- return MZ_FALSE;
- if (NULL == (pFile = MZ_FOPEN(pFilename, "wb")))
- {
- mz_zip_writer_end(pZip);
- return MZ_FALSE;
- }
- pZip->m_pState->m_pFile = pFile;
- if (size_to_reserve_at_beginning)
- {
- mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf);
- do
- {
- size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
- {
- mz_zip_writer_end(pZip);
- return MZ_FALSE;
- }
- cur_ofs += n; size_to_reserve_at_beginning -= n;
- } while (size_to_reserve_at_beginning);
- }
- return MZ_TRUE;
-}
-#endif // #ifndef MINIZ_NO_STDIO
-
-mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
-{
- mz_zip_internal_state *pState;
- if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
- return MZ_FALSE;
- // No sense in trying to write to an archive that's already at the support max size
- if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- pState = pZip->m_pState;
-
- if (pState->m_pFile)
- {
-#ifdef MINIZ_NO_STDIO
- pFilename; return MZ_FALSE;
-#else
- // Archive is being read from stdio - try to reopen as writable.
- if (pZip->m_pIO_opaque != pZip)
- return MZ_FALSE;
- if (!pFilename)
- return MZ_FALSE;
- pZip->m_pWrite = mz_zip_file_write_func;
- if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
- {
- // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it.
- mz_zip_reader_end(pZip);
- return MZ_FALSE;
- }
-#endif // #ifdef MINIZ_NO_STDIO
- }
- else if (pState->m_pMem)
- {
- // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback.
- if (pZip->m_pIO_opaque != pZip)
- return MZ_FALSE;
- pState->m_mem_capacity = pState->m_mem_size;
- pZip->m_pWrite = mz_zip_heap_write_func;
- }
- // Archive is being read via a user provided read function - make sure the user has specified a write function too.
- else if (!pZip->m_pWrite)
- return MZ_FALSE;
-
- // Start writing new files at the archive's current central directory location.
- pZip->m_archive_size = pZip->m_central_directory_file_ofs;
- pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
- pZip->m_central_directory_file_ofs = 0;
-
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
-{
- return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
-}
-
-typedef struct
-{
- mz_zip_archive *m_pZip;
- mz_uint64 m_cur_archive_file_ofs;
- mz_uint64 m_comp_size;
-} mz_zip_writer_add_state;
-
-static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser)
-{
- mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
- if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
- return MZ_FALSE;
- pState->m_cur_archive_file_ofs += len;
- pState->m_comp_size += len;
- return MZ_TRUE;
-}
-
-static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
-{
- (void)pZip;
- memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
- MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
- MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
- MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
- MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
- MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
- return MZ_TRUE;
-}
-
-static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
-{
- (void)pZip;
- memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
- MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
- MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
- return MZ_TRUE;
-}
-
-static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
-{
- mz_zip_internal_state *pState = pZip->m_pState;
- mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
- size_t orig_central_dir_size = pState->m_central_dir.m_size;
- mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
-
- // No zip64 support yet
- if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
- return MZ_FALSE;
-
- if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
- (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
- (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
- (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
- (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
- {
- // Try to push the central directory array back into its original state.
- mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
- return MZ_FALSE;
- }
-
- return MZ_TRUE;
-}
-
-static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
-{
- // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes.
- if (*pArchive_name == '/')
- return MZ_FALSE;
- while (*pArchive_name)
- {
- if ((*pArchive_name == '\\') || (*pArchive_name == ':'))
- return MZ_FALSE;
- pArchive_name++;
- }
- return MZ_TRUE;
-}
-
-static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
-{
- mz_uint32 n;
- if (!pZip->m_file_offset_alignment)
- return 0;
- n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
- return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1);
-}
-
-static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
-{
- char buf[4096];
- memset(buf, 0, MZ_MIN(sizeof(buf), n));
- while (n)
- {
- mz_uint32 s = MZ_MIN(sizeof(buf), n);
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
- return MZ_FALSE;
- cur_file_ofs += s; n -= s;
- }
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
-{
- mz_uint16 method = 0, dos_time = 0, dos_date = 0;
- mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
- mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, comp_size = 0;
- size_t archive_name_size;
- mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
- tdefl_compressor *pComp = NULL;
- mz_bool store_data_uncompressed;
- mz_zip_internal_state *pState;
-
- if ((int)level_and_flags < 0)
- level_and_flags = MZ_DEFAULT_LEVEL;
- level = level_and_flags & 0xF;
- store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
-
- if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
- return MZ_FALSE;
-
- local_dir_header_ofs = cur_archive_file_ofs = pZip->m_archive_size;
- pState = pZip->m_pState;
-
- if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
- return MZ_FALSE;
- // No zip64 support yet
- if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
- return MZ_FALSE;
- if (!mz_zip_writer_validate_archive_name(pArchive_name))
- return MZ_FALSE;
-
-#ifndef MINIZ_NO_TIME
- {
- time_t cur_time; time(&cur_time);
- mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date);
- }
-#endif // #ifndef MINIZ_NO_TIME
-
- archive_name_size = strlen(pArchive_name);
- if (archive_name_size > 0xFFFF)
- return MZ_FALSE;
-
- num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
-
- // no zip64 support yet
- if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
- {
- // Set DOS Subdirectory attribute bit.
- ext_attributes |= 0x10;
- // Subdirectories cannot contain data.
- if ((buf_size) || (uncomp_size))
- return MZ_FALSE;
- }
-
- // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.)
- if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
- return MZ_FALSE;
-
- if ((!store_data_uncompressed) && (buf_size))
- {
- if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
- return MZ_FALSE;
- }
-
- if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- return MZ_FALSE;
- }
- local_dir_header_ofs += num_alignment_padding_bytes;
- if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
- cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
-
- MZ_CLEAR_OBJ(local_dir_header);
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- return MZ_FALSE;
- }
- cur_archive_file_ofs += archive_name_size;
-
- if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
- {
- uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size);
- uncomp_size = buf_size;
- if (uncomp_size <= 3)
- {
- level = 0;
- store_data_uncompressed = MZ_TRUE;
- }
- }
-
- if (store_data_uncompressed)
- {
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- return MZ_FALSE;
- }
-
- cur_archive_file_ofs += buf_size;
- comp_size = buf_size;
-
- if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
- method = MZ_DEFLATED;
- }
- else if (buf_size)
- {
- mz_zip_writer_add_state state;
-
- state.m_pZip = pZip;
- state.m_cur_archive_file_ofs = cur_archive_file_ofs;
- state.m_comp_size = 0;
-
- if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
- (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- return MZ_FALSE;
- }
-
- comp_size = state.m_comp_size;
- cur_archive_file_ofs = state.m_cur_archive_file_ofs;
-
- method = MZ_DEFLATED;
- }
-
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- pComp = NULL;
-
- // no zip64 support yet
- if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
- return MZ_FALSE;
-
- if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
- return MZ_FALSE;
-
- if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
- return MZ_FALSE;
-
- if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
- return MZ_FALSE;
-
- pZip->m_total_files++;
- pZip->m_archive_size = cur_archive_file_ofs;
-
- return MZ_TRUE;
-}
-
-#ifndef MINIZ_NO_STDIO
-mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
-{
- mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
- mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
- mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0, comp_size = 0;
- size_t archive_name_size;
- mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
- MZ_FILE *pSrc_file = NULL;
-
- if ((int)level_and_flags < 0)
- level_and_flags = MZ_DEFAULT_LEVEL;
- level = level_and_flags & 0xF;
-
- if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
- return MZ_FALSE;
-
- local_dir_header_ofs = cur_archive_file_ofs = pZip->m_archive_size;
-
-
- if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
- return MZ_FALSE;
- if (!mz_zip_writer_validate_archive_name(pArchive_name))
- return MZ_FALSE;
-
- archive_name_size = strlen(pArchive_name);
- if (archive_name_size > 0xFFFF)
- return MZ_FALSE;
-
- num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
-
- // no zip64 support yet
- if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
- return MZ_FALSE;
-
- pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
- if (!pSrc_file)
- return MZ_FALSE;
- MZ_FSEEK64(pSrc_file, 0, SEEK_END);
- uncomp_size = MZ_FTELL64(pSrc_file);
- MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
-
- if (uncomp_size > 0xFFFFFFFF)
- {
- // No zip64 support yet
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
- if (uncomp_size <= 3)
- level = 0;
-
- if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
- {
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
- local_dir_header_ofs += num_alignment_padding_bytes;
- if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
- cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
-
- MZ_CLEAR_OBJ(local_dir_header);
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
- {
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
- cur_archive_file_ofs += archive_name_size;
-
- if (uncomp_size)
- {
- mz_uint64 uncomp_remaining = uncomp_size;
- void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
- if (!pRead_buf)
- {
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
-
- if (!level)
- {
- while (uncomp_remaining)
- {
- mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
- if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
- uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
- uncomp_remaining -= n;
- cur_archive_file_ofs += n;
- }
- comp_size = uncomp_size;
- }
- else
- {
- mz_bool result = MZ_FALSE;
- mz_zip_writer_add_state state;
- tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
- if (!pComp)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
-
- state.m_pZip = pZip;
- state.m_cur_archive_file_ofs = cur_archive_file_ofs;
- state.m_comp_size = 0;
-
- if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
-
- for ( ; ; )
- {
- size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE);
- tdefl_status status;
-
- if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
- break;
-
- uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
- uncomp_remaining -= in_buf_size;
-
- status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
- if (status == TDEFL_STATUS_DONE)
- {
- result = MZ_TRUE;
- break;
- }
- else if (status != TDEFL_STATUS_OKAY)
- break;
- }
-
- pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
-
- if (!result)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- MZ_FCLOSE(pSrc_file);
- return MZ_FALSE;
- }
-
- comp_size = state.m_comp_size;
- cur_archive_file_ofs = state.m_cur_archive_file_ofs;
-
- method = MZ_DEFLATED;
- }
-
- pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
- }
-
- MZ_FCLOSE(pSrc_file); pSrc_file = NULL;
-
- // no zip64 support yet
- if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
- return MZ_FALSE;
-
- if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
- return MZ_FALSE;
-
- if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
- return MZ_FALSE;
-
- if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
- return MZ_FALSE;
-
- pZip->m_total_files++;
- pZip->m_archive_size = cur_archive_file_ofs;
-
- return MZ_TRUE;
-}
-#endif // #ifndef MINIZ_NO_STDIO
-
-mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index)
-{
- mz_uint n, bit_flags, num_alignment_padding_bytes;
- mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
- mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
- mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
- mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
- size_t orig_central_dir_size;
- mz_zip_internal_state *pState;
- void *pBuf; const mz_uint8 *pSrc_central_header;
-
- if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
- return MZ_FALSE;
- if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
- return MZ_FALSE;
- pState = pZip->m_pState;
-
- num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
-
- // no zip64 support yet
- if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
- cur_dst_file_ofs = pZip->m_archive_size;
-
- if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
- return MZ_FALSE;
- cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
-
- if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
- return MZ_FALSE;
- cur_dst_file_ofs += num_alignment_padding_bytes;
- local_dir_header_ofs = cur_dst_file_ofs;
- if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
-
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
- return MZ_FALSE;
- cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
-
- n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
- comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
-
- if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining)))))
- return MZ_FALSE;
-
- while (comp_bytes_remaining)
- {
- n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
- if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
- return MZ_FALSE;
- }
- cur_src_file_ofs += n;
-
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
- return MZ_FALSE;
- }
- cur_dst_file_ofs += n;
-
- comp_bytes_remaining -= n;
- }
-
- bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
- if (bit_flags & 8)
- {
- // Copy data descriptor
- if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
- return MZ_FALSE;
- }
-
- n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
- if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
- return MZ_FALSE;
- }
-
- cur_dst_file_ofs += n;
- }
- pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
-
- // no zip64 support yet
- if (cur_dst_file_ofs > 0xFFFFFFFF)
- return MZ_FALSE;
-
- orig_central_dir_size = pState->m_central_dir.m_size;
-
- memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
- MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
- if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
- return MZ_FALSE;
-
- n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
- if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n))
- {
- mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
- return MZ_FALSE;
- }
-
- if (pState->m_central_dir.m_size > 0xFFFFFFFF)
- return MZ_FALSE;
- n = (mz_uint32)orig_central_dir_size;
- if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
- {
- mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
- return MZ_FALSE;
- }
-
- pZip->m_total_files++;
- pZip->m_archive_size = cur_dst_file_ofs;
-
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
-{
- mz_zip_internal_state *pState;
- mz_uint64 central_dir_ofs, central_dir_size;
- mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE];
-
- if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
- return MZ_FALSE;
-
- pState = pZip->m_pState;
-
- // no zip64 support yet
- if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
- return MZ_FALSE;
-
- central_dir_ofs = 0;
- central_dir_size = 0;
- if (pZip->m_total_files)
- {
- // Write central directory
- central_dir_ofs = pZip->m_archive_size;
- central_dir_size = pState->m_central_dir.m_size;
- pZip->m_central_directory_file_ofs = central_dir_ofs;
- if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
- return MZ_FALSE;
- pZip->m_archive_size += central_dir_size;
- }
-
- // Write end of central directory record
- MZ_CLEAR_OBJ(hdr);
- MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
- MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
- MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
- MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
- MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
-
- if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr))
- return MZ_FALSE;
-#ifndef MINIZ_NO_STDIO
- if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
- return MZ_FALSE;
-#endif // #ifndef MINIZ_NO_STDIO
-
- pZip->m_archive_size += sizeof(hdr);
-
- pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize)
-{
- if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize))
- return MZ_FALSE;
- if (pZip->m_pWrite != mz_zip_heap_write_func)
- return MZ_FALSE;
- if (!mz_zip_writer_finalize_archive(pZip))
- return MZ_FALSE;
-
- *pBuf = pZip->m_pState->m_pMem;
- *pSize = pZip->m_pState->m_mem_size;
- pZip->m_pState->m_pMem = NULL;
- pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
- return MZ_TRUE;
-}
-
-mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
-{
- mz_zip_internal_state *pState;
- mz_bool status = MZ_TRUE;
- if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
- return MZ_FALSE;
-
- pState = pZip->m_pState;
- pZip->m_pState = NULL;
- mz_zip_array_clear(pZip, &pState->m_central_dir);
- mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
- mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
-
-#ifndef MINIZ_NO_STDIO
- if (pState->m_pFile)
- {
- MZ_FCLOSE(pState->m_pFile);
- pState->m_pFile = NULL;
- }
-#endif // #ifndef MINIZ_NO_STDIO
-
- if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
- {
- pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
- pState->m_pMem = NULL;
- }
-
- pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
- pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
- return status;
-}
-
-#ifndef MINIZ_NO_STDIO
-mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
-{
- mz_bool status, created_new_archive = MZ_FALSE;
- mz_zip_archive zip_archive;
- struct MZ_FILE_STAT_STRUCT file_stat;
- MZ_CLEAR_OBJ(zip_archive);
- if ((int)level_and_flags < 0)
- level_and_flags = MZ_DEFAULT_LEVEL;
- if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
- return MZ_FALSE;
- if (!mz_zip_writer_validate_archive_name(pArchive_name))
- return MZ_FALSE;
- if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
- {
- // Create a new archive.
- if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
- return MZ_FALSE;
- created_new_archive = MZ_TRUE;
- }
- else
- {
- // Append to an existing archive.
- if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
- return MZ_FALSE;
- if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename))
- {
- mz_zip_reader_end(&zip_archive);
- return MZ_FALSE;
- }
- }
- status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
- // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.)
- if (!mz_zip_writer_finalize_archive(&zip_archive))
- status = MZ_FALSE;
- if (!mz_zip_writer_end(&zip_archive))
- status = MZ_FALSE;
- if ((!status) && (created_new_archive))
- {
- // It's a new archive and something went wrong, so just delete it.
- int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
- (void)ignoredStatus;
- }
- return status;
-}
-
-void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
-{
- int file_index;
- mz_zip_archive zip_archive;
- void *p = NULL;
-
- if (pSize)
- *pSize = 0;
-
- if ((!pZip_filename) || (!pArchive_name))
- return NULL;
-
- MZ_CLEAR_OBJ(zip_archive);
- if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
- return NULL;
-
- if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0)
- p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
-
- mz_zip_reader_end(&zip_archive);
- return p;
-}
-
-#endif // #ifndef MINIZ_NO_STDIO
-
-#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
-
-#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // MINIZ_HEADER_FILE_ONLY
-
-/*
- This is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this software, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this software dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to <http://unlicense.org/>
-*/
diff --git a/src/3rdparty/assimp/contrib/zip/src/zip.c b/src/3rdparty/assimp/contrib/zip/src/zip.c
deleted file mode 100644
index 80573096b..000000000
--- a/src/3rdparty/assimp/contrib/zip/src/zip.c
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "zip.h"
-#include "miniz.h"
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>
-
-#if defined _WIN32 || defined __WIN32__
-/* Win32, DOS */
-#include <direct.h>
-
-#define MKDIR(DIRNAME) _mkdir(DIRNAME)
-#define STRCLONE(STR) ((STR) ? _strdup(STR) : NULL)
-#define HAS_DEVICE(P) \
- ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) && \
- (P)[1] == ':')
-#define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE(P) ? 2 : 0)
-#define ISSLASH(C) ((C) == '/' || (C) == '\\')
-
-#else
-#define MKDIR(DIRNAME) mkdir(DIRNAME, 0755)
-#define STRCLONE(STR) ((STR) ? strdup(STR) : NULL)
-#endif
-
-#ifndef FILESYSTEM_PREFIX_LEN
-#define FILESYSTEM_PREFIX_LEN(P) 0
-#endif
-
-#ifndef ISSLASH
-#define ISSLASH(C) ((C) == '/')
-#endif
-
-#define CLEANUP(ptr) \
- do { \
- if (ptr) { \
- free((void *)ptr); \
- ptr = NULL; \
- } \
- } while (0)
-
-static char *basename(const char *name) {
- char const *p;
- char const *base = name += FILESYSTEM_PREFIX_LEN(name);
- int all_slashes = 1;
-
- for (p = name; *p; p++) {
- if (ISSLASH(*p))
- base = p + 1;
- else
- all_slashes = 0;
- }
-
- /* If NAME is all slashes, arrange to return `/'. */
- if (*base == '\0' && ISSLASH(*name) && all_slashes) --base;
-
- return (char *)base;
-}
-
-static int mkpath(const char *path) {
- char const *p;
- char npath[MAX_PATH + 1] = {0};
- int len = 0;
-
- for (p = path; *p && len < MAX_PATH; p++) {
- if (ISSLASH(*p) && len > 0) {
- if (MKDIR(npath) == -1)
- if (errno != EEXIST) return -1;
- }
- npath[len++] = *p;
- }
-
- return 0;
-}
-
-static char *strrpl(const char *str, char oldchar, char newchar) {
- char *rpl = (char *)malloc(sizeof(char) * (1 + strlen(str)));
- char *begin = rpl;
- char c;
- while((c = *str++)) {
- if (c == oldchar) {
- c = newchar;
- }
- *rpl++ = c;
- }
- *rpl = '\0';
-
- return begin;
-}
-
-struct zip_entry_t {
- int index;
- const char *name;
- mz_uint64 uncomp_size;
- mz_uint64 comp_size;
- mz_uint32 uncomp_crc32;
- mz_uint64 offset;
- mz_uint8 header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
- mz_uint64 header_offset;
- mz_uint16 method;
- mz_zip_writer_add_state state;
- tdefl_compressor comp;
-};
-
-struct zip_t {
- mz_zip_archive archive;
- mz_uint level;
- struct zip_entry_t entry;
- char mode;
-};
-
-struct zip_t *zip_open(const char *zipname, int level, char mode) {
- struct zip_t *zip = NULL;
-
- if (!zipname || strlen(zipname) < 1) {
- // zip_t archive name is empty or NULL
- goto cleanup;
- }
-
- if (level < 0) level = MZ_DEFAULT_LEVEL;
- if ((level & 0xF) > MZ_UBER_COMPRESSION) {
- // Wrong compression level
- goto cleanup;
- }
-
- zip = (struct zip_t *)calloc((size_t)1, sizeof(struct zip_t));
- if (!zip) goto cleanup;
-
- zip->level = level;
- zip->mode = mode;
- switch (mode) {
- case 'w':
- // Create a new archive.
- if (!mz_zip_writer_init_file(&(zip->archive), zipname, 0)) {
- // Cannot initialize zip_archive writer
- goto cleanup;
- }
- break;
-
- case 'r':
- case 'a':
- if (!mz_zip_reader_init_file(
- &(zip->archive), zipname,
- level | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) {
- // An archive file does not exist or cannot initialize
- // zip_archive reader
- goto cleanup;
- }
-
- if (mode == 'a' &&
- !mz_zip_writer_init_from_reader(&(zip->archive), zipname)) {
- mz_zip_reader_end(&(zip->archive));
- goto cleanup;
- }
-
- break;
-
- default:
- goto cleanup;
- }
-
- return zip;
-
-cleanup:
- CLEANUP(zip);
- return NULL;
-}
-
-void zip_close(struct zip_t *zip) {
- if (zip) {
- // Always finalize, even if adding failed for some reason, so we have a
- // valid central directory.
- mz_zip_writer_finalize_archive(&(zip->archive));
-
- mz_zip_writer_end(&(zip->archive));
- mz_zip_reader_end(&(zip->archive));
-
- CLEANUP(zip);
- }
-}
-
-int zip_entry_open(struct zip_t *zip, const char *entryname) {
- char *locname = NULL;
- size_t entrylen = 0;
- mz_zip_archive *pzip = NULL;
- mz_uint num_alignment_padding_bytes, level;
-
- if (!zip || !entryname) {
- return -1;
- }
-
- entrylen = strlen(entryname);
- if (entrylen < 1) {
- return -1;
- }
-
- pzip = &(zip->archive);
- /*
- .ZIP File Format Specification Version: 6.3.3
-
- 4.4.17.1 The name of the file, with optional relative path.
- The path stored MUST not contain a drive or
- device letter, or a leading slash. All slashes
- MUST be forward slashes '/' as opposed to
- backwards slashes '\' for compatibility with Amiga
- and UNIX file systems etc. If input came from standard
- input, there is no file name field.
- */
- locname = strrpl(entryname, '\\', '/');
-
- if (zip->mode == 'r') {
- zip->entry.index = mz_zip_reader_locate_file(pzip, locname, NULL, 0);
- CLEANUP(locname);
- return (zip->entry.index < 0) ? -1 : 0;
- }
-
- zip->entry.index = zip->archive.m_total_files;
- zip->entry.name = locname;
- if (!zip->entry.name) {
- // Cannot parse zip entry name
- return -1;
- }
-
- zip->entry.comp_size = 0;
- zip->entry.uncomp_size = 0;
- zip->entry.uncomp_crc32 = MZ_CRC32_INIT;
- zip->entry.offset = zip->archive.m_archive_size;
- zip->entry.header_offset = zip->archive.m_archive_size;
- memset(zip->entry.header, 0,
- MZ_ZIP_LOCAL_DIR_HEADER_SIZE * sizeof(mz_uint8));
- zip->entry.method = 0;
-
- num_alignment_padding_bytes =
- mz_zip_writer_compute_padding_needed_for_file_alignment(pzip);
-
- if (!pzip->m_pState || (pzip->m_zip_mode != MZ_ZIP_MODE_WRITING)) {
- // Wrong zip mode
- return -1;
- }
- if (zip->level & MZ_ZIP_FLAG_COMPRESSED_DATA) {
- // Wrong zip compression level
- return -1;
- }
- // no zip64 support yet
- if ((pzip->m_total_files == 0xFFFF) ||
- ((pzip->m_archive_size + num_alignment_padding_bytes +
- MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
- entrylen) > 0xFFFFFFFF)) {
- // No zip64 support yet
- return -1;
- }
- if (!mz_zip_writer_write_zeros(
- pzip, zip->entry.offset,
- num_alignment_padding_bytes + sizeof(zip->entry.header))) {
- // Cannot memset zip entry header
- return -1;
- }
-
- zip->entry.header_offset += num_alignment_padding_bytes;
- if (pzip->m_file_offset_alignment) {
- MZ_ASSERT((zip->entry.header_offset &
- (pzip->m_file_offset_alignment - 1)) == 0);
- }
- zip->entry.offset +=
- num_alignment_padding_bytes + sizeof(zip->entry.header);
-
- if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, zip->entry.name,
- entrylen) != entrylen) {
- // Cannot write data to zip entry
- return -1;
- }
-
- zip->entry.offset += entrylen;
- level = zip->level & 0xF;
- if (level) {
- zip->entry.state.m_pZip = pzip;
- zip->entry.state.m_cur_archive_file_ofs = zip->entry.offset;
- zip->entry.state.m_comp_size = 0;
-
- if (tdefl_init(&(zip->entry.comp), mz_zip_writer_add_put_buf_callback,
- &(zip->entry.state),
- tdefl_create_comp_flags_from_zip_params(
- level, -15, MZ_DEFAULT_STRATEGY)) !=
- TDEFL_STATUS_OKAY) {
- // Cannot initialize the zip compressor
- return -1;
- }
- }
-
- return 0;
-}
-
-int zip_entry_close(struct zip_t *zip) {
- mz_zip_archive *pzip = NULL;
- mz_uint level;
- tdefl_status done;
- mz_uint16 entrylen;
- time_t t;
- struct tm *tm;
- mz_uint16 dos_time, dos_date;
- int status = -1;
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- if (zip->mode == 'r') {
- return 0;
- }
-
- pzip = &(zip->archive);
- level = zip->level & 0xF;
- if (level) {
- done = tdefl_compress_buffer(&(zip->entry.comp), "", 0, TDEFL_FINISH);
- if (done != TDEFL_STATUS_DONE && done != TDEFL_STATUS_OKAY) {
- // Cannot flush compressed buffer
- goto cleanup;
- }
- zip->entry.comp_size = zip->entry.state.m_comp_size;
- zip->entry.offset = zip->entry.state.m_cur_archive_file_ofs;
- zip->entry.method = MZ_DEFLATED;
- }
-
- entrylen = (mz_uint16)strlen(zip->entry.name);
- t = time(NULL);
- tm = localtime(&t);
- dos_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) +
- ((tm->tm_sec) >> 1));
- dos_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) +
- ((tm->tm_mon + 1) << 5) + tm->tm_mday);
-
- // no zip64 support yet
- if ((zip->entry.comp_size > 0xFFFFFFFF) ||
- (zip->entry.offset > 0xFFFFFFFF)) {
- // No zip64 support, yet
- goto cleanup;
- }
-
- if (!mz_zip_writer_create_local_dir_header(
- pzip, zip->entry.header, entrylen, 0, zip->entry.uncomp_size,
- zip->entry.comp_size, zip->entry.uncomp_crc32, zip->entry.method, 0,
- dos_time, dos_date)) {
- // Cannot create zip entry header
- goto cleanup;
- }
-
- if (pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.header_offset,
- zip->entry.header, sizeof(zip->entry.header)) !=
- sizeof(zip->entry.header)) {
- // Cannot write zip entry header
- goto cleanup;
- }
-
- if (!mz_zip_writer_add_to_central_dir(
- pzip, zip->entry.name, entrylen, NULL, 0, "", 0,
- zip->entry.uncomp_size, zip->entry.comp_size,
- zip->entry.uncomp_crc32, zip->entry.method, 0, dos_time, dos_date,
- zip->entry.header_offset, 0)) {
- // Cannot write to zip central dir
- goto cleanup;
- }
-
- pzip->m_total_files++;
- pzip->m_archive_size = zip->entry.offset;
- status = 0;
-
-cleanup:
- CLEANUP(zip->entry.name);
- return status;
-}
-
-int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize) {
- mz_uint level;
- mz_zip_archive *pzip = NULL;
- tdefl_status status;
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- pzip = &(zip->archive);
- if (buf && bufsize > 0) {
- zip->entry.uncomp_size += bufsize;
- zip->entry.uncomp_crc32 = (mz_uint32)mz_crc32(
- zip->entry.uncomp_crc32, (const mz_uint8 *)buf, bufsize);
-
- level = zip->level & 0xF;
- if (!level) {
- if ((pzip->m_pWrite(pzip->m_pIO_opaque, zip->entry.offset, buf,
- bufsize) != bufsize)) {
- // Cannot write buffer
- return -1;
- }
- zip->entry.offset += bufsize;
- zip->entry.comp_size += bufsize;
- } else {
- status = tdefl_compress_buffer(&(zip->entry.comp), buf, bufsize,
- TDEFL_NO_FLUSH);
- if (status != TDEFL_STATUS_DONE && status != TDEFL_STATUS_OKAY) {
- // Cannot compress buffer
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-int zip_entry_fwrite(struct zip_t *zip, const char *filename) {
- int status = 0;
- size_t n = 0;
- FILE *stream = NULL;
- mz_uint8 buf[MZ_ZIP_MAX_IO_BUF_SIZE] = {0};
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- stream = fopen(filename, "rb");
- if (!stream) {
- // Cannot open filename
- return -1;
- }
-
- while ((n = fread(buf, sizeof(mz_uint8), MZ_ZIP_MAX_IO_BUF_SIZE, stream)) >
- 0) {
- if (zip_entry_write(zip, buf, n) < 0) {
- status = -1;
- break;
- }
- }
- fclose(stream);
-
- return status;
-}
-
-int zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize) {
- mz_zip_archive *pzip = NULL;
- mz_uint idx;
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- if (zip->mode != 'r' || zip->entry.index < 0) {
- // the entry is not found or we do not have read access
- return -1;
- }
-
- pzip = &(zip->archive);
- idx = (mz_uint)zip->entry.index;
- if (mz_zip_reader_is_file_a_directory(pzip, idx)) {
- // the entry is a directory
- return -1;
- }
-
- *buf = mz_zip_reader_extract_to_heap(pzip, idx, bufsize, 0);
- return (*buf) ? 0 : -1;
-}
-
-int zip_entry_fread(struct zip_t *zip, const char *filename) {
- mz_zip_archive *pzip = NULL;
- mz_uint idx;
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- if (zip->mode != 'r' || zip->entry.index < 0) {
- // the entry is not found or we do not have read access
- return -1;
- }
-
- pzip = &(zip->archive);
- idx = (mz_uint)zip->entry.index;
- if (mz_zip_reader_is_file_a_directory(pzip, idx)) {
- // the entry is a directory
- return -1;
- }
-
- return (mz_zip_reader_extract_to_file(pzip, idx, filename, 0)) ? 0 : -1;
-}
-
-int zip_entry_extract(struct zip_t *zip,
- size_t (*on_extract)(void *arg, unsigned long long offset,
- const void *buf, size_t bufsize),
- void *arg) {
- mz_zip_archive *pzip = NULL;
- mz_uint idx;
-
- if (!zip) {
- // zip_t handler is not initialized
- return -1;
- }
-
- if (zip->mode != 'r' || zip->entry.index < 0) {
- // the entry is not found or we do not have read access
- return -1;
- }
-
- pzip = &(zip->archive);
- idx = (mz_uint)zip->entry.index;
-
- return (mz_zip_reader_extract_to_callback(pzip, idx, on_extract, arg, 0))
- ? 0
- : -1;
-}
-
-int zip_create(const char *zipname, const char *filenames[], size_t len) {
- int status = 0;
- size_t i;
- mz_zip_archive zip_archive;
-
- if (!zipname || strlen(zipname) < 1) {
- // zip_t archive name is empty or NULL
- return -1;
- }
-
- // Create a new archive.
- if (!memset(&(zip_archive), 0, sizeof(zip_archive))) {
- // Cannot memset zip archive
- return -1;
- }
-
- if (!mz_zip_writer_init_file(&zip_archive, zipname, 0)) {
- // Cannot initialize zip_archive writer
- return -1;
- }
-
- for (i = 0; i < len; ++i) {
- const char *name = filenames[i];
- if (!name) {
- status = -1;
- break;
- }
-
- if (!mz_zip_writer_add_file(&zip_archive, basename(name), name, "", 0,
- ZIP_DEFAULT_COMPRESSION_LEVEL)) {
- // Cannot add file to zip_archive
- status = -1;
- break;
- }
- }
-
- mz_zip_writer_finalize_archive(&zip_archive);
- mz_zip_writer_end(&zip_archive);
- return status;
-}
-
-int zip_extract(const char *zipname, const char *dir,
- int (*on_extract)(const char *filename, void *arg), void *arg) {
- int status = -1;
- mz_uint i, n;
- char path[MAX_PATH + 1] = {0};
- mz_zip_archive zip_archive;
- mz_zip_archive_file_stat info;
- size_t dirlen = 0;
-
- if (!memset(&(zip_archive), 0, sizeof(zip_archive))) {
- // Cannot memset zip archive
- return -1;
- }
-
- if (!zipname || !dir) {
- // Cannot parse zip archive name
- return -1;
- }
-
- dirlen = strlen(dir);
- if (dirlen + 1 > MAX_PATH) {
- return -1;
- }
-
- // Now try to open the archive.
- if (!mz_zip_reader_init_file(&zip_archive, zipname, 0)) {
- // Cannot initialize zip_archive reader
- return -1;
- }
-
- strcpy(path, dir);
- if (!ISSLASH(path[dirlen - 1])) {
-#if defined _WIN32 || defined __WIN32__
- path[dirlen] = '\\';
-#else
- path[dirlen] = '/';
-#endif
- ++dirlen;
- }
-
- // Get and print information about each file in the archive.
- n = mz_zip_reader_get_num_files(&zip_archive);
- for (i = 0; i < n; ++i) {
- if (!mz_zip_reader_file_stat(&zip_archive, i, &info)) {
- // Cannot get information about zip archive;
- goto out;
- }
- strncpy(&path[dirlen], info.m_filename, MAX_PATH - dirlen);
- if (mkpath(path) < 0) {
- // Cannot make a path
- goto out;
- }
-
- if (!mz_zip_reader_is_file_a_directory(&zip_archive, i)) {
- if (!mz_zip_reader_extract_to_file(&zip_archive, i, path, 0)) {
- // Cannot extract zip archive to file
- goto out;
- }
- }
-
- if (on_extract) {
- if (on_extract(path, arg) < 0) {
- goto out;
- }
- }
- }
- status = 0;
-
-out:
- // Close the archive, freeing any resources it was using
- if (!mz_zip_reader_end(&zip_archive)) {
- // Cannot end zip reader
- status = -1;
- }
-
- return status;
-}
diff --git a/src/3rdparty/assimp/contrib/zip/src/zip.h b/src/3rdparty/assimp/contrib/zip/src/zip.h
deleted file mode 100644
index 1611b5417..000000000
--- a/src/3rdparty/assimp/contrib/zip/src/zip.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#pragma once
-#ifndef ZIP_H
-#define ZIP_H
-
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef MAX_PATH
-#define MAX_PATH 32767 /* # chars in a path name including NULL */
-#endif
-
-#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
-
-/*
- This data structure is used throughout the library to represent zip archive
- - forward declaration.
-*/
-struct zip_t;
-
-/*
- Opens zip archive with compression level using the given mode.
-
- Args:
- zipname: zip archive file name.
- level: compression level (0-9 are the standard zlib-style levels).
- mode: file access mode.
- 'r': opens a file for reading/extracting (the file must exists).
- 'w': creates an empty file for writing.
- 'a': appends to an existing archive.
-
- Returns:
- The zip archive handler or NULL on error
-*/
-extern struct zip_t *zip_open(const char *zipname, int level, char mode);
-
-/*
- Closes zip archive, releases resources - always finalize.
-
- Args:
- zip: zip archive handler.
-*/
-extern void zip_close(struct zip_t *zip);
-
-/*
- Opens a new entry for writing in a zip archive.
-
- Args:
- zip: zip archive handler.
- entryname: an entry name in local dictionary.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_open(struct zip_t *zip, const char *entryname);
-
-/*
- Closes a zip entry, flushes buffer and releases resources.
-
- Args:
- zip: zip archive handler.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_close(struct zip_t *zip);
-
-/*
- Compresses an input buffer for the current zip entry.
-
- Args:
- zip: zip archive handler.
- buf: input buffer.
- bufsize: input buffer size (in bytes).
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
-
-/*
- Compresses a file for the current zip entry.
-
- Args:
- zip: zip archive handler.
- filename: input file.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
-
-/*
- Extracts the current zip entry into output buffer.
- The function allocates sufficient memory for a output buffer.
-
- Args:
- zip: zip archive handler.
- buf: output buffer.
- bufsize: output buffer size (in bytes).
-
- Note:
- - remember to release memory allocated for a output buffer.
- - for large entries, please take a look at zip_entry_extract function.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
-
-/*
- Extracts the current zip entry into output file.
-
- Args:
- zip: zip archive handler.
- filename: output file.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_entry_fread(struct zip_t *zip, const char *filename);
-
-/*
- Extract the current zip entry using a callback function (on_extract).
-
- Args:
- zip: zip archive handler.
- on_extract: callback function.
- arg: opaque pointer (optional argument,
- which you can pass to the on_extract callback)
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
- */
-extern int zip_entry_extract(struct zip_t *zip,
- size_t (*on_extract)(void *arg,
- unsigned long long offset,
- const void *data,
- size_t size),
- void *arg);
-
-/*
- Creates a new archive and puts files into a single zip archive.
-
- Args:
- zipname: zip archive file.
- filenames: input files.
- len: number of input files.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_create(const char *zipname, const char *filenames[], size_t len);
-
-/*
- Extracts a zip archive file into directory.
-
- If on_extract_entry is not NULL, the callback will be called after
- successfully extracted each zip entry.
- Returning a negative value from the callback will cause abort and return an
- error. The last argument (void *arg) is optional, which you can use to pass
- data to the on_extract_entry callback.
-
- Args:
- zipname: zip archive file.
- dir: output directory.
- on_extract_entry: on extract callback.
- arg: opaque pointer.
-
- Returns:
- The return code - 0 on success, negative number (< 0) on error.
-*/
-extern int zip_extract(const char *zipname, const char *dir,
- int (*on_extract_entry)(const char *filename, void *arg),
- void *arg);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/3rdparty/assimp/include/assimp/Compiler/poppack1.h b/src/3rdparty/assimp/include/assimp/Compiler/poppack1.h
deleted file mode 100644
index e033bc147..000000000
--- a/src/3rdparty/assimp/include/assimp/Compiler/poppack1.h
+++ /dev/null
@@ -1,22 +0,0 @@
-
-// ===============================================================================
-// May be included multiple times - resets structure packing to the defaults
-// for all supported compilers. Reverts the changes made by #include <pushpack1.h>
-//
-// Currently this works on the following compilers:
-// MSVC 7,8,9
-// GCC
-// BORLAND (complains about 'pack state changed but not reverted', but works)
-// ===============================================================================
-
-#ifndef AI_PUSHPACK_IS_DEFINED
-# error pushpack1.h must be included after poppack1.h
-#endif
-
-// reset packing to the original value
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack( pop )
-#endif
-#undef PACK_STRUCT
-
-#undef AI_PUSHPACK_IS_DEFINED
diff --git a/src/3rdparty/assimp/include/assimp/Compiler/pstdint.h b/src/3rdparty/assimp/include/assimp/Compiler/pstdint.h
deleted file mode 100644
index 4de4ce2a9..000000000
--- a/src/3rdparty/assimp/include/assimp/Compiler/pstdint.h
+++ /dev/null
@@ -1,912 +0,0 @@
-/* A portable stdint.h
- ****************************************************************************
- * BSD License:
- ****************************************************************************
- *
- * Copyright (c) 2005-2016 Paul Hsieh
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
- ****************************************************************************
- *
- * Version 0.1.15.4
- *
- * The ANSI C standard committee, for the C99 standard, specified the
- * inclusion of a new standard include file called stdint.h. This is
- * a very useful and long desired include file which contains several
- * very precise definitions for integer scalar types that is
- * critically important for making portable several classes of
- * applications including cryptography, hashing, variable length
- * integer libraries and so on. But for most developers its likely
- * useful just for programming sanity.
- *
- * The problem is that some compiler vendors chose to ignore the C99
- * standard and some older compilers have no opportunity to be updated.
- * Because of this situation, simply including stdint.h in your code
- * makes it unportable.
- *
- * So that's what this file is all about. Its an attempt to build a
- * single universal include file that works on as many platforms as
- * possible to deliver what stdint.h is supposed to. Even compilers
- * that already come with stdint.h can use this file instead without
- * any loss of functionality. A few things that should be noted about
- * this file:
- *
- * 1) It is not guaranteed to be portable and/or present an identical
- * interface on all platforms. The extreme variability of the
- * ANSI C standard makes this an impossibility right from the
- * very get go. Its really only meant to be useful for the vast
- * majority of platforms that possess the capability of
- * implementing usefully and precisely defined, standard sized
- * integer scalars. Systems which are not intrinsically 2s
- * complement may produce invalid constants.
- *
- * 2) There is an unavoidable use of non-reserved symbols.
- *
- * 3) Other standard include files are invoked.
- *
- * 4) This file may come in conflict with future platforms that do
- * include stdint.h. The hope is that one or the other can be
- * used with no real difference.
- *
- * 5) In the current version, if your platform can't represent
- * int32_t, int16_t and int8_t, it just dumps out with a compiler
- * error.
- *
- * 6) 64 bit integers may or may not be defined. Test for their
- * presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
- * Note that this is different from the C99 specification which
- * requires the existence of 64 bit support in the compiler. If
- * this is not defined for your platform, yet it is capable of
- * dealing with 64 bits then it is because this file has not yet
- * been extended to cover all of your system's capabilities.
- *
- * 7) (u)intptr_t may or may not be defined. Test for its presence
- * with the test: #ifdef PTRDIFF_MAX. If this is not defined
- * for your platform, then it is because this file has not yet
- * been extended to cover all of your system's capabilities, not
- * because its optional.
- *
- * 8) The following might not been defined even if your platform is
- * capable of defining it:
- *
- * WCHAR_MIN
- * WCHAR_MAX
- * (u)int64_t
- * PTRDIFF_MIN
- * PTRDIFF_MAX
- * (u)intptr_t
- *
- * 9) The following have not been defined:
- *
- * WINT_MIN
- * WINT_MAX
- *
- * 10) The criteria for defining (u)int_least(*)_t isn't clear,
- * except for systems which don't have a type that precisely
- * defined 8, 16, or 32 bit types (which this include file does
- * not support anyways). Default definitions have been given.
- *
- * 11) The criteria for defining (u)int_fast(*)_t isn't something I
- * would trust to any particular compiler vendor or the ANSI C
- * committee. It is well known that "compatible systems" are
- * commonly created that have very different performance
- * characteristics from the systems they are compatible with,
- * especially those whose vendors make both the compiler and the
- * system. Default definitions have been given, but its strongly
- * recommended that users never use these definitions for any
- * reason (they do *NOT* deliver any serious guarantee of
- * improved performance -- not in this file, nor any vendor's
- * stdint.h).
- *
- * 12) The following macros:
- *
- * PRINTF_INTMAX_MODIFIER
- * PRINTF_INT64_MODIFIER
- * PRINTF_INT32_MODIFIER
- * PRINTF_INT16_MODIFIER
- * PRINTF_LEAST64_MODIFIER
- * PRINTF_LEAST32_MODIFIER
- * PRINTF_LEAST16_MODIFIER
- * PRINTF_INTPTR_MODIFIER
- *
- * are strings which have been defined as the modifiers required
- * for the "d", "u" and "x" printf formats to correctly output
- * (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
- * (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
- * PRINTF_INTPTR_MODIFIER is not defined for some systems which
- * provide their own stdint.h. PRINTF_INT64_MODIFIER is not
- * defined if INT64_MAX is not defined. These are an extension
- * beyond what C99 specifies must be in stdint.h.
- *
- * In addition, the following macros are defined:
- *
- * PRINTF_INTMAX_HEX_WIDTH
- * PRINTF_INT64_HEX_WIDTH
- * PRINTF_INT32_HEX_WIDTH
- * PRINTF_INT16_HEX_WIDTH
- * PRINTF_INT8_HEX_WIDTH
- * PRINTF_INTMAX_DEC_WIDTH
- * PRINTF_INT64_DEC_WIDTH
- * PRINTF_INT32_DEC_WIDTH
- * PRINTF_INT16_DEC_WIDTH
- * PRINTF_UINT8_DEC_WIDTH
- * PRINTF_UINTMAX_DEC_WIDTH
- * PRINTF_UINT64_DEC_WIDTH
- * PRINTF_UINT32_DEC_WIDTH
- * PRINTF_UINT16_DEC_WIDTH
- * PRINTF_UINT8_DEC_WIDTH
- *
- * Which specifies the maximum number of characters required to
- * print the number of that type in either hexadecimal or decimal.
- * These are an extension beyond what C99 specifies must be in
- * stdint.h.
- *
- * Compilers tested (all with 0 warnings at their highest respective
- * settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
- * bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
- * .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
- *
- * This file should be considered a work in progress. Suggestions for
- * improvements, especially those which increase coverage are strongly
- * encouraged.
- *
- * Acknowledgements
- *
- * The following people have made significant contributions to the
- * development and testing of this file:
- *
- * Chris Howie
- * John Steele Scott
- * Dave Thorup
- * John Dill
- * Florian Wobbe
- * Christopher Sean Morrison
- * Mikkel Fahnoe Jorgensen
- *
- */
-
-#include <stddef.h>
-#include <limits.h>
-#include <signal.h>
-
-/*
- * For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
- * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
- */
-
-#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
-#include <stdint.h>
-#define _PSTDINT_H_INCLUDED
-# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "l"
-# endif
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-# else
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# ifndef PRINTF_INT32_MODIFIER
-# if (UINT_MAX == UINT32_MAX)
-# define PRINTF_INT32_MODIFIER ""
-# else
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-# endif
-# endif
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-# endif
-# ifndef PRINTF_UINT64_HEX_WIDTH
-# define PRINTF_UINT64_HEX_WIDTH "16"
-# endif
-# ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-# endif
-# ifndef PRINTF_UINT32_HEX_WIDTH
-# define PRINTF_UINT32_HEX_WIDTH "8"
-# endif
-# ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-# endif
-# ifndef PRINTF_UINT16_HEX_WIDTH
-# define PRINTF_UINT16_HEX_WIDTH "4"
-# endif
-# ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-# endif
-# ifndef PRINTF_UINT8_HEX_WIDTH
-# define PRINTF_UINT8_HEX_WIDTH "2"
-# endif
-# ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "19"
-# endif
-# ifndef PRINTF_UINT64_DEC_WIDTH
-# define PRINTF_UINT64_DEC_WIDTH "20"
-# endif
-# ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-# endif
-# ifndef PRINTF_UINT32_DEC_WIDTH
-# define PRINTF_UINT32_DEC_WIDTH "10"
-# endif
-# ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-# endif
-# ifndef PRINTF_UINT16_DEC_WIDTH
-# define PRINTF_UINT16_DEC_WIDTH "5"
-# endif
-# ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-# endif
-# ifndef PRINTF_UINT8_DEC_WIDTH
-# define PRINTF_UINT8_DEC_WIDTH "3"
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_UINTMAX_HEX_WIDTH
-# define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
-# endif
-# ifndef PRINTF_UINTMAX_DEC_WIDTH
-# define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
-# endif
-
-/*
- * Something really weird is going on with Open Watcom. Just pull some of
- * these duplicated definitions from Open Watcom's stdint.h file for now.
- */
-
-# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
-# if !defined (INT64_C)
-# define INT64_C(x) (x + (INT64_MAX - INT64_MAX))
-# endif
-# if !defined (UINT64_C)
-# define UINT64_C(x) (x + (UINT64_MAX - UINT64_MAX))
-# endif
-# if !defined (INT32_C)
-# define INT32_C(x) (x + (INT32_MAX - INT32_MAX))
-# endif
-# if !defined (UINT32_C)
-# define UINT32_C(x) (x + (UINT32_MAX - UINT32_MAX))
-# endif
-# if !defined (INT16_C)
-# define INT16_C(x) (x)
-# endif
-# if !defined (UINT16_C)
-# define UINT16_C(x) (x)
-# endif
-# if !defined (INT8_C)
-# define INT8_C(x) (x)
-# endif
-# if !defined (UINT8_C)
-# define UINT8_C(x) (x)
-# endif
-# if !defined (UINT64_MAX)
-# define UINT64_MAX 18446744073709551615ULL
-# endif
-# if !defined (INT64_MAX)
-# define INT64_MAX 9223372036854775807LL
-# endif
-# if !defined (UINT32_MAX)
-# define UINT32_MAX 4294967295UL
-# endif
-# if !defined (INT32_MAX)
-# define INT32_MAX 2147483647L
-# endif
-# if !defined (INTMAX_MAX)
-# define INTMAX_MAX INT64_MAX
-# endif
-# if !defined (INTMAX_MIN)
-# define INTMAX_MIN INT64_MIN
-# endif
-# endif
-#endif
-
-/*
- * I have no idea what is the truly correct thing to do on older Solaris.
- * From some online discussions, this seems to be what is being
- * recommended. For people who actually are developing on older Solaris,
- * what I would like to know is, does this define all of the relevant
- * macros of a complete stdint.h? Remember, in pstdint.h 64 bit is
- * considered optional.
- */
-
-#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
-#include <sys/inttypes.h>
-#define _PSTDINT_H_INCLUDED
-#endif
-
-#ifndef _PSTDINT_H_INCLUDED
-#define _PSTDINT_H_INCLUDED
-
-#ifndef SIZE_MAX
-# define SIZE_MAX (~(size_t)0)
-#endif
-
-/*
- * Deduce the type assignments from limits.h under the assumption that
- * integer sizes in bits are powers of 2, and follow the ANSI
- * definitions.
- */
-
-#ifndef UINT8_MAX
-# define UINT8_MAX 0xff
-#endif
-#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
-# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
- typedef unsigned char uint8_t;
-# define UINT8_C(v) ((uint8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef INT8_MAX
-# define INT8_MAX 0x7f
-#endif
-#ifndef INT8_MIN
-# define INT8_MIN INT8_C(0x80)
-#endif
-#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
-# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
- typedef signed char int8_t;
-# define INT8_C(v) ((int8_t) v)
-# else
-# error "Platform not supported"
-# endif
-#endif
-
-#ifndef UINT16_MAX
-# define UINT16_MAX 0xffff
-#endif
-#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
-#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
- typedef unsigned int uint16_t;
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-# define UINT16_C(v) ((uint16_t) (v))
-#elif (USHRT_MAX == UINT16_MAX)
- typedef unsigned short uint16_t;
-# define UINT16_C(v) ((uint16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT16_MAX
-# define INT16_MAX 0x7fff
-#endif
-#ifndef INT16_MIN
-# define INT16_MIN INT16_C(0x8000)
-#endif
-#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
-#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
- typedef signed int int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT16_MAX)
- typedef signed short int16_t;
-# define INT16_C(v) ((int16_t) (v))
-# ifndef PRINTF_INT16_MODIFIER
-# define PRINTF_INT16_MODIFIER "h"
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef UINT32_MAX
-# define UINT32_MAX (0xffffffffUL)
-#endif
-#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
-#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
- typedef unsigned long uint32_t;
-# define UINT32_C(v) v ## UL
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (UINT_MAX == UINT32_MAX)
- typedef unsigned int uint32_t;
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-# define UINT32_C(v) v ## U
-#elif (USHRT_MAX == UINT32_MAX)
- typedef unsigned short uint32_t;
-# define UINT32_C(v) ((unsigned short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-#ifndef INT32_MAX
-# define INT32_MAX (0x7fffffffL)
-#endif
-#ifndef INT32_MIN
-# define INT32_MIN INT32_C(0x80000000)
-#endif
-#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
-#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
- typedef signed long int32_t;
-# define INT32_C(v) v ## L
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER "l"
-# endif
-#elif (INT_MAX == INT32_MAX)
- typedef signed int int32_t;
-# define INT32_C(v) v
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#elif (SHRT_MAX == INT32_MAX)
- typedef signed short int32_t;
-# define INT32_C(v) ((short) (v))
-# ifndef PRINTF_INT32_MODIFIER
-# define PRINTF_INT32_MODIFIER ""
-# endif
-#else
-#error "Platform not supported"
-#endif
-#endif
-
-/*
- * The macro stdint_int64_defined is temporarily used to record
- * whether or not 64 integer support is available. It must be
- * defined for any 64 integer extensions for new platforms that are
- * added.
- */
-
-#undef stdint_int64_defined
-#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
-# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# endif
-#endif
-
-#if !defined (stdint_int64_defined)
-# if defined(__GNUC__) && !defined(vxWorks)
-# define stdint_int64_defined
- __extension__ typedef long long int64_t;
- __extension__ typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
-# define stdint_int64_defined
- typedef long long int64_t;
- typedef unsigned long long uint64_t;
-# define UINT64_C(v) v ## ULL
-# define INT64_C(v) v ## LL
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "ll"
-# endif
-# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
-# define stdint_int64_defined
- typedef __int64 int64_t;
- typedef unsigned __int64 uint64_t;
-# define UINT64_C(v) v ## UI64
-# define INT64_C(v) v ## I64
-# ifndef PRINTF_INT64_MODIFIER
-# define PRINTF_INT64_MODIFIER "I64"
-# endif
-# endif
-#endif
-
-#if !defined (LONG_LONG_MAX) && defined (INT64_C)
-# define LONG_LONG_MAX INT64_C (9223372036854775807)
-#endif
-#ifndef ULONG_LONG_MAX
-# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
-#endif
-
-#if !defined (INT64_MAX) && defined (INT64_C)
-# define INT64_MAX INT64_C (9223372036854775807)
-#endif
-#if !defined (INT64_MIN) && defined (INT64_C)
-# define INT64_MIN INT64_C (-9223372036854775808)
-#endif
-#if !defined (UINT64_MAX) && defined (INT64_C)
-# define UINT64_MAX UINT64_C (18446744073709551615)
-#endif
-
-/*
- * Width of hexadecimal for number field.
- */
-
-#ifndef PRINTF_INT64_HEX_WIDTH
-# define PRINTF_INT64_HEX_WIDTH "16"
-#endif
-#ifndef PRINTF_INT32_HEX_WIDTH
-# define PRINTF_INT32_HEX_WIDTH "8"
-#endif
-#ifndef PRINTF_INT16_HEX_WIDTH
-# define PRINTF_INT16_HEX_WIDTH "4"
-#endif
-#ifndef PRINTF_INT8_HEX_WIDTH
-# define PRINTF_INT8_HEX_WIDTH "2"
-#endif
-#ifndef PRINTF_INT64_DEC_WIDTH
-# define PRINTF_INT64_DEC_WIDTH "19"
-#endif
-#ifndef PRINTF_INT32_DEC_WIDTH
-# define PRINTF_INT32_DEC_WIDTH "10"
-#endif
-#ifndef PRINTF_INT16_DEC_WIDTH
-# define PRINTF_INT16_DEC_WIDTH "5"
-#endif
-#ifndef PRINTF_INT8_DEC_WIDTH
-# define PRINTF_INT8_DEC_WIDTH "3"
-#endif
-#ifndef PRINTF_UINT64_DEC_WIDTH
-# define PRINTF_UINT64_DEC_WIDTH "20"
-#endif
-#ifndef PRINTF_UINT32_DEC_WIDTH
-# define PRINTF_UINT32_DEC_WIDTH "10"
-#endif
-#ifndef PRINTF_UINT16_DEC_WIDTH
-# define PRINTF_UINT16_DEC_WIDTH "5"
-#endif
-#ifndef PRINTF_UINT8_DEC_WIDTH
-# define PRINTF_UINT8_DEC_WIDTH "3"
-#endif
-
-/*
- * Ok, lets not worry about 128 bit integers for now. Moore's law says
- * we don't need to worry about that until about 2040 at which point
- * we'll have bigger things to worry about.
- */
-
-#ifdef stdint_int64_defined
- typedef int64_t intmax_t;
- typedef uint64_t uintmax_t;
-# define INTMAX_MAX INT64_MAX
-# define INTMAX_MIN INT64_MIN
-# define UINTMAX_MAX UINT64_MAX
-# define UINTMAX_C(v) UINT64_C(v)
-# define INTMAX_C(v) INT64_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
-# endif
-#else
- typedef int32_t intmax_t;
- typedef uint32_t uintmax_t;
-# define INTMAX_MAX INT32_MAX
-# define UINTMAX_MAX UINT32_MAX
-# define UINTMAX_C(v) UINT32_C(v)
-# define INTMAX_C(v) INT32_C(v)
-# ifndef PRINTF_INTMAX_MODIFIER
-# define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
-# endif
-# ifndef PRINTF_INTMAX_HEX_WIDTH
-# define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
-# endif
-# ifndef PRINTF_INTMAX_DEC_WIDTH
-# define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
-# endif
-#endif
-
-/*
- * Because this file currently only supports platforms which have
- * precise powers of 2 as bit sizes for the default integers, the
- * least definitions are all trivial. Its possible that a future
- * version of this file could have different definitions.
- */
-
-#ifndef stdint_least_defined
- typedef int8_t int_least8_t;
- typedef uint8_t uint_least8_t;
- typedef int16_t int_least16_t;
- typedef uint16_t uint_least16_t;
- typedef int32_t int_least32_t;
- typedef uint32_t uint_least32_t;
-# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
-# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
-# define UINT_LEAST8_MAX UINT8_MAX
-# define INT_LEAST8_MAX INT8_MAX
-# define UINT_LEAST16_MAX UINT16_MAX
-# define INT_LEAST16_MAX INT16_MAX
-# define UINT_LEAST32_MAX UINT32_MAX
-# define INT_LEAST32_MAX INT32_MAX
-# define INT_LEAST8_MIN INT8_MIN
-# define INT_LEAST16_MIN INT16_MIN
-# define INT_LEAST32_MIN INT32_MIN
-# ifdef stdint_int64_defined
- typedef int64_t int_least64_t;
- typedef uint64_t uint_least64_t;
-# define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
-# define UINT_LEAST64_MAX UINT64_MAX
-# define INT_LEAST64_MAX INT64_MAX
-# define INT_LEAST64_MIN INT64_MIN
-# endif
-#endif
-#undef stdint_least_defined
-
-/*
- * The ANSI C committee pretending to know or specify anything about
- * performance is the epitome of misguided arrogance. The mandate of
- * this file is to *ONLY* ever support that absolute minimum
- * definition of the fast integer types, for compatibility purposes.
- * No extensions, and no attempt to suggest what may or may not be a
- * faster integer type will ever be made in this file. Developers are
- * warned to stay away from these types when using this or any other
- * stdint.h.
- */
-
-typedef int_least8_t int_fast8_t;
-typedef uint_least8_t uint_fast8_t;
-typedef int_least16_t int_fast16_t;
-typedef uint_least16_t uint_fast16_t;
-typedef int_least32_t int_fast32_t;
-typedef uint_least32_t uint_fast32_t;
-#define UINT_FAST8_MAX UINT_LEAST8_MAX
-#define INT_FAST8_MAX INT_LEAST8_MAX
-#define UINT_FAST16_MAX UINT_LEAST16_MAX
-#define INT_FAST16_MAX INT_LEAST16_MAX
-#define UINT_FAST32_MAX UINT_LEAST32_MAX
-#define INT_FAST32_MAX INT_LEAST32_MAX
-#define INT_FAST8_MIN INT_LEAST8_MIN
-#define INT_FAST16_MIN INT_LEAST16_MIN
-#define INT_FAST32_MIN INT_LEAST32_MIN
-#ifdef stdint_int64_defined
- typedef int_least64_t int_fast64_t;
- typedef uint_least64_t uint_fast64_t;
-# define UINT_FAST64_MAX UINT_LEAST64_MAX
-# define INT_FAST64_MAX INT_LEAST64_MAX
-# define INT_FAST64_MIN INT_LEAST64_MIN
-#endif
-
-#undef stdint_int64_defined
-
-/*
- * Whatever piecemeal, per compiler thing we can do about the wchar_t
- * type limits.
- */
-
-#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
-# include <wchar.h>
-# ifndef WCHAR_MIN
-# define WCHAR_MIN 0
-# endif
-# ifndef WCHAR_MAX
-# define WCHAR_MAX ((wchar_t)-1)
-# endif
-#endif
-
-/*
- * Whatever piecemeal, per compiler/platform thing we can do about the
- * (u)intptr_t types and limits.
- */
-
-#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-#ifndef STDINT_H_UINTPTR_T_DEFINED
-# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
-# define stdint_intptr_bits 64
-# elif defined (__WATCOMC__) || defined (__TURBOC__)
-# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
-# define stdint_intptr_bits 16
-# else
-# define stdint_intptr_bits 32
-# endif
-# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
-# define stdint_intptr_bits 32
-# elif defined (__INTEL_COMPILER)
-/* TODO -- what did Intel do about x86-64? */
-# else
-/* #error "This platform might not be supported yet" */
-# endif
-
-# ifdef stdint_intptr_bits
-# define stdint_intptr_glue3_i(a,b,c) a##b##c
-# define stdint_intptr_glue3(a,b,c) stdint_intptr_glue3_i(a,b,c)
-# ifndef PRINTF_INTPTR_MODIFIER
-# define PRINTF_INTPTR_MODIFIER stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
-# endif
-# ifndef PTRDIFF_MAX
-# define PTRDIFF_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef PTRDIFF_MIN
-# define PTRDIFF_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef UINTPTR_MAX
-# define UINTPTR_MAX stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MAX
-# define INTPTR_MAX stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
-# endif
-# ifndef INTPTR_MIN
-# define INTPTR_MIN stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
-# endif
-# ifndef INTPTR_C
-# define INTPTR_C(x) stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
-# endif
-# ifndef UINTPTR_C
-# define UINTPTR_C(x) stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
-# endif
- typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
- typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t) intptr_t;
-# else
-/* TODO -- This following is likely wrong for some platforms, and does
- nothing for the definition of uintptr_t. */
- typedef ptrdiff_t intptr_t;
-# endif
-# define STDINT_H_UINTPTR_T_DEFINED
-#endif
-
-/*
- * Assumes sig_atomic_t is signed and we have a 2s complement machine.
- */
-
-#ifndef SIG_ATOMIC_MAX
-# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
-#endif
-
-#endif
-
-#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)
-
-/*
- * Please compile with the maximum warning settings to make sure macros are
- * not defined more than once.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#define glue3_aux(x,y,z) x ## y ## z
-#define glue3(x,y,z) glue3_aux(x,y,z)
-
-#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
-#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);
-
-#define DECL(us,bits) glue3(DECL,us,) (bits)
-
-#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)
-
-#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }
-
-int main () {
- int err_n = 0;
- int err_first = 0;
- DECL(I,8)
- DECL(U,8)
- DECL(I,16)
- DECL(U,16)
- DECL(I,32)
- DECL(U,32)
-#ifdef INT64_MAX
- DECL(I,64)
- DECL(U,64)
-#endif
- intmax_t imax = INTMAX_C(0);
- uintmax_t umax = UINTMAX_C(0);
- char str0[256], str1[256];
-
- sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
- if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
- if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
- sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
- if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
- if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
-#ifdef INT64_MAX
- sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
- if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
- if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
- sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
- if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
- if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
-#endif
-
- sprintf (str0, "%d %x\n", 0, ~0);
-
- sprintf (str1, "%d %x\n", i8, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
- sprintf (str1, "%u %x\n", u8, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
- sprintf (str1, "%d %x\n", i16, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
- sprintf (str1, "%u %x\n", u16, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
- sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n", i32, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
- sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n", u32, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
-#ifdef INT64_MAX
- sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n", i64, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
-#endif
- sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n", imax, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
- sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n", umax, ~0);
- if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));
-
- TESTUMAX(8);
- TESTUMAX(16);
- TESTUMAX(32);
-#ifdef INT64_MAX
- TESTUMAX(64);
-#endif
-
-#define STR(v) #v
-#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
- if (err_n) {
- printf ("pstdint.h is not correct. Please use sizes below to correct it:\n");
- }
-
- Q(int)
- Q(unsigned)
- Q(long int)
- Q(short int)
- Q(int8_t)
- Q(int16_t)
- Q(int32_t)
-#ifdef INT64_MAX
- Q(int64_t)
-#endif
-
- return EXIT_SUCCESS;
-}
-
-#endif
diff --git a/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h b/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h
deleted file mode 100644
index 94ee1e474..000000000
--- a/src/3rdparty/assimp/include/assimp/Compiler/pushpack1.h
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-// ===============================================================================
-// May be included multiple times - sets structure packing to 1
-// for all supported compilers. #include <poppack1.h> reverts the changes.
-//
-// Currently this works on the following compilers:
-// MSVC 7,8,9
-// GCC
-// BORLAND (complains about 'pack state changed but not reverted', but works)
-// Clang
-//
-//
-// USAGE:
-//
-// struct StructToBePacked {
-// } PACK_STRUCT;
-//
-// ===============================================================================
-
-#ifdef AI_PUSHPACK_IS_DEFINED
-# error poppack1.h must be included after pushpack1.h
-#endif
-
-#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
-# pragma pack(push,1)
-# define PACK_STRUCT
-#elif defined( __GNUC__ )
-# if !defined(HOST_MINGW)
-# define PACK_STRUCT __attribute__((__packed__))
-# else
-# define PACK_STRUCT __attribute__((gcc_struct, __packed__))
-# endif
-#else
-# error Compiler not supported
-#endif
-
-#if defined(_MSC_VER)
-// C4103: Packing was changed after the inclusion of the header, probably missing #pragma pop
-# pragma warning (disable : 4103)
-#endif
-
-#define AI_PUSHPACK_IS_DEFINED
diff --git a/src/3rdparty/assimp/include/assimp/DefaultIOStream.h b/src/3rdparty/assimp/include/assimp/DefaultIOStream.h
deleted file mode 100644
index 3668b27ec..000000000
--- a/src/3rdparty/assimp/include/assimp/DefaultIOStream.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Default file I/O using fXXX()-family of functions */
-#ifndef AI_DEFAULTIOSTREAM_H_INC
-#define AI_DEFAULTIOSTREAM_H_INC
-
-#include <stdio.h>
-#include <assimp/IOStream.hpp>
-#include <assimp/importerdesc.h>
-#include <assimp/Defines.h>
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-//! @class DefaultIOStream
-//! @brief Default IO implementation, use standard IO operations
-//! @note An instance of this class can exist without a valid file handle
-//! attached to it. All calls fail, but the instance can nevertheless be
-//! used with no restrictions.
-class ASSIMP_API DefaultIOStream : public IOStream
-{
- friend class DefaultIOSystem;
-#if __ANDROID__
-# if __ANDROID_API__ > 9
-# if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
- friend class AndroidJNIIOSystem;
-# endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
-# endif // __ANDROID_API__ > 9
-#endif // __ANDROID__
-
-protected:
- DefaultIOStream();
- DefaultIOStream(FILE* pFile, const std::string &strFilename);
-
-public:
- /** Destructor public to allow simple deletion to close the file. */
- ~DefaultIOStream ();
-
- // -------------------------------------------------------------------
- /// Read from stream
- size_t Read(void* pvBuffer,
- size_t pSize,
- size_t pCount);
-
-
- // -------------------------------------------------------------------
- /// Write to stream
- size_t Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount);
-
- // -------------------------------------------------------------------
- /// Seek specific position
- aiReturn Seek(size_t pOffset,
- aiOrigin pOrigin);
-
- // -------------------------------------------------------------------
- /// Get current seek position
- size_t Tell() const;
-
- // -------------------------------------------------------------------
- /// Get size of file
- size_t FileSize() const;
-
- // -------------------------------------------------------------------
- /// Flush file contents
- void Flush();
-
-private:
- // File data-structure, using clib
- FILE* mFile;
- // Filename
- std::string mFilename;
-
- // Cached file size
- mutable size_t mCachedSize;
-};
-
-// ----------------------------------------------------------------------------------
-inline DefaultIOStream::DefaultIOStream () :
- mFile (NULL),
- mFilename (""),
- mCachedSize(SIZE_MAX)
-{
- // empty
-}
-
-// ----------------------------------------------------------------------------------
-inline DefaultIOStream::DefaultIOStream (FILE* pFile,
- const std::string &strFilename) :
- mFile(pFile),
- mFilename(strFilename),
- mCachedSize(SIZE_MAX)
-{
- // empty
-}
-// ----------------------------------------------------------------------------------
-
-} // ns assimp
-
-#endif //!!AI_DEFAULTIOSTREAM_H_INC
-
diff --git a/src/3rdparty/assimp/include/assimp/DefaultIOSystem.h b/src/3rdparty/assimp/include/assimp/DefaultIOSystem.h
deleted file mode 100644
index d7cf031cf..000000000
--- a/src/3rdparty/assimp/include/assimp/DefaultIOSystem.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Default implementation of IOSystem using the standard C file functions */
-#ifndef AI_DEFAULTIOSYSTEM_H_INC
-#define AI_DEFAULTIOSYSTEM_H_INC
-
-#include <assimp/IOSystem.hpp>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Default implementation of IOSystem using the standard C file functions */
-class ASSIMP_API DefaultIOSystem : public IOSystem
-{
-public:
- /** Constructor. */
- DefaultIOSystem();
-
- /** Destructor. */
- ~DefaultIOSystem();
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const;
-
- // -------------------------------------------------------------------
- /** Returns the directory separator. */
- char getOsSeparator() const;
-
- // -------------------------------------------------------------------
- /** Open a new file with a given path. */
- IOStream* Open( const char* pFile, const char* pMode = "rb");
-
- // -------------------------------------------------------------------
- /** Closes the given file and releases all resources associated with it. */
- void Close( IOStream* pFile);
-
- // -------------------------------------------------------------------
- /** Compare two paths */
- bool ComparePaths (const char* one, const char* second) const;
-
- /** @brief get the file name of a full filepath
- * example: /tmp/archive.tar.gz -> archive.tar.gz
- */
- static std::string fileName( const std::string &path );
-
- /** @brief get the complete base name of a full filepath
- * example: /tmp/archive.tar.gz -> archive.tar
- */
- static std::string completeBaseName( const std::string &path);
-
- /** @brief get the path of a full filepath
- * example: /tmp/archive.tar.gz -> /tmp/
- */
- static std::string absolutePath( const std::string &path);
-};
-
-} //!ns Assimp
-
-#endif //AI_DEFAULTIOSYSTEM_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/DefaultLogger.hpp b/src/3rdparty/assimp/include/assimp/DefaultLogger.hpp
deleted file mode 100644
index 4f1a7e1f4..000000000
--- a/src/3rdparty/assimp/include/assimp/DefaultLogger.hpp
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 DefaultLogger.hpp
-*/
-
-#ifndef INCLUDED_AI_DEFAULTLOGGER
-#define INCLUDED_AI_DEFAULTLOGGER
-
-#include "Logger.hpp"
-#include "LogStream.hpp"
-#include "NullLogger.hpp"
-#include <vector>
-
-namespace Assimp {
-// ------------------------------------------------------------------------------------
-class IOStream;
-struct LogStreamInfo;
-
-/** default name of logfile */
-#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
-
-// ------------------------------------------------------------------------------------
-/** @brief CPP-API: Primary logging facility of Assimp.
- *
- * The library stores its primary #Logger as a static member of this class.
- * #get() returns this primary logger. By default the underlying implementation is
- * just a #NullLogger which rejects all log messages. By calling #create(), logging
- * is turned on. To capture the log output multiple log streams (#LogStream) can be
- * attach to the logger. Some default streams for common streaming locations (such as
- * a file, std::cout, OutputDebugString()) are also provided.
- *
- * If you wish to customize the logging at an even deeper level supply your own
- * implementation of #Logger to #set().
- * @note The whole logging stuff causes a small extra overhead for all imports. */
-class ASSIMP_API DefaultLogger :
- public Logger {
-
-public:
-
- // ----------------------------------------------------------------------
- /** @brief Creates a logging instance.
- * @param name Name for log file. Only valid in combination
- * with the aiDefaultLogStream_FILE flag.
- * @param severity Log severity, VERBOSE turns on debug messages
- * @param defStreams Default log streams to be attached. Any bitwise
- * combination of the aiDefaultLogStream enumerated values.
- * If #aiDefaultLogStream_FILE is specified but an empty string is
- * passed for 'name', no log file is created at all.
- * @param io IOSystem to be used to open external files (such as the
- * log file). Pass NULL to rely on the default implementation.
- * This replaces the default #NullLogger with a #DefaultLogger instance. */
- static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME,
- LogSeverity severity = NORMAL,
- unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
- IOSystem* io = NULL);
-
- // ----------------------------------------------------------------------
- /** @brief Setup a custom #Logger implementation.
- *
- * Use this if the provided #DefaultLogger class doesn't fit into
- * your needs. If the provided message formatting is OK for you,
- * it's much easier to use #create() and to attach your own custom
- * output streams to it.
- * @param logger Pass NULL to setup a default NullLogger*/
- static void set (Logger *logger);
-
- // ----------------------------------------------------------------------
- /** @brief Getter for singleton instance
- * @return Only instance. This is never null, but it could be a
- * NullLogger. Use isNullLogger to check this.*/
- static Logger *get();
-
- // ----------------------------------------------------------------------
- /** @brief Return whether a #NullLogger is currently active
- * @return true if the current logger is a #NullLogger.
- * Use create() or set() to setup a logger that does actually do
- * something else than just rejecting all log messages. */
- static bool isNullLogger();
-
- // ----------------------------------------------------------------------
- /** @brief Kills the current singleton logger and replaces it with a
- * #NullLogger instance. */
- static void kill();
-
- // ----------------------------------------------------------------------
- /** @copydoc Logger::attachStream */
- bool attachStream(LogStream *pStream,
- unsigned int severity);
-
- // ----------------------------------------------------------------------
- /** @copydoc Logger::detatchStream */
- bool detatchStream(LogStream *pStream,
- unsigned int severity);
-
-
-private:
-
- // ----------------------------------------------------------------------
- /** @briefPrivate construction for internal use by create().
- * @param severity Logging granularity */
- explicit DefaultLogger(LogSeverity severity);
-
- // ----------------------------------------------------------------------
- /** @briefDestructor */
- ~DefaultLogger();
-
-private:
-
- /** @brief Logs debug infos, only been written when severity level VERBOSE is set */
- void OnDebug(const char* message);
-
- /** @brief Logs an info message */
- void OnInfo(const char* message);
-
- /** @brief Logs a warning message */
- void OnWarn(const char* message);
-
- /** @brief Logs an error message */
- void OnError(const char* message);
-
- // ----------------------------------------------------------------------
- /** @brief Writes a message to all streams */
- void WriteToStreams(const char* message, ErrorSeverity ErrorSev );
-
- // ----------------------------------------------------------------------
- /** @brief Returns the thread id.
- * @note This is an OS specific feature, if not supported, a
- * zero will be returned.
- */
- unsigned int GetThreadID();
-
-private:
- // Aliases for stream container
- typedef std::vector<LogStreamInfo*> StreamArray;
- typedef std::vector<LogStreamInfo*>::iterator StreamIt;
- typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
-
- //! only logging instance
- static Logger *m_pLogger;
- static NullLogger s_pNullLogger;
-
- //! Attached streams
- StreamArray m_StreamArray;
-
- bool noRepeatMsg;
- char lastMsg[MAX_LOG_MESSAGE_LENGTH*2];
- size_t lastLen;
-};
-// ------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! INCLUDED_AI_DEFAULTLOGGER
diff --git a/src/3rdparty/assimp/include/assimp/Defines.h b/src/3rdparty/assimp/include/assimp/Defines.h
deleted file mode 100644
index 15e1d83c2..000000000
--- a/src/3rdparty/assimp/include/assimp/Defines.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-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.
-
-----------------------------------------------------------------------
-*/
-
-// We need those constants, workaround for any platforms where nobody defined them yet
-#if (!defined SIZE_MAX)
-# define SIZE_MAX (~((size_t)0))
-#endif
-
-#if (!defined UINT_MAX)
-# define UINT_MAX (~((unsigned int)0))
-#endif
-
diff --git a/src/3rdparty/assimp/include/assimp/Exporter.hpp b/src/3rdparty/assimp/include/assimp/Exporter.hpp
deleted file mode 100644
index c6a6f684a..000000000
--- a/src/3rdparty/assimp/include/assimp/Exporter.hpp
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Exporter.hpp
-* @brief Defines the CPP-API for the Assimp export interface
-*/
-#pragma once
-#ifndef AI_EXPORT_HPP_INC
-#define AI_EXPORT_HPP_INC
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-
-#include "cexport.h"
-#include <map>
-
-namespace Assimp {
-
-class ExporterPimpl;
-class IOSystem;
-
-// ----------------------------------------------------------------------------------
-/** CPP-API: The Exporter class forms an C++ interface to the export functionality
- * of the Open Asset Import Library. Note that the export interface is available
- * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
- *
- * The interface is modeled after the importer interface and mostly
- * symmetric. The same rules for threading etc. apply.
- *
- * In a nutshell, there are two export interfaces: #Export, which writes the
- * output file(s) either to the regular file system or to a user-supplied
- * #IOSystem, and #ExportToBlob which returns a linked list of memory
- * buffers (blob), each referring to one output file (in most cases
- * there will be only one output file of course, but this extra complexity is
- * needed since Assimp aims at supporting a wide range of file formats).
- *
- * #ExportToBlob is especially useful if you intend to work
- * with the data in-memory.
-*/
-class ASSIMP_API ExportProperties;
-
-class ASSIMP_API Exporter {
-public:
- /** Function pointer type of a Export worker function */
- typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
-
- /** Internal description of an Assimp export format option */
- struct ExportFormatEntry
- {
- /// Public description structure to be returned by aiGetExportFormatDescription()
- aiExportFormatDesc mDescription;
-
- // Worker function to do the actual exporting
- fpExportFunc mExportFunction;
-
- // Post-processing steps to be executed PRIOR to invoking mExportFunction
- unsigned int mEnforcePP;
-
- // Constructor to fill all entries
- ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u)
- {
- mDescription.id = pId;
- mDescription.description = pDesc;
- mDescription.fileExtension = pExtension;
- mExportFunction = pFunction;
- mEnforcePP = pEnforcePP;
- }
-
- ExportFormatEntry() :
- mExportFunction()
- , mEnforcePP()
- {
- mDescription.id = NULL;
- mDescription.description = NULL;
- mDescription.fileExtension = NULL;
- }
- };
-
-
-public:
- Exporter();
- ~Exporter();
-
-public:
- // -------------------------------------------------------------------
- /** Supplies a custom IO handler to the exporter to use to open and
- * access files.
- *
- * If you need #Export to use custom IO logic to access the files,
- * you need to supply a custom implementation of IOSystem and
- * IOFile to the exporter.
- *
- * #Exporter takes ownership of the object and will destroy it
- * afterwards. The previously assigned handler will be deleted.
- * Pass NULL to take again ownership of your IOSystem and reset Assimp
- * to use its default implementation, which uses plain file IO.
- *
- * @param pIOHandler The IO handler to be used in all file accesses
- * of the Importer. */
- void SetIOHandler( IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Retrieves the IO handler that is currently set.
- * You can use #IsDefaultIOHandler() to check whether the returned
- * interface is the default IO handler provided by ASSIMP. The default
- * handler is active as long the application doesn't supply its own
- * custom IO handler via #SetIOHandler().
- * @return A valid IOSystem interface, never NULL. */
- IOSystem* GetIOHandler() const;
-
- // -------------------------------------------------------------------
- /** Checks whether a default IO handler is active
- * A default handler is active as long the application doesn't
- * supply its own custom IO handler via #SetIOHandler().
- * @return true by default */
- bool IsDefaultIOHandler() const;
-
- // -------------------------------------------------------------------
- /** Exports the given scene to a chosen file format. Returns the exported
- * data as a binary blob which you can write into a file or something.
- * When you're done with the data, simply let the #Exporter instance go
- * out of scope to have it released automatically.
- * @param pScene The scene to export. Stays in possession of the caller,
- * is not changed by the function.
- * @param pFormatId ID string to specify to which format you want to
- * export to. Use
- * #GetExportFormatCount / #GetExportFormatDescription to learn which
- * export formats are available.
- * @param pPreprocessing See the documentation for #Export
- * @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.
- * @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, const ExportProperties* = NULL);
- const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
-
- // -------------------------------------------------------------------
- /** Convenience function to export directly to a file. Use
- * #SetIOSystem to supply a custom IOSystem to gain fine-grained control
- * about the output data flow of the export process.
- * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
- * @param pPath Full target file name. Target must be accessible.
- * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
- * flags, but in reality only a subset of them makes sense here. Specifying
- * 'preprocessing' flags is useful if the input scene does not conform to
- * Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
- * In short, this means the geometry data should use a right-handed coordinate systems, face
- * winding should be counter-clockwise and the UV coordinate origin is assumed to be in
- * the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
- * #aiProcess_FlipWindingOrder flags are used in the import side to allow users
- * to have those defaults automatically adapted to their conventions. Specifying those flags
- * for exporting has the opposite effect, respectively. Some other of the
- * #aiPostProcessSteps enumerated values may be useful as well, but you'll need
- * to try out what their effect on the exported file is. Many formats impose
- * their own restrictions on the structure of the geometry stored therein,
- * so some preprocessing may have little or no effect at all, or may be
- * 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.
- *
- * If assimp detects that the input scene was directly taken from the importer side of
- * the library (i.e. not copied using aiCopyScene and potentially modified afterwards),
- * any post-processing steps already applied to the scene will not be applied again, unless
- * they show non-idempotent behavior (#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, const ExportProperties* pProperties = NULL);
- aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
-
- // -------------------------------------------------------------------
- /** Returns an error description of an error that occurred in #Export
- * or #ExportToBlob
- *
- * Returns an empty string if no error occurred.
- * @return A description of the last error, an empty string if no
- * error occurred. The string is never NULL.
- *
- * @note The returned function remains valid until one of the
- * following methods is called: #Export, #ExportToBlob, #FreeBlob */
- const char* GetErrorString() const;
-
- // -------------------------------------------------------------------
- /** Return the blob obtained from the last call to #ExportToBlob */
- const aiExportDataBlob* GetBlob() const;
-
- // -------------------------------------------------------------------
- /** Orphan the blob from the last call to #ExportToBlob. This means
- * the caller takes ownership and is thus responsible for calling
- * the C API function #aiReleaseExportBlob to release it. */
- const aiExportDataBlob* GetOrphanedBlob() const;
-
- // -------------------------------------------------------------------
- /** Frees the current blob.
- *
- * The function does nothing if no blob has previously been
- * previously produced via #ExportToBlob. #FreeBlob is called
- * automatically by the destructor. The only reason to call
- * it manually would be to reclaim as much storage as possible
- * without giving up the #Exporter instance yet. */
- void FreeBlob( );
-
- // -------------------------------------------------------------------
- /** Returns the number of export file formats available in the current
- * Assimp build. Use #Exporter::GetExportFormatDescription to
- * retrieve infos of a specific export format.
- *
- * This includes built-in exporters as well as exporters registered
- * using #RegisterExporter.
- **/
- size_t GetExportFormatCount() const;
-
- // -------------------------------------------------------------------
- /** Returns a description of the nth export file format. Use #
- * #Exporter::GetExportFormatCount to learn how many export
- * formats are supported.
- *
- * The returned pointer is of static storage duration if the
- * pIndex pertains to a built-in exporter (i.e. one not registered
- * via #RegistrerExporter). It is restricted to the life-time of the
- * #Exporter instance otherwise.
- *
- * @param pIndex Index of the export format to retrieve information
- * for. Valid range is 0 to #Exporter::GetExportFormatCount
- * @return A description of that specific export format.
- * NULL if pIndex is out of range. */
- const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const;
-
- // -------------------------------------------------------------------
- /** Register a custom exporter. Custom export formats are limited to
- * to the current #Exporter instance and do not affect the
- * library globally. The indexes under which the format's
- * export format description can be queried are assigned
- * monotonously.
- * @param desc Exporter description.
- * @return aiReturn_SUCCESS if the export format was successfully
- * registered. A common cause that would prevent an exporter
- * from being registered is that its format id is already
- * occupied by another format. */
- aiReturn RegisterExporter(const ExportFormatEntry& desc);
-
- // -------------------------------------------------------------------
- /** Remove an export format previously registered with #RegisterExporter
- * from the #Exporter instance (this can also be used to drop
- * built-in exporters because those are implicitly registered
- * using #RegisterExporter).
- * @param id Format id to be unregistered, this refers to the
- * 'id' field of #aiExportFormatDesc.
- * @note Calling this method on a format description not yet registered
- * has no effect.*/
- void UnregisterExporter(const char* id);
-
-protected:
- // Just because we don't want you to know how we're hacking around.
- ExporterPimpl* pimpl;
-};
-
-class ASSIMP_API ExportProperties {
-public:
- // Data type to store the key hash
- typedef unsigned int KeyType;
-
- // 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, ai_real> FloatPropertyMap;
- typedef std::map<KeyType, std::string> StringPropertyMap;
- typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
-
-public:
- /** Standard constructor
- * @see ExportProperties()
- */
- ExportProperties();
-
- // -------------------------------------------------------------------
- /** Copy constructor.
- *
- * This copies the configuration properties of another ExportProperties.
- * @see ExportProperties(const ExportProperties& other)
- */
- ExportProperties(const ExportProperties& other);
-
- // -------------------------------------------------------------------
- /** Set an integer configuration property.
- * @param szName Name of the property. All supported properties
- * are defined in the aiConfig.g header (all constants share the
- * prefix AI_CONFIG_XXX and are simple strings).
- * @param iValue New value of the property
- * @return true if the property was set before. The new value replaces
- * the previous value in this case.
- * @note Property of different types (float, int, string ..) are kept
- * on different stacks, so calling SetPropertyInteger() for a
- * floating-point property has no effect - the loader will call
- * GetPropertyFloat() to read the property, but it won't be there.
- */
- bool SetPropertyInteger(const char* szName, int iValue);
-
- // -------------------------------------------------------------------
- /** Set a boolean configuration property. Boolean properties
- * are stored on the integer stack internally so it's possible
- * to set them via #SetPropertyBool and query them with
- * #GetPropertyBool and vice versa.
- * @see SetPropertyInteger()
- */
- bool SetPropertyBool(const char* szName, bool value) {
- return SetPropertyInteger(szName,value);
- }
-
- // -------------------------------------------------------------------
- /** Set a floating-point configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyFloat(const char* szName, ai_real fValue);
-
- // -------------------------------------------------------------------
- /** Set a string configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyString(const char* szName, const std::string& sValue);
-
- // -------------------------------------------------------------------
- /** Set a matrix configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
-
- // -------------------------------------------------------------------
- /** Get a configuration property.
- * @param szName Name of the property. All supported properties
- * are defined in the aiConfig.g header (all constants share the
- * prefix AI_CONFIG_XXX).
- * @param iErrorReturn Value that is returned if the property
- * is not found.
- * @return Current value of the property
- * @note Property of different types (float, int, string ..) are kept
- * on different lists, so calling SetPropertyInteger() for a
- * floating-point property has no effect - the loader will call
- * GetPropertyFloat() to read the property, but it won't be there.
- */
- int GetPropertyInteger(const char* szName,
- int iErrorReturn = 0xffffffff) const;
-
- // -------------------------------------------------------------------
- /** Get a boolean configuration property. Boolean properties
- * are stored on the integer stack internally so it's possible
- * to set them via #SetPropertyBool and query them with
- * #GetPropertyBool and vice versa.
- * @see GetPropertyInteger()
- */
- bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
- return GetPropertyInteger(szName,bErrorReturn)!=0;
- }
-
- // -------------------------------------------------------------------
- /** Get a floating-point configuration property
- * @see GetPropertyInteger()
- */
- ai_real GetPropertyFloat(const char* szName,
- ai_real fErrorReturn = 10e10f) const;
-
- // -------------------------------------------------------------------
- /** Get a string configuration property
- *
- * The return value remains valid until the property is modified.
- * @see GetPropertyInteger()
- */
- 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;
-
- // -------------------------------------------------------------------
- /** Determine a integer configuration property has been set.
- * @see HasPropertyInteger()
- */
- bool HasPropertyInteger(const char* szName) const;
-
- /** Determine a boolean configuration property has been set.
- * @see HasPropertyBool()
- */
- bool HasPropertyBool(const char* szName) const;
-
- /** Determine a boolean configuration property has been set.
- * @see HasPropertyFloat()
- */
- bool HasPropertyFloat(const char* szName) const;
-
- /** Determine a String configuration property has been set.
- * @see HasPropertyString()
- */
- bool HasPropertyString(const char* szName) const;
-
- /** Determine a Matrix configuration property has been set.
- * @see HasPropertyMatrix()
- */
- bool HasPropertyMatrix(const char* szName) const;
-
-protected:
-
- /** List of integer properties */
- IntPropertyMap mIntProperties;
-
- /** List of floating-point properties */
- FloatPropertyMap mFloatProperties;
-
- /** List of string properties */
- StringPropertyMap mStringProperties;
-
- /** List of Matrix properties */
- MatrixPropertyMap mMatrixProperties;
-};
-
-// ----------------------------------------------------------------------------------
-inline
-const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
- unsigned int pPreprocessing, const ExportProperties* pProperties)
-{
- return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
-}
-
-// ----------------------------------------------------------------------------------
-inline
-aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId,
- const std::string& pPath, unsigned int pPreprocessing,
- const ExportProperties* pProperties)
-{
- return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
-}
-
-} // namespace Assimp
-
-#endif // ASSIMP_BUILD_NO_EXPORT
-#endif // AI_EXPORT_HPP_INC
diff --git a/src/3rdparty/assimp/include/assimp/IOStream.hpp b/src/3rdparty/assimp/include/assimp/IOStream.hpp
deleted file mode 100644
index ce5907a47..000000000
--- a/src/3rdparty/assimp/include/assimp/IOStream.hpp
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IOStream.hpp
- * @brief File I/O wrappers for C++.
- */
-
-#pragma once
-#ifndef AI_IOSTREAM_H_INC
-#define AI_IOSTREAM_H_INC
-
-#include "types.h"
-
-#ifndef __cplusplus
-# error This header requires C++ to be used. aiFileIO.h is the \
- corresponding C interface.
-#endif
-
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** @brief CPP-API: Class to handle file I/O for C++
- *
- * Derive an own implementation from this interface to provide custom IO handling
- * 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
-#ifndef SWIG
- : public Intern::AllocateFromAssimpHeap
-#endif
-{
-protected:
- /** Constructor protected, use IOSystem::Open() to create an instance. */
- IOStream(void);
-
-public:
- // -------------------------------------------------------------------
- /** @brief Destructor. Deleting the object closes the underlying file,
- * alternatively you may use IOSystem::Close() to release the file.
- */
- virtual ~IOStream();
-
- // -------------------------------------------------------------------
- /** @brief Read from the file
- *
- * See fread() for more details
- * This fails for write-only files */
- virtual size_t Read(void* pvBuffer,
- size_t pSize,
- size_t pCount) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Write to the file
- *
- * See fwrite() for more details
- * This fails for read-only files */
- virtual size_t Write(const void* pvBuffer,
- size_t pSize,
- size_t pCount) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Set the read/write cursor of the file
- *
- * Note that the offset is _negative_ for aiOrigin_END.
- * See fseek() for more details */
- virtual aiReturn Seek(size_t pOffset,
- aiOrigin pOrigin) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Get the current position of the read/write cursor
- *
- * See ftell() for more details */
- virtual size_t Tell() const = 0;
-
- // -------------------------------------------------------------------
- /** @brief Returns filesize
- * Returns the filesize. */
- virtual size_t FileSize() const = 0;
-
- // -------------------------------------------------------------------
- /** @brief Flush the contents of the file buffer (for writers)
- * See fflush() for more details.
- */
- virtual void Flush() = 0;
-}; //! class IOStream
-
-// ----------------------------------------------------------------------------------
-inline IOStream::IOStream()
-{
- // empty
-}
-
-// ----------------------------------------------------------------------------------
-inline IOStream::~IOStream()
-{
- // empty
-}
-// ----------------------------------------------------------------------------------
-} //!namespace Assimp
-
-#endif //!!AI_IOSTREAM_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/IOSystem.hpp b/src/3rdparty/assimp/include/assimp/IOSystem.hpp
deleted file mode 100644
index f4fbb6023..000000000
--- a/src/3rdparty/assimp/include/assimp/IOSystem.hpp
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 IOSystem.hpp
- * @brief File system wrapper for C++. Inherit this class to supply
- * custom file handling logic to the Import library.
-*/
-
-#pragma once
-#ifndef AI_IOSYSTEM_H_INC
-#define AI_IOSYSTEM_H_INC
-
-#ifndef __cplusplus
-# error This header requires C++ to be used. aiFileIO.h is the \
- corresponding C interface.
-#endif
-
-#include "types.h"
-
-#ifdef _WIN32
-# include <direct.h>
-# include <stdlib.h>
-# include <stdio.h>
-#else
-# include <sys/stat.h>
-# include <sys/types.h>
-# include <unistd.h>
-#endif // _WIN32
-
-#include <vector>
-
-namespace Assimp {
-
- class IOStream;
-
-// ---------------------------------------------------------------------------
-/** @brief CPP-API: Interface to the file system.
- *
- * Derive an own implementation from this interface to supply custom file handling
- * to the importer library. If you implement this interface, you also want to
- * supply a custom implementation for IOStream.
- *
- * @see Importer::SetIOHandler()
- */
-class ASSIMP_API IOSystem
-#ifndef SWIG
- : public Intern::AllocateFromAssimpHeap
-#endif
-{
-public:
-
- // -------------------------------------------------------------------
- /** @brief Default constructor.
- *
- * Create an instance of your derived class and assign it to an
- * #Assimp::Importer instance by calling Importer::SetIOHandler().
- */
- IOSystem();
-
- // -------------------------------------------------------------------
- /** @brief Virtual destructor.
- *
- * It is safe to be called from within DLL Assimp, we're constructed
- * on Assimp's heap.
- */
- virtual ~IOSystem();
-
-
-public:
-
- // -------------------------------------------------------------------
- /** @brief For backward compatibility
- * @see Exists(const char*)
- */
- AI_FORCE_INLINE bool Exists( const std::string& pFile) const;
-
- // -------------------------------------------------------------------
- /** @brief Tests for the existence of a file at the given path.
- *
- * @param pFile Path to the file
- * @return true if there is a file with this path, else false.
- */
- virtual bool Exists( const char* pFile) const = 0;
-
- // -------------------------------------------------------------------
- /** @brief Returns the system specific directory separator
- * @return System specific directory separator
- */
- virtual char getOsSeparator() const = 0;
-
- // -------------------------------------------------------------------
- /** @brief Open a new file with a given path.
- *
- * When the access to the file is finished, call Close() to release
- * all associated resources (or the virtual dtor of the IOStream).
- *
- * @param pFile Path to the file
- * @param pMode Desired file I/O mode. Required are: "wb", "w", "wt",
- * "rb", "r", "rt".
- *
- * @return New IOStream interface allowing the lib to access
- * the underlying file.
- * @note When implementing this class to provide custom IO handling,
- * you probably have to supply an own implementation of IOStream as well.
- */
- virtual IOStream* Open(const char* pFile,
- const char* pMode = "rb") = 0;
-
- // -------------------------------------------------------------------
- /** @brief For backward compatibility
- * @see Open(const char*, const char*)
- */
- inline IOStream* Open(const std::string& pFile,
- const std::string& pMode = std::string("rb"));
-
- // -------------------------------------------------------------------
- /** @brief Closes the given file and releases all resources
- * associated with it.
- * @param pFile The file instance previously created by Open().
- */
- virtual void Close( IOStream* pFile) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Compares two paths and check whether the point to
- * identical files.
- *
- * The dummy implementation of this virtual member performs a
- * case-insensitive comparison of the given strings. The default IO
- * system implementation uses OS mechanisms to convert relative into
- * absolute paths, so the result can be trusted.
- * @param one First file
- * @param second Second file
- * @return true if the paths point to the same file. The file needn't
- * be existing, however.
- */
- virtual bool ComparePaths (const char* one,
- const char* second) const;
-
- // -------------------------------------------------------------------
- /** @brief For backward compatibility
- * @see ComparePaths(const char*, const char*)
- */
- inline bool ComparePaths (const std::string& one,
- const std::string& second) const;
-
- // -------------------------------------------------------------------
- /** @brief Pushes a new directory onto the directory stack.
- * @param path Path to push onto the stack.
- * @return True, when push was successful, false if path is empty.
- */
- virtual bool PushDirectory( const std::string &path );
-
- // -------------------------------------------------------------------
- /** @brief Returns the top directory from the stack.
- * @return The directory on the top of the stack.
- * Returns empty when no directory was pushed to the stack.
- */
- virtual const std::string &CurrentDirectory() const;
-
- // -------------------------------------------------------------------
- /** @brief Returns the number of directories stored on the stack.
- * @return The number of directories of the stack.
- */
- virtual size_t StackSize() const;
-
- // -------------------------------------------------------------------
- /** @brief Pops the top directory from the stack.
- * @return True, when a directory was on the stack. False if no
- * directory was on the stack.
- */
- virtual bool PopDirectory();
-
- // -------------------------------------------------------------------
- /** @brief CReates an new directory at the given path.
- * @param path [in] The path to create.
- * @return True, when a directory was created. False if the directory
- * cannot be created.
- */
- virtual bool CreateDirectory( const std::string &path );
-
- // -------------------------------------------------------------------
- /** @brief Will change the current directory to the given path.
- * @param path [in] The path to change to.
- * @return True, when the directory has changed successfully.
- */
- virtual bool ChangeDirectory( const std::string &path );
-
- virtual bool DeleteFile( const std::string &file );
-
-private:
- std::vector<std::string> m_pathStack;
-};
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-IOSystem::IOSystem()
-: m_pathStack() {
- // empty
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-IOSystem::~IOSystem() {
- // empty
-}
-
-// ----------------------------------------------------------------------------
-// For compatibility, the interface of some functions taking a std::string was
-// changed to const char* to avoid crashes between binary incompatible STL
-// versions. This code her is inlined, so it shouldn't cause any problems.
-// ----------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-IOStream* IOSystem::Open(const std::string& pFile, const std::string& pMode) {
- // NOTE:
- // For compatibility, interface was changed to const char* to
- // avoid crashes between binary incompatible STL versions
- return Open(pFile.c_str(),pMode.c_str());
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::Exists( const std::string& pFile) const {
- // NOTE:
- // For compatibility, interface was changed to const char* to
- // avoid crashes between binary incompatible STL versions
- return Exists(pFile.c_str());
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::ComparePaths (const std::string& one, const std::string& second) const {
- // NOTE:
- // For compatibility, interface was changed to const char* to
- // avoid crashes between binary incompatible STL versions
- return ComparePaths(one.c_str(),second.c_str());
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::PushDirectory( const std::string &path ) {
- if ( path.empty() ) {
- return false;
- }
-
- m_pathStack.push_back( path );
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-const std::string &IOSystem::CurrentDirectory() const {
- if ( m_pathStack.empty() ) {
- static const std::string Dummy("");
- return Dummy;
- }
- return m_pathStack[ m_pathStack.size()-1 ];
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-size_t IOSystem::StackSize() const {
- return m_pathStack.size();
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::PopDirectory() {
- if ( m_pathStack.empty() ) {
- return false;
- }
-
- m_pathStack.pop_back();
-
- return true;
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::CreateDirectory( const std::string &path ) {
- if ( path.empty() ) {
- return false;
- }
-
-#ifdef _WIN32
- return 0 != ::_mkdir( path.c_str() );
-#else
- return 0 != ::mkdir( path.c_str(), 0777 );
-#endif // _WIN32
-}
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::ChangeDirectory( const std::string &path ) {
- if ( path.empty() ) {
- return false;
- }
-
-#ifdef _WIN32
- return 0 != ::_chdir( path.c_str() );
-#else
- return 0 != ::chdir( path.c_str() );
-#endif // _WIN32
-}
-
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE
-bool IOSystem::DeleteFile( const std::string &file ) {
- if ( file.empty() ) {
- return false;
- }
- const int retCode( ::remove( file.c_str() ) );
- return ( 0 == retCode );
-}
-} //!ns Assimp
-
-#endif //AI_IOSYSTEM_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/Importer.hpp b/src/3rdparty/assimp/include/assimp/Importer.hpp
deleted file mode 100644
index f42a2deaf..000000000
--- a/src/3rdparty/assimp/include/assimp/Importer.hpp
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Importer.hpp
- * @brief Defines the C++-API to the Open Asset Import Library.
- */
-#pragma once
-#ifndef AI_ASSIMP_HPP_INC
-#define AI_ASSIMP_HPP_INC
-
-#ifndef __cplusplus
-# error This header requires C++ to be used. Use assimp.h for plain C.
-#endif // __cplusplus
-
-// Public ASSIMP data structures
-#include <assimp/types.h>
-
-namespace Assimp {
- // =======================================================================
- // Public interface to Assimp
- class Importer;
- class IOStream;
- class IOSystem;
- class ProgressHandler;
-
- // =======================================================================
- // Plugin development
- //
- // Include the following headers for the declarations:
- // BaseImporter.h
- // BaseProcess.h
- class BaseImporter;
- class BaseProcess;
- class SharedPostProcessInfo;
- class BatchLoader;
-
- // =======================================================================
- // Holy stuff, only for members of the high council of the Jedi.
- class ImporterPimpl;
-} //! namespace Assimp
-
-#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff
-
-struct aiScene;
-
-// importerdesc.h
-struct aiImporterDesc;
-
-/** @namespace Assimp Assimp's CPP-API and all internal APIs */
-namespace Assimp {
-
-// ----------------------------------------------------------------------------------
-/** CPP-API: The Importer class forms an C++ interface to the functionality of the
-* Open Asset Import Library.
-*
-* Create an object of this class and call ReadFile() to import a file.
-* If the import succeeds, the function returns a pointer to the imported data.
-* The data remains property of the object, it is intended to be accessed
-* read-only. The imported data will be destroyed along with the Importer
-* object. If the import fails, ReadFile() returns a NULL pointer. In this
-* case you can retrieve a human-readable error description be calling
-* GetErrorString(). You can call ReadFile() multiple times with a single Importer
-* instance. Actually, constructing Importer objects involves quite many
-* allocations and may take some time, so it's better to reuse them as often as
-* possible.
-*
-* If you need the Importer to do custom file handling to access the files,
-* implement IOSystem and IOStream and supply an instance of your custom
-* IOSystem implementation by calling SetIOHandler() before calling ReadFile().
-* If you do not assign a custion IO handler, a default handler using the
-* standard C++ IO logic will be used.
-*
-* @note One Importer instance is not thread-safe. If you use multiple
-* threads for loading, each thread should maintain its own Importer instance.
-*/
-class ASSIMP_API Importer {
-public:
- /**
- * @brief The upper limit for hints.
- */
- static const unsigned int MaxLenHint = 200;
-
-public:
-
- // -------------------------------------------------------------------
- /** Constructor. Creates an empty importer object.
- *
- * Call ReadFile() to start the import process. The configuration
- * property table is initially empty.
- */
- Importer();
-
- // -------------------------------------------------------------------
- /** Copy constructor.
- *
- * This copies the configuration properties of another Importer.
- * If this Importer owns a scene it won't be copied.
- * Call ReadFile() to start the import process.
- */
- Importer(const Importer& other);
-
- // -------------------------------------------------------------------
- /** Destructor. The object kept ownership of the imported data,
- * which now will be destroyed along with the object.
- */
- ~Importer();
-
-
- // -------------------------------------------------------------------
- /** Registers a new loader.
- *
- * @param pImp Importer to be added. The Importer instance takes
- * ownership of the pointer, so it will be automatically deleted
- * with the Importer instance.
- * @return AI_SUCCESS if the loader has been added. The registration
- * fails if there is already a loader for a specific file extension.
- */
- aiReturn RegisterLoader(BaseImporter* pImp);
-
- // -------------------------------------------------------------------
- /** Unregisters a loader.
- *
- * @param pImp Importer to be unregistered.
- * @return AI_SUCCESS if the loader has been removed. The function
- * fails if the loader is currently in use (this could happen
- * if the #Importer instance is used by more than one thread) or
- * if it has not yet been registered.
- */
- aiReturn UnregisterLoader(BaseImporter* pImp);
-
- // -------------------------------------------------------------------
- /** Registers a new post-process step.
- *
- * At the moment, there's a small limitation: new post processing
- * steps are added to end of the list, or in other words, executed
- * last, after all built-in steps.
- * @param pImp Post-process step to be added. The Importer instance
- * takes ownership of the pointer, so it will be automatically
- * deleted with the Importer instance.
- * @return AI_SUCCESS if the step has been added correctly.
- */
- aiReturn RegisterPPStep(BaseProcess* pImp);
-
- // -------------------------------------------------------------------
- /** Unregisters a post-process step.
- *
- * @param pImp Step to be unregistered.
- * @return AI_SUCCESS if the step has been removed. The function
- * fails if the step is currently in use (this could happen
- * if the #Importer instance is used by more than one thread) or
- * if it has not yet been registered.
- */
- aiReturn UnregisterPPStep(BaseProcess* pImp);
-
- // -------------------------------------------------------------------
- /** Set an integer configuration property.
- * @param szName Name of the property. All supported properties
- * are defined in the aiConfig.g header (all constants share the
- * prefix AI_CONFIG_XXX and are simple strings).
- * @param iValue New value of the property
- * @return true if the property was set before. The new value replaces
- * the previous value in this case.
- * @note Property of different types (float, int, string ..) are kept
- * on different stacks, so calling SetPropertyInteger() for a
- * floating-point property has no effect - the loader will call
- * GetPropertyFloat() to read the property, but it won't be there.
- */
- bool SetPropertyInteger(const char* szName, int iValue);
-
- // -------------------------------------------------------------------
- /** Set a boolean configuration property. Boolean properties
- * are stored on the integer stack internally so it's possible
- * to set them via #SetPropertyBool and query them with
- * #GetPropertyBool and vice versa.
- * @see SetPropertyInteger()
- */
- bool SetPropertyBool(const char* szName, bool value) {
- return SetPropertyInteger(szName,value);
- }
-
- // -------------------------------------------------------------------
- /** Set a floating-point configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyFloat(const char* szName, ai_real fValue);
-
- // -------------------------------------------------------------------
- /** Set a string configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyString(const char* szName, const std::string& sValue);
-
- // -------------------------------------------------------------------
- /** Set a matrix configuration property.
- * @see SetPropertyInteger()
- */
- bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
-
- // -------------------------------------------------------------------
- /** Get a configuration property.
- * @param szName Name of the property. All supported properties
- * are defined in the aiConfig.g header (all constants share the
- * prefix AI_CONFIG_XXX).
- * @param iErrorReturn Value that is returned if the property
- * is not found.
- * @return Current value of the property
- * @note Property of different types (float, int, string ..) are kept
- * on different lists, so calling SetPropertyInteger() for a
- * floating-point property has no effect - the loader will call
- * GetPropertyFloat() to read the property, but it won't be there.
- */
- int GetPropertyInteger(const char* szName,
- int iErrorReturn = 0xffffffff) const;
-
- // -------------------------------------------------------------------
- /** Get a boolean configuration property. Boolean properties
- * are stored on the integer stack internally so it's possible
- * to set them via #SetPropertyBool and query them with
- * #GetPropertyBool and vice versa.
- * @see GetPropertyInteger()
- */
- bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
- return GetPropertyInteger(szName,bErrorReturn)!=0;
- }
-
- // -------------------------------------------------------------------
- /** Get a floating-point configuration property
- * @see GetPropertyInteger()
- */
- ai_real GetPropertyFloat(const char* szName,
- ai_real fErrorReturn = 10e10) const;
-
- // -------------------------------------------------------------------
- /** Get a string configuration property
- *
- * The return value remains valid until the property is modified.
- * @see GetPropertyInteger()
- */
- 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 custom IO logic to
- * access the files, you need to provide a custom implementation of
- * IOSystem and IOFile to the importer. Then create an instance of
- * your custom IOSystem implementation and supply it by this function.
- *
- * The Importer takes ownership of the object and will destroy it
- * afterwards. The previously assigned handler will be deleted.
- * Pass NULL to take again ownership of your IOSystem and reset Assimp
- * to use its default implementation.
- *
- * @param pIOHandler The IO handler to be used in all file accesses
- * of the Importer.
- */
- void SetIOHandler( IOSystem* pIOHandler);
-
- // -------------------------------------------------------------------
- /** Retrieves the IO handler that is currently set.
- * You can use #IsDefaultIOHandler() to check whether the returned
- * interface is the default IO handler provided by ASSIMP. The default
- * handler is active as long the application doesn't supply its own
- * custom IO handler via #SetIOHandler().
- * @return A valid IOSystem interface, never NULL.
- */
- IOSystem* GetIOHandler() const;
-
- // -------------------------------------------------------------------
- /** Checks whether a default IO handler is active
- * A default handler is active as long the application doesn't
- * supply its own custom IO handler via #SetIOHandler().
- * @return true by default
- */
- bool IsDefaultIOHandler() const;
-
- // -------------------------------------------------------------------
- /** Supplies a custom progress handler to the importer. This
- * interface exposes a #Update() callback, which is called
- * more or less periodically (please don't sue us if it
- * isn't as periodically as you'd like it to have ...).
- * This can be used to implement progress bars and loading
- * timeouts.
- * @param pHandler Progress callback interface. Pass NULL to
- * disable progress reporting.
- * @note Progress handlers can be used to abort the loading
- * at almost any time.*/
- void SetProgressHandler ( ProgressHandler* pHandler );
-
- // -------------------------------------------------------------------
- /** Retrieves the progress handler that is currently set.
- * You can use #IsDefaultProgressHandler() to check whether the returned
- * interface is the default handler provided by ASSIMP. The default
- * handler is active as long the application doesn't supply its own
- * custom handler via #SetProgressHandler().
- * @return A valid ProgressHandler interface, never NULL.
- */
- ProgressHandler* GetProgressHandler() const;
-
- // -------------------------------------------------------------------
- /** Checks whether a default progress handler is active
- * A default handler is active as long the application doesn't
- * supply its own custom progress handler via #SetProgressHandler().
- * @return true by default
- */
- bool IsDefaultProgressHandler() const;
-
- // -------------------------------------------------------------------
- /** @brief Check whether a given set of post-processing flags
- * is supported.
- *
- * Some flags are mutually exclusive, others are probably
- * not available because your excluded them from your
- * Assimp builds. Calling this function is recommended if
- * you're unsure.
- *
- * @param pFlags Bitwise combination of the aiPostProcess flags.
- * @return true if this flag combination is fine.
- */
- bool ValidateFlags(unsigned int pFlags) const;
-
- // -------------------------------------------------------------------
- /** Reads the given file and returns its contents if successful.
- *
- * If the call succeeds, the contents of the file are returned as a
- * pointer to an aiScene object. The returned data is intended to be
- * read-only, the importer object keeps ownership of the data and will
- * destroy it upon destruction. If the import fails, NULL is returned.
- * A human-readable error description can be retrieved by calling
- * GetErrorString(). The previous scene will be deleted during this call.
- * @param pFile Path and filename to the file to be imported.
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags. If you wish to inspect the imported
- * scene first in order to fine-tune your post-processing setup,
- * consider to use #ApplyPostProcessing().
- * @return A pointer to the imported data, NULL if the import failed.
- * The pointer to the scene remains in possession of the Importer
- * instance. Use GetOrphanedScene() to take ownership of it.
- *
- * @note Assimp is able to determine the file format of a file
- * automatically.
- */
- const aiScene* ReadFile(
- const char* pFile,
- unsigned int pFlags);
-
- // -------------------------------------------------------------------
- /** Reads the given file from a memory buffer and returns its
- * contents if successful.
- *
- * If the call succeeds, the contents of the file are returned as a
- * pointer to an aiScene object. The returned data is intended to be
- * read-only, the importer object keeps ownership of the data and will
- * destroy it upon destruction. If the import fails, NULL is returned.
- * A human-readable error description can be retrieved by calling
- * GetErrorString(). The previous scene will be deleted during this call.
- * Calling this method doesn't affect the active IOSystem.
- * @param pBuffer Pointer to the file data
- * @param pLength Length of pBuffer, in bytes
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags. If you wish to inspect the imported
- * scene first in order to fine-tune your post-processing setup,
- * consider to use #ApplyPostProcessing().
- * @param pHint An additional hint to the library. If this is a non
- * empty string, the library looks for a loader to support
- * the file extension specified by pHint and passes the file to
- * the first matching loader. If this loader is unable to completely
- * the request, the library continues and tries to determine the
- * file format on its own, a task that may or may not be successful.
- * Check the return value, and you'll know ...
- * @return A pointer to the imported data, NULL if the import failed.
- * The pointer to the scene remains in possession of the Importer
- * 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 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 ReadFile() API.
- */
- const aiScene* ReadFileFromMemory(
- const void* pBuffer,
- size_t pLength,
- unsigned int pFlags,
- const char* pHint = "");
-
- // -------------------------------------------------------------------
- /** Apply post-processing to an already-imported scene.
- *
- * This is strictly equivalent to calling #ReadFile() with the same
- * flags. However, you can use this separate function to inspect
- * the imported scene first to fine-tune your post-processing setup.
- * @param pFlags Provide a bitwise combination of the
- * #aiPostProcessSteps flags.
- * @return A pointer to the post-processed data. This is still the
- * same as the pointer returned by #ReadFile(). However, if
- * post-processing fails, the scene could now be NULL.
- * That's quite a rare case, post processing steps are not really
- * designed to 'fail'. To be exact, the #aiProcess_ValidateDS
- * flag is currently the only post processing step which can actually
- * cause the scene to be reset to NULL.
- *
- * @note The method does nothing if no scene is currently bound
- * to the #Importer instance. */
- const aiScene* ApplyPostProcessing(unsigned int pFlags);
-
- const aiScene* ApplyCustomizedPostProcessing( BaseProcess *rootProcess, bool requestValidation );
-
- // -------------------------------------------------------------------
- /** @brief Reads the given file and returns its contents if successful.
- *
- * This function is provided for backward compatibility.
- * See the const char* version for detailed docs.
- * @see ReadFile(const char*, pFlags) */
- const aiScene* ReadFile(
- const std::string& pFile,
- unsigned int pFlags);
-
- // -------------------------------------------------------------------
- /** Frees the current scene.
- *
- * The function does nothing if no scene has previously been
- * read via ReadFile(). FreeScene() is called automatically by the
- * destructor and ReadFile() itself. */
- void FreeScene( );
-
- // -------------------------------------------------------------------
- /** Returns an error description of an error that occurred in ReadFile().
- *
- * Returns an empty string if no error occurred.
- * @return A description of the last error, an empty string if no
- * error occurred. The string is never NULL.
- *
- * @note The returned function remains valid until one of the
- * following methods is called: #ReadFile(), #FreeScene(). */
- const char* GetErrorString() const;
-
- // -------------------------------------------------------------------
- /** Returns the scene loaded by the last successful call to ReadFile()
- *
- * @return Current scene or NULL if there is currently no scene loaded */
- const aiScene* GetScene() const;
-
- // -------------------------------------------------------------------
- /** Returns the scene loaded by the last successful call to ReadFile()
- * and releases the scene from the ownership of the Importer
- * instance. The application is now responsible for deleting the
- * scene. Any further calls to GetScene() or GetOrphanedScene()
- * will return NULL - until a new scene has been loaded via ReadFile().
- *
- * @return Current scene or NULL if there is currently no scene loaded
- * @note Use this method with maximal caution, and only if you have to.
- * By design, aiScene's are exclusively maintained, allocated and
- * deallocated by Assimp and no one else. The reasoning behind this
- * is the golden rule that deallocations should always be done
- * by the module that did the original allocation because heaps
- * are not necessarily shared. GetOrphanedScene() enforces you
- * to delete the returned scene by yourself, but this will only
- * be fine if and only if you're using the same heap as assimp.
- * On Windows, it's typically fine provided everything is linked
- * against the multithreaded-dll version of the runtime library.
- * It will work as well for static linkage with Assimp.*/
- aiScene* GetOrphanedScene();
-
- // -------------------------------------------------------------------
- /** Returns whether a given file extension is supported by ASSIMP.
- *
- * @param szExtension Extension to be checked.
- * Must include a trailing dot '.'. Example: ".3ds", ".md3".
- * Cases-insensitive.
- * @return true if the extension is supported, false otherwise */
- bool IsExtensionSupported(const char* szExtension) const;
-
- // -------------------------------------------------------------------
- /** @brief Returns whether a given file extension is supported by ASSIMP.
- *
- * This function is provided for backward compatibility.
- * See the const char* version for detailed and up-to-date docs.
- * @see IsExtensionSupported(const char*) */
- inline bool IsExtensionSupported(const std::string& szExtension) const;
-
- // -------------------------------------------------------------------
- /** Get a full list of all file extensions supported by ASSIMP.
- *
- * If a file extension is contained in the list this does of course not
- * mean that ASSIMP is able to load all files with this extension ---
- * it simply means there is an importer loaded which claims to handle
- * files with this file extension.
- * @param szOut String to receive the extension list.
- * Format of the list: "*.3ds;*.obj;*.dae". This is useful for
- * use with the WinAPI call GetOpenFileName(Ex). */
- void GetExtensionList(aiString& szOut) const;
-
- // -------------------------------------------------------------------
- /** @brief Get a full list of all file extensions supported by ASSIMP.
- *
- * This function is provided for backward compatibility.
- * See the aiString version for detailed and up-to-date docs.
- * @see GetExtensionList(aiString&)*/
- inline void GetExtensionList(std::string& szOut) const;
-
- // -------------------------------------------------------------------
- /** Get the number of importers currently registered with Assimp. */
- size_t GetImporterCount() const;
-
- // -------------------------------------------------------------------
- /** Get meta data for the importer corresponding to a specific index..
- *
- * For the declaration of #aiImporterDesc, include <assimp/importerdesc.h>.
- * @param index Index to query, must be within [0,GetImporterCount())
- * @return Importer meta data structure, NULL if the index does not
- * exist or if the importer doesn't offer meta information (
- * importers may do this at the cost of being hated by their peers).*/
- const aiImporterDesc* GetImporterInfo(size_t index) const;
-
- // -------------------------------------------------------------------
- /** Find the importer corresponding to a specific index.
- *
- * @param index Index to query, must be within [0,GetImporterCount())
- * @return Importer instance. NULL if the index does not
- * exist. */
- BaseImporter* GetImporter(size_t index) const;
-
- // -------------------------------------------------------------------
- /** Find the importer corresponding to a specific file extension.
- *
- * This is quite similar to #IsExtensionSupported except a
- * BaseImporter instance is returned.
- * @param szExtension Extension to check for. The following formats
- * are recognized (BAH being the file extension): "BAH" (comparison
- * is case-insensitive), ".bah", "*.bah" (wild card and dot
- * characters at the beginning of the extension are skipped).
- * @return NULL if no importer is found*/
- BaseImporter* GetImporter (const char* szExtension) const;
-
- // -------------------------------------------------------------------
- /** Find the importer index corresponding to a specific file extension.
- *
- * @param szExtension Extension to check for. The following formats
- * are recognized (BAH being the file extension): "BAH" (comparison
- * is case-insensitive), ".bah", "*.bah" (wild card and dot
- * characters at the beginning of the extension are skipped).
- * @return (size_t)-1 if no importer is found */
- size_t GetImporterIndex (const char* szExtension) const;
-
- // -------------------------------------------------------------------
- /** Returns the storage allocated by ASSIMP to hold the scene data
- * in memory.
- *
- * This refers to the currently loaded file, see #ReadFile().
- * @param in Data structure to be filled.
- * @note The returned memory statistics refer to the actual
- * size of the use data of the aiScene. Heap-related overhead
- * is (naturally) not included.*/
- void GetMemoryRequirements(aiMemoryInfo& in) const;
-
- // -------------------------------------------------------------------
- /** Enables "extra verbose" mode.
- *
- * 'Extra verbose' means the data structure is validated after *every*
- * single post processing step to make sure everyone modifies the data
- * structure in a well-defined manner. This is a debug feature and not
- * intended for use in production environments. */
- void SetExtraVerbose(bool bDo);
-
- // -------------------------------------------------------------------
- /** Private, do not use. */
- ImporterPimpl* Pimpl() { return pimpl; }
- const ImporterPimpl* Pimpl() const { return pimpl; }
-
-protected:
-
- // Just because we don't want you to know how we're hacking around.
- ImporterPimpl* pimpl;
-}; //! class Importer
-
-
-// ----------------------------------------------------------------------------
-// For compatibility, the interface of some functions taking a std::string was
-// changed to const char* to avoid crashes between binary incompatible STL
-// versions. This code her is inlined, so it shouldn't cause any problems.
-// ----------------------------------------------------------------------------
-
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){
- return ReadFile(pFile.c_str(),pFlags);
-}
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const {
- aiString s;
- GetExtensionList(s);
- szOut = s.data;
-}
-// ----------------------------------------------------------------------------
-AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const {
- return IsExtensionSupported(szExtension.c_str());
-}
-
-} // !namespace Assimp
-
-#endif // AI_ASSIMP_HPP_INC
diff --git a/src/3rdparty/assimp/include/assimp/LogStream.hpp b/src/3rdparty/assimp/include/assimp/LogStream.hpp
deleted file mode 100644
index 1052f1fda..000000000
--- a/src/3rdparty/assimp/include/assimp/LogStream.hpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 LogStream.hpp
- * @brief Abstract base class 'LogStream', representing an output log stream.
- */
-#ifndef INCLUDED_AI_LOGSTREAM_H
-#define INCLUDED_AI_LOGSTREAM_H
-
-#include "types.h"
-
-namespace Assimp {
-
-class IOSystem;
-
-// ------------------------------------------------------------------------------------
-/** @brief CPP-API: Abstract interface for log stream implementations.
- *
- * 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
-#ifndef SWIG
- : public Intern::AllocateFromAssimpHeap
-#endif
-{
-protected:
- /** @brief Default constructor */
- LogStream();
-
-public:
- /** @brief Virtual destructor */
- virtual ~LogStream();
-
- // -------------------------------------------------------------------
- /** @brief Overwrite this for your own output methods
- *
- * Log messages *may* consist of multiple lines and you shouldn't
- * expect a consistent formatting. If you want custom formatting
- * (e.g. generate HTML), supply a custom instance of Logger to
- * #DefaultLogger:set(). Usually you can *expect* that a log message
- * is exactly one line and terminated with a single \n character.
- * @param message Message to be written */
- virtual void write(const char* message) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Creates a default log stream
- * @param streams Type of the default stream
- * @param name For aiDefaultLogStream_FILE: name of the output file
- * @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output
- * file. Pass NULL for the default implementation.
- * @return New LogStream instance. */
- static LogStream* createDefaultStream(aiDefaultLogStream stream,
- const char* name = "AssimpLog.txt",
- IOSystem* io = NULL);
-
-}; // !class LogStream
-
-inline
-LogStream::LogStream() {
- // empty
-}
-
-inline
-LogStream::~LogStream() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------
-} // Namespace Assimp
-
-#endif
diff --git a/src/3rdparty/assimp/include/assimp/Logger.hpp b/src/3rdparty/assimp/include/assimp/Logger.hpp
deleted file mode 100644
index 0875b6d7d..000000000
--- a/src/3rdparty/assimp/include/assimp/Logger.hpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Logger.hpp
- * @brief Abstract base class 'Logger', base of the logging system.
- */
-#ifndef INCLUDED_AI_LOGGER_H
-#define INCLUDED_AI_LOGGER_H
-
-#include "types.h"
-
-namespace Assimp {
-
-class LogStream;
-
-// Maximum length of a log message. Longer messages are rejected.
-#define MAX_LOG_MESSAGE_LENGTH 1024u
-
-// ----------------------------------------------------------------------------------
-/** @brief CPP-API: Abstract interface for logger implementations.
- * 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
-#ifndef SWIG
- : public Intern::AllocateFromAssimpHeap
-#endif
-{
-public:
-
- // ----------------------------------------------------------------------
- /** @enum LogSeverity
- * @brief Log severity to describe the granularity of logging.
- */
- enum LogSeverity
- {
- NORMAL, //!< Normal granularity of logging
- VERBOSE //!< Debug infos will be logged, too
- };
-
- // ----------------------------------------------------------------------
- /** @enum ErrorSeverity
- * @brief Description for severity of a log message.
- *
- * Every LogStream has a bitwise combination of these flags.
- * A LogStream doesn't receive any messages of a specific type
- * if it doesn't specify the corresponding ErrorSeverity flag.
- */
- enum ErrorSeverity
- {
- Debugging = 1, //!< Debug log message
- Info = 2, //!< Info log message
- Warn = 4, //!< Warn log message
- Err = 8 //!< Error log message
- };
-
-public:
-
- /** @brief Virtual destructor */
- virtual ~Logger();
-
- // ----------------------------------------------------------------------
- /** @brief Writes a debug message
- * @param message Debug message*/
- void debug(const char* message);
- inline void debug(const std::string &message);
-
- // ----------------------------------------------------------------------
- /** @brief Writes a info message
- * @param message Info message*/
- void info(const char* message);
- inline void info(const std::string &message);
-
- // ----------------------------------------------------------------------
- /** @brief Writes a warning message
- * @param message Warn message*/
- void warn(const char* message);
- inline void warn(const std::string &message);
-
- // ----------------------------------------------------------------------
- /** @brief Writes an error message
- * @param message Error message*/
- void error(const char* message);
- inline void error(const std::string &message);
-
- // ----------------------------------------------------------------------
- /** @brief Set a new log severity.
- * @param log_severity New severity for logging*/
- void setLogSeverity(LogSeverity log_severity);
-
- // ----------------------------------------------------------------------
- /** @brief Get the current log severity*/
- LogSeverity getLogSeverity() const;
-
- // ----------------------------------------------------------------------
- /** @brief Attach a new log-stream
- *
- * The logger takes ownership of the stream and is responsible
- * for its destruction (which is done using ::delete when the logger
- * itself is destroyed). Call detachStream to detach a stream and to
- * gain ownership of it again.
- * @param pStream Log-stream to attach
- * @param severity Message filter, specified which types of log
- * messages are dispatched to the stream. Provide a bitwise
- * combination of the ErrorSeverity flags.
- * @return true if the stream has been attached, false otherwise.*/
- virtual bool attachStream(LogStream *pStream,
- unsigned int severity = Debugging | Err | Warn | Info) = 0;
-
- // ----------------------------------------------------------------------
- /** @brief Detach a still attached stream from the logger (or
- * modify the filter flags bits)
- * @param pStream Log-stream instance for detaching
- * @param severity Provide a bitwise combination of the ErrorSeverity
- * flags. This value is &~ed with the current flags of the stream,
- * if the result is 0 the stream is detached from the Logger and
- * the caller retakes the possession of the stream.
- * @return true if the stream has been detached, false otherwise.*/
- virtual bool detatchStream(LogStream *pStream,
- unsigned int severity = Debugging | Err | Warn | Info) = 0;
-
-protected:
-
- /** Default constructor */
- Logger();
-
- /** Construction with a given log severity */
- explicit Logger(LogSeverity severity);
-
- // ----------------------------------------------------------------------
- /** @brief Called as a request to write a specific debug message
- * @param message Debug message. Never longer than
- * MAX_LOG_MESSAGE_LENGTH characters (excluding the '0').
- * @note The message string is only valid until the scope of
- * the function is left.
- */
- virtual void OnDebug(const char* message)= 0;
-
- // ----------------------------------------------------------------------
- /** @brief Called as a request to write a specific info message
- * @param message Info message. Never longer than
- * MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0').
- * @note The message string is only valid until the scope of
- * the function is left.
- */
- virtual void OnInfo(const char* message) = 0;
-
- // ----------------------------------------------------------------------
- /** @brief Called as a request to write a specific warn message
- * @param message Warn message. Never longer than
- * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
- * @note The message string is only valid until the scope of
- * the function is left.
- */
- virtual void OnWarn(const char* essage) = 0;
-
- // ----------------------------------------------------------------------
- /** @brief Called as a request to write a specific error message
- * @param message Error message. Never longer than
- * MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
- * @note The message string is only valid until the scope of
- * the function is left.
- */
- virtual void OnError(const char* message) = 0;
-
-protected:
-
- //! Logger severity
- LogSeverity m_Severity;
-};
-
-// ----------------------------------------------------------------------------------
-// Default constructor
-inline Logger::Logger() {
- setLogSeverity(NORMAL);
-}
-
-// ----------------------------------------------------------------------------------
-// Virtual destructor
-inline Logger::~Logger()
-{
-}
-
-// ----------------------------------------------------------------------------------
-// Construction with given logging severity
-inline Logger::Logger(LogSeverity severity) {
- setLogSeverity(severity);
-}
-
-// ----------------------------------------------------------------------------------
-// Log severity setter
-inline void Logger::setLogSeverity(LogSeverity log_severity){
- m_Severity = log_severity;
-}
-
-// ----------------------------------------------------------------------------------
-// Log severity getter
-inline Logger::LogSeverity Logger::getLogSeverity() const {
- return m_Severity;
-}
-
-// ----------------------------------------------------------------------------------
-inline void Logger::debug(const std::string &message)
-{
- return debug(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-inline void Logger::error(const std::string &message)
-{
- return error(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-inline void Logger::warn(const std::string &message)
-{
- return warn(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-inline void Logger::info(const std::string &message)
-{
- return info(message.c_str());
-}
-
-// ----------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! INCLUDED_AI_LOGGER_H
diff --git a/src/3rdparty/assimp/include/assimp/NullLogger.hpp b/src/3rdparty/assimp/include/assimp/NullLogger.hpp
deleted file mode 100644
index 191db1aaa..000000000
--- a/src/3rdparty/assimp/include/assimp/NullLogger.hpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 NullLogger.hpp
- * @brief Dummy logger
-*/
-
-#ifndef INCLUDED_AI_NULLLOGGER_H
-#define INCLUDED_AI_NULLLOGGER_H
-
-#include "Logger.hpp"
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** @brief CPP-API: Empty logging implementation.
- *
- * Does nothing! Used by default if the application hasn't requested a
- * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */
-class ASSIMP_API NullLogger
- : public Logger {
-
-public:
-
- /** @brief Logs a debug message */
- void OnDebug(const char* message) {
- (void)message; //this avoids compiler warnings
- }
-
- /** @brief Logs an info message */
- void OnInfo(const char* message) {
- (void)message; //this avoids compiler warnings
- }
-
- /** @brief Logs a warning message */
- void OnWarn(const char* message) {
- (void)message; //this avoids compiler warnings
- }
-
- /** @brief Logs an error message */
- void OnError(const char* message) {
- (void)message; //this avoids compiler warnings
- }
-
- /** @brief Detach a still attached stream from logger */
- bool attachStream(LogStream *pStream, unsigned int severity) {
- (void)pStream; (void)severity; //this avoids compiler warnings
- return false;
- }
-
- /** @brief Detach a still attached stream from logger */
- bool detatchStream(LogStream *pStream, unsigned int severity) {
- (void)pStream; (void)severity; //this avoids compiler warnings
- return false;
- }
-
-private:
-};
-}
-#endif // !! AI_NULLLOGGER_H_INCLUDED
diff --git a/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp b/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp
deleted file mode 100644
index 2c5b2f4c5..000000000
--- a/src/3rdparty/assimp/include/assimp/ProgressHandler.hpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 ProgressHandler.hpp
- * @brief Abstract base class 'ProgressHandler'.
- */
-#pragma once
-#ifndef AI_PROGRESSHANDLER_H_INC
-#define AI_PROGRESSHANDLER_H_INC
-
-#include "types.h"
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------
-/** @brief CPP-API: Abstract interface for custom progress report receivers.
- *
- * Each #Importer instance maintains its own #ProgressHandler. The default
- * implementation provided by Assimp doesn't do anything at all. */
-class ASSIMP_API ProgressHandler
-#ifndef SWIG
- : public Intern::AllocateFromAssimpHeap
-#endif
-{
-protected:
- /** @brief Default constructor */
- ProgressHandler () {
- }
-public:
- /** @brief Virtual destructor */
- virtual ~ProgressHandler () {
- }
-
- // -------------------------------------------------------------------
- /** @brief Progress callback.
- * @param percentage An estimate of the current loading progress,
- * in percent. Or -1.f if such an estimate is not available.
- *
- * There are restriction on what you may do from within your
- * implementation of this method: no exceptions may be thrown and no
- * non-const #Importer methods may be called. It is
- * not generally possible to predict the number of callbacks
- * fired during a single import.
- *
- * @return Return false to abort loading at the next possible
- * occasion (loaders and Assimp are generally allowed to perform
- * all needed cleanup tasks prior to returning control to the
- * caller). If the loading is aborted, #Importer::ReadFile()
- * returns always NULL.
- * */
- virtual bool Update(float percentage = -1.f) = 0;
-
- // -------------------------------------------------------------------
- /** @brief Progress callback for file loading steps
- * @param numberOfSteps The number of total post-processing
- * steps
- * @param currentStep The index of the current post-processing
- * step that will run, or equal to numberOfSteps if all of
- * them has finished. This number is always strictly monotone
- * increasing, although not necessarily linearly.
- *
- * @note This is currently only used at the start and the end
- * of the file parsing.
- * */
- virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
- float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
- Update( f * 0.5f );
- }
-
- // -------------------------------------------------------------------
- /** @brief Progress callback for post-processing steps
- * @param numberOfSteps The number of total post-processing
- * steps
- * @param currentStep The index of the current post-processing
- * step that will run, or equal to numberOfSteps if all of
- * them has finished. This number is always strictly monotone
- * increasing, although not necessarily linearly.
- * */
- virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
- float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
- Update( f * 0.5f + 0.5f );
- }
-
-}; // !class ProgressHandler
-// ------------------------------------------------------------------------------------
-} // Namespace Assimp
-
-#endif // AI_PROGRESSHANDLER_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/SceneCombiner.h b/src/3rdparty/assimp/include/assimp/SceneCombiner.h
deleted file mode 100644
index aa57406b9..000000000
--- a/src/3rdparty/assimp/include/assimp/SceneCombiner.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 Declares a helper class, "SceneCombiner" providing various
- * utilities to merge scenes.
- */
-#ifndef AI_SCENE_COMBINER_H_INC
-#define AI_SCENE_COMBINER_H_INC
-
-#include <assimp/ai_assert.h>
-#include <assimp/types.h>
-#include <assimp/Defines.h>
-#include <stddef.h>
-#include <set>
-#include <list>
-#include <stdint.h>
-
-#include <vector>
-
-struct aiScene;
-struct aiNode;
-struct aiMaterial;
-struct aiTexture;
-struct aiCamera;
-struct aiLight;
-struct aiMetadata;
-struct aiBone;
-struct aiMesh;
-struct aiAnimation;
-struct aiNodeAnim;
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** \brief Helper data structure for SceneCombiner.
- *
- * Describes to which node a scene must be attached to.
- */
-struct AttachmentInfo
-{
- AttachmentInfo()
- : scene (NULL)
- , attachToNode (NULL)
- {}
-
- AttachmentInfo(aiScene* _scene, aiNode* _attachToNode)
- : scene (_scene)
- , attachToNode (_attachToNode)
- {}
-
- aiScene* scene;
- aiNode* attachToNode;
-};
-
-// ---------------------------------------------------------------------------
-struct NodeAttachmentInfo
-{
- NodeAttachmentInfo()
- : node (NULL)
- , attachToNode (NULL)
- , resolved (false)
- , src_idx (SIZE_MAX)
- {}
-
- NodeAttachmentInfo(aiNode* _scene, aiNode* _attachToNode,size_t idx)
- : node (_scene)
- , attachToNode (_attachToNode)
- , resolved (false)
- , src_idx (idx)
- {}
-
- aiNode* node;
- aiNode* attachToNode;
- bool resolved;
- size_t src_idx;
-};
-
-// ---------------------------------------------------------------------------
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES
- * Generate unique names for all named scene items
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES 0x1
-
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES
- * Generate unique names for materials, too.
- * This is not absolutely required to pass the validation.
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_MATNAMES 0x2
-
-/** @def AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY
- * Use deep copies of duplicate scenes
- */
-#define AI_INT_MERGE_SCENE_DUPLICATES_DEEP_CPY 0x4
-
-/** @def AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS
- * If attachment nodes are not found in the given master scene,
- * search the other imported scenes for them in an any order.
- */
-#define AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS 0x8
-
-/** @def AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY
- * Can be combined with AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES.
- * Unique names are generated, but only if this is absolutely
- * required to avoid name conflicts.
- */
-#define AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY 0x10
-
-typedef std::pair<aiBone*,unsigned int> BoneSrcIndex;
-
-// ---------------------------------------------------------------------------
-/** @brief Helper data structure for SceneCombiner::MergeBones.
- */
-struct BoneWithHash : public std::pair<uint32_t,aiString*> {
- std::vector<BoneSrcIndex> pSrcBones;
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Utility for SceneCombiner
- */
-struct SceneHelper
-{
- SceneHelper ()
- : scene (NULL)
- , idlen (0)
- {
- id[0] = 0;
- }
-
- explicit SceneHelper (aiScene* _scene)
- : scene (_scene)
- , idlen (0)
- {
- id[0] = 0;
- }
-
- AI_FORCE_INLINE aiScene* operator-> () const
- {
- return scene;
- }
-
- // scene we're working on
- aiScene* scene;
-
- // prefix to be added to all identifiers in the scene ...
- char id [32];
-
- // and its strlen()
- unsigned int idlen;
-
- // hash table to quickly check whether a name is contained in the scene
- std::set<unsigned int> hashes;
-};
-
-// ---------------------------------------------------------------------------
-/** \brief Static helper class providing various utilities to merge two
- * scenes. It is intended as internal utility and NOT for use by
- * applications.
- *
- * The class is currently being used by various postprocessing steps
- * and loaders (ie. LWS).
- */
-class ASSIMP_API SceneCombiner {
- // class cannot be instanced
- SceneCombiner() {
- // empty
- }
-
- ~SceneCombiner() {
- // empty
- }
-
-public:
- // -------------------------------------------------------------------
- /** Merges two or more scenes.
- *
- * @param dest Receives a pointer to the destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param src Non-empty list of scenes to be merged. The function
- * deletes the input scenes afterwards. There may be duplicate scenes.
- * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
- */
- static void MergeScenes(aiScene** dest,std::vector<aiScene*>& src,
- unsigned int flags = 0);
-
- // -------------------------------------------------------------------
- /** Merges two or more scenes and attaches all scenes to a specific
- * position in the node graph of the master scene.
- *
- * @param dest Receives a pointer to the destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param master Master scene. It will be deleted afterwards. All
- * other scenes will be inserted in its node graph.
- * @param src Non-empty list of scenes to be merged along with their
- * corresponding attachment points in the master scene. The function
- * deletes the input scenes afterwards. There may be duplicate scenes.
- * @param flags Combination of the AI_INT_MERGE_SCENE flags defined above
- */
- static void MergeScenes(aiScene** dest, aiScene* master,
- std::vector<AttachmentInfo>& src,
- unsigned int flags = 0);
-
- // -------------------------------------------------------------------
- /** Merges two or more meshes
- *
- * The meshes should have equal vertex formats. Only components
- * that are provided by ALL meshes will be present in the output mesh.
- * An exception is made for VColors - they are set to black. The
- * meshes should have the same material indices, too. The output
- * material index is always the material index of the first mesh.
- *
- * @param dest Destination mesh. Must be empty.
- * @param flags Currently no parameters
- * @param begin First mesh to be processed
- * @param end Points to the mesh after the last mesh to be processed
- */
- static void MergeMeshes(aiMesh** dest,unsigned int flags,
- std::vector<aiMesh*>::const_iterator begin,
- std::vector<aiMesh*>::const_iterator end);
-
- // -------------------------------------------------------------------
- /** Merges two or more bones
- *
- * @param out Mesh to receive the output bone list
- * @param flags Currently no parameters
- * @param begin First mesh to be processed
- * @param end Points to the mesh after the last mesh to be processed
- */
- 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 occurrence
- * 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
- *
- * @param asBones Receives the output list
- * @param it First mesh to be processed
- * @param end Last mesh to be processed
- */
- static void BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
- std::vector<aiMesh*>::const_iterator it,
- std::vector<aiMesh*>::const_iterator end);
-
- // -------------------------------------------------------------------
- /** Add a name prefix to all nodes in a scene.
- *
- * @param Current node. This function is called recursively.
- * @param prefix Prefix to be added to all nodes
- * @param len STring length
- */
- static void AddNodePrefixes(aiNode* node, const char* prefix,
- unsigned int len);
-
- // -------------------------------------------------------------------
- /** Add an offset to all mesh indices in a node graph
- *
- * @param Current node. This function is called recursively.
- * @param offset Offset to be added to all mesh indices
- */
- static void OffsetNodeMeshIndices (aiNode* node, unsigned int offset);
-
- // -------------------------------------------------------------------
- /** Attach a list of node graphs to well-defined nodes in a master
- * graph. This is a helper for MergeScenes()
- *
- * @param master Master scene
- * @param srcList List of source scenes along with their attachment
- * points. If an attachment point is NULL (or does not exist in
- * the master graph), a scene is attached to the root of the master
- * graph (as an additional child node)
- * @duplicates List of duplicates. If elem[n] == n the scene is not
- * a duplicate. Otherwise elem[n] links scene n to its first occurrence.
- */
- static void AttachToGraph ( aiScene* master,
- std::vector<NodeAttachmentInfo>& srcList);
-
- static void AttachToGraph (aiNode* attach,
- std::vector<NodeAttachmentInfo>& srcList);
-
-
- // -------------------------------------------------------------------
- /** Get a deep copy of a scene
- *
- * @param dest Receives a pointer to the destination scene
- * @param src Source scene - remains unmodified.
- */
- static void CopyScene(aiScene** dest,const aiScene* source,bool allocate = true);
-
-
- // -------------------------------------------------------------------
- /** Get a flat copy of a scene
- *
- * Only the first hierarchy layer is copied. All pointer members of
- * aiScene are shared by source and destination scene. If the
- * pointer doesn't point to NULL when the function is called, the
- * existing scene is cleared and refilled.
- * @param dest Receives a pointer to the destination scene
- * @param src Source scene - remains unmodified.
- */
- static void CopySceneFlat(aiScene** dest,const aiScene* source);
-
-
- // -------------------------------------------------------------------
- /** Get a deep copy of a mesh
- *
- * @param dest Receives a pointer to the destination mesh
- * @param src Source mesh - remains unmodified.
- */
- static void Copy (aiMesh** dest, const aiMesh* src);
-
- // similar to Copy():
- static void Copy (aiMaterial** dest, const aiMaterial* src);
- static void Copy (aiTexture** dest, const aiTexture* src);
- static void Copy (aiAnimation** dest, const aiAnimation* src);
- static void Copy (aiCamera** dest, const aiCamera* src);
- static void Copy (aiBone** dest, const aiBone* src);
- static void Copy (aiLight** dest, const aiLight* src);
- static void Copy (aiNodeAnim** dest, const aiNodeAnim* src);
- static void Copy (aiMetadata** dest, const aiMetadata* src);
-
- // recursive, of course
- static void Copy (aiNode** dest, const aiNode* src);
-
-
-private:
-
- // -------------------------------------------------------------------
- // Same as AddNodePrefixes, but with an additional check
- static void AddNodePrefixesChecked(aiNode* node, const char* prefix,
- unsigned int len,
- std::vector<SceneHelper>& input,
- unsigned int cur);
-
- // -------------------------------------------------------------------
- // Add node identifiers to a hashing set
- static void AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes);
-
-
- // -------------------------------------------------------------------
- // Search for duplicate names
- static bool FindNameMatch(const aiString& name,
- std::vector<SceneHelper>& input, unsigned int cur);
-};
-
-}
-
-#endif // !! AI_SCENE_COMBINER_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/ai_assert.h b/src/3rdparty/assimp/include/assimp/ai_assert.h
deleted file mode 100644
index d8dbac8d2..000000000
--- a/src/3rdparty/assimp/include/assimp/ai_assert.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
----------------------------------------------------------------------------
-*/
-#pragma once
-#ifndef AI_ASSERT_H_INC
-#define AI_ASSERT_H_INC
-
-#ifdef ASSIMP_BUILD_DEBUG
-# include <assert.h>
-# define ai_assert(expression) assert(expression)
-#else
-# define ai_assert(expression)
-#endif //
-
-#endif // AI_ASSERT_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/anim.h b/src/3rdparty/assimp/include/assimp/anim.h
deleted file mode 100644
index f8774b8fd..000000000
--- a/src/3rdparty/assimp/include/assimp/anim.h
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 anim.h
- * @brief Defines the data structures in which the imported animations
- * are returned.
- */
-#pragma once
-#ifndef AI_ANIM_H_INC
-#define AI_ANIM_H_INC
-
-#include <assimp/types.h>
-#include <assimp/quaternion.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-/** A time-value pair specifying a certain 3D vector for the given time. */
-struct aiVectorKey
-{
- /** The time of this key */
- double mTime;
-
- /** The value of this key */
- C_STRUCT aiVector3D mValue;
-
-#ifdef __cplusplus
-
- /// @brief The default constructor.
- aiVectorKey()
- : mTime( 0.0 )
- , mValue() {
- // empty
- }
-
- /// @brief Construction from a given time and key value.
-
- aiVectorKey(double time, const aiVector3D& value)
- : mTime (time)
- , mValue (value)
- {}
-
- typedef aiVector3D elem_type;
-
- // Comparison operators. For use with std::find();
- bool operator == (const aiVectorKey& o) const {
- return o.mValue == this->mValue;
- }
- bool operator != (const aiVectorKey& o) const {
- return o.mValue != this->mValue;
- }
-
- // Relational operators. For use with std::sort();
- bool operator < (const aiVectorKey& o) const {
- return mTime < o.mTime;
- }
- bool operator > (const aiVectorKey& o) const {
- return mTime > o.mTime;
- }
-#endif // __cplusplus
-};
-
-// ---------------------------------------------------------------------------
-/** A time-value pair specifying a rotation for the given time.
- * Rotations are expressed with quaternions. */
-struct aiQuatKey
-{
- /** The time of this key */
- double mTime;
-
- /** The value of this key */
- C_STRUCT aiQuaternion mValue;
-
-#ifdef __cplusplus
- aiQuatKey()
- : mTime( 0.0 )
- , mValue() {
- // empty
- }
-
- /** Construction from a given time and key value */
- aiQuatKey(double time, const aiQuaternion& value)
- : mTime (time)
- , mValue (value)
- {}
-
- typedef aiQuaternion elem_type;
-
- // Comparison operators. For use with std::find();
- bool operator == (const aiQuatKey& o) const {
- return o.mValue == this->mValue;
- }
- bool operator != (const aiQuatKey& o) const {
- return o.mValue != this->mValue;
- }
-
- // Relational operators. For use with std::sort();
- bool operator < (const aiQuatKey& o) const {
- return mTime < o.mTime;
- }
- bool operator > (const aiQuatKey& o) const {
- return mTime > o.mTime;
- }
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Binds a anim mesh to a specific point in time. */
-struct aiMeshKey
-{
- /** The time of this key */
- double mTime;
-
- /** Index into the aiMesh::mAnimMeshes array of the
- * mesh corresponding to the #aiMeshAnim hosting this
- * key frame. The referenced anim mesh is evaluated
- * according to the rules defined in the docs for #aiAnimMesh.*/
- unsigned int mValue;
-
-#ifdef __cplusplus
-
- aiMeshKey() {
- }
-
- /** Construction from a given time and key value */
- aiMeshKey(double time, const unsigned int value)
- : mTime (time)
- , mValue (value)
- {}
-
- typedef unsigned int elem_type;
-
- // Comparison operators. For use with std::find();
- bool operator == (const aiMeshKey& o) const {
- return o.mValue == this->mValue;
- }
- bool operator != (const aiMeshKey& o) const {
- return o.mValue != this->mValue;
- }
-
- // Relational operators. For use with std::sort();
- bool operator < (const aiMeshKey& o) const {
- return mTime < o.mTime;
- }
- bool operator > (const aiMeshKey& o) const {
- return mTime > o.mTime;
- }
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Binds a morph anim mesh to a specific point in time. */
-struct aiMeshMorphKey
-{
- /** The time of this key */
- double mTime;
-
- /** The values and weights at the time of this key */
- unsigned int *mValues;
- double *mWeights;
-
- /** The number of values and weights */
- unsigned int mNumValuesAndWeights;
-#ifdef __cplusplus
- aiMeshMorphKey()
- : mTime(0.0)
- , mValues(NULL)
- , mWeights(NULL)
- , mNumValuesAndWeights(0)
- {
-
- }
-
- ~aiMeshMorphKey()
- {
- if (mNumValuesAndWeights && mValues && mWeights) {
- delete [] mValues;
- delete [] mWeights;
- }
- }
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Defines how an animation channel behaves outside the defined time
- * range. This corresponds to aiNodeAnim::mPreState and
- * aiNodeAnim::mPostState.*/
-enum aiAnimBehaviour
-{
- /** The value from the default node transformation is taken*/
- aiAnimBehaviour_DEFAULT = 0x0,
-
- /** The nearest key value is used without interpolation */
- aiAnimBehaviour_CONSTANT = 0x1,
-
- /** The value of the nearest two keys is linearly
- * extrapolated for the current time value.*/
- aiAnimBehaviour_LINEAR = 0x2,
-
- /** The animation is repeated.
- *
- * If the animation key go from n to m and the current
- * time is t, use the value at (t-n) % (|m-n|).*/
- aiAnimBehaviour_REPEAT = 0x3,
-
- /** 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 = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Describes the animation of a single node. The name specifies the
- * bone/node which is affected by this animation channel. The keyframes
- * are given in three separate series of values, one each for position,
- * rotation and scaling. The transformation matrix computed from these
- * values replaces the node's original transformation matrix at a
- * specific time.
- * This means all keys are absolute and not relative to the bone default pose.
- * The order in which the transformations are applied is
- * - as usual - scaling, rotation, translation.
- *
- * @note All keys are returned in their correct, chronological order.
- * Duplicate keys don't pass the validation step. Most likely there
- * will be no negative time values, but they are not forbidden also ( so
- * implementations need to cope with them! ) */
-struct aiNodeAnim {
- /** The name of the node affected by this animation. The node
- * must exist and it must be unique.*/
- C_STRUCT aiString mNodeName;
-
- /** The number of position keys */
- unsigned int mNumPositionKeys;
-
- /** The position keys of this animation channel. Positions are
- * specified as 3D vector. The array is mNumPositionKeys in size.
- *
- * If there are position keys, there will also be at least one
- * scaling and one rotation key.*/
- C_STRUCT aiVectorKey* mPositionKeys;
-
- /** The number of rotation keys */
- unsigned int mNumRotationKeys;
-
- /** The rotation keys of this animation channel. Rotations are
- * given as quaternions, which are 4D vectors. The array is
- * mNumRotationKeys in size.
- *
- * If there are rotation keys, there will also be at least one
- * scaling and one position key. */
- C_STRUCT aiQuatKey* mRotationKeys;
-
- /** The number of scaling keys */
- unsigned int mNumScalingKeys;
-
- /** The scaling keys of this animation channel. Scalings are
- * specified as 3D vector. The array is mNumScalingKeys in size.
- *
- * If there are scaling keys, there will also be at least one
- * position and one rotation key.*/
- C_STRUCT aiVectorKey* mScalingKeys;
-
- /** Defines how the animation behaves before the first
- * key is encountered.
- *
- * The default value is aiAnimBehaviour_DEFAULT (the original
- * transformation matrix of the affected node is used).*/
- C_ENUM aiAnimBehaviour mPreState;
-
- /** Defines how the animation behaves after the last
- * key was processed.
- *
- * The default value is aiAnimBehaviour_DEFAULT (the original
- * transformation matrix of the affected node is taken).*/
- C_ENUM aiAnimBehaviour mPostState;
-
-#ifdef __cplusplus
- aiNodeAnim()
- : mNumPositionKeys( 0 )
- , mPositionKeys( NULL )
- , mNumRotationKeys( 0 )
- , mRotationKeys( NULL )
- , mNumScalingKeys( 0 )
- , mScalingKeys( NULL )
- , mPreState( aiAnimBehaviour_DEFAULT )
- , mPostState( aiAnimBehaviour_DEFAULT ) {
- // empty
- }
-
- ~aiNodeAnim() {
- delete [] mPositionKeys;
- delete [] mRotationKeys;
- delete [] mScalingKeys;
- }
-#endif // __cplusplus
-};
-
-// ---------------------------------------------------------------------------
-/** Describes vertex-based animations for a single mesh or a group of
- * meshes. Meshes carry the animation data for each frame in their
- * aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to
- * define keyframes linking each mesh attachment to a particular
- * point in time. */
-struct aiMeshAnim
-{
- /** Name of the mesh to be animated. An empty string is not allowed,
- * animated meshes need to be named (not necessarily uniquely,
- * the name can basically serve as wild-card to select a group
- * of meshes with similar animation setup)*/
- C_STRUCT aiString mName;
-
- /** Size of the #mKeys array. Must be 1, at least. */
- unsigned int mNumKeys;
-
- /** Key frames of the animation. May not be NULL. */
- C_STRUCT aiMeshKey* mKeys;
-
-#ifdef __cplusplus
-
- aiMeshAnim()
- : mNumKeys()
- , mKeys()
- {}
-
- ~aiMeshAnim()
- {
- delete[] mKeys;
- }
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Describes a morphing animation of a given mesh. */
-struct aiMeshMorphAnim
-{
- /** Name of the mesh to be animated. An empty string is not allowed,
- * animated meshes need to be named (not necessarily uniquely,
- * the name can basically serve as wildcard to select a group
- * of meshes with similar animation setup)*/
- C_STRUCT aiString mName;
-
- /** Size of the #mKeys array. Must be 1, at least. */
- unsigned int mNumKeys;
-
- /** Key frames of the animation. May not be NULL. */
- C_STRUCT aiMeshMorphKey* mKeys;
-
-#ifdef __cplusplus
-
- aiMeshMorphAnim()
- : mNumKeys()
- , mKeys()
- {}
-
- ~aiMeshMorphAnim()
- {
- delete[] mKeys;
- }
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** An animation consists of key-frame data for a number of nodes. For
- * each node affected by the animation a separate series of data is given.*/
-struct aiAnimation {
- /** The name of the animation. If the modeling package this data was
- * exported from does support only a single animation channel, this
- * name is usually empty (length is zero). */
- C_STRUCT aiString mName;
-
- /** Duration of the animation in ticks. */
- double mDuration;
-
- /** Ticks per second. 0 if not specified in the imported file */
- double mTicksPerSecond;
-
- /** The number of bone animation channels. Each channel affects
- * a single node. */
- unsigned int mNumChannels;
-
- /** The node animation channels. Each channel affects a single node.
- * The array is mNumChannels in size. */
- C_STRUCT aiNodeAnim** mChannels;
-
-
- /** The number of mesh animation channels. Each channel affects
- * a single mesh and defines vertex-based animation. */
- unsigned int mNumMeshChannels;
-
- /** The mesh animation channels. Each channel affects a single mesh.
- * The array is mNumMeshChannels in size. */
- C_STRUCT aiMeshAnim** mMeshChannels;
-
- /** The number of mesh animation channels. Each channel affects
- * a single mesh and defines morphing animation. */
- unsigned int mNumMorphMeshChannels;
-
- /** The morph mesh animation channels. Each channel affects a single mesh.
- * The array is mNumMorphMeshChannels in size. */
- C_STRUCT aiMeshMorphAnim **mMorphMeshChannels;
-
-#ifdef __cplusplus
- aiAnimation()
- : mDuration(-1.)
- , mTicksPerSecond(0.)
- , mNumChannels(0)
- , mChannels(NULL)
- , mNumMeshChannels(0)
- , mMeshChannels(NULL)
- , mNumMorphMeshChannels(0)
- , mMorphMeshChannels(NULL) {
- // empty
- }
-
- ~aiAnimation() {
- // DO NOT REMOVE THIS ADDITIONAL CHECK
- if ( mNumChannels && mChannels ) {
- for( unsigned int a = 0; a < mNumChannels; a++) {
- delete mChannels[ a ];
- }
-
- delete [] mChannels;
- }
- if (mNumMeshChannels && mMeshChannels) {
- for( unsigned int a = 0; a < mNumMeshChannels; a++) {
- delete mMeshChannels[a];
- }
-
- delete [] mMeshChannels;
- }
- if (mNumMorphMeshChannels && mMorphMeshChannels) {
- for( unsigned int a = 0; a < mNumMorphMeshChannels; a++) {
- delete mMorphMeshChannels[a];
- }
-
- delete [] mMorphMeshChannels;
- }
- }
-#endif // __cplusplus
-};
-
-#ifdef __cplusplus
-
-}
-
-/// @brief Some C++ utilities for inter- and extrapolation
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/**
- * @brief CPP-API: Utility class to simplify interpolations of various data types.
- *
- * The type of interpolation is chosen automatically depending on the
- * types of the arguments.
- */
-template <typename T>
-struct Interpolator
-{
- // ------------------------------------------------------------------
- /** @brief Get the result of the interpolation between a,b.
- *
- * The interpolation algorithm depends on the type of the operands.
- * aiQuaternion's and aiQuatKey's SLERP, the rest does a simple
- * linear interpolation. */
- void operator () (T& out,const T& a, const T& b, ai_real d) const {
- out = a + (b-a)*d;
- }
-}; // ! Interpolator <T>
-
-//! @cond Never
-
-template <>
-struct Interpolator <aiQuaternion> {
- void operator () (aiQuaternion& out,const aiQuaternion& a,
- const aiQuaternion& b, ai_real d) const
- {
- aiQuaternion::Interpolate(out,a,b,d);
- }
-}; // ! Interpolator <aiQuaternion>
-
-template <>
-struct Interpolator <unsigned int> {
- void operator () (unsigned int& out,unsigned int a,
- unsigned int b, ai_real d) const
- {
- out = d>0.5f ? b : a;
- }
-}; // ! Interpolator <aiQuaternion>
-
-template <>
-struct Interpolator<aiVectorKey> {
- void operator () (aiVector3D& out,const aiVectorKey& a,
- const aiVectorKey& b, ai_real d) const
- {
- Interpolator<aiVector3D> ipl;
- ipl(out,a.mValue,b.mValue,d);
- }
-}; // ! Interpolator <aiVectorKey>
-
-template <>
-struct Interpolator<aiQuatKey> {
- void operator () (aiQuaternion& out, const aiQuatKey& a,
- const aiQuatKey& b, ai_real d) const
- {
- Interpolator<aiQuaternion> ipl;
- ipl(out,a.mValue,b.mValue,d);
- }
-}; // ! Interpolator <aiQuatKey>
-
-template <>
-struct Interpolator<aiMeshKey> {
- void operator () (unsigned int& out, const aiMeshKey& a,
- const aiMeshKey& b, ai_real d) const
- {
- Interpolator<unsigned int> ipl;
- ipl(out,a.mValue,b.mValue,d);
- }
-}; // ! Interpolator <aiQuatKey>
-
-//! @endcond
-
-} // ! end namespace Assimp
-
-#endif // __cplusplus
-
-#endif // AI_ANIM_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/camera.h b/src/3rdparty/assimp/include/assimp/camera.h
deleted file mode 100644
index 7b7bd0922..000000000
--- a/src/3rdparty/assimp/include/assimp/camera.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 camera.h
- * @brief Defines the aiCamera data structure
- */
-
-#pragma once
-#ifndef AI_CAMERA_H_INC
-#define AI_CAMERA_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-/** Helper structure to describe a virtual camera.
- *
- * Cameras have a representation in the node graph and can be animated.
- * An important aspect is that the camera itself is also part of the
- * scenegraph. This means, any values such as the look-at vector are not
- * *absolute*, they're <b>relative</b> to the coordinate system defined
- * by the node which corresponds to the camera. This allows for camera
- * animations. For static cameras parameters like the 'look-at' or 'up' vectors
- * are usually specified directly in aiCamera, but beware, they could also
- * be encoded in the node transformation. The following (pseudo)code sample
- * shows how to do it: <br><br>
- * @code
- * // Get the camera matrix for a camera at a specific time
- * // if the node hierarchy for the camera does not contain
- * // at least one animated node this is a static computation
- * get-camera-matrix (node sceneRoot, camera cam) : matrix
- * {
- * node cnd = find-node-for-camera(cam)
- * matrix cmt = identity()
- *
- * // as usual - get the absolute camera transformation for this frame
- * for each node nd in hierarchy from sceneRoot to cnd
- * matrix cur
- * if (is-animated(nd))
- * cur = eval-animation(nd)
- * else cur = nd->mTransformation;
- * cmt = mult-matrices( cmt, cur )
- * end for
- *
- * // now multiply with the camera's own local transform
- * cam = mult-matrices (cam, get-camera-matrix(cmt) )
- * }
- * @endcode
- *
- * @note some file formats (such as 3DS, ASE) export a "target point" -
- * the point the camera is looking at (it can even be animated). Assimp
- * writes the target point as a subnode of the camera's main node,
- * called "<camName>.Target". However this is just additional information
- * then the transformation tracks of the camera main node make the
- * camera already look in the right direction.
- *
-*/
-struct aiCamera
-{
- /** The name of the camera.
- *
- * There must be a node in the scenegraph with the same name.
- * This node specifies the position of the camera in the scene
- * hierarchy and can be animated.
- */
- C_STRUCT aiString mName;
-
- /** Position of the camera relative to the coordinate space
- * defined by the corresponding node.
- *
- * The default value is 0|0|0.
- */
- C_STRUCT aiVector3D mPosition;
-
-
- /** 'Up' - vector of the camera coordinate system relative to
- * the coordinate space defined by the corresponding node.
- *
- * The 'right' vector of the camera coordinate system is
- * the cross product of the up and lookAt vectors.
- * The default value is 0|1|0. The vector
- * may be normalized, but it needn't.
- */
- C_STRUCT aiVector3D mUp;
-
-
- /** 'LookAt' - vector of the camera coordinate system relative to
- * the coordinate space defined by the corresponding node.
- *
- * This is the viewing direction of the user.
- * The default value is 0|0|1. The vector
- * may be normalized, but it needn't.
- */
- C_STRUCT aiVector3D mLookAt;
-
-
- /** Half horizontal field of view angle, in radians.
- *
- * The field of view angle is the angle between the center
- * line of the screen and the left or right border.
- * The default value is 1/4PI.
- */
- float mHorizontalFOV;
-
- /** Distance of the near clipping plane from the camera.
- *
- * The value may not be 0.f (for arithmetic reasons to prevent
- * a division through zero). The default value is 0.1f.
- */
- float mClipPlaneNear;
-
- /** Distance of the far clipping plane from the camera.
- *
- * The far clipping plane must, of course, be further away than the
- * near clipping plane. The default value is 1000.f. The ratio
- * between the near and the far plane should not be too
- * large (between 1000-10000 should be ok) to avoid floating-point
- * inaccuracies which could lead to z-fighting.
- */
- float mClipPlaneFar;
-
-
- /** Screen aspect ratio.
- *
- * This is the ration between the width and the height of the
- * screen. Typical values are 4/3, 1/2 or 1/1. This value is
- * 0 if the aspect ratio is not defined in the source file.
- * 0 is also the default value.
- */
- float mAspect;
-
-#ifdef __cplusplus
-
- aiCamera()
- : mUp (0.f,1.f,0.f)
- , mLookAt (0.f,0.f,1.f)
- , mHorizontalFOV (0.25f * (float)AI_MATH_PI)
- , mClipPlaneNear (0.1f)
- , mClipPlaneFar (1000.f)
- , mAspect (0.f)
- {}
-
- /** @brief Get a *right-handed* camera matrix from me
- * @param out Camera matrix to be filled
- */
- void GetCameraMatrix (aiMatrix4x4& out) const
- {
- /** todo: test ... should work, but i'm not absolutely sure */
-
- /** We don't know whether these vectors are already normalized ...*/
- aiVector3D zaxis = mLookAt; zaxis.Normalize();
- aiVector3D yaxis = mUp; yaxis.Normalize();
- aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize();
-
- out.a4 = -(xaxis * mPosition);
- out.b4 = -(yaxis * mPosition);
- out.c4 = -(zaxis * mPosition);
-
- out.a1 = xaxis.x;
- out.a2 = xaxis.y;
- out.a3 = xaxis.z;
-
- out.b1 = yaxis.x;
- out.b2 = yaxis.y;
- out.b3 = yaxis.z;
-
- out.c1 = zaxis.x;
- out.c2 = zaxis.y;
- out.c3 = zaxis.z;
-
- out.d1 = out.d2 = out.d3 = 0.f;
- out.d4 = 1.f;
- }
-
-#endif
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // AI_CAMERA_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/cexport.h b/src/3rdparty/assimp/include/assimp/cexport.h
deleted file mode 100644
index 44b06fb3c..000000000
--- a/src/3rdparty/assimp/include/assimp/cexport.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2011, 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 cexport.h
-* @brief Defines the C-API for the Assimp export interface
-*/
-#pragma once
-#ifndef AI_EXPORT_H_INC
-#define AI_EXPORT_H_INC
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-
-// Public ASSIMP data structures
-#include <assimp/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct aiScene; // aiScene.h
-struct aiFileIO; // aiFileIO.h
-
-// --------------------------------------------------------------------------------
-/** Describes an file format which Assimp can export to. Use #aiGetExportFormatCount() to
-* learn how many export formats the current Assimp build supports and #aiGetExportFormatDescription()
-* to retrieve a description of an export format option.
-*/
-struct aiExportFormatDesc
-{
- /// a short string ID to uniquely identify the export format. Use this ID string to
- /// specify which file format you want to export to when calling #aiExportScene().
- /// Example: "dae" or "obj"
- const char* id;
-
- /// A short description of the file format to present to users. Useful if you want
- /// to allow the user to select an export format.
- const char* description;
-
- /// Recommended file extension for the exported file in lower case.
- const char* fileExtension;
-};
-
-
-// --------------------------------------------------------------------------------
-/** Returns the number of export file formats available in the current Assimp build.
- * Use aiGetExportFormatDescription() to retrieve infos of a specific export format.
- */
-ASSIMP_API size_t aiGetExportFormatCount(void);
-
-
-// --------------------------------------------------------------------------------
-/** Returns a description of the nth export file format. Use #aiGetExportFormatCount()
- * to learn how many export formats are supported. The description must be released by
- * calling aiReleaseExportFormatDescription afterwards.
- * @param pIndex Index of the export format to retrieve information for. Valid range is
- * 0 to #aiGetExportFormatCount()
- * @return A description of that specific export format. NULL if pIndex is out of range.
- */
-ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex);
-
-// --------------------------------------------------------------------------------
-/** Release a description of the nth export file format. Must be returned by
-* aiGetExportFormatDescription
-* @param desc Pointer to the description
-*/
-ASSIMP_API void aiReleaseExportFormatDescription( const C_STRUCT aiExportFormatDesc *desc );
-
-// --------------------------------------------------------------------------------
-/** 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 modifiable copy is needed.
- * @param pIn Valid scene to be copied
- * @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.
-* The scene is expected to conform to Assimp's Importer output format as specified
-* in the @link data Data Structures Page @endlink. In short, this means the model data
-* should use a right-handed coordinate systems, face winding should be counter-clockwise
-* and the UV coordinate origin is assumed to be in the upper left. If your input data
-* uses different conventions, have a look at the last parameter.
-* @param pFormatId ID string to specify to which format you want to export to. Use
-* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
-* @param pFileName Output file to write
-* @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
-* flags, but in reality only a subset of them makes sense here. Specifying
-* 'preprocessing' flags is useful if the input scene does not conform to
-* Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
-* In short, this means the geometry data should use a right-handed coordinate systems, face
-* winding should be counter-clockwise and the UV coordinate origin is assumed to be in
-* the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
-* #aiProcess_FlipWindingOrder flags are used in the import side to allow users
-* to have those defaults automatically adapted to their conventions. Specifying those flags
-* for exporting has the opposite effect, respectively. Some other of the
-* #aiPostProcessSteps enumerated values may be useful as well, but you'll need
-* to try out what their effect on the exported file is. Many formats impose
-* their own restrictions on the structure of the geometry stored therein,
-* so some preprocessing may have little or no effect at all, or may be
-* 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 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,
- const char* pFileName,
- unsigned int pPreprocessing);
-
-
-// --------------------------------------------------------------------------------
-/** Exports the given scene to a chosen file format using custom IO logic supplied by you.
-* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
-* @param pFormatId ID string to specify to which format you want to export to. Use
-* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
-* @param pFileName Output file to write
-* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
-* If none is supplied, a default implementation using standard file IO is used. Note that
-* #aiExportSceneToBlob is provided as convenience function to export to memory buffers.
-* @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,
- const char* pFileName,
- C_STRUCT aiFileIO* pIO,
- unsigned int pPreprocessing );
-
-
-// --------------------------------------------------------------------------------
-/** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an
-* exported scene. The memory referred by this structure is owned by Assimp.
-* to free its resources. Don't try to free the memory on your side - it will crash for most build configurations
-* due to conflicting heaps.
-*
-* Blobs can be nested - each blob may reference another blob, which may in turn reference another blob and so on.
-* This is used when exporters write more than one output file for a given #aiScene. See the remarks for
-* #aiExportDataBlob::name for more information.
-*/
-struct aiExportDataBlob
-{
- /// Size of the data in bytes
- size_t size;
-
- /// The data.
- void* data;
-
- /** Name of the blob. An empty string always
- indicates the first (and primary) blob,
- which contains the actual file data.
- Any other blobs are auxiliary files produced
- by exporters (i.e. material files). Existence
- of such files depends on the file format. Most
- formats don't split assets across multiple files.
-
- If used, blob names usually contain the file
- extension that should be used when writing
- the data to disc.
- */
- C_STRUCT aiString name;
-
- /** Pointer to the next blob in the chain or NULL if there is none. */
- C_STRUCT aiExportDataBlob * next;
-
-#ifdef __cplusplus
- /// Default constructor
- aiExportDataBlob() { size = 0; data = next = NULL; }
- /// Releases the data
- ~aiExportDataBlob() { delete [] static_cast<unsigned char*>( data ); delete next; }
-
-private:
- // no copying
- aiExportDataBlob(const aiExportDataBlob& );
- aiExportDataBlob& operator= (const aiExportDataBlob& );
-#endif // __cplusplus
-};
-
-// --------------------------------------------------------------------------------
-/** Exports the given scene to a chosen file format. Returns the exported data as a binary blob which
-* you can write into a file or something. When you're done with the data, use #aiReleaseExportBlob()
-* to free the resources associated with the export.
-* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
-* @param pFormatId ID string to specify to which format you want to export to. Use
-* #aiGetExportFormatCount() / #aiGetExportFormatDescription() to learn which export formats are available.
-* @param pPreprocessing Please see the documentation for #aiExportScene
-* @return the exported data or NULL in case of error
-*/
-ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing );
-
-
-// --------------------------------------------------------------------------------
-/** Releases the memory associated with the given exported data. Use this function to free a data blob
-* returned by aiExportScene().
-* @param pData the data blob returned by #aiExportSceneToBlob
-*/
-ASSIMP_API void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ASSIMP_BUILD_NO_EXPORT
-#endif // AI_EXPORT_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/cfileio.h b/src/3rdparty/assimp/include/assimp/cfileio.h
deleted file mode 100644
index 63eeb59b0..000000000
--- a/src/3rdparty/assimp/include/assimp/cfileio.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 cfileio.h
- * @brief Defines generic C routines to access memory-mapped files
- */
-#pragma once
-#ifndef AI_FILEIO_H_INC
-#define AI_FILEIO_H_INC
-
-#include <assimp/types.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-struct aiFileIO;
-struct aiFile;
-
-// aiFile callbacks
-typedef size_t (*aiFileWriteProc) (C_STRUCT aiFile*, const char*, size_t, size_t);
-typedef size_t (*aiFileReadProc) (C_STRUCT aiFile*, char*, size_t,size_t);
-typedef size_t (*aiFileTellProc) (C_STRUCT aiFile*);
-typedef void (*aiFileFlushProc) (C_STRUCT aiFile*);
-typedef C_ENUM aiReturn (*aiFileSeek) (C_STRUCT aiFile*, size_t, C_ENUM aiOrigin);
-
-// aiFileIO callbacks
-typedef C_STRUCT aiFile* (*aiFileOpenProc) (C_STRUCT aiFileIO*, const char*, const char*);
-typedef void (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
-
-// Represents user-defined data
-typedef char* aiUserData;
-
-// ----------------------------------------------------------------------------------
-/** @brief C-API: File system callbacks
- *
- * Provided are functions to open and close files. Supply a custom structure to
- * the import function. If you don't, a default implementation is used. Use custom
- * file systems to enable reading from other sources, such as ZIPs
- * or memory locations. */
-struct aiFileIO
-{
- /** Function used to open a new file
- */
- aiFileOpenProc OpenProc;
-
- /** Function used to close an existing file
- */
- aiFileCloseProc CloseProc;
-
- /** User-defined, opaque data */
- aiUserData UserData;
-};
-
-// ----------------------------------------------------------------------------------
-/** @brief C-API: File callbacks
- *
- * Actually, it's a data structure to wrap a set of fXXXX (e.g fopen)
- * replacement functions.
- *
- * The default implementation of the functions utilizes the fXXX functions from
- * the CRT. However, you can supply a custom implementation to Assimp by
- * delivering a custom aiFileIO. Use this to enable reading from other sources,
- * such as ZIP archives or memory locations. */
-struct aiFile
-{
- /** Callback to read from a file */
- aiFileReadProc ReadProc;
-
- /** Callback to write to a file */
- aiFileWriteProc WriteProc;
-
- /** Callback to retrieve the current position of
- * the file cursor (ftell())
- */
- aiFileTellProc TellProc;
-
- /** Callback to retrieve the size of the file,
- * in bytes
- */
- aiFileTellProc FileSizeProc;
-
- /** Callback to set the current position
- * of the file cursor (fseek())
- */
- aiFileSeek SeekProc;
-
- /** Callback to flush the file contents
- */
- aiFileFlushProc FlushProc;
-
- /** User-defined, opaque data
- */
- aiUserData UserData;
-};
-
-#ifdef __cplusplus
-}
-#endif
-#endif // AI_FILEIO_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/cimport.h b/src/3rdparty/assimp/include/assimp/cimport.h
deleted file mode 100644
index 8aa125c67..000000000
--- a/src/3rdparty/assimp/include/assimp/cimport.h
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 cimport.h
- * @brief Defines the C-API to the Open Asset Import Library.
- */
-#pragma once
-#ifndef AI_ASSIMP_H_INC
-#define AI_ASSIMP_H_INC
-
-#include <assimp/types.h>
-#include "importerdesc.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct aiScene; // aiScene.h
-struct aiFileIO; // aiFileIO.h
-typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);
-
-// --------------------------------------------------------------------------------
-/** C-API: Represents a log stream. A log stream receives all log messages and
- * streams them _somewhere_.
- * @see aiGetPredefinedLogStream
- * @see aiAttachLogStream
- * @see aiDetachLogStream */
-// --------------------------------------------------------------------------------
-struct aiLogStream
-{
- /** callback to be called */
- aiLogStreamCallback callback;
-
- /** user data to be passed to the callback */
- char* user;
-};
-
-
-// --------------------------------------------------------------------------------
-/** C-API: Represents an opaque set of settings to be used during importing.
- * @see aiCreatePropertyStore
- * @see aiReleasePropertyStore
- * @see aiImportFileExWithProperties
- * @see aiSetPropertyInteger
- * @see aiSetPropertyFloat
- * @see aiSetPropertyString
- * @see aiSetPropertyMatrix
- */
-// --------------------------------------------------------------------------------
-struct aiPropertyStore { char sentinel; };
-
-/** Our own C boolean type */
-typedef int aiBool;
-
-#define AI_FALSE 0
-#define AI_TRUE 1
-
-// --------------------------------------------------------------------------------
-/** Reads the given file and returns its content.
- *
- * If the call succeeds, the imported data is returned in an aiScene structure.
- * The data is intended to be read-only, it stays property of the ASSIMP
- * library and will be stable until aiReleaseImport() is called. After you're
- * done with it, call aiReleaseImport() to free the resources associated with
- * this file. If the import fails, NULL is returned instead. Call
- * aiGetErrorString() to retrieve a human-readable error text.
- * @param pFile Path and filename of the file to be imported,
- * expected to be a null-terminated c-string. NULL is not a valid value.
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags.
- * @return Pointer to the imported data or NULL if the import failed.
- */
-ASSIMP_API const C_STRUCT aiScene* aiImportFile(
- const char* pFile,
- unsigned int pFlags);
-
-// --------------------------------------------------------------------------------
-/** Reads the given file using user-defined I/O functions and returns
- * its content.
- *
- * If the call succeeds, the imported data is returned in an aiScene structure.
- * The data is intended to be read-only, it stays property of the ASSIMP
- * library and will be stable until aiReleaseImport() is called. After you're
- * done with it, call aiReleaseImport() to free the resources associated with
- * this file. If the import fails, NULL is returned instead. Call
- * aiGetErrorString() to retrieve a human-readable error text.
- * @param pFile Path and filename of the file to be imported,
- * expected to be a null-terminated c-string. NULL is not a valid value.
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags.
- * @param pFS aiFileIO structure. Will be used to open the model file itself
- * and any other files the loader needs to open. Pass NULL to use the default
- * implementation.
- * @return Pointer to the imported data or NULL if the import failed.
- * @note Include <aiFileIO.h> for the definition of #aiFileIO.
- */
-ASSIMP_API const C_STRUCT aiScene* aiImportFileEx(
- const char* pFile,
- unsigned int pFlags,
- C_STRUCT aiFileIO* pFS);
-
-// --------------------------------------------------------------------------------
-/** Same as #aiImportFileEx, but adds an extra parameter containing importer settings.
- *
- * @param pFile Path and filename of the file to be imported,
- * expected to be a null-terminated c-string. NULL is not a valid value.
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags.
- * @param pFS aiFileIO structure. Will be used to open the model file itself
- * and any other files the loader needs to open. Pass NULL to use the default
- * implementation.
- * @param pProps #aiPropertyStore instance containing import settings.
- * @return Pointer to the imported data or NULL if the import failed.
- * @note Include <aiFileIO.h> for the definition of #aiFileIO.
- * @see aiImportFileEx
- */
-ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties(
- const char* pFile,
- unsigned int pFlags,
- C_STRUCT aiFileIO* pFS,
- const C_STRUCT aiPropertyStore* pProps);
-
-// --------------------------------------------------------------------------------
-/** Reads the given file from a given memory buffer,
- *
- * If the call succeeds, the contents of the file are returned as a pointer to an
- * aiScene object. The returned data is intended to be read-only, the importer keeps
- * ownership of the data and will destroy it upon destruction. If the import fails,
- * NULL is returned.
- * A human-readable error description can be retrieved by calling aiGetErrorString().
- * @param pBuffer Pointer to the file data
- * @param pLength Length of pBuffer, in bytes
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags. If you wish to inspect the imported
- * scene first in order to fine-tune your post-processing setup,
- * consider to use #aiApplyPostProcessing().
- * @param pHint An additional hint to the library. If this is a non empty string,
- * the library looks for a loader to support the file extension specified by pHint
- * and passes the file to the first matching loader. If this loader is unable to
- * completely the request, the library continues and tries to determine the file
- * format on its own, a task that may or may not be successful.
- * 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 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,
- unsigned int pLength,
- unsigned int pFlags,
- const char* pHint);
-
-// --------------------------------------------------------------------------------
-/** Same as #aiImportFileFromMemory, but adds an extra parameter containing importer settings.
- *
- * @param pBuffer Pointer to the file data
- * @param pLength Length of pBuffer, in bytes
- * @param pFlags Optional post processing steps to be executed after
- * a successful import. Provide a bitwise combination of the
- * #aiPostProcessSteps flags. If you wish to inspect the imported
- * scene first in order to fine-tune your post-processing setup,
- * consider to use #aiApplyPostProcessing().
- * @param pHint An additional hint to the library. If this is a non empty string,
- * the library looks for a loader to support the file extension specified by pHint
- * and passes the file to the first matching loader. If this loader is unable to
- * completely the request, the library continues and tries to determine the file
- * format on its own, a task that may or may not be successful.
- * Check the return value, and you'll know ...
- * @param pProps #aiPropertyStore instance containing import settings.
- * @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 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.
- * @see aiImportFileFromMemory
- */
-ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties(
- const char* pBuffer,
- unsigned int pLength,
- unsigned int pFlags,
- const char* pHint,
- const C_STRUCT aiPropertyStore* pProps);
-
-// --------------------------------------------------------------------------------
-/** Apply post-processing to an already-imported scene.
- *
- * This is strictly equivalent to calling #aiImportFile()/#aiImportFileEx with the
- * same flags. However, you can use this separate function to inspect the imported
- * scene first to fine-tune your post-processing setup.
- * @param pScene Scene to work on.
- * @param pFlags Provide a bitwise combination of the #aiPostProcessSteps flags.
- * @return A pointer to the post-processed data. Post processing is done in-place,
- * meaning this is still the same #aiScene which you passed for pScene. However,
- * _if_ post-processing failed, the scene could now be NULL. That's quite a rare
- * case, post processing steps are not really designed to 'fail'. To be exact,
- * the #aiProcess_ValidateDataStructure flag is currently the only post processing step
- * which can actually cause the scene to be reset to NULL.
- */
-ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing(
- const C_STRUCT aiScene* pScene,
- unsigned int pFlags);
-
-// --------------------------------------------------------------------------------
-/** Get one of the predefine log streams. This is the quick'n'easy solution to
- * access Assimp's log system. Attaching a log stream can slightly reduce Assimp's
- * overall import performance.
- *
- * Usage is rather simple (this will stream the log to a file, named log.txt, and
- * the stdout stream of the process:
- * @code
- * struct aiLogStream c;
- * c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"log.txt");
- * aiAttachLogStream(&c);
- * c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
- * aiAttachLogStream(&c);
- * @endcode
- *
- * @param pStreams One of the #aiDefaultLogStream enumerated values.
- * @param file Solely for the #aiDefaultLogStream_FILE flag: specifies the file to write to.
- * Pass NULL for all other flags.
- * @return The log stream. callback is set to NULL if something went wrong.
- */
-ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream(
- C_ENUM aiDefaultLogStream pStreams,
- const char* file);
-
-// --------------------------------------------------------------------------------
-/** Attach a custom log stream to the libraries' logging system.
- *
- * Attaching a log stream can slightly reduce Assimp's overall import
- * performance. Multiple log-streams can be attached.
- * @param stream Describes the new log stream.
- * @note To ensure proper destruction of the logging system, you need to manually
- * call aiDetachLogStream() on every single log stream you attach.
- * Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided.
- */
-ASSIMP_API void aiAttachLogStream(
- const C_STRUCT aiLogStream* stream);
-
-// --------------------------------------------------------------------------------
-/** Enable verbose logging. Verbose logging includes debug-related stuff and
- * detailed import statistics. This can have severe impact on import performance
- * and memory consumption. However, it might be useful to find out why a file
- * didn't read correctly.
- * @param d AI_TRUE or AI_FALSE, your decision.
- */
-ASSIMP_API void aiEnableVerboseLogging(aiBool d);
-
-// --------------------------------------------------------------------------------
-/** Detach a custom log stream from the libraries' logging system.
- *
- * This is the counterpart of #aiAttachLogStream. If you attached a stream,
- * don't forget to detach it again.
- * @param stream The log stream to be detached.
- * @return AI_SUCCESS if the log stream has been detached successfully.
- * @see aiDetachAllLogStreams
- */
-ASSIMP_API C_ENUM aiReturn aiDetachLogStream(
- const C_STRUCT aiLogStream* stream);
-
-// --------------------------------------------------------------------------------
-/** Detach all active log streams from the libraries' logging system.
- * This ensures that the logging system is terminated properly and all
- * resources allocated by it are actually freed. If you attached a stream,
- * don't forget to detach it again.
- * @see aiAttachLogStream
- * @see aiDetachLogStream
- */
-ASSIMP_API void aiDetachAllLogStreams(void);
-
-// --------------------------------------------------------------------------------
-/** Releases all resources associated with the given import process.
- *
- * Call this function after you're done with the imported data.
- * @param pScene The imported data to release. NULL is a valid value.
- */
-ASSIMP_API void aiReleaseImport(
- const C_STRUCT aiScene* pScene);
-
-// --------------------------------------------------------------------------------
-/** Returns the error text of the last failed import process.
- *
- * @return A textual description of the error that occurred at the last
- * import process. NULL if there was no error. There can't be an error if you
- * got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
- */
-ASSIMP_API const char* aiGetErrorString(void);
-
-// --------------------------------------------------------------------------------
-/** Returns whether a given file extension is supported by ASSIMP
- *
- * @param szExtension Extension for which the function queries support for.
- * Must include a leading dot '.'. Example: ".3ds", ".md3"
- * @return AI_TRUE if the file extension is supported.
- */
-ASSIMP_API aiBool aiIsExtensionSupported(
- const char* szExtension);
-
-// --------------------------------------------------------------------------------
-/** Get a list of all file extensions supported by ASSIMP.
- *
- * If a file extension is contained in the list this does, of course, not
- * mean that ASSIMP is able to load all files with this extension.
- * @param szOut String to receive the extension list.
- * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
- */
-ASSIMP_API void aiGetExtensionList(
- C_STRUCT aiString* szOut);
-
-// --------------------------------------------------------------------------------
-/** Get the approximated storage required by an imported asset
- * @param pIn Input asset.
- * @param in Data structure to be filled.
- */
-ASSIMP_API void aiGetMemoryRequirements(
- const C_STRUCT aiScene* pIn,
- C_STRUCT aiMemoryInfo* in);
-
-
-
-// --------------------------------------------------------------------------------
-/** Create an empty property store. Property stores are used to collect import
- * settings.
- * @return New property store. Property stores need to be manually destroyed using
- * the #aiReleasePropertyStore API function.
- */
-ASSIMP_API C_STRUCT aiPropertyStore* aiCreatePropertyStore(void);
-
-// --------------------------------------------------------------------------------
-/** Delete a property store.
- * @param p Property store to be deleted.
- */
-ASSIMP_API void aiReleasePropertyStore(C_STRUCT aiPropertyStore* p);
-
-// --------------------------------------------------------------------------------
-/** Set an integer property.
- *
- * This is the C-version of #Assimp::Importer::SetPropertyInteger(). In the C
- * interface, properties are always shared by all imports. It is not possible to
- * specify them per import.
- *
- * @param store 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 aiSetImportPropertyInteger(
- C_STRUCT aiPropertyStore* store,
- const char* szName,
- int value);
-
-// --------------------------------------------------------------------------------
-/** Set a floating-point property.
- *
- * This is the C-version of #Assimp::Importer::SetPropertyFloat(). In the C
- * interface, properties are always shared by all imports. It is not possible to
- * specify them per import.
- *
- * @param store 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 aiSetImportPropertyFloat(
- C_STRUCT aiPropertyStore* store,
- const char* szName,
- ai_real value);
-
-// --------------------------------------------------------------------------------
-/** Set a string property.
- *
- * This is the C-version of #Assimp::Importer::SetPropertyString(). In the C
- * interface, properties are always shared by all imports. It is not possible to
- * specify them per import.
- *
- * @param store 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 st New value for the property
- */
-ASSIMP_API void aiSetImportPropertyString(
- C_STRUCT aiPropertyStore* store,
- const char* szName,
- 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 store 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 mat 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'.
- * @see aiQuaternion(const aiMatrix3x3& pRotMatrix)
- */
-ASSIMP_API void aiCreateQuaternionFromMatrix(
- C_STRUCT aiQuaternion* quat,
- const C_STRUCT aiMatrix3x3* mat);
-
-// --------------------------------------------------------------------------------
-/** Decompose a transformation matrix into its rotational, translational and
- * scaling components.
- *
- * @param mat Matrix to decompose
- * @param scaling Receives the scaling component
- * @param rotation Receives the rotational component
- * @param position Receives the translational component.
- * @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const;
- */
-ASSIMP_API void aiDecomposeMatrix(
- const C_STRUCT aiMatrix4x4* mat,
- C_STRUCT aiVector3D* scaling,
- C_STRUCT aiQuaternion* rotation,
- C_STRUCT aiVector3D* position);
-
-// --------------------------------------------------------------------------------
-/** Transpose a 4x4 matrix.
- * @param mat Pointer to the matrix to be transposed
- */
-ASSIMP_API void aiTransposeMatrix4(
- C_STRUCT aiMatrix4x4* mat);
-
-// --------------------------------------------------------------------------------
-/** Transpose a 3x3 matrix.
- * @param mat Pointer to the matrix to be transposed
- */
-ASSIMP_API void aiTransposeMatrix3(
- C_STRUCT aiMatrix3x3* mat);
-
-// --------------------------------------------------------------------------------
-/** Transform a vector by a 3x3 matrix
- * @param vec Vector to be transformed.
- * @param mat Matrix to transform the vector with.
- */
-ASSIMP_API void aiTransformVecByMatrix3(
- C_STRUCT aiVector3D* vec,
- const C_STRUCT aiMatrix3x3* mat);
-
-// --------------------------------------------------------------------------------
-/** Transform a vector by a 4x4 matrix
- * @param vec Vector to be transformed.
- * @param mat Matrix to transform the vector with.
- */
-ASSIMP_API void aiTransformVecByMatrix4(
- C_STRUCT aiVector3D* vec,
- const C_STRUCT aiMatrix4x4* mat);
-
-// --------------------------------------------------------------------------------
-/** Multiply two 4x4 matrices.
- * @param dst First factor, receives result.
- * @param src Matrix to be multiplied with 'dst'.
- */
-ASSIMP_API void aiMultiplyMatrix4(
- C_STRUCT aiMatrix4x4* dst,
- const C_STRUCT aiMatrix4x4* src);
-
-// --------------------------------------------------------------------------------
-/** Multiply two 3x3 matrices.
- * @param dst First factor, receives result.
- * @param src Matrix to be multiplied with 'dst'.
- */
-ASSIMP_API void aiMultiplyMatrix3(
- C_STRUCT aiMatrix3x3* dst,
- const C_STRUCT aiMatrix3x3* src);
-
-// --------------------------------------------------------------------------------
-/** Get a 3x3 identity matrix.
- * @param mat Matrix to receive its personal identity
- */
-ASSIMP_API void aiIdentityMatrix3(
- C_STRUCT aiMatrix3x3* mat);
-
-// --------------------------------------------------------------------------------
-/** Get a 4x4 identity matrix.
- * @param mat Matrix to receive its personal identity
- */
-ASSIMP_API void aiIdentityMatrix4(
- C_STRUCT aiMatrix4x4* mat);
-
-// --------------------------------------------------------------------------------
-/** Returns the number of import file formats available in the current Assimp build.
- * Use aiGetImportFormatDescription() to retrieve infos of a specific import format.
- */
-ASSIMP_API size_t aiGetImportFormatCount(void);
-
-// --------------------------------------------------------------------------------
-/** Returns a description of the nth import file format. Use #aiGetImportFormatCount()
- * to learn how many import formats are supported.
- * @param pIndex Index of the import format to retrieve information for. Valid range is
- * 0 to #aiGetImportFormatCount()
- * @return A description of that specific import format. NULL if pIndex is out of range.
- */
-ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImportFormatDescription( size_t pIndex);
-#ifdef __cplusplus
-}
-#endif
-
-#endif // AI_ASSIMP_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/color4.h b/src/3rdparty/assimp/include/assimp/color4.h
deleted file mode 100644
index 48e7aad30..000000000
--- a/src/3rdparty/assimp/include/assimp/color4.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 color4.h
- * @brief RGBA color structure, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_COLOR4D_H_INC
-#define AI_COLOR4D_H_INC
-
-#include "defs.h"
-
-#ifdef __cplusplus
-
-// ----------------------------------------------------------------------------------
-/** Represents a color in Red-Green-Blue space including an
-* alpha component. Color values range from 0 to 1. */
-// ----------------------------------------------------------------------------------
-template <typename TReal>
-class aiColor4t
-{
-public:
- aiColor4t () : r(), g(), b(), a() {}
- aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
- : r(_r), g(_g), b(_b), a(_a) {}
- explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
- aiColor4t (const aiColor4t& o)
- : r(o.r), g(o.g), b(o.b), a(o.a) {}
-
-public:
- // combined operators
- const aiColor4t& operator += (const aiColor4t& o);
- const aiColor4t& operator -= (const aiColor4t& o);
- const aiColor4t& operator *= (TReal f);
- const aiColor4t& operator /= (TReal f);
-
-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;
- inline TReal& operator[](unsigned int i);
-
- /** check whether a color is (close to) black */
- inline bool IsBlack() const;
-
-public:
-
- // Red, green, blue and alpha color values
- TReal r, g, b, a;
-}; // !struct aiColor4D
-
-typedef aiColor4t<ai_real> aiColor4D;
-
-#else
-
-struct aiColor4D {
- ai_real r, g, b, a;
-};
-
-#endif // __cplusplus
-
-#endif // AI_COLOR4D_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/color4.inl b/src/3rdparty/assimp/include/assimp/color4.inl
deleted file mode 100644
index b242c4e77..000000000
--- a/src/3rdparty/assimp/include/assimp/color4.inl
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 color4.inl
- * @brief Inline implementation of aiColor4t<TReal> operators
- */
-#pragma once
-#ifndef AI_COLOR4D_INL_INC
-#define AI_COLOR4D_INL_INC
-
-#ifdef __cplusplus
-#include "color4.h"
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
- r += o.r; g += o.g; b += o.b; a += o.a;
- return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
- r -= o.r; g -= o.g; b -= o.b; a -= o.a;
- return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
- r *= f; g *= f; b *= f; a *= f;
- return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
- r /= f; g /= f; b /= f; a /= f;
- return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
- switch ( i ) {
- case 0:
- return r;
- case 1:
- return g;
- case 2:
- return b;
- default:
- break;
- }
- return r;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
- switch ( i ) {
- case 0:
- return r;
- case 1:
- return g;
- case 2:
- return b;
- default:
- break;
- }
- return r;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
- return r == other.r && g == other.g && b == other.b && a == other.a;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
- return r != other.r || g != other.g || b != other.b || a != other.a;
-}
-// ------------------------------------------------------------------------------------------------
-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);
-}
-// ------------------------------------------------------------------------------------------------
-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);
-}
-// ------------------------------------------------------------------------------------------------
-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);
-}
-// ------------------------------------------------------------------------------------------------
-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);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v) {
- return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f) {
- return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f) {
- return v * (1/f);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v) {
- return aiColor4t<TReal>(f,f,f,f)/v;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f) {
- return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f) {
- return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v) {
- return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v) {
- return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline bool aiColor4t<TReal> :: IsBlack() const {
- // The alpha component doesn't care here. black is black.
- static const TReal epsilon = 10e-3f;
- return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
-}
-
-#endif // __cplusplus
-#endif // AI_VECTOR3D_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/defs.h b/src/3rdparty/assimp/include/assimp/defs.h
deleted file mode 100644
index 20b234f90..000000000
--- a/src/3rdparty/assimp/include/assimp/defs.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 defs.h
- * @brief Assimp build configuration setup. See the notes in the comment
- * blocks to find out how to customize _your_ Assimp build.
- */
-
-#pragma once
-#ifndef AI_DEFINES_H_INC
-#define AI_DEFINES_H_INC
-
-#include <assimp/config.h>
-
- //////////////////////////////////////////////////////////////////////////
- /* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific
- * file format loader. The loader is be excluded from the
- * build in this case. 'XX' stands for the most common file
- * extension of the file format. E.g.:
- * ASSIMP_BUILD_NO_X_IMPORTER disables the X loader.
- *
- * If you're unsure about that, take a look at the implementation of the
- * import plugin you wish to disable. You'll find the right define in the
- * first lines of the corresponding unit.
- *
- * Other (mixed) configuration switches are listed here:
- * ASSIMP_BUILD_NO_COMPRESSED_X
- * - Disable support for compressed X files (zip)
- * ASSIMP_BUILD_NO_COMPRESSED_BLEND
- * - Disable support for compressed Blender files (zip)
- * ASSIMP_BUILD_NO_COMPRESSED_IFC
- * - Disable support for IFCZIP files (unzip)
- */
- //////////////////////////////////////////////////////////////////////////
-
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
-# define ASSIMP_BUILD_NEED_Z_INFLATE
-#endif
-
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-# 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'):
- * CALCTANGENTS
- * JOINVERTICES
- * TRIANGULATE
- * GENFACENORMALS
- * GENVERTEXNORMALS
- * REMOVEVC
- * SPLITLARGEMESHES
- * PRETRANSFORMVERTICES
- * LIMITBONEWEIGHTS
- * VALIDATEDS
- * IMPROVECACHELOCALITY
- * FIXINFACINGNORMALS
- * REMOVE_REDUNDANTMATERIALS
- * OPTIMIZEGRAPH
- * SORTBYPTYPE
- * FINDINVALIDDATA
- * TRANSFORMTEXCOORDS
- * GENUVCOORDS
- * ENTITYMESHBUILDER
- * MAKELEFTHANDED
- * FLIPUVS
- * FLIPWINDINGORDER
- * OPTIMIZEMESHES
- * OPTIMIZEANIMS
- * OPTIMIZEGRAPH
- * GENENTITYMESHES
- * FIXTEXTUREPATHS */
- //////////////////////////////////////////////////////////////////////////
-
-#ifdef _MSC_VER
-# undef ASSIMP_API
-
- //////////////////////////////////////////////////////////////////////////
- /* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
- //////////////////////////////////////////////////////////////////////////
-# ifdef ASSIMP_BUILD_DLL_EXPORT
-# define ASSIMP_API __declspec(dllexport)
-# define ASSIMP_API_WINONLY __declspec(dllexport)
-# pragma warning (disable : 4251)
-
- //////////////////////////////////////////////////////////////////////////
- /* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
- * an external DLL under Windows. Default is static linkage. */
- //////////////////////////////////////////////////////////////////////////
-# elif (defined ASSIMP_DLL)
-# define ASSIMP_API __declspec(dllimport)
-# define ASSIMP_API_WINONLY __declspec(dllimport)
-# else
-# define ASSIMP_API
-# define ASSIMP_API_WINONLY
-# endif
-
- /* Force the compiler to inline a function, if possible
- */
-# define AI_FORCE_INLINE __forceinline
-
- /* 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
-
-# define ASSIMP_API __attribute__ ((visibility("default")))
-# define ASSIMP_API_WINONLY
-# define AI_FORCE_INLINE inline
-#endif // (defined _MSC_VER)
-
-#ifdef __GNUC__
-# define AI_WONT_RETURN_SUFFIX __attribute__((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.
- */
-# define C_STRUCT
-# define C_ENUM
-#else
- //////////////////////////////////////////////////////////////////////////
- /* To build the documentation, make sure ASSIMP_DOXYGEN_BUILD
- * is defined by Doxygen's preprocessor. The corresponding
- * entries in the DOXYFILE are: */
- //////////////////////////////////////////////////////////////////////////
-#if 0
- ENABLE_PREPROCESSING = YES
- MACRO_EXPANSION = YES
- EXPAND_ONLY_PREDEF = YES
- SEARCH_INCLUDES = YES
- INCLUDE_PATH =
- INCLUDE_FILE_PATTERNS =
- PREDEFINED = ASSIMP_DOXYGEN_BUILD=1
- EXPAND_AS_DEFINED = C_STRUCT C_ENUM
- SKIP_FUNCTION_MACROS = YES
-#endif
- //////////////////////////////////////////////////////////////////////////
- /* Doxygen gets confused if we use c-struct typedefs to avoid
- * the explicit 'struct' notation. This trick here has the same
- * effect as the TYPEDEF_HIDES_STRUCT option, but we don't need
- * to typedef all structs/enums. */
- //////////////////////////////////////////////////////////////////////////
-# if (defined ASSIMP_DOXYGEN_BUILD)
-# define C_STRUCT
-# define C_ENUM
-# else
-# define C_STRUCT struct
-# define C_ENUM enum
-# endif
-#endif
-
-#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
-#error Currently, Borland is unsupported. Feel free to port Assimp.
-
-// "W8059 Packgröße der Struktur geändert"
-
-#endif
-
-
- //////////////////////////////////////////////////////////////////////////
- /* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp
- * without threading support. The library doesn't utilize
- * threads then and is itself not threadsafe. */
- //////////////////////////////////////////////////////////////////////////
-#ifndef ASSIMP_BUILD_SINGLETHREADED
-# define ASSIMP_BUILD_SINGLETHREADED
-#endif
-
-#if defined(_DEBUG) || ! defined(NDEBUG)
-# define ASSIMP_BUILD_DEBUG
-#endif
-
- //////////////////////////////////////////////////////////////////////////
- /* Define ASSIMP_DOUBLE_PRECISION to compile assimp
- * with double precision support (64-bit). */
- //////////////////////////////////////////////////////////////////////////
-
-#ifdef ASSIMP_DOUBLE_PRECISION
- typedef double ai_real;
- typedef signed long long int ai_int;
- typedef unsigned long long int ai_uint;
-#else // ASSIMP_DOUBLE_PRECISION
- typedef float ai_real;
- typedef signed int ai_int;
- typedef unsigned int ai_uint;
-#endif // ASSIMP_DOUBLE_PRECISION
-
- //////////////////////////////////////////////////////////////////////////
- /* Useful constants */
- //////////////////////////////////////////////////////////////////////////
-
-/* This is PI. Hi PI. */
-#define AI_MATH_PI (3.141592653589793238462643383279 )
-#define AI_MATH_TWO_PI (AI_MATH_PI * 2.0)
-#define AI_MATH_HALF_PI (AI_MATH_PI * 0.5)
-
-/* And this is to avoid endless casts to float */
-#define AI_MATH_PI_F (3.1415926538f)
-#define AI_MATH_TWO_PI_F (AI_MATH_PI_F * 2.0f)
-#define AI_MATH_HALF_PI_F (AI_MATH_PI_F * 0.5f)
-
-/* Tiny macro to convert from radians to degrees and back */
-#define AI_DEG_TO_RAD(x) ((x)*(ai_real)0.0174532925)
-#define AI_RAD_TO_DEG(x) ((x)*(ai_real)57.2957795)
-
-/* Support for big-endian builds */
-#if defined(__BYTE_ORDER__)
-# if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
-# if !defined(__BIG_ENDIAN__)
-# define __BIG_ENDIAN__
-# endif
-# else /* little endian */
-# if defined (__BIG_ENDIAN__)
-# undef __BIG_ENDIAN__
-# endif
-# endif
-#endif
-#if defined(__BIG_ENDIAN__)
-# define AI_BUILD_BIG_ENDIAN
-#endif
-
-
-/* To avoid running out of memory
- * This can be adjusted for specific use cases
- * It's NOT a total limit, just a limit for individual allocations
- */
-#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type))
-
-#endif // !! AI_DEFINES_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/importerdesc.h b/src/3rdparty/assimp/include/assimp/importerdesc.h
deleted file mode 100644
index 6b83b8aa2..000000000
--- a/src/3rdparty/assimp/include/assimp/importerdesc.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 importerdesc.h
- * @brief #aiImporterFlags, aiImporterDesc implementation.
- */
-#pragma once
-#ifndef AI_IMPORTER_DESC_H_INC
-#define AI_IMPORTER_DESC_H_INC
-
-
-/** Mixed set of flags for #aiImporterDesc, indicating some features
- * common to many importers*/
-enum aiImporterFlags
-{
- /** Indicates that there is a textual encoding of the
- * file format; and that it is supported.*/
- aiImporterFlags_SupportTextFlavour = 0x1,
-
- /** Indicates that there is a binary encoding of the
- * file format; and that it is supported.*/
- aiImporterFlags_SupportBinaryFlavour = 0x2,
-
- /** Indicates that there is a compressed encoding of the
- * file format; and that it is supported.*/
- aiImporterFlags_SupportCompressedFlavour = 0x4,
-
- /** Indicates that the importer reads only a very particular
- * subset of the file format. This happens commonly for
- * declarative or procedural formats which cannot easily
- * be mapped to #aiScene */
- aiImporterFlags_LimitedSupport = 0x8,
-
- /** Indicates that the importer is highly experimental and
- * should be used with care. This only happens for trunk
- * (i.e. SVN) versions, experimental code is not included
- * in releases. */
- aiImporterFlags_Experimental = 0x10
-};
-
-
-/** Meta information about a particular importer. Importers need to fill
- * this structure, but they can freely decide how talkative they are.
- * A common use case for loader meta info is a user interface
- * in which the user can choose between various import/export file
- * formats. Building such an UI by hand means a lot of maintenance
- * as importers/exporters are added to Assimp, so it might be useful
- * to have a common mechanism to query some rough importer
- * characteristics. */
-struct aiImporterDesc
-{
- /** Full name of the importer (i.e. Blender3D importer)*/
- const char* mName;
-
- /** Original author (left blank if unknown or whole assimp team) */
- const char* mAuthor;
-
- /** Current maintainer, left blank if the author maintains */
- const char* mMaintainer;
-
- /** Implementation comments, i.e. unimplemented features*/
- const char* mComments;
-
- /** These flags indicate some characteristics common to many
- importers. */
- unsigned int mFlags;
-
- /** Minimum format version that can be loaded im major.minor format,
- both are set to 0 if there is either no version scheme
- or if the loader doesn't care. */
- unsigned int mMinMajor;
- unsigned int mMinMinor;
-
- /** Maximum format version that can be loaded im major.minor format,
- both are set to 0 if there is either no version scheme
- or if the loader doesn't care. Loaders that expect to be
- forward-compatible to potential future format versions should
- indicate zero, otherwise they should specify the current
- maximum version.*/
- unsigned int mMaxMajor;
- unsigned int mMaxMinor;
-
- /** List of file extensions this importer can handle.
- List entries are separated by space characters.
- All entries are lower case without a leading dot (i.e.
- "xml dae" would be a valid value. Note that multiple
- importers may respond to the same file extension -
- assimp calls all importers in the order in which they
- are registered and each importer gets the opportunity
- to load the file until one importer "claims" the file. Apart
- from file extension checks, importers typically use
- other methods to quickly reject files (i.e. magic
- words) so this does not mean that common or generic
- file extensions such as XML would be tediously slow. */
- const char* mFileExtensions;
-};
-
-/** \brief Returns the Importer description for a given extension.
-
-Will return a NULL-pointer if no assigned importer desc. was found for the given extension
- \param extension [in] The extension to look for
- \return A pointer showing to the ImporterDesc, \see aiImporterDesc.
-*/
-ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImporterDesc( const char *extension );
-
-#endif // AI_IMPORTER_DESC_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/light.h b/src/3rdparty/assimp/include/assimp/light.h
deleted file mode 100644
index 324339a97..000000000
--- a/src/3rdparty/assimp/include/assimp/light.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 light.h
- * @brief Defines the aiLight data structure
- */
-
-#pragma once
-#ifndef AI_LIGHT_H_INC
-#define AI_LIGHT_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-/** Enumerates all supported types of light sources.
- */
-enum aiLightSourceType
-{
- aiLightSource_UNDEFINED = 0x0,
-
- //! A directional light source has a well-defined direction
- //! but is infinitely far away. That's quite a good
- //! approximation for sun light.
- aiLightSource_DIRECTIONAL = 0x1,
-
- //! A point light source has a well-defined position
- //! in space but no direction - it emits light in all
- //! directions. A normal bulb is a point light.
- aiLightSource_POINT = 0x2,
-
- //! A spot light source emits light in a specific
- //! angle. It has a position and a direction it is pointing to.
- //! A good example for a spot light is a light spot in
- //! sport arenas.
- aiLightSource_SPOT = 0x3,
-
- //! The generic light level of the world, including the bounces
- //! of all other light sources.
- //! Typically, there's at most one ambient light in a scene.
- //! This light type doesn't have a valid position, direction, or
- //! other properties, just a color.
- aiLightSource_AMBIENT = 0x4,
-
- //! An area light is a rectangle with predefined size that uniformly
- //! emits light from one of its sides. The position is center of the
- //! rectangle and direction is its normal vector.
- aiLightSource_AREA = 0x5,
-
- /** This value is not used. It is just there to force the
- * compiler to map this enum to a 32 Bit integer.
- */
-#ifndef SWIG
- _aiLightSource_Force32Bit = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** Helper structure to describe a light source.
- *
- * Assimp supports multiple sorts of light sources, including
- * directional, point and spot lights. All of them are defined with just
- * a single structure and distinguished by their parameters.
- * Note - some file formats (such as 3DS, ASE) export a "target point" -
- * the point a spot light is looking at (it can even be animated). Assimp
- * writes the target point as a subnode of a spotlights's main node,
- * called "<spotName>.Target". However, this is just additional information
- * then, the transformation tracks of the main node make the
- * spot light already point in the right direction.
-*/
-struct aiLight
-{
- /** The name of the light source.
- *
- * There must be a node in the scenegraph with the same name.
- * This node specifies the position of the light in the scene
- * hierarchy and can be animated.
- */
- C_STRUCT aiString mName;
-
- /** The type of the light source.
- *
- * aiLightSource_UNDEFINED is not a valid value for this member.
- */
- C_ENUM aiLightSourceType mType;
-
- /** Position of the light source in space. Relative to the
- * transformation of the node corresponding to the light.
- *
- * The position is undefined for directional lights.
- */
- C_STRUCT aiVector3D mPosition;
-
- /** Direction of the light source in space. Relative to the
- * transformation of the node corresponding to the light.
- *
- * The direction is undefined for point lights. The vector
- * may be normalized, but it needn't.
- */
- C_STRUCT aiVector3D mDirection;
-
- /** Up direction of the light source in space. Relative to the
- * transformation of the node corresponding to the light.
- *
- * The direction is undefined for point lights. The vector
- * may be normalized, but it needn't.
- */
- C_STRUCT aiVector3D mUp;
-
- /** Constant light attenuation factor.
- *
- * The intensity of the light source at a given distance 'd' from
- * the light's position is
- * @code
- * Atten = 1/( att0 + att1 * d + att2 * d*d)
- * @endcode
- * This member corresponds to the att0 variable in the equation.
- * Naturally undefined for directional lights.
- */
- float mAttenuationConstant;
-
- /** Linear light attenuation factor.
- *
- * The intensity of the light source at a given distance 'd' from
- * the light's position is
- * @code
- * Atten = 1/( att0 + att1 * d + att2 * d*d)
- * @endcode
- * This member corresponds to the att1 variable in the equation.
- * Naturally undefined for directional lights.
- */
- float mAttenuationLinear;
-
- /** Quadratic light attenuation factor.
- *
- * The intensity of the light source at a given distance 'd' from
- * the light's position is
- * @code
- * Atten = 1/( att0 + att1 * d + att2 * d*d)
- * @endcode
- * This member corresponds to the att2 variable in the equation.
- * Naturally undefined for directional lights.
- */
- float mAttenuationQuadratic;
-
- /** Diffuse color of the light source
- *
- * The diffuse light color is multiplied with the diffuse
- * material color to obtain the final color that contributes
- * to the diffuse shading term.
- */
- C_STRUCT aiColor3D mColorDiffuse;
-
- /** Specular color of the light source
- *
- * The specular light color is multiplied with the specular
- * material color to obtain the final color that contributes
- * to the specular shading term.
- */
- C_STRUCT aiColor3D mColorSpecular;
-
- /** Ambient color of the light source
- *
- * The ambient light color is multiplied with the ambient
- * material color to obtain the final color that contributes
- * to the ambient shading term. Most renderers will ignore
- * this value it, is just a remaining of the fixed-function pipeline
- * that is still supported by quite many file formats.
- */
- C_STRUCT aiColor3D mColorAmbient;
-
- /** Inner angle of a spot light's light cone.
- *
- * The spot light has maximum influence on objects inside this
- * angle. The angle is given in radians. It is 2PI for point
- * lights and undefined for directional lights.
- */
- float mAngleInnerCone;
-
- /** Outer angle of a spot light's light cone.
- *
- * The spot light does not affect objects outside this angle.
- * The angle is given in radians. It is 2PI for point lights and
- * undefined for directional lights. The outer angle must be
- * greater than or equal to the inner angle.
- * It is assumed that the application uses a smooth
- * interpolation between the inner and the outer cone of the
- * spot light.
- */
- float mAngleOuterCone;
-
- /** Size of area light source. */
- C_STRUCT aiVector2D mSize;
-
-#ifdef __cplusplus
-
- aiLight()
- : mType (aiLightSource_UNDEFINED)
- , mAttenuationConstant (0.f)
- , mAttenuationLinear (1.f)
- , mAttenuationQuadratic (0.f)
- , mAngleInnerCone ((float)AI_MATH_TWO_PI)
- , mAngleOuterCone ((float)AI_MATH_TWO_PI)
- , mSize (0.f, 0.f)
- {
- }
-
-#endif
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif // !! AI_LIGHT_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/material.h b/src/3rdparty/assimp/include/assimp/material.h
deleted file mode 100644
index a12e7d076..000000000
--- a/src/3rdparty/assimp/include/assimp/material.h
+++ /dev/null
@@ -1,1564 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 material.h
- * @brief Defines the material system of the library
- */
-#pragma once
-#ifndef AI_MATERIAL_H_INC
-#define AI_MATERIAL_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Name for default materials (2nd is used if meshes have UV coords)
-#define AI_DEFAULT_MATERIAL_NAME "DefaultMaterial"
-
-// ---------------------------------------------------------------------------
-/** @brief Defines how the Nth texture of a specific type is combined with
- * the result of all previous layers.
- *
- * Example (left: key, right: value): <br>
- * @code
- * DiffColor0 - gray
- * DiffTextureOp0 - aiTextureOpMultiply
- * DiffTexture0 - tex1.png
- * DiffTextureOp0 - aiTextureOpAdd
- * DiffTexture1 - tex2.png
- * @endcode
- * Written as equation, the final diffuse term for a specific pixel would be:
- * @code
- * diffFinal = DiffColor0 * sampleTex(DiffTexture0,UV0) +
- * sampleTex(DiffTexture1,UV0) * diffContrib;
- * @endcode
- * where 'diffContrib' is the intensity of the incoming light for that pixel.
- */
-enum aiTextureOp
-{
- /** T = T1 * T2 */
- aiTextureOp_Multiply = 0x0,
-
- /** T = T1 + T2 */
- aiTextureOp_Add = 0x1,
-
- /** T = T1 - T2 */
- aiTextureOp_Subtract = 0x2,
-
- /** T = T1 / T2 */
- aiTextureOp_Divide = 0x3,
-
- /** T = (T1 + T2) - (T1 * T2) */
- aiTextureOp_SmoothAdd = 0x4,
-
- /** T = T1 + (T2-0.5) */
- aiTextureOp_SignedAdd = 0x5,
-
-
-#ifndef SWIG
- _aiTextureOp_Force32Bit = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Defines how UV coordinates outside the [0...1] range are handled.
- *
- * Commonly referred to as 'wrapping mode'.
- */
-enum aiTextureMapMode
-{
- /** A texture coordinate u|v is translated to u%1|v%1
- */
- aiTextureMapMode_Wrap = 0x0,
-
- /** Texture coordinates outside [0...1]
- * are clamped to the nearest valid value.
- */
- aiTextureMapMode_Clamp = 0x1,
-
- /** If the texture coordinates for a pixel are outside [0...1]
- * the texture is not applied to that pixel
- */
- aiTextureMapMode_Decal = 0x3,
-
- /** A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and
- * 1-(u%1)|1-(v%1) otherwise
- */
- aiTextureMapMode_Mirror = 0x2,
-
-#ifndef SWIG
- _aiTextureMapMode_Force32Bit = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Defines how the mapping coords for a texture are generated.
- *
- * Real-time applications typically require full UV coordinates, so the use of
- * the aiProcess_GenUVCoords step is highly recommended. It generates proper
- * UV channels for non-UV mapped objects, as long as an accurate description
- * how the mapping should look like (e.g spherical) is given.
- * See the #AI_MATKEY_MAPPING property for more details.
- */
-enum aiTextureMapping
-{
- /** The mapping coordinates are taken from an UV channel.
- *
- * The #AI_MATKEY_UVWSRC key specifies from which UV channel
- * the texture coordinates are to be taken from (remember,
- * meshes can have more than one UV channel).
- */
- aiTextureMapping_UV = 0x0,
-
- /** Spherical mapping */
- aiTextureMapping_SPHERE = 0x1,
-
- /** Cylindrical mapping */
- aiTextureMapping_CYLINDER = 0x2,
-
- /** Cubic mapping */
- aiTextureMapping_BOX = 0x3,
-
- /** Planar mapping */
- aiTextureMapping_PLANE = 0x4,
-
- /** Undefined mapping. Have fun. */
- aiTextureMapping_OTHER = 0x5,
-
-
-#ifndef SWIG
- _aiTextureMapping_Force32Bit = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Defines the purpose of a texture
- *
- * This is a very difficult topic. Different 3D packages support different
- * kinds of textures. For very common texture types, such as bumpmaps, the
- * rendering results depend on implementation details in the rendering
- * pipelines of these applications. Assimp loads all texture references from
- * the model file and tries to determine which of the predefined texture
- * types below is the best choice to match the original use of the texture
- * as closely as possible.<br>
- *
- * In content pipelines you'll usually define how textures have to be handled,
- * and the artists working on models have to conform to this specification,
- * regardless which 3D tool they're using.
- */
-enum aiTextureType
-{
- /** Dummy value.
- *
- * No texture, but the value to be used as 'texture semantic'
- * (#aiMaterialProperty::mSemantic) for all material properties
- * *not* related to textures.
- */
- aiTextureType_NONE = 0x0,
-
-
-
- /** The texture is combined with the result of the diffuse
- * lighting equation.
- */
- aiTextureType_DIFFUSE = 0x1,
-
- /** The texture is combined with the result of the specular
- * lighting equation.
- */
- aiTextureType_SPECULAR = 0x2,
-
- /** The texture is combined with the result of the ambient
- * lighting equation.
- */
- aiTextureType_AMBIENT = 0x3,
-
- /** The texture is added to the result of the lighting
- * calculation. It isn't influenced by incoming light.
- */
- aiTextureType_EMISSIVE = 0x4,
-
- /** The texture is a height map.
- *
- * By convention, higher gray-scale values stand for
- * higher elevations from the base height.
- */
- aiTextureType_HEIGHT = 0x5,
-
- /** The texture is a (tangent space) normal-map.
- *
- * Again, there are several conventions for tangent-space
- * normal maps. Assimp does (intentionally) not
- * distinguish here.
- */
- aiTextureType_NORMALS = 0x6,
-
- /** The texture defines the glossiness of the material.
- *
- * The glossiness is in fact the exponent of the specular
- * (phong) lighting equation. Usually there is a conversion
- * function defined to map the linear color values in the
- * texture to a suitable exponent. Have fun.
- */
- aiTextureType_SHININESS = 0x7,
-
- /** The texture defines per-pixel opacity.
- *
- * Usually 'white' means opaque and 'black' means
- * 'transparency'. Or quite the opposite. Have fun.
- */
- aiTextureType_OPACITY = 0x8,
-
- /** Displacement texture
- *
- * The exact purpose and format is application-dependent.
- * Higher color values stand for higher vertex displacements.
- */
- aiTextureType_DISPLACEMENT = 0x9,
-
- /** Lightmap texture (aka Ambient Occlusion)
- *
- * Both 'Lightmaps' and dedicated 'ambient occlusion maps' are
- * covered by this material property. The texture contains a
- * scaling value for the final color value of a pixel. Its
- * intensity is not affected by incoming light.
- */
- aiTextureType_LIGHTMAP = 0xA,
-
- /** Reflection texture
- *
- * Contains the color of a perfect mirror reflection.
- * Rarely used, almost never for real-time applications.
- */
- aiTextureType_REFLECTION = 0xB,
-
- /** Unknown texture
- *
- * A texture reference that does not match any of the definitions
- * above is considered to be 'unknown'. It is still imported,
- * but is excluded from any further postprocessing.
- */
- aiTextureType_UNKNOWN = 0xC,
-
-
-#ifndef SWIG
- _aiTextureType_Force32Bit = INT_MAX
-#endif
-};
-
-#define AI_TEXTURE_TYPE_MAX aiTextureType_UNKNOWN
-
-// ---------------------------------------------------------------------------
-/** @brief Defines all shading models supported by the library
- *
- * The list of shading modes has been taken from Blender.
- * See Blender documentation for more information. The API does
- * not distinguish between "specular" and "diffuse" shaders (thus the
- * specular term for diffuse shading models like Oren-Nayar remains
- * undefined). <br>
- * Again, this value is just a hint. Assimp tries to select the shader whose
- * most common implementation matches the original rendering results of the
- * 3D modeller which wrote a particular model as closely as possible.
- */
-enum aiShadingMode
-{
- /** Flat shading. Shading is done on per-face base,
- * diffuse only. Also known as 'faceted shading'.
- */
- aiShadingMode_Flat = 0x1,
-
- /** Simple Gouraud shading.
- */
- aiShadingMode_Gouraud = 0x2,
-
- /** Phong-Shading -
- */
- aiShadingMode_Phong = 0x3,
-
- /** Phong-Blinn-Shading
- */
- aiShadingMode_Blinn = 0x4,
-
- /** Toon-Shading per pixel
- *
- * Also known as 'comic' shader.
- */
- aiShadingMode_Toon = 0x5,
-
- /** OrenNayar-Shading per pixel
- *
- * Extension to standard Lambertian shading, taking the
- * roughness of the material into account
- */
- aiShadingMode_OrenNayar = 0x6,
-
- /** Minnaert-Shading per pixel
- *
- * Extension to standard Lambertian shading, taking the
- * "darkness" of the material into account
- */
- aiShadingMode_Minnaert = 0x7,
-
- /** CookTorrance-Shading per pixel
- *
- * Special shader for metallic surfaces.
- */
- aiShadingMode_CookTorrance = 0x8,
-
- /** No shading at all. Constant light influence of 1.0.
- */
- aiShadingMode_NoShading = 0x9,
-
- /** Fresnel shading
- */
- aiShadingMode_Fresnel = 0xa,
-
-
-#ifndef SWIG
- _aiShadingMode_Force32Bit = INT_MAX
-#endif
-};
-
-
-// ---------------------------------------------------------------------------
-/** @brief Defines some mixed flags for a particular texture.
- *
- * Usually you'll instruct your cg artists how textures have to look like ...
- * and how they will be processed in your application. However, if you use
- * Assimp for completely generic loading purposes you might also need to
- * process these flags in order to display as many 'unknown' 3D models as
- * possible correctly.
- *
- * This corresponds to the #AI_MATKEY_TEXFLAGS property.
-*/
-enum aiTextureFlags
-{
- /** The texture's color values have to be inverted (componentwise 1-n)
- */
- aiTextureFlags_Invert = 0x1,
-
- /** Explicit request to the application to process the alpha channel
- * of the texture.
- *
- * Mutually exclusive with #aiTextureFlags_IgnoreAlpha. These
- * flags are set if the library can say for sure that the alpha
- * channel is used/is not used. If the model format does not
- * define this, it is left to the application to decide whether
- * the texture alpha channel - if any - is evaluated or not.
- */
- aiTextureFlags_UseAlpha = 0x2,
-
- /** Explicit request to the application to ignore the alpha channel
- * of the texture.
- *
- * Mutually exclusive with #aiTextureFlags_UseAlpha.
- */
- aiTextureFlags_IgnoreAlpha = 0x4,
-
-#ifndef SWIG
- _aiTextureFlags_Force32Bit = INT_MAX
-#endif
-};
-
-
-// ---------------------------------------------------------------------------
-/** @brief Defines alpha-blend flags.
- *
- * If you're familiar with OpenGL or D3D, these flags aren't new to you.
- * They define *how* the final color value of a pixel is computed, basing
- * on the previous color at that pixel and the new color value from the
- * material.
- * The blend formula is:
- * @code
- * SourceColor * SourceBlend + DestColor * DestBlend
- * @endcode
- * where DestColor is the previous color in the framebuffer at this
- * position and SourceColor is the material color before the transparency
- * calculation.<br>
- * This corresponds to the #AI_MATKEY_BLEND_FUNC property.
-*/
-enum aiBlendMode
-{
- /**
- * Formula:
- * @code
- * SourceColor*SourceAlpha + DestColor*(1-SourceAlpha)
- * @endcode
- */
- aiBlendMode_Default = 0x0,
-
- /** Additive blending
- *
- * Formula:
- * @code
- * SourceColor*1 + DestColor*1
- * @endcode
- */
- aiBlendMode_Additive = 0x1,
-
- // we don't need more for the moment, but we might need them
- // in future versions ...
-
-#ifndef SWIG
- _aiBlendMode_Force32Bit = INT_MAX
-#endif
-};
-
-
-#include "./Compiler/pushpack1.h"
-
-// ---------------------------------------------------------------------------
-/** @brief Defines how an UV channel is transformed.
- *
- * This is just a helper structure for the #AI_MATKEY_UVTRANSFORM key.
- * See its documentation for more details.
- *
- * Typically you'll want to build a matrix of this information. However,
- * we keep separate scaling/translation/rotation values to make it
- * easier to process and optimize UV transformations internally.
- */
-struct aiUVTransform
-{
- /** Translation on the u and v axes.
- *
- * The default value is (0|0).
- */
- C_STRUCT aiVector2D mTranslation;
-
- /** Scaling on the u and v axes.
- *
- * The default value is (1|1).
- */
- C_STRUCT aiVector2D mScaling;
-
- /** Rotation - in counter-clockwise direction.
- *
- * The rotation angle is specified in radians. The
- * rotation center is 0.5f|0.5f. The default value
- * 0.f.
- */
- ai_real mRotation;
-
-
-#ifdef __cplusplus
- aiUVTransform()
- : mTranslation (0.0,0.0)
- , mScaling (1.0,1.0)
- , mRotation (0.0)
- {
- // nothing to be done here ...
- }
-#endif
-
-} PACK_STRUCT;
-
-#include "./Compiler/poppack1.h"
-
-//! @cond AI_DOX_INCLUDE_INTERNAL
-// ---------------------------------------------------------------------------
-/** @brief A very primitive RTTI system for the contents of material
- * properties.
- */
-enum aiPropertyTypeInfo
-{
- /** Array of single-precision (32 Bit) floats
- *
- * It is possible to use aiGetMaterialInteger[Array]() (or the C++-API
- * aiMaterial::Get()) to query properties stored in floating-point format.
- * The material system performs the type conversion automatically.
- */
- aiPTI_Float = 0x1,
-
- /** Array of double-precision (64 Bit) floats
- *
- * It is possible to use aiGetMaterialInteger[Array]() (or the C++-API
- * aiMaterial::Get()) to query properties stored in floating-point format.
- * The material system performs the type conversion automatically.
- */
- aiPTI_Double = 0x2,
-
- /** The material property is an aiString.
- *
- * Arrays of strings aren't possible, aiGetMaterialString() (or the
- * C++-API aiMaterial::Get()) *must* be used to query a string property.
- */
- aiPTI_String = 0x3,
-
- /** Array of (32 Bit) integers
- *
- * It is possible to use aiGetMaterialFloat[Array]() (or the C++-API
- * aiMaterial::Get()) to query properties stored in integer format.
- * The material system performs the type conversion automatically.
- */
- aiPTI_Integer = 0x4,
-
-
- /** Simple binary buffer, content undefined. Not convertible to anything.
- */
- aiPTI_Buffer = 0x5,
-
-
- /** This value is not used. It is just there to force the
- * compiler to map this enum to a 32 Bit integer.
- */
-#ifndef SWIG
- _aiPTI_Force32Bit = INT_MAX
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Data structure for a single material property
- *
- * As an user, you'll probably never need to deal with this data structure.
- * Just use the provided aiGetMaterialXXX() or aiMaterial::Get() family
- * of functions to query material properties easily. Processing them
- * manually is faster, but it is not the recommended way. It isn't worth
- * the effort. <br>
- * Material property names follow a simple scheme:
- * @code
- * $<name>
- * ?<name>
- * A public property, there must be corresponding AI_MATKEY_XXX define
- * 2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials
- * post-processing step.
- * ~<name>
- * A temporary property for internal use.
- * @endcode
- * @see aiMaterial
- */
-struct aiMaterialProperty
-{
- /** Specifies the name of the property (key)
- * Keys are generally case insensitive.
- */
- C_STRUCT aiString mKey;
-
- /** Textures: Specifies their exact usage semantic.
- * For non-texture properties, this member is always 0
- * (or, better-said, #aiTextureType_NONE).
- */
- unsigned int mSemantic;
-
- /** Textures: Specifies the index of the texture.
- * For non-texture properties, this member is always 0.
- */
- unsigned int mIndex;
-
- /** Size of the buffer mData is pointing to, in bytes.
- * This value may not be 0.
- */
- unsigned int mDataLength;
-
- /** Type information for the property.
- *
- * Defines the data layout inside the data buffer. This is used
- * by the library internally to perform debug checks and to
- * utilize proper type conversions.
- * (It's probably a hacky solution, but it works.)
- */
- C_ENUM aiPropertyTypeInfo mType;
-
- /** Binary buffer to hold the property's value.
- * The size of the buffer is always mDataLength.
- */
- char* mData;
-
-#ifdef __cplusplus
-
- aiMaterialProperty()
- : mSemantic( 0 )
- , mIndex( 0 )
- , mDataLength( 0 )
- , mType( aiPTI_Float )
- , mData( NULL )
- {
- }
-
- ~aiMaterialProperty() {
- delete[] mData;
- }
-
-#endif
-};
-//! @endcond
-
-#ifdef __cplusplus
-} // We need to leave the "C" block here to allow template member functions
-#endif
-
-// ---------------------------------------------------------------------------
-/** @brief Data structure for a material
-*
-* Material data is stored using a key-value structure. A single key-value
-* pair is called a 'material property'. C++ users should use the provided
-* member functions of aiMaterial to process material properties, C users
-* 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
-
-public:
-
- aiMaterial();
- ~aiMaterial();
-
- // -------------------------------------------------------------------
- /** @brief Retrieve an array of Type values with a specific key
- * from the material
- *
- * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
- * @param type .. set by AI_MATKEY_XXX
- * @param idx .. set by AI_MATKEY_XXX
- * @param pOut Pointer to a buffer to receive the result.
- * @param pMax Specifies the size of the given buffer, in Type's.
- * Receives the number of values (not bytes!) read.
- * NULL is a valid value for this parameter.
- */
- template <typename Type>
- 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, ai_real* pOut, unsigned int* pMax) const;
-
- // -------------------------------------------------------------------
- /** @brief Retrieve a Type value with a specific key
- * from the material
- *
- * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
- * @param type Specifies the type of the texture to be retrieved (
- * e.g. diffuse, specular, height map ...)
- * @param idx Index of the texture to be retrieved.
- * @param pOut Reference to receive the output value
- */
- template <typename Type>
- 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, ai_real& 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
- * @return Number of textures for this type.
- * @note A texture can be easily queried using #GetTexture() */
- unsigned int GetTextureCount(aiTextureType type) const;
-
- // -------------------------------------------------------------------
- /** Helper function to get all parameters pertaining to a
- * particular texture slot from a material.
- *
- * This function is provided just for convenience, you could also
- * read the single material properties manually.
- * @param type Specifies the type of the texture to be retrieved (
- * e.g. diffuse, specular, height map ...)
- * @param index Index of the texture to be retrieved. The function fails
- * if there is no texture of that type with this index.
- * #GetTextureCount() can be used to determine the number of textures
- * per texture type.
- * @param path Receives the path to the texture.
- * If the texture is embedded, receives a '*' followed by the id of
- * the texture (for the textures stored in the corresponding scene) which
- * can be converted to an int using a function like atoi.
- * NULL is a valid value.
- * @param mapping The texture mapping.
- * NULL is allowed as value.
- * @param uvindex Receives the UV index of the texture.
- * NULL is a valid value.
- * @param blend Receives the blend factor for the texture
- * NULL is a valid value.
- * @param op Receives the texture operation to be performed between
- * this texture and the previous texture. NULL is allowed as value.
- * @param mapmode Receives the mapping modes to be used for the texture.
- * The parameter may be NULL but if it is a valid pointer it MUST
- * point to an array of 3 aiTextureMapMode's (one for each
- * axis: UVW order (=XYZ)).
- */
- // -------------------------------------------------------------------
- aiReturn GetTexture(aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* mapping = NULL,
- unsigned int* uvindex = NULL,
- ai_real* blend = NULL,
- aiTextureOp* op = NULL,
- aiTextureMapMode* mapmode = NULL) const;
-
-
- // Setters
-
-
- // ------------------------------------------------------------------------------
- /** @brief Add a property with a given key and type info to the material
- * structure
- *
- * @param pInput Pointer to input data
- * @param pSizeInBytes Size of input data
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro
- * @param pType Type information hint */
- aiReturn AddBinaryProperty (const void* pInput,
- unsigned int pSizeInBytes,
- const char* pKey,
- unsigned int type ,
- unsigned int index ,
- aiPropertyTypeInfo pType);
-
- // ------------------------------------------------------------------------------
- /** @brief Add a string property with a given key and type info to the
- * material structure
- *
- * @param pInput Input string
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro */
- aiReturn AddProperty (const aiString* pInput,
- const char* pKey,
- unsigned int type = 0,
- unsigned int index = 0);
-
- // ------------------------------------------------------------------------------
- /** @brief Add a property with a given key to the material structure
- * @param pInput Pointer to the input data
- * @param pNumValues Number of values in the array
- * @param pKey Key/Usage of the property (AI_MATKEY_XXX)
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro */
- template<class TYPE>
- aiReturn AddProperty (const TYPE* pInput,
- unsigned int pNumValues,
- const char* pKey,
- 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 double* 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.
- *
- * The function fails if the key isn't found
- * @param pKey Key to be deleted
- * @param type Set by the AI_MATKEY_XXX macro
- * @param index Set by the AI_MATKEY_XXX macro */
- aiReturn RemoveProperty (const char* pKey,
- unsigned int type = 0,
- unsigned int index = 0);
-
- // ------------------------------------------------------------------------------
- /** @brief Removes all properties from the material.
- *
- * The data array remains allocated so adding new properties is quite fast. */
- void Clear();
-
- // ------------------------------------------------------------------------------
- /** Copy the property list of a material
- * @param pcDest Destination material
- * @param pcSrc Source material
- */
- static void CopyPropertyList(aiMaterial* pcDest,
- const aiMaterial* pcSrc);
-
-
-#endif
-
- /** List of all material properties loaded. */
- C_STRUCT aiMaterialProperty** mProperties;
-
- /** Number of properties in the data base */
- unsigned int mNumProperties;
-
- /** Storage allocated */
- unsigned int mNumAllocated;
-};
-
-// Go back to extern "C" again
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_NAME "?mat.name",0,0
-#define AI_MATKEY_TWOSIDED "$mat.twosided",0,0
-#define AI_MATKEY_SHADING_MODEL "$mat.shadingm",0,0
-#define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0
-#define AI_MATKEY_BLEND_FUNC "$mat.blend",0,0
-#define AI_MATKEY_OPACITY "$mat.opacity",0,0
-#define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0
-#define AI_MATKEY_SHININESS "$mat.shininess",0,0
-#define AI_MATKEY_REFLECTIVITY "$mat.reflectivity",0,0
-#define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent",0,0
-#define AI_MATKEY_REFRACTI "$mat.refracti",0,0
-#define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse",0,0
-#define AI_MATKEY_COLOR_AMBIENT "$clr.ambient",0,0
-#define AI_MATKEY_COLOR_SPECULAR "$clr.specular",0,0
-#define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive",0,0
-#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0
-#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0
-#define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0
-
-// ---------------------------------------------------------------------------
-// Pure key names for all texture-related properties
-//! @cond MATS_DOC_FULL
-#define _AI_MATKEY_TEXTURE_BASE "$tex.file"
-#define _AI_MATKEY_UVWSRC_BASE "$tex.uvwsrc"
-#define _AI_MATKEY_TEXOP_BASE "$tex.op"
-#define _AI_MATKEY_MAPPING_BASE "$tex.mapping"
-#define _AI_MATKEY_TEXBLEND_BASE "$tex.blend"
-#define _AI_MATKEY_MAPPINGMODE_U_BASE "$tex.mapmodeu"
-#define _AI_MATKEY_MAPPINGMODE_V_BASE "$tex.mapmodev"
-#define _AI_MATKEY_TEXMAP_AXIS_BASE "$tex.mapaxis"
-#define _AI_MATKEY_UVTRANSFORM_BASE "$tex.uvtrafo"
-#define _AI_MATKEY_TEXFLAGS_BASE "$tex.flags"
-//! @endcond
-
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_TEXTURE(type, N) _AI_MATKEY_TEXTURE_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_TEXTURE_DIFFUSE(N) \
- AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_TEXTURE_SPECULAR(N) \
- AI_MATKEY_TEXTURE(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_TEXTURE_AMBIENT(N) \
- AI_MATKEY_TEXTURE(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_TEXTURE_EMISSIVE(N) \
- AI_MATKEY_TEXTURE(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_TEXTURE_NORMALS(N) \
- AI_MATKEY_TEXTURE(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_TEXTURE_HEIGHT(N) \
- AI_MATKEY_TEXTURE(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_TEXTURE_SHININESS(N) \
- AI_MATKEY_TEXTURE(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_TEXTURE_OPACITY(N) \
- AI_MATKEY_TEXTURE(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_TEXTURE_DISPLACEMENT(N) \
- AI_MATKEY_TEXTURE(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_TEXTURE_LIGHTMAP(N) \
- AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_TEXTURE_REFLECTION(N) \
- AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,N)
-
-//! @endcond
-
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_UVWSRC(type, N) _AI_MATKEY_UVWSRC_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_UVWSRC_DIFFUSE(N) \
- AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_UVWSRC_SPECULAR(N) \
- AI_MATKEY_UVWSRC(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_UVWSRC_AMBIENT(N) \
- AI_MATKEY_UVWSRC(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_UVWSRC_EMISSIVE(N) \
- AI_MATKEY_UVWSRC(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_UVWSRC_NORMALS(N) \
- AI_MATKEY_UVWSRC(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_UVWSRC_HEIGHT(N) \
- AI_MATKEY_UVWSRC(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_UVWSRC_SHININESS(N) \
- AI_MATKEY_UVWSRC(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_UVWSRC_OPACITY(N) \
- AI_MATKEY_UVWSRC(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_UVWSRC_DISPLACEMENT(N) \
- AI_MATKEY_UVWSRC(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_UVWSRC_LIGHTMAP(N) \
- AI_MATKEY_UVWSRC(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_UVWSRC_REFLECTION(N) \
- AI_MATKEY_UVWSRC(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_TEXOP(type, N) _AI_MATKEY_TEXOP_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_TEXOP_DIFFUSE(N) \
- AI_MATKEY_TEXOP(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_TEXOP_SPECULAR(N) \
- AI_MATKEY_TEXOP(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_TEXOP_AMBIENT(N) \
- AI_MATKEY_TEXOP(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_TEXOP_EMISSIVE(N) \
- AI_MATKEY_TEXOP(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_TEXOP_NORMALS(N) \
- AI_MATKEY_TEXOP(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_TEXOP_HEIGHT(N) \
- AI_MATKEY_TEXOP(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_TEXOP_SHININESS(N) \
- AI_MATKEY_TEXOP(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_TEXOP_OPACITY(N) \
- AI_MATKEY_TEXOP(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_TEXOP_DISPLACEMENT(N) \
- AI_MATKEY_TEXOP(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_TEXOP_LIGHTMAP(N) \
- AI_MATKEY_TEXOP(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_TEXOP_REFLECTION(N) \
- AI_MATKEY_TEXOP(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_MAPPING(type, N) _AI_MATKEY_MAPPING_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_MAPPING_DIFFUSE(N) \
- AI_MATKEY_MAPPING(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_MAPPING_SPECULAR(N) \
- AI_MATKEY_MAPPING(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_MAPPING_AMBIENT(N) \
- AI_MATKEY_MAPPING(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_MAPPING_EMISSIVE(N) \
- AI_MATKEY_MAPPING(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_MAPPING_NORMALS(N) \
- AI_MATKEY_MAPPING(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_MAPPING_HEIGHT(N) \
- AI_MATKEY_MAPPING(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_MAPPING_SHININESS(N) \
- AI_MATKEY_MAPPING(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_MAPPING_OPACITY(N) \
- AI_MATKEY_MAPPING(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_MAPPING_DISPLACEMENT(N) \
- AI_MATKEY_MAPPING(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_MAPPING_LIGHTMAP(N) \
- AI_MATKEY_MAPPING(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_MAPPING_REFLECTION(N) \
- AI_MATKEY_MAPPING(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_TEXBLEND(type, N) _AI_MATKEY_TEXBLEND_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_TEXBLEND_DIFFUSE(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_TEXBLEND_SPECULAR(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_TEXBLEND_AMBIENT(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_TEXBLEND_EMISSIVE(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_TEXBLEND_NORMALS(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_TEXBLEND_HEIGHT(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_TEXBLEND_SHININESS(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_TEXBLEND_OPACITY(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_TEXBLEND_DISPLACEMENT(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_TEXBLEND_LIGHTMAP(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_TEXBLEND_REFLECTION(N) \
- AI_MATKEY_TEXBLEND(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_MAPPINGMODE_U(type, N) _AI_MATKEY_MAPPINGMODE_U_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_MAPPINGMODE_U_DIFFUSE(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_SPECULAR(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_AMBIENT(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_EMISSIVE(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_NORMALS(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_HEIGHT(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_SHININESS(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_OPACITY(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_DISPLACEMENT(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_MAPPINGMODE_U_REFLECTION(N) \
- AI_MATKEY_MAPPINGMODE_U(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_MAPPINGMODE_V(type, N) _AI_MATKEY_MAPPINGMODE_V_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_MAPPINGMODE_V_DIFFUSE(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_SPECULAR(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_AMBIENT(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_EMISSIVE(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_NORMALS(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_HEIGHT(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_SHININESS(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_OPACITY(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_DISPLACEMENT(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_MAPPINGMODE_V_REFLECTION(N) \
- AI_MATKEY_MAPPINGMODE_V(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_TEXMAP_AXIS(type, N) _AI_MATKEY_TEXMAP_AXIS_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_TEXMAP_AXIS_DIFFUSE(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_SPECULAR(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_AMBIENT(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_EMISSIVE(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_NORMALS(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_HEIGHT(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_SHININESS(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_OPACITY(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_DISPLACEMENT(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_LIGHTMAP(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_TEXMAP_AXIS_REFLECTION(N) \
- AI_MATKEY_TEXMAP_AXIS(aiTextureType_REFLECTION,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_UVTRANSFORM(type, N) _AI_MATKEY_UVTRANSFORM_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_UVTRANSFORM_DIFFUSE(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_UVTRANSFORM_SPECULAR(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_UVTRANSFORM_AMBIENT(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_UVTRANSFORM_EMISSIVE(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_UVTRANSFORM_NORMALS(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_UVTRANSFORM_HEIGHT(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_UVTRANSFORM_SHININESS(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_UVTRANSFORM_OPACITY(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_UVTRANSFORM_DISPLACEMENT(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_UVTRANSFORM_LIGHTMAP(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_UVTRANSFORM_REFLECTION(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_REFLECTION,N)
-
-#define AI_MATKEY_UVTRANSFORM_UNKNOWN(N) \
- AI_MATKEY_UVTRANSFORM(aiTextureType_UNKNOWN,N)
-
-//! @endcond
-// ---------------------------------------------------------------------------
-#define AI_MATKEY_TEXFLAGS(type, N) _AI_MATKEY_TEXFLAGS_BASE,type,N
-
-// For backward compatibility and simplicity
-//! @cond MATS_DOC_FULL
-#define AI_MATKEY_TEXFLAGS_DIFFUSE(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_DIFFUSE,N)
-
-#define AI_MATKEY_TEXFLAGS_SPECULAR(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_SPECULAR,N)
-
-#define AI_MATKEY_TEXFLAGS_AMBIENT(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_AMBIENT,N)
-
-#define AI_MATKEY_TEXFLAGS_EMISSIVE(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_EMISSIVE,N)
-
-#define AI_MATKEY_TEXFLAGS_NORMALS(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_NORMALS,N)
-
-#define AI_MATKEY_TEXFLAGS_HEIGHT(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_HEIGHT,N)
-
-#define AI_MATKEY_TEXFLAGS_SHININESS(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_SHININESS,N)
-
-#define AI_MATKEY_TEXFLAGS_OPACITY(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_OPACITY,N)
-
-#define AI_MATKEY_TEXFLAGS_DISPLACEMENT(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_DISPLACEMENT,N)
-
-#define AI_MATKEY_TEXFLAGS_LIGHTMAP(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_LIGHTMAP,N)
-
-#define AI_MATKEY_TEXFLAGS_REFLECTION(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_REFLECTION,N)
-
-#define AI_MATKEY_TEXFLAGS_UNKNOWN(N) \
- AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N)
-
-//! @endcond
-//!
-// ---------------------------------------------------------------------------
-/** @brief Retrieve a material property with a specific key from the material
- *
- * @param pMat Pointer to the input material. May not be NULL
- * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
- * @param type Specifies the type of the texture to be retrieved (
- * e.g. diffuse, specular, height map ...)
- * @param index Index of the texture to be retrieved.
- * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
- * structure or NULL if the key has not been found. */
-// ---------------------------------------------------------------------------
-ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
- const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- const C_STRUCT aiMaterialProperty** pPropOut);
-
-// ---------------------------------------------------------------------------
-/** @brief Retrieve an array of float values with a specific key
- * from the material
- *
- * Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
- * example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture)
- * @code
- * aiUVTransform trafo;
- * unsigned int max = sizeof(aiUVTransform);
- * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
- * (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
- * {
- * // error handling
- * }
- * @endcode
- *
- * @param pMat Pointer to the input material. May not be NULL
- * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
- * @param pOut Pointer to a buffer to receive the result.
- * @param pMax Specifies the size of the given buffer, in float's.
- * Receives the number of values (not bytes!) read.
- * @param type (see the code sample above)
- * @param index (see the code sample above)
- * @return Specifies whether the key has been found. If not, the output
- * arrays remains unmodified and pMax is set to 0.*/
-// ---------------------------------------------------------------------------
-ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
- const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- ai_real* pOut,
- unsigned int* pMax);
-
-
-#ifdef __cplusplus
-
-// ---------------------------------------------------------------------------
-/** @brief Retrieve a single float property with a specific key from the material.
-*
-* Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
-* example reads the #AI_MATKEY_SHININESS_STRENGTH property of the first diffuse texture)
-* @code
-* float specStrength = 1.f; // default value, remains unmodified if we fail.
-* aiGetMaterialFloat(mat, AI_MATKEY_SHININESS_STRENGTH,
-* (float*)&specStrength);
-* @endcode
-*
-* @param pMat Pointer to the input material. May not be NULL
-* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
-* @param pOut Receives the output float.
-* @param type (see the code sample above)
-* @param index (see the code sample above)
-* @return Specifies whether the key has been found. If not, the output
-* float remains unmodified.*/
-// ---------------------------------------------------------------------------
-inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- ai_real* pOut)
-{
- return aiGetMaterialFloatArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
-}
-
-#else
-
-// Use our friend, the C preprocessor
-#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \
- aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL)
-
-#endif //!__cplusplus
-
-
-// ---------------------------------------------------------------------------
-/** @brief Retrieve an array of integer values with a specific key
- * from a material
- *
- * See the sample for aiGetMaterialFloatArray for more information.*/
-ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- int* pOut,
- unsigned int* pMax);
-
-
-#ifdef __cplusplus
-
-// ---------------------------------------------------------------------------
-/** @brief Retrieve an integer property with a specific key from a material
- *
- * See the sample for aiGetMaterialFloat for more information.*/
-// ---------------------------------------------------------------------------
-inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- int* pOut)
-{
- return aiGetMaterialIntegerArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
-}
-
-#else
-
-// use our friend, the C preprocessor
-#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \
- aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL)
-
-#endif //!__cplusplus
-
-
-
-// ---------------------------------------------------------------------------
-/** @brief Retrieve a color value from the material property table
-*
-* See the sample for aiGetMaterialFloat for more information*/
-// ---------------------------------------------------------------------------
-ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- C_STRUCT aiColor4D* pOut);
-
-
-// ---------------------------------------------------------------------------
-/** @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.*/
-// ---------------------------------------------------------------------------
-ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat,
- const char* pKey,
- unsigned int type,
- unsigned int index,
- C_STRUCT aiString* pOut);
-
-// ---------------------------------------------------------------------------
-/** Get the number of textures for a particular texture type.
- * @param[in] pMat Pointer to the input material. May not be NULL
- * @param type Texture type to check for
- * @return Number of textures for this type.
- * @note A texture can be easily queried using #aiGetMaterialTexture() */
-// ---------------------------------------------------------------------------
-ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
- C_ENUM aiTextureType type);
-
-// ---------------------------------------------------------------------------
-/** @brief Helper function to get all values pertaining to a particular
- * texture slot from a material structure.
- *
- * This function is provided just for convenience. You could also read the
- * texture by parsing all of its properties manually. This function bundles
- * all of them in a huge function monster.
- *
- * @param[in] mat Pointer to the input material. May not be NULL
- * @param[in] type Specifies the texture stack to read from (e.g. diffuse,
- * specular, height map ...).
- * @param[in] index Index of the texture. The function fails if the
- * requested index is not available for this texture type.
- * #aiGetMaterialTextureCount() can be used to determine the number of
- * textures in a particular texture stack.
- * @param[out] path Receives the output path
- * If the texture is embedded, receives a '*' followed by the id of
- * the texture (for the textures stored in the corresponding scene) which
- * can be converted to an int using a function like atoi.
- * This parameter must be non-null.
- * @param mapping The texture mapping mode to be used.
- * Pass NULL if you're not interested in this information.
- * @param[out] uvindex For UV-mapped textures: receives the index of the UV
- * source channel. Unmodified otherwise.
- * Pass NULL if you're not interested in this information.
- * @param[out] blend Receives the blend factor for the texture
- * Pass NULL if you're not interested in this information.
- * @param[out] op Receives the texture blend operation to be perform between
- * this texture and the previous texture.
- * Pass NULL if you're not interested in this information.
- * @param[out] mapmode Receives the mapping modes to be used for the texture.
- * Pass NULL if you're not interested in this information. Otherwise,
- * pass a pointer to an array of two aiTextureMapMode's (one for each
- * axis, UV order).
- * @param[out] flags Receives the the texture flags.
- * @return AI_SUCCESS on success, otherwise something else. Have fun.*/
-// ---------------------------------------------------------------------------
-#ifdef __cplusplus
-ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
- aiTextureType type,
- unsigned int index,
- aiString* path,
- aiTextureMapping* mapping = NULL,
- unsigned int* uvindex = NULL,
- ai_real* blend = NULL,
- aiTextureOp* op = NULL,
- aiTextureMapMode* mapmode = NULL,
- unsigned int* flags = NULL);
-#else
-C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
- C_ENUM aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- C_ENUM aiTextureMapping* mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- ai_real* blend /*= NULL*/,
- C_ENUM aiTextureOp* op /*= NULL*/,
- C_ENUM aiTextureMapMode* mapmode /*= NULL*/,
- unsigned int* flags /*= NULL*/);
-#endif // !#ifdef __cplusplus
-
-#ifdef __cplusplus
-}
-
-#include "material.inl"
-
-#endif //!__cplusplus
-#endif //!!AI_MATERIAL_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/material.inl b/src/3rdparty/assimp/include/assimp/material.inl
deleted file mode 100644
index 2c31fd571..000000000
--- a/src/3rdparty/assimp/include/assimp/material.inl
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 material.inl
- * @brief Defines the C++ getters for the material system
- */
-
-#pragma once
-#ifndef AI_MATERIAL_INL_INC
-#define AI_MATERIAL_INL_INC
-
-// ---------------------------------------------------------------------------
-inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
-{
- return aiPTI_Float;
-}
-
-inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
-{
- return aiPTI_Double;
-}
-// ---------------------------------------------------------------------------
-
-//! @cond never
-
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::GetTexture( aiTextureType type,
- unsigned int index,
- C_STRUCT aiString* path,
- aiTextureMapping* mapping /*= NULL*/,
- unsigned int* uvindex /*= NULL*/,
- ai_real* blend /*= NULL*/,
- aiTextureOp* op /*= NULL*/,
- aiTextureMapMode* mapmode /*= NULL*/) const
-{
- return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode);
-}
-
-// ---------------------------------------------------------------------------
-inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const
-{
- return ::aiGetMaterialTextureCount(this,type);
-}
-
-// ---------------------------------------------------------------------------
-template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx, Type* pOut,
- unsigned int* pMax) const
-{
- unsigned int iNum = pMax ? *pMax : 1;
-
- const aiMaterialProperty* prop;
- const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
- (const aiMaterialProperty**)&prop);
- if ( AI_SUCCESS == ret ) {
-
- if (prop->mDataLength < sizeof(Type)*iNum) {
- return AI_FAILURE;
- }
-
- if (prop->mType != aiPTI_Buffer) {
- return AI_FAILURE;
- }
-
- iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type));
- ::memcpy(pOut,prop->mData,iNum * sizeof(Type));
- if (pMax) {
- *pMax = iNum;
- }
- }
- return ret;
-}
-
-// ---------------------------------------------------------------------------
-template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,Type& pOut) const
-{
- const aiMaterialProperty* prop;
- const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
- (const aiMaterialProperty**)&prop);
- if ( AI_SUCCESS == ret ) {
-
- if (prop->mDataLength < sizeof(Type)) {
- return AI_FAILURE;
- }
-
- if (prop->mType != aiPTI_Buffer) {
- return AI_FAILURE;
- }
-
- ::memcpy(&pOut,prop->mData,sizeof(Type));
- }
- return ret;
-}
-
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real* pOut,
- unsigned int* pMax) const
-{
- return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
-}
-// ---------------------------------------------------------------------------
-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);
-}
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,ai_real& pOut) const
-{
- return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
-}
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,int& pOut) const
-{
- return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
-}
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor4D& pOut) const
-{
- return aiGetMaterialColor(this,pKey,type,idx,&pOut);
-}
-// ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
- unsigned int idx,aiColor3D& pOut) const
-{
- aiColor4D c;
- const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
- pOut = aiColor3D(c.r,c.g,c.b);
- return ret;
-}
-// ---------------------------------------------------------------------------
-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);
-}
-
-
-// ---------------------------------------------------------------------------
-template<class TYPE>
-aiReturn aiMaterial::AddProperty (const TYPE* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(TYPE),
- pKey,type,index,aiPTI_Buffer);
-}
-
-// ---------------------------------------------------------------------------
-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 double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(double),
- pKey,type,index,aiPTI_Double);
-}
-
-// ---------------------------------------------------------------------------
-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,ai_real_to_property_type_info(pInput->mRotation));
-}
-
-// ---------------------------------------------------------------------------
-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,ai_real_to_property_type_info(pInput->a));
-}
-
-// ---------------------------------------------------------------------------
-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,ai_real_to_property_type_info(pInput->b));
-}
-
-// ---------------------------------------------------------------------------
-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,ai_real_to_property_type_info(pInput->x));
-}
-
-// ---------------------------------------------------------------------------
-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,
- 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);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
- const unsigned int pNumValues,
- const char* pKey,
- unsigned int type,
- unsigned int index)
-{
- return AddBinaryProperty((const void*)pInput,
- pNumValues * sizeof(double),
- pKey,type,index,aiPTI_Double);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<aiUVTransform>(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);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<aiColor4D>(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);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<aiColor3D>(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);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<aiVector3D>(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);
-}
-
-// ---------------------------------------------------------------------------
-template<>
-inline aiReturn aiMaterial::AddProperty<int>(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);
-}
-
-//! @endcond
-
-#endif //! AI_MATERIAL_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/matrix3x3.h b/src/3rdparty/assimp/include/assimp/matrix3x3.h
deleted file mode 100644
index 3cf575e38..000000000
--- a/src/3rdparty/assimp/include/assimp/matrix3x3.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 matrix3x3.h
- * @brief Definition of a 3x3 matrix, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_MATRIX3X3_H_INC
-#define AI_MATRIX3X3_H_INC
-
-#include "defs.h"
-
-#ifdef __cplusplus
-
-template <typename T> class aiMatrix4x4t;
-template <typename T> class aiVector2t;
-
-// ---------------------------------------------------------------------------
-/** @brief Represents a row-major 3x3 matrix
- *
- * There's much confusion about matrix layouts (column vs. row order).
- * This is *always* a row-major matrix. Not even with the
- * #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
- * matrix order - it just affects the handedness of the coordinate system
- * defined thereby.
- */
-template <typename TReal>
-class aiMatrix3x3t
-{
-public:
-
- aiMatrix3x3t () :
- a1(static_cast<TReal>(1.0f)), a2(), a3(),
- b1(), b2(static_cast<TReal>(1.0f)), b3(),
- c1(), c2(), c3(static_cast<TReal>(1.0f)) {}
-
- aiMatrix3x3t ( TReal _a1, TReal _a2, TReal _a3,
- TReal _b1, TReal _b2, TReal _b3,
- TReal _c1, TReal _c2, TReal _c3) :
- a1(_a1), a2(_a2), a3(_a3),
- b1(_b1), b2(_b2), b3(_b3),
- c1(_c1), c2(_c2), c3(_c3)
- {}
-
-public:
-
- // matrix multiplication.
- aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
- aiMatrix3x3t operator * (const aiMatrix3x3t& m) const;
-
- // array access operators
- TReal* operator[] (unsigned int p_iIndex);
- 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 Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon = 1e-6) const;
-
- template <typename TOther>
- operator aiMatrix3x3t<TOther> () const;
-
-public:
-
- // -------------------------------------------------------------------
- /** @brief Construction from a 4x4 matrix. The remaining parts
- * of the matrix are ignored.
- */
- explicit aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix);
-
- // -------------------------------------------------------------------
- /** @brief Transpose the matrix
- */
- aiMatrix3x3t& Transpose();
-
- // -------------------------------------------------------------------
- /** @brief Invert the matrix.
- * If the matrix is not invertible all elements are set to qnan.
- * Beware, use (f != f) to check whether a TReal f is qnan.
- */
- aiMatrix3x3t& Inverse();
- TReal Determinant() const;
-
-public:
- // -------------------------------------------------------------------
- /** @brief Returns a rotation matrix for a rotation around z
- * @param a Rotation angle, in radians
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix3x3t& RotationZ(TReal a, aiMatrix3x3t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a rotation matrix for a rotation around
- * an arbitrary axis.
- *
- * @param a Rotation angle, in radians
- * @param axis Axis to rotate around
- * @param out To be filled
- */
- static aiMatrix3x3t& Rotation( TReal a,
- const aiVector3t<TReal>& axis, aiMatrix3x3t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a translation matrix
- * @param v Translation vector
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix3x3t& Translation( const aiVector2t<TReal>& v, aiMatrix3x3t& out);
-
- // -------------------------------------------------------------------
- /** @brief A function for creating a rotation matrix that rotates a
- * vector called "from" into another vector called "to".
- * Input : from[3], to[3] which both must be *normalized* non-zero vectors
- * Output: mtx[3][3] -- a 3x3 matrix in column-major form
- * Authors: Tomas Möller, John Hughes
- * "Efficiently Building a Matrix to Rotate One Vector to Another"
- * Journal of Graphics Tools, 4(4):1-4, 1999
- */
- static aiMatrix3x3t& FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix3x3t& out);
-
-public:
- TReal a1, a2, a3;
- TReal b1, b2, b3;
- TReal c1, c2, c3;
-};
-
-typedef aiMatrix3x3t<ai_real> aiMatrix3x3;
-
-#else
-
-struct aiMatrix3x3 {
- ai_real a1, a2, a3;
- ai_real b1, b2, b3;
- ai_real c1, c2, c3;
-};
-
-#endif // __cplusplus
-
-#endif // AI_MATRIX3X3_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/matrix3x3.inl b/src/3rdparty/assimp/include/assimp/matrix3x3.inl
deleted file mode 100644
index 14f2cd2fc..000000000
--- a/src/3rdparty/assimp/include/assimp/matrix3x3.inl
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 matrix3x3.inl
- * @brief Inline implementation of the 3x3 matrix operators
- */
-#pragma once
-#ifndef AI_MATRIX3X3_INL_INC
-#define AI_MATRIX3X3_INL_INC
-
-#ifdef __cplusplus
-#include "matrix3x3.h"
-
-#include "matrix4x4.h"
-#include <algorithm>
-#include <cmath>
-#include <limits>
-
-// ------------------------------------------------------------------------------------------------
-// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
-template <typename TReal>
-inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
-{
- a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
- b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
- c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
-{
- *this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
- m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
- m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
- m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
- m.a2 * b1 + m.b2 * b2 + m.c2 * b3,
- m.a3 * b1 + m.b3 * b2 + m.c3 * b3,
- m.a1 * c1 + m.b1 * c2 + m.c1 * c3,
- m.a2 * c1 + m.b2 * c2 + m.c2 * c3,
- m.a3 * c1 + m.b3 * c2 + m.c3 * c3);
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-template <typename TOther>
-aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
-{
- return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
- static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
- static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
-{
- aiMatrix3x3t<TReal> temp( *this);
- temp *= m;
- return temp;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
- switch ( p_iIndex ) {
- case 0:
- return &a1;
- case 1:
- return &b1;
- case 2:
- return &c1;
- default:
- break;
- }
- return &a1;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
- switch ( p_iIndex ) {
- case 0:
- return &a1;
- case 1:
- return &b1;
- case 2:
- return &c1;
- default:
- break;
- }
- return &a1;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-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 &&
- c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-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()
-{
- // (TReal&) don't remove, GCC complains cause of packed fields
- std::swap( (TReal&)a2, (TReal&)b1);
- std::swap( (TReal&)a3, (TReal&)c1);
- std::swap( (TReal&)b3, (TReal&)c2);
- return *this;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline TReal aiMatrix3x3t<TReal>::Determinant() const
-{
- return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
-{
- // Compute the reciprocal determinant
- TReal det = Determinant();
- if(det == static_cast<TReal>(0.0))
- {
- // Matrix not invertible. Setting all elements to nan is not really
- // correct in a mathematical sense; but at least qnans are easy to
- // spot. XXX we might throw an exception instead, which would
- // be even much better to spot :/.
- const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
- *this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
-
- return *this;
- }
-
- TReal invdet = static_cast<TReal>(1.0) / det;
-
- aiMatrix3x3t<TReal> res;
- res.a1 = invdet * (b2 * c3 - b3 * c2);
- res.a2 = -invdet * (a2 * c3 - a3 * c2);
- res.a3 = invdet * (a2 * b3 - a3 * b2);
- res.b1 = -invdet * (b1 * c3 - b3 * c1);
- res.b2 = invdet * (a1 * c3 - a3 * c1);
- res.b3 = -invdet * (a1 * b3 - a3 * b1);
- res.c1 = invdet * (b1 * c2 - b2 * c1);
- res.c2 = -invdet * (a1 * c2 - a2 * c1);
- res.c3 = invdet * (a1 * b2 - a2 * b1);
- *this = res;
-
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
-{
- out.a1 = out.b2 = std::cos(a);
- out.b1 = std::sin(a);
- out.a2 = - out.b1;
-
- out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
- out.c3 = 1.f;
-
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-// Returns a rotation matrix for a rotation around an arbitrary axis.
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
-{
- TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
- TReal x = axis.x, y = axis.y, z = axis.z;
-
- // Many thanks to MathWorld and Wikipedia
- out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
- out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
- out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
-
- return out;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
-{
- out = aiMatrix3x3t<TReal>();
- out.a3 = v.x;
- out.b3 = v.y;
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-/** A function for creating a rotation matrix that rotates a vector called
- * "from" into another vector called "to".
- * Input : from[3], to[3] which both must be *normalized* non-zero vectors
- * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
- * Authors: Tomas Möller, John Hughes
- * "Efficiently Building a Matrix to Rotate One Vector to Another"
- * Journal of Graphics Tools, 4(4):1-4, 1999
- */
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
-{
- const TReal e = from * to;
- const TReal f = (e < 0)? -e:e;
-
- if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001)) /* "from" and "to"-vector almost parallel */
- {
- aiVector3D u,v; /* temporary storage vectors */
- aiVector3D x; /* vector most nearly orthogonal to "from" */
-
- x.x = (from.x > 0.0)? from.x : -from.x;
- x.y = (from.y > 0.0)? from.y : -from.y;
- x.z = (from.z > 0.0)? from.z : -from.z;
-
- if (x.x < x.y)
- {
- if (x.x < x.z)
- {
- x.x = static_cast<TReal>(1.0);
- x.y = x.z = static_cast<TReal>(0.0);
- }
- else
- {
- x.z = static_cast<TReal>(1.0);
- x.x = x.y = static_cast<TReal>(0.0);
- }
- }
- else
- {
- if (x.y < x.z)
- {
- x.y = static_cast<TReal>(1.0);
- x.x = x.z = static_cast<TReal>(0.0);
- }
- else
- {
- x.z = static_cast<TReal>(1.0);
- x.x = x.y = static_cast<TReal>(0.0);
- }
- }
-
- u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
- v.x = x.x - to.x; v.y = x.y - to.y; v.z = x.z - to.z;
-
- const TReal c1 = static_cast<TReal>(2.0) / (u * u);
- const TReal c2 = static_cast<TReal>(2.0) / (v * v);
- const TReal c3 = c1 * c2 * (u * v);
-
- for (unsigned int i = 0; i < 3; i++)
- {
- for (unsigned int j = 0; j < 3; j++)
- {
- mtx[i][j] = - c1 * u[i] * u[j] - c2 * v[i] * v[j]
- + c3 * v[i] * u[j];
- }
- mtx[i][i] += static_cast<TReal>(1.0);
- }
- }
- else /* the most common case, unless "from"="to", or "from"=-"to" */
- {
- const aiVector3D v = from ^ to;
- /* ... use this hand optimized version (9 mults less) */
- const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e); /* optimization by Gottfried Chen */
- const TReal hvx = h * v.x;
- const TReal hvz = h * v.z;
- const TReal hvxy = hvx * v.y;
- const TReal hvxz = hvx * v.z;
- const TReal hvyz = hvz * v.y;
- mtx[0][0] = e + hvx * v.x;
- mtx[0][1] = hvxy - v.z;
- mtx[0][2] = hvxz + v.y;
-
- mtx[1][0] = hvxy + v.z;
- mtx[1][1] = e + h * v.y * v.y;
- mtx[1][2] = hvyz - v.x;
-
- mtx[2][0] = hvxz - v.y;
- mtx[2][1] = hvyz + v.x;
- mtx[2][2] = e + hvz * v.z;
- }
- return mtx;
-}
-
-
-#endif // __cplusplus
-#endif // AI_MATRIX3X3_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/matrix4x4.h b/src/3rdparty/assimp/include/assimp/matrix4x4.h
deleted file mode 100644
index 4311fa118..000000000
--- a/src/3rdparty/assimp/include/assimp/matrix4x4.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 matrix4x4.h
- * @brief 4x4 matrix structure, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_MATRIX4X4_H_INC
-#define AI_MATRIX4X4_H_INC
-
-#include "vector3.h"
-#include "defs.h"
-
-#ifdef __cplusplus
-
-template<typename TReal> class aiMatrix3x3t;
-template<typename TReal> class aiQuaterniont;
-
-// ---------------------------------------------------------------------------
-/** @brief Represents a row-major 4x4 matrix, use this for homogeneous
- * coordinates.
- *
- * There's much confusion about matrix layouts (column vs. row order).
- * This is *always* a row-major matrix. Not even with the
- * #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
- * matrix order - it just affects the handedness of the coordinate system
- * defined thereby.
- */
-template<typename TReal>
-class aiMatrix4x4t
-{
-public:
-
- /** set to identity */
- aiMatrix4x4t ();
-
- /** construction from single values */
- 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);
-
-
- /** 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(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation,
- const aiVector3t<TReal>& position);
-
-public:
-
- // array access operators
- /** @fn TReal* operator[] (unsigned int p_iIndex)
- * @param [in] p_iIndex - index of the row.
- * @return pointer to pointed row.
- */
- TReal* operator[] (unsigned int p_iIndex);
-
- /** @fn const TReal* operator[] (unsigned int p_iIndex) const
- * @overload TReal* operator[] (unsigned int p_iIndex)
- */
- const TReal* operator[] (unsigned int p_iIndex) const;
-
- // comparison operators
- 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);
- aiMatrix4x4t operator * (const aiMatrix4x4t& m) const;
- aiMatrix4x4t operator * (const TReal& aFloat) const;
- aiMatrix4x4t operator + (const aiMatrix4x4t& aMatrix) const;
-
- template <typename TOther>
- operator aiMatrix4x4t<TOther> () const;
-
-public:
-
- // -------------------------------------------------------------------
- /** @brief Transpose the matrix */
- aiMatrix4x4t& Transpose();
-
- // -------------------------------------------------------------------
- /** @brief Invert the matrix.
- * If the matrix is not invertible all elements are set to qnan.
- * Beware, use (f != f) to check whether a TReal f is qnan.
- */
- aiMatrix4x4t& Inverse();
- TReal Determinant() const;
-
-
- // -------------------------------------------------------------------
- /** @brief Returns true of the matrix is the identity matrix.
- * The check is performed against a not so small epsilon.
- */
- inline bool IsIdentity() const;
-
- // -------------------------------------------------------------------
- /** @brief Decompose a trafo matrix into its original components
- * @param scaling Receives the output scaling for the x,y,z axes
- * @param rotation Receives the output rotation as a hamilton
- * quaternion
- * @param position Receives the output position for the x,y,z axes
- */
- void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
- aiVector3t<TReal>& position) const;
-
- // -------------------------------------------------------------------
- /** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
- * @brief Decompose a trafo matrix into its original components.
- * Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat
- * @param [out] pScaling - Receives the output scaling for the x,y,z axes.
- * @param [out] pRotation - Receives the output rotation as a Euler angles.
- * @param [out] pPosition - Receives the output position for the x,y,z axes.
- */
- void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const;
-
- // -------------------------------------------------------------------
- /** @fn void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const
- * @brief Decompose a trafo matrix into its original components
- * Thx to good FAQ at http://www.gamedev.ru/code/articles/faq_matrix_quat
- * @param [out] pScaling - Receives the output scaling for the x,y,z axes.
- * @param [out] pRotationAxis - Receives the output rotation axis.
- * @param [out] pRotationAngle - Receives the output rotation angle for @ref pRotationAxis.
- * @param [out] pPosition - Receives the output position for the x,y,z axes.
- */
- void Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle, aiVector3t<TReal>& pPosition) const;
-
- // -------------------------------------------------------------------
- /** @brief Decompose a trafo matrix with no scaling into its
- * original components
- * @param rotation Receives the output rotation as a hamilton
- * quaternion
- * @param position Receives the output position for the x,y,z axes
- */
- void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
- aiVector3t<TReal>& position) const;
-
-
- // -------------------------------------------------------------------
- /** @brief Creates a trafo matrix from a set of euler angles
- * @param x Rotation angle for the x-axis, in radians
- * @param y Rotation angle for the y-axis, in radians
- * @param z Rotation angle for the z-axis, in radians
- */
- aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
- aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
-
-public:
- // -------------------------------------------------------------------
- /** @brief Returns a rotation matrix for a rotation around the x axis
- * @param a Rotation angle, in radians
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& RotationX(TReal a, aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a rotation matrix for a rotation around the y axis
- * @param a Rotation angle, in radians
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& RotationY(TReal a, aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a rotation matrix for a rotation around the z axis
- * @param a Rotation angle, in radians
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& RotationZ(TReal a, aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** Returns a rotation matrix for a rotation around an arbitrary axis.
- * @param a Rotation angle, in radians
- * @param axis Rotation axis, should be a normalized vector.
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
- aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a translation matrix
- * @param v Translation vector
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v,
- aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** @brief Returns a scaling matrix
- * @param v Scaling vector
- * @param out Receives the output matrix
- * @return Reference to the output matrix
- */
- static aiMatrix4x4t& Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
-
- // -------------------------------------------------------------------
- /** @brief A function for creating a rotation matrix that rotates a
- * vector called "from" into another vector called "to".
- * Input : from[3], to[3] which both must be *normalized* non-zero vectors
- * Output: mtx[3][3] -- a 3x3 matrix in column-major form
- * Authors: Tomas Mueller, John Hughes
- * "Efficiently Building a Matrix to Rotate One Vector to Another"
- * Journal of Graphics Tools, 4(4):1-4, 1999
- */
- static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
- const aiVector3t<TReal>& to, aiMatrix4x4t& out);
-
-public:
- TReal a1, a2, a3, a4;
- TReal b1, b2, b3, b4;
- TReal c1, c2, c3, c4;
- TReal d1, d2, d3, d4;
-};
-
-typedef aiMatrix4x4t<ai_real> aiMatrix4x4;
-
-#else
-
-struct aiMatrix4x4 {
- ai_real a1, a2, a3, a4;
- ai_real b1, b2, b3, b4;
- ai_real c1, c2, c3, c4;
- ai_real d1, d2, d3, d4;
-};
-
-
-#endif // __cplusplus
-
-#endif // AI_MATRIX4X4_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/matrix4x4.inl b/src/3rdparty/assimp/include/assimp/matrix4x4.inl
deleted file mode 100644
index b15d50a09..000000000
--- a/src/3rdparty/assimp/include/assimp/matrix4x4.inl
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 matrix4x4.inl
- * @brief Inline implementation of the 4x4 matrix operators
- */
-#pragma once
-#ifndef AI_MATRIX4X4_INL_INC
-#define AI_MATRIX4X4_INL_INC
-
-#ifdef __cplusplus
-
-#include "matrix4x4.h"
-#include "matrix3x3.h"
-#include "quaternion.h"
-
-#include <algorithm>
-#include <limits>
-#include <cmath>
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-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)
-{
-
-}
-
-// ----------------------------------------------------------------------------------------
-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),
- c1(_c1), c2(_c2), c3(_c3), c4(_c4),
- d1(_d1), d2(_d2), d3(_d3), d4(_d4)
-{
-
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-template <typename TOther>
-aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
-{
- return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
- static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
- static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
- static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
-}
-
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
-{
- a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
- b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
- c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
- 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 (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const 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>(
- m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
- m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
- m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
- m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
- m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
- m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
- m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
- m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
- m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
- m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
- m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
- m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
- m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
- m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
- m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
- m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
- return *this;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const
-{
- aiMatrix4x4t<TReal> temp(
- a1 * aFloat,
- a2 * aFloat,
- a3 * aFloat,
- a4 * aFloat,
- b1 * aFloat,
- b2 * aFloat,
- b3 * aFloat,
- b4 * aFloat,
- c1 * aFloat,
- c2 * aFloat,
- c3 * aFloat,
- c4 * aFloat,
- d1 * aFloat,
- d2 * aFloat,
- d3 * aFloat,
- d4 * aFloat);
- return temp;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const
-{
- aiMatrix4x4t<TReal> temp(
- m.a1 + a1,
- m.a2 + a2,
- m.a3 + a3,
- m.a4 + a4,
- m.b1 + b1,
- m.b2 + b2,
- m.b3 + b3,
- m.b4 + b4,
- m.c1 + c1,
- m.c2 + c2,
- m.c3 + c3,
- m.c4 + c4,
- m.d1 + d1,
- m.d2 + d2,
- m.d3 + d3,
- m.d4 + d4);
- return temp;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
-{
- aiMatrix4x4t<TReal> temp( *this);
- temp *= m;
- return temp;
-}
-
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
-{
- // (TReal&) don't remove, GCC complains cause of packed fields
- std::swap( (TReal&)b1, (TReal&)a2);
- std::swap( (TReal&)c1, (TReal&)a3);
- std::swap( (TReal&)c2, (TReal&)b3);
- std::swap( (TReal&)d1, (TReal&)a4);
- std::swap( (TReal&)d2, (TReal&)b4);
- std::swap( (TReal&)d3, (TReal&)c4);
- return *this;
-}
-
-
-// ----------------------------------------------------------------------------------------
-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
- + 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;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
-{
- // Compute the reciprocal determinant
- const TReal det = Determinant();
- 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
- // programmer.
- const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
- *this = aiMatrix4x4t<TReal>(
- nan,nan,nan,nan,
- nan,nan,nan,nan,
- nan,nan,nan,nan,
- nan,nan,nan,nan);
-
- return *this;
- }
-
- const TReal invdet = static_cast<TReal>(1.0) / det;
-
- aiMatrix4x4t<TReal> res;
- res.a1 = invdet * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
- res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
- res.a3 = invdet * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
- res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
- res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
- res.b2 = invdet * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
- res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
- res.b4 = invdet * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
- res.c1 = invdet * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
- res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
- res.c3 = invdet * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
- res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
- 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));
- *this = res;
-
- return *this;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
- if (p_iIndex > 3) {
- return NULL;
- }
- switch ( p_iIndex ) {
- case 0:
- return &a1;
- case 1:
- return &b1;
- case 2:
- return &c1;
- case 3:
- return &d1;
- default:
- break;
- }
- return &a1;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
- if (p_iIndex > 3) {
- return NULL;
- }
-
- switch ( p_iIndex ) {
- case 0:
- return &a1;
- case 1:
- return &b1;
- case 2:
- return &c1;
- case 3:
- return &d1;
- default:
- break;
- }
- return &a1;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-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 &&
- c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
- d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-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;
-}
-
-// ----------------------------------------------------------------------------------------
-
-#define ASSIMP_MATRIX4_4_DECOMPOSE_PART \
- const aiMatrix4x4t<TReal>& _this = *this;/* Create alias for conveniance. */ \
- \
- /* extract translation */ \
- pPosition.x = _this[0][3]; \
- pPosition.y = _this[1][3]; \
- pPosition.z = _this[2][3]; \
- \
- /* extract the columns of the matrix. */ \
- aiVector3t<TReal> vCols[3] = { \
- aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]), \
- aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]), \
- aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2]) \
- }; \
- \
- /* extract the scaling factors */ \
- pScaling.x = vCols[0].Length(); \
- pScaling.y = vCols[1].Length(); \
- pScaling.z = vCols[2].Length(); \
- \
- /* and the sign of the scaling */ \
- if (Determinant() < 0) pScaling = -pScaling; \
- \
- /* and remove all scaling from the matrix */ \
- if(pScaling.x) vCols[0] /= pScaling.x; \
- if(pScaling.y) vCols[1] /= pScaling.y; \
- if(pScaling.z) vCols[2] /= pScaling.z; \
- \
- do {} while(false)
-
-
-
-
-template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
- aiVector3t<TReal>& pPosition) const
-{
- ASSIMP_MATRIX4_4_DECOMPOSE_PART;
-
- // build a 3x3 rotation matrix
- aiMatrix3x3t<TReal> m(vCols[0].x,vCols[1].x,vCols[2].x,
- vCols[0].y,vCols[1].y,vCols[2].y,
- vCols[0].z,vCols[1].z,vCols[2].z);
-
- // and generate the rotation quaternion from it
- pRotation = aiQuaterniont<TReal>(m);
-}
-
-template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
-{
- ASSIMP_MATRIX4_4_DECOMPOSE_PART;
-
- /*
- | CE -CF D 0 |
- M = | BDE+AF -BDF+AE -BC 0 |
- | -ADE+BF -ADF+BE AC 0 |
- | 0 0 0 1 |
-
- A = cos(angle_x), B = sin(angle_x);
- C = cos(angle_y), D = sin(angle_y);
- E = cos(angle_z), F = sin(angle_z);
- */
-
- // Use a small epsilon to solve floating-point inaccuracies
- const TReal epsilon = 10e-3f;
-
- pRotation.y = std::asin(vCols[2].x);// D. Angle around oY.
-
- TReal C = std::cos(pRotation.y);
-
- if(std::fabs(C) > epsilon)
- {
- // Finding angle around oX.
- TReal tan_x = vCols[2].z / C;// A
- TReal tan_y = -vCols[2].y / C;// B
-
- pRotation.x = std::atan2(tan_y, tan_x);
- // Finding angle around oZ.
- tan_x = vCols[0].x / C;// E
- tan_y = -vCols[1].x / C;// F
- pRotation.z = std::atan2(tan_y, tan_x);
- }
- else
- {// oY is fixed.
- pRotation.x = 0;// Set angle around oX to 0. => A == 1, B == 0, C == 0, D == 1.
-
- // And finding angle around oZ.
- TReal tan_x = vCols[1].y;// -BDF+AE => E
- TReal tan_y = vCols[0].y;// BDE+AF => F
-
- pRotation.z = std::atan2(tan_y, tan_x);
- }
-}
-
-#undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
-
-template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
- aiVector3t<TReal>& pPosition) const
-{
-aiQuaterniont<TReal> pRotation;
-
- Decompose(pScaling, pRotation, pPosition);
- pRotation.Normalize();
-
- TReal angle_cos = pRotation.w;
- TReal angle_sin = std::sqrt(1.0f - angle_cos * angle_cos);
-
- pRotationAngle = std::acos(angle_cos) * 2;
-
- // Use a small epsilon to solve floating-point inaccuracies
- const TReal epsilon = 10e-3f;
-
- if(std::fabs(angle_sin) < epsilon) angle_sin = 1;
-
- pRotationAxis.x = pRotation.x / angle_sin;
- pRotationAxis.y = pRotation.y / angle_sin;
- pRotationAxis.z = pRotation.z / angle_sin;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
- aiVector3t<TReal>& position) const
-{
- const aiMatrix4x4t<TReal>& _this = *this;
-
- // extract translation
- position.x = _this[0][3];
- position.y = _this[1][3];
- position.z = _this[2][3];
-
- // extract rotation
- rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
-{
- return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
-{
- aiMatrix4x4t<TReal>& _this = *this;
-
- TReal cr = std::cos( x );
- TReal sr = std::sin( x );
- TReal cp = std::cos( y );
- TReal sp = std::sin( y );
- TReal cy = std::cos( z );
- TReal sy = std::sin( z );
-
- _this.a1 = cp*cy ;
- _this.a2 = cp*sy;
- _this.a3 = -sp ;
-
- TReal srsp = sr*sp;
- TReal crsp = cr*sp;
-
- _this.b1 = srsp*cy-cr*sy ;
- _this.b2 = srsp*sy+cr*cy ;
- _this.b3 = sr*cp ;
-
- _this.c1 = crsp*cy+sr*sy ;
- _this.c2 = crsp*sy-sr*cy ;
- _this.c3 = cr*cp ;
-
- return *this;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::IsIdentity() const
-{
- // Use a small epsilon to solve floating-point inaccuracies
- const static TReal epsilon = 10e-3f;
-
- return (a2 <= epsilon && a2 >= -epsilon &&
- a3 <= epsilon && a3 >= -epsilon &&
- a4 <= epsilon && a4 >= -epsilon &&
- b1 <= epsilon && b1 >= -epsilon &&
- b3 <= epsilon && b3 >= -epsilon &&
- b4 <= epsilon && b4 >= -epsilon &&
- c1 <= epsilon && c1 >= -epsilon &&
- c2 <= epsilon && c2 >= -epsilon &&
- c4 <= epsilon && c4 >= -epsilon &&
- 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 &&
- d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
-{
- /*
- | 1 0 0 0 |
- M = | 0 cos(A) -sin(A) 0 |
- | 0 sin(A) cos(A) 0 |
- | 0 0 0 1 | */
- out = aiMatrix4x4t<TReal>();
- out.b2 = out.c3 = std::cos(a);
- out.b3 = -(out.c2 = std::sin(a));
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
-{
- /*
- | cos(A) 0 sin(A) 0 |
- M = | 0 1 0 0 |
- | -sin(A) 0 cos(A) 0 |
- | 0 0 0 1 |
- */
- out = aiMatrix4x4t<TReal>();
- out.a1 = out.c3 = std::cos(a);
- out.c1 = -(out.a3 = std::sin(a));
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
-{
- /*
- | cos(A) -sin(A) 0 0 |
- M = | sin(A) cos(A) 0 0 |
- | 0 0 1 0 |
- | 0 0 0 1 | */
- out = aiMatrix4x4t<TReal>();
- out.a1 = out.b2 = std::cos(a);
- out.a2 = -(out.b1 = std::sin(a));
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-// Returns a rotation matrix for a rotation around an arbitrary axis.
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
-{
- TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
- TReal x = axis.x, y = axis.y, z = axis.z;
-
- // Many thanks to MathWorld and Wikipedia
- out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
- out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
- out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
- out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
- out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
- out.d4 = static_cast<TReal>(1.0);
-
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
- out = aiMatrix4x4t<TReal>();
- out.a4 = v.x;
- out.b4 = v.y;
- out.c4 = v.z;
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
- out = aiMatrix4x4t<TReal>();
- out.a1 = v.x;
- out.b2 = v.y;
- out.c3 = v.z;
- return out;
-}
-
-// ----------------------------------------------------------------------------------------
-/** A function for creating a rotation matrix that rotates a vector called
- * "from" into another vector called "to".
- * Input : from[3], to[3] which both must be *normalized* non-zero vectors
- * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
- * Authors: Tomas Möller, John Hughes
- * "Efficiently Building a Matrix to Rotate One Vector to Another"
- * Journal of Graphics Tools, 4(4):1-4, 1999
- */
-// ----------------------------------------------------------------------------------------
-template <typename TReal>
-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);
- return mtx;
-}
-
-#endif // __cplusplus
-#endif // AI_MATRIX4X4_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/mesh.h b/src/3rdparty/assimp/include/assimp/mesh.h
deleted file mode 100644
index c8648c778..000000000
--- a/src/3rdparty/assimp/include/assimp/mesh.h
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 mesh.h
- * @brief Declares the data structures in which the imported geometry is
- returned by ASSIMP: aiMesh, aiFace and aiBone data structures.
- */
-#pragma once
-#ifndef AI_MESH_H_INC
-#define AI_MESH_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-// Limits. These values are required to match the settings Assimp was
-// compiled against. Therefore, do not redefine them unless you build the
-// library from source using the same definitions.
-// ---------------------------------------------------------------------------
-
-/** @def AI_MAX_FACE_INDICES
- * Maximum number of indices per face (polygon). */
-
-#ifndef AI_MAX_FACE_INDICES
-# define AI_MAX_FACE_INDICES 0x7fff
-#endif
-
-/** @def AI_MAX_BONE_WEIGHTS
- * Maximum number of indices per face (polygon). */
-
-#ifndef AI_MAX_BONE_WEIGHTS
-# define AI_MAX_BONE_WEIGHTS 0x7fffffff
-#endif
-
-/** @def AI_MAX_VERTICES
- * Maximum number of vertices per mesh. */
-
-#ifndef AI_MAX_VERTICES
-# define AI_MAX_VERTICES 0x7fffffff
-#endif
-
-/** @def AI_MAX_FACES
- * Maximum number of faces per mesh. */
-
-#ifndef AI_MAX_FACES
-# define AI_MAX_FACES 0x7fffffff
-#endif
-
-/** @def AI_MAX_NUMBER_OF_COLOR_SETS
- * Supported number of vertex color sets per mesh. */
-
-#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
-# define AI_MAX_NUMBER_OF_COLOR_SETS 0x8
-#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
-
-/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
- * Supported number of texture coord sets (UV(W) channels) per mesh */
-
-#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
-# define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8
-#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
-
-// ---------------------------------------------------------------------------
-/** @brief A single face in a mesh, referring to multiple vertices.
- *
- * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3
- * it's called 'polygon' (hey, that's just a definition!).
- * <br>
- * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of
- * primitive are actually present in a mesh. The #aiProcess_SortByPType flag
- * executes a special post-processing algorithm which splits meshes with
- * *different* primitive types mixed up (e.g. lines and triangles) in several
- * 'clean' submeshes. Furthermore there is a configuration option (
- * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove
- * specific kinds of primitives from the imported scene, completely and forever.
- * In many cases you'll probably want to set this setting to
- * @code
- * aiPrimitiveType_LINE|aiPrimitiveType_POINT
- * @endcode
- * Together with the #aiProcess_Triangulate flag you can then be sure that
- * #aiFace::mNumIndices is always 3.
- * @note Take a look at the @link data Data Structures page @endlink for
- * more information on the layout and winding order of a face.
- */
-struct aiFace
-{
- //! Number of indices defining this face.
- //! The maximum value for this member is #AI_MAX_FACE_INDICES.
- unsigned int mNumIndices;
-
- //! Pointer to the indices array. Size of the array is given in numIndices.
- unsigned int* mIndices;
-
-#ifdef __cplusplus
-
- //! Default constructor
- aiFace()
- : mNumIndices( 0 )
- , mIndices( NULL )
- {
- }
-
- //! Default destructor. Delete the index array
- ~aiFace()
- {
- delete [] mIndices;
- }
-
- //! Copy constructor. Copy the index array
- aiFace( const aiFace& o)
- : mIndices( NULL )
- {
- *this = o;
- }
-
- //! Assignment operator. Copy the index array
- aiFace& operator = ( const aiFace& o)
- {
- if (&o == this)
- return *this;
-
- delete[] mIndices;
- mNumIndices = o.mNumIndices;
- if (mNumIndices) {
- mIndices = new unsigned int[mNumIndices];
- ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
- }
- else {
- mIndices = NULL;
- }
- return *this;
- }
-
- //! Comparison operator. Checks whether the index array
- //! of two faces is identical
- bool operator== (const aiFace& o) const
- {
- if (mIndices == o.mIndices)return true;
- else if (mIndices && mNumIndices == o.mNumIndices)
- {
- for (unsigned int i = 0;i < this->mNumIndices;++i)
- if (mIndices[i] != o.mIndices[i])return false;
- return true;
- }
- return false;
- }
-
- //! Inverse comparison operator. Checks whether the index
- //! array of two faces is NOT identical
- bool operator != (const aiFace& o) const
- {
- return !(*this == o);
- }
-#endif // __cplusplus
-}; // struct aiFace
-
-
-// ---------------------------------------------------------------------------
-/** @brief A single influence of a bone on a vertex.
- */
-struct aiVertexWeight
-{
- //! Index of the vertex which is influenced by the bone.
- unsigned int mVertexId;
-
- //! The strength of the influence in the range (0...1).
- //! The influence from all bones at one vertex amounts to 1.
- float mWeight;
-
-#ifdef __cplusplus
-
- //! Default constructor
- aiVertexWeight() { }
-
- //! Initialisation from a given index and vertex weight factor
- //! \param pID ID
- //! \param pWeight Vertex weight factor
- aiVertexWeight( unsigned int pID, float pWeight)
- : mVertexId( pID), mWeight( pWeight)
- { /* nothing to do here */ }
-
-#endif // __cplusplus
-};
-
-
-// ---------------------------------------------------------------------------
-/** @brief A single bone of a mesh.
- *
- * A bone has a name by which it can be found in the frame hierarchy and by
- * which it can be addressed by animations. In addition it has a number of
- * influences on vertices.
- */
-struct aiBone
-{
- //! The name of the bone.
- C_STRUCT aiString mName;
-
- //! The number of vertices affected by this bone
- //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
- unsigned int mNumWeights;
-
- //! The vertices affected by this bone
- C_STRUCT aiVertexWeight* mWeights;
-
- //! Matrix that transforms from mesh space to bone space in bind pose
- C_STRUCT aiMatrix4x4 mOffsetMatrix;
-
-#ifdef __cplusplus
-
- //! Default constructor
- aiBone()
- : mName()
- , mNumWeights( 0 )
- , mWeights( NULL )
- {
- }
-
- //! Copy constructor
- aiBone(const aiBone& other)
- : mName( other.mName )
- , mNumWeights( other.mNumWeights )
- , mOffsetMatrix( other.mOffsetMatrix )
- {
- if (other.mWeights && other.mNumWeights)
- {
- mWeights = new aiVertexWeight[mNumWeights];
- ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight));
- }
- }
-
- //! Destructor - deletes the array of vertex weights
- ~aiBone()
- {
- delete [] mWeights;
- }
-#endif // __cplusplus
-};
-
-
-// ---------------------------------------------------------------------------
-/** @brief Enumerates the types of geometric primitives supported by Assimp.
- *
- * @see aiFace Face data structure
- * @see aiProcess_SortByPType Per-primitive sorting of meshes
- * @see aiProcess_Triangulate Automatic triangulation
- * @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types.
- */
-enum aiPrimitiveType
-{
- /** A point primitive.
- *
- * This is just a single vertex in the virtual world,
- * #aiFace contains just one index for such a primitive.
- */
- aiPrimitiveType_POINT = 0x1,
-
- /** A line primitive.
- *
- * This is a line defined through a start and an end position.
- * #aiFace contains exactly two indices for such a primitive.
- */
- aiPrimitiveType_LINE = 0x2,
-
- /** A triangular primitive.
- *
- * A triangle consists of three indices.
- */
- aiPrimitiveType_TRIANGLE = 0x4,
-
- /** A higher-level polygon with more than 3 edges.
- *
- * A triangle is a polygon, but polygon in this context means
- * "all polygons that are not triangles". The "Triangulate"-Step
- * is provided for your convenience, it splits all polygons in
- * triangles (which are much easier to handle).
- */
- aiPrimitiveType_POLYGON = 0x8,
-
-
- /** This value is not used. It is just here to force the
- * compiler to map this enum to a 32 Bit integer.
- */
-#ifndef SWIG
- _aiPrimitiveType_Force32Bit = INT_MAX
-#endif
-}; //! enum aiPrimitiveType
-
-// Get the #aiPrimitiveType flag for a specific number of face indices
-#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
- ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
-
-
-
-// ---------------------------------------------------------------------------
-/** @brief NOT CURRENTLY IN USE. An AnimMesh is an attachment to an #aiMesh stores per-vertex
- * animations for a particular frame.
- *
- * You may think of an #aiAnimMesh as a `patch` for the host mesh, which
- * replaces only certain vertex data streams at a particular time.
- * Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
- * The actual relationship between the time line and anim meshes is
- * established by #aiMeshAnim, which references singular mesh attachments
- * by their ID and binds them to a time offset.
-*/
-struct aiAnimMesh
-{
- /** Replacement for aiMesh::mVertices. If this array is non-NULL,
- * it *must* contain mNumVertices entries. The corresponding
- * array in the host mesh must be non-NULL as well - animation
- * meshes may neither add or nor remove vertex components (if
- * a replacement array is NULL and the corresponding source
- * array is not, the source data is taken instead)*/
- C_STRUCT aiVector3D* mVertices;
-
- /** Replacement for aiMesh::mNormals. */
- C_STRUCT aiVector3D* mNormals;
-
- /** Replacement for aiMesh::mTangents. */
- C_STRUCT aiVector3D* mTangents;
-
- /** Replacement for aiMesh::mBitangents. */
- C_STRUCT aiVector3D* mBitangents;
-
- /** Replacement for aiMesh::mColors */
- C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- /** Replacement for aiMesh::mTextureCoords */
- C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- /** The number of vertices in the aiAnimMesh, and thus the length of all
- * the member arrays.
- *
- * This has always the same value as the mNumVertices property in the
- * corresponding aiMesh. It is duplicated here merely to make the length
- * of the member arrays accessible even if the aiMesh is not known, e.g.
- * from language bindings.
- */
- unsigned int mNumVertices;
-
- /**
- * Weight of the AnimMesh.
- */
- float mWeight;
-
-#ifdef __cplusplus
-
- aiAnimMesh()
- : mVertices( NULL )
- , mNormals( NULL )
- , mTangents( NULL )
- , mBitangents( NULL )
- , mNumVertices( 0 )
- , mWeight( 0.0f )
- {
- // fixme consider moving this to the ctor initializer list as well
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
- mTextureCoords[a] = NULL;
- }
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
- mColors[a] = NULL;
- }
- }
-
- ~aiAnimMesh()
- {
- delete [] mVertices;
- delete [] mNormals;
- delete [] mTangents;
- delete [] mBitangents;
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
- delete [] mTextureCoords[a];
- }
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
- delete [] mColors[a];
- }
- }
-
- /** Check whether the anim mesh overrides the vertex positions
- * of its host mesh*/
- bool HasPositions() const {
- return mVertices != NULL;
- }
-
- /** Check whether the anim mesh overrides the vertex normals
- * of its host mesh*/
- bool HasNormals() const {
- return mNormals != NULL;
- }
-
- /** Check whether the anim mesh overrides the vertex tangents
- * and bitangents of its host mesh. As for aiMesh,
- * tangents and bitangents always go together. */
- bool HasTangentsAndBitangents() const {
- return mTangents != NULL;
- }
-
- /** Check whether the anim mesh overrides a particular
- * set of vertex colors on his host mesh.
- * @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */
- bool HasVertexColors( unsigned int pIndex) const {
- return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != NULL;
- }
-
- /** Check whether the anim mesh overrides a particular
- * set of texture coordinates on his host mesh.
- * @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */
- bool HasTextureCoords( unsigned int pIndex) const {
- return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != NULL;
- }
-
-#endif
-};
-
-// ---------------------------------------------------------------------------
-/** @brief Enumerates the methods of mesh morphing supported by Assimp.
- */
-enum aiMorphingMethod
-{
- /** Interpolation between morph targets */
- aiMorphingMethod_VERTEX_BLEND = 0x1,
-
- /** Normalized morphing between morph targets */
- aiMorphingMethod_MORPH_NORMALIZED = 0x2,
-
- /** Relative morphing between morph targets */
- aiMorphingMethod_MORPH_RELATIVE = 0x3,
-
- /** This value is not used. It is just here to force the
- * compiler to map this enum to a 32 Bit integer.
- */
-#ifndef SWIG
- _aiMorphingMethod_Force32Bit = INT_MAX
-#endif
-}; //! enum aiMorphingMethod
-
-// ---------------------------------------------------------------------------
-/** @brief A mesh represents a geometry or model with a single material.
-*
-* It usually consists of a number of vertices and a series of primitives/faces
-* referencing the vertices. In addition there might be a series of bones, each
-* of them addressing a number of vertices with a certain weight. Vertex data
-* is presented in channels with each channel containing a single per-vertex
-* information such as a set of texture coords or a normal vector.
-* If a data pointer is non-null, the corresponding data stream is present.
-* From C++-programs you can also use the comfort functions Has*() to
-* test for the presence of various data streams.
-*
-* A Mesh uses only a single material which is referenced by a material ID.
-* @note The mPositions member is usually not optional. However, vertex positions
-* *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in
-* @code
-* aiScene::mFlags
-* @endcode
-*/
-struct aiMesh
-{
- /** Bitwise combination of the members of the #aiPrimitiveType enum.
- * This specifies which types of primitives are present in the mesh.
- * The "SortByPrimitiveType"-Step can be used to make sure the
- * output meshes consist of one primitive type each.
- */
- unsigned int mPrimitiveTypes;
-
- /** The number of vertices in this mesh.
- * This is also the size of all of the per-vertex data arrays.
- * The maximum value for this member is #AI_MAX_VERTICES.
- */
- unsigned int mNumVertices;
-
- /** The number of primitives (triangles, polygons, lines) in this mesh.
- * This is also the size of the mFaces array.
- * The maximum value for this member is #AI_MAX_FACES.
- */
- unsigned int mNumFaces;
-
- /** Vertex positions.
- * This array is always present in a mesh. The array is
- * mNumVertices in size.
- */
- C_STRUCT aiVector3D* mVertices;
-
- /** Vertex normals.
- * The array contains normalized vectors, NULL if not present.
- * The array is mNumVertices in size. Normals are undefined for
- * point and line primitives. A mesh consisting of points and
- * lines only may not have normal vectors. Meshes with mixed
- * primitive types (i.e. lines and triangles) may have normals,
- * but the normals for vertices that are only referenced by
- * point or line primitives are undefined and set to QNaN (WARN:
- * qNaN compares to inequal to *everything*, even to qNaN itself.
- * Using code like this to check whether a field is qnan is:
- * @code
- * #define IS_QNAN(f) (f != f)
- * @endcode
- * still dangerous because even 1.f == 1.f could evaluate to false! (
- * remember the subtleties of IEEE754 artithmetics). Use stuff like
- * @c fpclassify instead.
- * @note Normal vectors computed by Assimp are always unit-length.
- * However, this needn't apply for normals that have been taken
- * directly from the model file.
- */
- C_STRUCT aiVector3D* mNormals;
-
- /** Vertex tangents.
- * The tangent of a vertex points in the direction of the positive
- * X texture axis. The array contains normalized vectors, NULL if
- * not present. The array is mNumVertices in size. A mesh consisting
- * of points and lines only may not have normal vectors. Meshes with
- * mixed primitive types (i.e. lines and triangles) may have
- * normals, but the normals for vertices that are only referenced by
- * point or line primitives are undefined and set to qNaN. See
- * the #mNormals member for a detailed discussion of qNaNs.
- * @note If the mesh contains tangents, it automatically also
- * contains bitangents.
- */
- C_STRUCT aiVector3D* mTangents;
-
- /** Vertex bitangents.
- * The bitangent of a vertex points in the direction of the positive
- * Y texture axis. The array contains normalized vectors, NULL if not
- * present. The array is mNumVertices in size.
- * @note If the mesh contains tangents, it automatically also contains
- * bitangents.
- */
- C_STRUCT aiVector3D* mBitangents;
-
- /** Vertex color sets.
- * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
- * colors per vertex. NULL if not present. Each array is
- * mNumVertices in size if present.
- */
- C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
-
- /** Vertex texture coords, also known as UV channels.
- * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
- * vertex. NULL if not present. The array is mNumVertices in size.
- */
- C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- /** Specifies the number of components for a given UV channel.
- * Up to three channels are supported (UVW, for accessing volume
- * or cube maps). If the value is 2 for a given channel n, the
- * component p.z of mTextureCoords[n][p] is set to 0.0f.
- * If the value is 1 for a given channel, p.y is set to 0.0f, too.
- * @note 4D coords are not supported
- */
- unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
-
- /** The faces the mesh is constructed from.
- * Each face refers to a number of vertices by their indices.
- * This array is always present in a mesh, its size is given
- * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
- * is NOT set each face references an unique set of vertices.
- */
- C_STRUCT aiFace* mFaces;
-
- /** The number of bones this mesh contains.
- * Can be 0, in which case the mBones array is NULL.
- */
- unsigned int mNumBones;
-
- /** The bones of this mesh.
- * A bone consists of a name by which it can be found in the
- * frame hierarchy and a set of vertex weights.
- */
- C_STRUCT aiBone** mBones;
-
- /** The material used by this mesh.
- * A mesh uses only a single material. If an imported model uses
- * multiple materials, the import splits up the mesh. Use this value
- * as index into the scene's material list.
- */
- unsigned int mMaterialIndex;
-
- /** Name of the mesh. Meshes can be named, but this is not a
- * requirement and leaving this field empty is totally fine.
- * There are mainly three uses for mesh names:
- * - some formats name nodes and meshes independently.
- * - importers tend to split meshes up to meet the
- * one-material-per-mesh requirement. Assigning
- * the same (dummy) name to each of the result meshes
- * aids the caller at recovering the original mesh
- * partitioning.
- * - Vertex animations refer to meshes by their names.
- **/
- C_STRUCT aiString mName;
-
-
- /** The number of attachment meshes. Note! Currently only works with Collada loader. */
- unsigned int mNumAnimMeshes;
-
- /** Attachment meshes for this mesh, for vertex-based animation.
- * Attachment meshes carry replacement data for some of the
- * mesh'es vertex components (usually positions, normals).
- * Note! Currently only works with Collada loader.*/
- C_STRUCT aiAnimMesh** mAnimMeshes;
-
- /**
- * Method of morphing when animeshes are specified.
- */
- unsigned int mMethod;
-
-#ifdef __cplusplus
-
- //! 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 )
- , mMethod( 0 )
- {
- 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;
- }
-
- //! Deletes all storage allocated for the mesh
- ~aiMesh()
- {
- delete [] mVertices;
- delete [] mNormals;
- delete [] mTangents;
- delete [] mBitangents;
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
- delete [] mTextureCoords[a];
- }
- for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
- delete [] mColors[a];
- }
-
- // DO NOT REMOVE THIS ADDITIONAL CHECK
- if (mNumBones && mBones) {
- for( unsigned int a = 0; a < mNumBones; a++) {
- delete mBones[a];
- }
- delete [] mBones;
- }
-
- if (mNumAnimMeshes && mAnimMeshes) {
- for( unsigned int a = 0; a < mNumAnimMeshes; a++) {
- delete mAnimMeshes[a];
- }
- delete [] mAnimMeshes;
- }
-
- delete [] mFaces;
- }
-
- //! Check whether the mesh contains positions. Provided no special
- //! scene flags are set, this will always be true
- bool HasPositions() const
- { return mVertices != NULL && mNumVertices > 0; }
-
- //! Check whether the mesh contains faces. If no special scene flags
- //! are set this should always return true
- bool HasFaces() const
- { return mFaces != NULL && mNumFaces > 0; }
-
- //! Check whether the mesh contains normal vectors
- bool HasNormals() const
- { return mNormals != NULL && mNumVertices > 0; }
-
- //! Check whether the mesh contains tangent and bitangent vectors
- //! It is not possible that it contains tangents and no bitangents
- //! (or the other way round). The existence of one of them
- //! implies that the second is there, too.
- bool HasTangentsAndBitangents() const
- { return mTangents != NULL && mBitangents != NULL && mNumVertices > 0; }
-
- //! Check whether the mesh contains a vertex color set
- //! \param pIndex Index of the vertex color set
- bool HasVertexColors( unsigned int pIndex) const
- {
- if( pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS)
- return false;
- else
- return mColors[pIndex] != NULL && mNumVertices > 0;
- }
-
- //! Check whether the mesh contains a texture coordinate set
- //! \param pIndex Index of the texture coordinates set
- bool HasTextureCoords( unsigned int pIndex) const
- {
- if( pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS)
- return false;
- else
- return mTextureCoords[pIndex] != NULL && mNumVertices > 0;
- }
-
- //! Get the number of UV channels the mesh contains
- unsigned int GetNumUVChannels() const
- {
- unsigned int n = 0;
- while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n])++n;
- return n;
- }
-
- //! Get the number of vertex color channels the mesh contains
- unsigned int GetNumColorChannels() const
- {
- unsigned int n = 0;
- while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n])++n;
- return n;
- }
-
- //! Check whether the mesh contains bones
- inline bool HasBones() const
- { return mBones != NULL && mNumBones > 0; }
-
-#endif // __cplusplus
-};
-
-#ifdef __cplusplus
-}
-#endif //! extern "C"
-#endif // AI_MESH_H_INC
-
diff --git a/src/3rdparty/assimp/include/assimp/metadata.h b/src/3rdparty/assimp/include/assimp/metadata.h
deleted file mode 100644
index 92db9b59a..000000000
--- a/src/3rdparty/assimp/include/assimp/metadata.h
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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.
- */
-#pragma once
-#ifndef AI_METADATA_H_INC
-#define AI_METADATA_H_INC
-
-#if defined(_MSC_VER) && (_MSC_VER <= 1500)
-# include "Compiler/pstdint.h"
-#else
-# include <stdint.h>
-#endif
-
-// -------------------------------------------------------------------------------
-/**
- * Enum used to distinguish data types
- */
- // -------------------------------------------------------------------------------
-typedef enum aiMetadataType {
- AI_BOOL = 0,
- AI_INT32 = 1,
- AI_UINT64 = 2,
- AI_FLOAT = 3,
- AI_DOUBLE = 4,
- AI_AISTRING = 5,
- AI_AIVECTOR3D = 6,
-
-#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( int32_t ) { return AI_INT32; }
-inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
-inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
-inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
-inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; }
-inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
-
-#endif // __cplusplus
-
-// -------------------------------------------------------------------------------
-/**
- * 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
-
- /**
- * @brief The default constructor, set all members to zero by default.
- */
- aiMetadata()
- : mNumProperties(0)
- , mKeys(NULL)
- , mValues(NULL) {
- // empty
- }
-
- /**
- * @brief The 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_INT32:
- delete static_cast<int32_t*>(data);
- break;
- case AI_UINT64:
- delete static_cast<uint64_t*>(data);
- break;
- case AI_FLOAT:
- delete static_cast<float*>(data);
- break;
- case AI_DOUBLE:
- delete static_cast<double*>(data);
- break;
- case AI_AISTRING:
- delete static_cast<aiString*>(data);
- break;
- case AI_AIVECTOR3D:
- delete static_cast<aiVector3D*>(data);
- break;
-#ifndef SWIG
- case FORCE_32BIT:
-#endif
- default:
- break;
- }
- }
-
- // Delete the metadata array
- delete [] mValues;
- mValues = NULL;
- }
- }
-
- /**
- * @brief Allocates property fields + keys.
- * @param numProperties Number of requested properties.
- */
- static inline
- aiMetadata *Alloc( unsigned int numProperties ) {
- if ( 0 == numProperties ) {
- return nullptr;
- }
-
- aiMetadata *data = new aiMetadata;
- data->mNumProperties = numProperties;
- data->mKeys = new aiString[ data->mNumProperties ]();
- data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
-
- return data;
- }
-
- /**
- * @brief Deallocates property fields + keys.
- */
- static inline
- void Dealloc( aiMetadata *metadata ) {
- delete metadata;
- }
-
- template<typename T>
- inline void Add(const std::string& key, const T& value)
- {
- aiString* new_keys = new aiString[mNumProperties + 1];
- aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
-
- for(unsigned int i = 0; i < mNumProperties; ++i)
- {
- new_keys[i] = mKeys[i];
- new_values[i] = mValues[i];
- }
-
- delete mKeys;
- delete mValues;
-
- mKeys = new_keys;
- mValues = new_values;
-
- mNumProperties++;
-
- Set(mNumProperties - 1, key, value);
- }
-
- template<typename T>
- inline
- bool Set( unsigned index, const std::string& key, const T& value ) {
- // In range assertion
- if ( index >= mNumProperties ) {
- return false;
- }
-
- // Ensure that we have a valid key.
- if ( key.empty() ) {
- return false;
- }
-
- // 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);
-
- return true;
- }
-
- template<typename T>
- inline
- bool Get( unsigned index, T& value ) {
- // In range assertion
- if ( index >= mNumProperties ) {
- return false;
- }
-
- // 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 int 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);
- }
-
- /// Return metadata entry for analyzing it by user.
- /// \param [in] pIndex - index of the entry.
- /// \param [out] pKey - pointer to the key value.
- /// \param [out] pEntry - pointer to the entry: type and value.
- /// \return false - if pIndex is out of range, else - true.
- inline bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) {
- if ( index >= mNumProperties ) {
- return false;
- }
-
- key = &mKeys[index];
- entry = &mValues[index];
-
- return true;
- }
-
-#endif // __cplusplus
-
-};
-
-#endif // AI_METADATA_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h b/src/3rdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h
deleted file mode 100644
index 41d800487..000000000
--- a/src/3rdparty/assimp/include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, 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 Android implementation of IOSystem using the standard C file functions.
- * Aimed to ease the access to android assets */
-
-#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
-#ifndef AI_ANDROIDJNIIOSYSTEM_H_INC
-#define AI_ANDROIDJNIIOSYSTEM_H_INC
-
-#include <assimp/DefaultIOSystem.h>
-#include <android/asset_manager.h>
-#include <android/asset_manager_jni.h>
-#include <android/native_activity.h>
-
-namespace Assimp {
-
-// ---------------------------------------------------------------------------
-/** Android extension to DefaultIOSystem using the standard C file functions */
-class ASSIMP_API AndroidJNIIOSystem : public DefaultIOSystem
-{
-public:
-
- /** Initialize android activity data */
- std::string mApkWorkspacePath;
- AAssetManager* mApkAssetManager;
-
- /** Constructor. */
- AndroidJNIIOSystem(ANativeActivity* activity);
-
- /** Destructor. */
- ~AndroidJNIIOSystem();
-
- // -------------------------------------------------------------------
- /** Tests for the existence of a file at the given path. */
- bool Exists( const char* pFile) const;
-
- // -------------------------------------------------------------------
- /** Opens a file at the given path, with given mode */
- IOStream* Open( const char* strFile, const char* strMode);
-
- // ------------------------------------------------------------------------------------------------
- // Inits Android extractor
- void AndroidActivityInit(ANativeActivity* activity);
-
- // ------------------------------------------------------------------------------------------------
- // Extracts android asset
- bool AndroidExtractAsset(std::string name);
-
-};
-
-} //!ns Assimp
-
-#endif //AI_ANDROIDJNIIOSYSTEM_H_INC
-#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
diff --git a/src/3rdparty/assimp/include/assimp/postprocess.h b/src/3rdparty/assimp/include/assimp/postprocess.h
deleted file mode 100644
index 970df8e8a..000000000
--- a/src/3rdparty/assimp/include/assimp/postprocess.h
+++ /dev/null
@@ -1,645 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 postprocess.h
- * @brief Definitions for import post processing steps
- */
-#pragma once
-#ifndef AI_POSTPROCESS_H_INC
-#define AI_POSTPROCESS_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// -----------------------------------------------------------------------------------
-/** @enum aiPostProcessSteps
- * @brief Defines the flags for all possible post processing steps.
- *
- * @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
- */
-// -----------------------------------------------------------------------------------
-enum aiPostProcessSteps
-{
-
- // -------------------------------------------------------------------------
- /** <hr>Calculates the tangents and bitangents for the imported meshes.
- *
- * 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 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.
- */
- aiProcess_CalcTangentSpace = 0x1,
-
- // -------------------------------------------------------------------------
- /** <hr>Identifies and joins identical vertex data sets within all
- * imported meshes.
- *
- * After this step is run, each mesh contains unique vertices,
- * so a vertex may be used by multiple faces. You usually want
- * to use this post processing step. If your application deals with
- * indexed geometry, this step is compulsory or you'll just waste rendering
- * time. <b>If this flag is not specified</b>, no vertices are referenced by
- * more than one face and <b>no index buffer is required</b> for rendering.
- */
- aiProcess_JoinIdenticalVertices = 0x2,
-
- // -------------------------------------------------------------------------
- /** <hr>Converts all the imported data to a left-handed coordinate space.
- *
- * By default the data is returned in a right-handed coordinate space (which
- * OpenGL prefers). In this space, +X points to the right,
- * +Z points towards the viewer, and +Y points upwards. In the DirectX
- * coordinate space +X points to the right, +Y points upwards, and +Z points
- * away from the viewer.
- *
- * You'll probably want to consider this flag if you use Direct3D for
- * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
- * setting and bundles all conversions typically required for D3D-based
- * applications.
- */
- aiProcess_MakeLeftHanded = 0x4,
-
- // -------------------------------------------------------------------------
- /** <hr>Triangulates all faces of all meshes.
- *
- * By default the imported mesh data might contain faces with more than 3
- * indices. For rendering you'll usually want all faces to be triangles.
- * This post processing step splits up faces with more than 3 indices into
- * triangles. Line and point primitives are *not* modified! If you want
- * 'triangles only' with no other kinds of primitives, try the following
- * 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>
- * </ul>
- */
- aiProcess_Triangulate = 0x8,
-
- // -------------------------------------------------------------------------
- /** <hr>Removes some parts of the data structure (animations, materials,
- * light sources, cameras, textures, vertex components).
- *
- * The components to be removed are specified in a separate
- * 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
- * performance and a more optimized output data structure.
- * This step is also useful if you want to force Assimp to recompute
- * normals or tangents. The corresponding steps don't recompute them if
- * they're already there (loaded from the source asset). By using this
- * step you can make sure they are NOT there.
- *
- * This flag is a poor one, mainly because its purpose is usually
- * misunderstood. Consider the following case: a 3D model has been exported
- * from a CAD app, and it has per-face vertex colors. Vertex positions can't be
- * shared, thus the #aiProcess_JoinIdenticalVertices step fails to
- * optimize the data because of these nasty little vertex colors.
- * Most apps don't even process them, so it's all for nothing. By using
- * this step, unneeded components are excluded as early as possible
- * thus opening more room for internal optimizations.
- */
- aiProcess_RemoveComponent = 0x10,
-
- // -------------------------------------------------------------------------
- /** <hr>Generates normals for all faces of all meshes.
- *
- * This is ignored if normals are already there at the time this flag
- * is evaluated. Model importers try to load them from the source file, so
- * they're usually already there. Face normals are shared between all points
- * of a single face, so a single point can have multiple normals, which
- * forces the library to duplicate vertices in some cases.
- * #aiProcess_JoinIdenticalVertices is *senseless* then.
- *
- * This flag may not be specified together with #aiProcess_GenSmoothNormals.
- */
- aiProcess_GenNormals = 0x20,
-
- // -------------------------------------------------------------------------
- /** <hr>Generates smooth normals for all vertices in the mesh.
- *
- * This is ignored if normals are already there at the time this flag
- * is evaluated. Model importers try to load them from the source file, so
- * they're usually already there.
- *
- * This flag may not be specified together with
- * #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.
- * Using a decent angle here (e.g. 80 degrees) results in very good visual
- * appearance.
- */
- aiProcess_GenSmoothNormals = 0x40,
-
- // -------------------------------------------------------------------------
- /** <hr>Splits large meshes into smaller sub-meshes.
- *
- * This is quite useful for real-time rendering, where the number of triangles
- * which can be maximally processed in a single draw-call is limited
- * by the video driver/hardware. The maximum vertex buffer is usually limited
- * too. Both requirements can be met with this step: you may specify both a
- * triangle and vertex limit for a single mesh.
- *
- * 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>
- * 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
- * something to split. The use of this step is recommended for most users.
- */
- aiProcess_SplitLargeMeshes = 0x80,
-
- // -------------------------------------------------------------------------
- /** <hr>Removes the node graph and pre-transforms all vertices with
- * the local transformation matrices of their nodes.
- *
- * The output scene still contains nodes, however there is only a
- * root node with children, each one referencing only one mesh,
- * and each mesh referencing one material. For rendering, you can
- * simply render all meshes in order - you don't need to pay
- * attention to local transformations and the node hierarchy.
- * Animations are removed during this step.
- * This step is intended for applications without a scenegraph.
- * The step CAN cause some problems: if e.g. a mesh of the asset
- * contains normals and another, using the same material index, does not,
- * they will be brought together, but the first meshes's part of
- * the normal list is zeroed. However, these artifacts are rare.
- * @note The <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property
- * can be set to normalize the scene's spatial dimension to the -1...1
- * range.
- */
- aiProcess_PreTransformVertices = 0x100,
-
- // -------------------------------------------------------------------------
- /** <hr>Limits the number of bones simultaneously affecting a single vertex
- * to a maximum value.
- *
- * If any vertex is affected by more than the maximum number of bones, the least
- * 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> 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.
- */
- aiProcess_LimitBoneWeights = 0x200,
-
- // -------------------------------------------------------------------------
- /** <hr>Validates the imported scene data structure.
- * This makes sure that all indices are valid, all animations and
- * bones are linked correctly, all material references are correct .. etc.
- *
- * It is recommended that you capture Assimp's log output if you use this flag,
- * so you can easily find out what's wrong if a file fails the
- * validation. The validator is quite strict and will find *all*
- * inconsistencies in the data structure... It is recommended that plugin
- * developers use it to debug their loaders. There are two types of
- * validation failures:
- * <ul>
- * <li>Error: There's something wrong with the imported data. Further
- * postprocessing is not possible and the data is not usable at all.
- * The import fails. #Importer::GetErrorString() or #aiGetErrorString()
- * carry the error message around.</li>
- * <li>Warning: There are some minor issues (e.g. 1000000 animation
- * keyframes with the same time), but further postprocessing and use
- * of the data structure is still safe. Warning details are written
- * to the log file, <tt>#AI_SCENE_FLAGS_VALIDATION_WARNING</tt> is set
- * in #aiScene::mFlags</li>
- * </ul>
- *
- * This post-processing step is not time-consuming. Its use is not
- * compulsory, but recommended.
- */
- aiProcess_ValidateDataStructure = 0x400,
-
- // -------------------------------------------------------------------------
- /** <hr>Reorders triangles for better vertex cache locality.
- *
- * The step tries to improve the ACMR (average post-transform vertex cache
- * miss ratio) for all meshes. The implementation runs in O(n) and is
- * roughly based on the 'tipsify' algorithm (see <a href="
- * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf">this
- * 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>
- * importer property can be used to fine-tune the cache optimization.
- */
- aiProcess_ImproveCacheLocality = 0x800,
-
- // -------------------------------------------------------------------------
- /** <hr>Searches for redundant/unreferenced materials and removes them.
- *
- * This is especially useful in combination with the
- * #aiProcess_PreTransformVertices and #aiProcess_OptimizeMeshes flags.
- * Both join small meshes with equal characteristics, but they can't do
- * their work if two meshes have different materials. Because several
- * material settings are lost during Assimp's import filters,
- * (and because many exporters don't check for redundant materials), huge
- * models often have materials which are are defined several times with
- * exactly the same settings.
- *
- * Several material settings not contributing to the final appearance of
- * a surface are ignored in all comparisons (e.g. the material name).
- * 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> importer property.
- */
- aiProcess_RemoveRedundantMaterials = 0x1000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step tries to determine which meshes have normal vectors
- * that are facing inwards and inverts them.
- *
- * The algorithm is simple but effective:
- * the bounding box of all vertices + their normals is compared against
- * the volume of the bounding box of all vertices without their normals.
- * This works well for most objects, problems might occur with planar
- * surfaces. However, the step tries to filter such cases.
- * The step inverts all in-facing normals. Generally it is recommended
- * to enable this step, although the result is not always correct.
- */
- aiProcess_FixInfacingNormals = 0x2000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step splits meshes with more than one primitive type in
- * homogeneous sub-meshes.
- *
- * The step is executed after the triangulation step. After the step
- * 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> 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,
-
- // -------------------------------------------------------------------------
- /** <hr>This step searches all meshes for degenerate primitives and
- * converts them to proper lines or points.
- *
- * A face is 'degenerate' if one or more of its points are identical.
- * To have the degenerate stuff not only detected and collapsed but
- * removed, try one of the following procedures:
- * <br><b>1.</b> (if you support lines and points for rendering but don't
- * want the degenerates)<br>
- * <ul>
- * <li>Specify the #aiProcess_FindDegenerates flag.
- * </li>
- * <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>
- * <br><b>2.</b>(if you don't support lines and points at all)<br>
- * <ul>
- * <li>Specify the #aiProcess_FindDegenerates flag.
- * </li>
- * <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> importer property to
- * @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES
- * @endcode to cause SortByPType to reject point
- * and line meshes from the scene.
- * </li>
- * </ul>
- * @note Degenerate polygons are not necessarily evil and that's why
- * they're not removed by default. There are several file formats which
- * don't support lines or points, and some exporters bypass the
- * format specification and write them as degenerate triangles instead.
- */
- aiProcess_FindDegenerates = 0x10000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step searches all meshes for invalid data, such as zeroed
- * normal vectors or invalid UV coords and removes/fixes them. This is
- * intended to get rid of some common exporter errors.
- *
- * This is especially useful for normals. If they are invalid, and
- * the step recognizes this, they will be removed and can later
- * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.<br>
- * The step will also remove meshes that are infinitely small and reduce
- * animation tracks consisting of hundreds if redundant keys to a single
- * key. The <tt>AI_CONFIG_PP_FID_ANIM_ACCURACY</tt> config property decides
- * the accuracy of the check for duplicate animation tracks.
- */
- aiProcess_FindInvalidData = 0x20000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step converts non-UV mappings (such as spherical or
- * cylindrical mapping) to proper texture coordinate channels.
- *
- * Most applications will support UV mapping only, so you will
- * probably want to specify this step in every case. Note that Assimp is not
- * always able to match the original mapping implementation of the
- * 3D app which produced a model perfectly. It's always better to let the
- * modelling app compute the UV channels - 3ds max, Maya, Blender,
- * LightWave, and Modo do this for example.
- *
- * @note If this step is not requested, you'll need to process the
- * <tt>#AI_MATKEY_MAPPING</tt> material property in order to display all assets
- * properly.
- */
- aiProcess_GenUVCoords = 0x40000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step applies per-texture UV transformations and bakes
- * them into stand-alone vtexture coordinate channels.
- *
- * UV transformations are specified per-texture - see the
- * <tt>#AI_MATKEY_UVTRANSFORM</tt> material key for more information.
- * This step processes all textures with
- * transformed input UV coordinates and generates a new (pre-transformed) UV channel
- * which replaces the old channel. Most applications won't support UV
- * transformations, so you will probably want to specify this step.
- *
- * @note UV transformations are usually implemented in real-time apps by
- * transforming texture coordinates at vertex shader stage with a 3x3
- * (homogenous) transformation matrix.
- */
- aiProcess_TransformUVCoords = 0x80000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step searches for duplicate meshes and replaces them
- * with references to the first mesh.
- *
- * This step takes a while, so don't use it if speed is a concern.
- * Its main purpose is to workaround the fact that many export
- * file formats don't support instanced meshes, so exporters need to
- * duplicate meshes. This step removes the duplicates again. Please
- * note that Assimp does not currently support per-node material
- * assignment to meshes, which means that identical meshes with
- * different materials are currently *not* joined, although this is
- * planned for future versions.
- */
- aiProcess_FindInstances = 0x100000,
-
- // -------------------------------------------------------------------------
- /** <hr>A postprocessing step to reduce the number of meshes.
- *
- * This will, in fact, reduce the number of draw calls.
- *
- * This is a very effective optimization and is recommended to be used
- * together with #aiProcess_OptimizeGraph, if possible. The flag is fully
- * compatible with both #aiProcess_SplitLargeMeshes and #aiProcess_SortByPType.
- */
- aiProcess_OptimizeMeshes = 0x200000,
-
-
- // -------------------------------------------------------------------------
- /** <hr>A postprocessing step to optimize the scene hierarchy.
- *
- * Nodes without animations, bones, lights or cameras assigned are
- * collapsed and joined.
- *
- * 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> 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
- * useful for editor environments, but probably a very effective
- * optimization if you just want to get the model data, convert it to your
- * own format, and render it as fast as possible.
- *
- * This flag is designed to be used with #aiProcess_OptimizeMeshes for best
- * results.
- *
- * @note 'Crappy' scenes with thousands of extremely small meshes packed
- * in deeply nested nodes exist for almost all file formats.
- * #aiProcess_OptimizeMeshes in combination with #aiProcess_OptimizeGraph
- * usually fixes them all and makes them renderable.
- */
- aiProcess_OptimizeGraph = 0x400000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step flips all UV coordinates along the y-axis and adjusts
- * material settings and bitangents accordingly.
- *
- * <b>Output UV coordinate system:</b>
- * @code
- * 0y|0y ---------- 1x|0y
- * | |
- * | |
- * | |
- * 0x|1y ---------- 1x|1y
- * @endcode
- *
- * You'll probably want to consider this flag if you use Direct3D for
- * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
- * setting and bundles all conversions typically required for D3D-based
- * applications.
- */
- aiProcess_FlipUVs = 0x800000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step adjusts the output face winding order to be CW.
- *
- * The default face winding order is counter clockwise (CCW).
- *
- * <b>Output face order:</b>
- * @code
- * x2
- *
- * x0
- * x1
- * @endcode
- */
- aiProcess_FlipWindingOrder = 0x1000000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step splits meshes with many bones into sub-meshes so that each
- * su-bmesh has fewer or as many bones as a given limit.
- */
- aiProcess_SplitByBoneCount = 0x2000000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step removes bones losslessly or according to some threshold.
- *
- * In some cases (i.e. formats that require it) exporters are forced to
- * assign dummy bone weights to otherwise static meshes assigned to
- * animated meshes. Full, weight-based skinning is expensive while
- * animating nodes is extremely cheap, so this step is offered to clean up
- * the data in that regard.
- *
- * Use <tt>#AI_CONFIG_PP_DB_THRESHOLD</tt> to control this.
- * Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and
- * only if all bones within the scene qualify for removal.
- */
- aiProcess_Debone = 0x4000000,
-
- // -------------------------------------------------------------------------
- /** <hr>This step will perform a global scale of the model.
- *
- * Some importers are providing a mechanism to define a scaling unit for the
- * model. This post processing step can be used to do so.
- *
- * Use <tt>#AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY</tt> to control this.
- */
- aiProcess_GlobalScale = 0x8000000
-
- // aiProcess_GenEntityMeshes = 0x100000,
- // aiProcess_OptimizeAnimations = 0x200000
- // aiProcess_FixTexturePaths = 0x200000
-};
-
-
-// ---------------------------------------------------------------------------------------
-/** @def aiProcess_ConvertToLeftHanded
- * @brief Shortcut flag for Direct3D-based applications.
- *
- * Supersedes the #aiProcess_MakeLeftHanded and #aiProcess_FlipUVs and
- * #aiProcess_FlipWindingOrder flags.
- * The output data matches Direct3D's conventions: left-handed geometry, upper-left
- * origin for UV coordinates and finally clockwise face order, suitable for CCW culling.
- *
- * @deprecated
- */
-#define aiProcess_ConvertToLeftHanded ( \
- aiProcess_MakeLeftHanded | \
- aiProcess_FlipUVs | \
- aiProcess_FlipWindingOrder | \
- 0 )
-
-
-// ---------------------------------------------------------------------------------------
-/** @def aiProcessPreset_TargetRealtime_Fast
- * @brief Default postprocess configuration optimizing the data for real-time rendering.
- *
- * Applications would want to use this preset to load models on end-user PCs,
- * maybe for direct use in game.
- *
- * If you're using DirectX, don't forget to combine this value with
- * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
- * in your application apply the #aiProcess_TransformUVCoords step, too.
- * @note Please take the time to read the docs for the steps enabled by this preset.
- * Some of them offer further configurable properties, while some of them might not be of
- * use for you so it might be better to not specify them.
- */
-#define aiProcessPreset_TargetRealtime_Fast ( \
- aiProcess_CalcTangentSpace | \
- aiProcess_GenNormals | \
- aiProcess_JoinIdenticalVertices | \
- aiProcess_Triangulate | \
- aiProcess_GenUVCoords | \
- aiProcess_SortByPType | \
- 0 )
-
- // ---------------------------------------------------------------------------------------
- /** @def aiProcessPreset_TargetRealtime_Quality
- * @brief Default postprocess configuration optimizing the data for real-time rendering.
- *
- * Unlike #aiProcessPreset_TargetRealtime_Fast, this configuration
- * performs some extra optimizations to improve rendering speed and
- * to minimize memory usage. It could be a good choice for a level editor
- * environment where import speed is not so important.
- *
- * If you're using DirectX, don't forget to combine this value with
- * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
- * in your application apply the #aiProcess_TransformUVCoords step, too.
- * @note Please take the time to read the docs for the steps enabled by this preset.
- * Some of them offer further configurable properties, while some of them might not be
- * of use for you so it might be better to not specify them.
- */
-#define aiProcessPreset_TargetRealtime_Quality ( \
- aiProcess_CalcTangentSpace | \
- aiProcess_GenSmoothNormals | \
- aiProcess_JoinIdenticalVertices | \
- aiProcess_ImproveCacheLocality | \
- aiProcess_LimitBoneWeights | \
- aiProcess_RemoveRedundantMaterials | \
- aiProcess_SplitLargeMeshes | \
- aiProcess_Triangulate | \
- aiProcess_GenUVCoords | \
- aiProcess_SortByPType | \
- aiProcess_FindDegenerates | \
- aiProcess_FindInvalidData | \
- 0 )
-
- // ---------------------------------------------------------------------------------------
- /** @def aiProcessPreset_TargetRealtime_MaxQuality
- * @brief Default postprocess configuration optimizing the data for real-time rendering.
- *
- * This preset enables almost every optimization step to achieve perfectly
- * optimized data. It's your choice for level editor environments where import speed
- * is not important.
- *
- * If you're using DirectX, don't forget to combine this value with
- * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
- * in your application, apply the #aiProcess_TransformUVCoords step, too.
- * @note Please take the time to read the docs for the steps enabled by this preset.
- * Some of them offer further configurable properties, while some of them might not be
- * of use for you so it might be better to not specify them.
- */
-#define aiProcessPreset_TargetRealtime_MaxQuality ( \
- aiProcessPreset_TargetRealtime_Quality | \
- aiProcess_FindInstances | \
- aiProcess_ValidateDataStructure | \
- aiProcess_OptimizeMeshes | \
- 0 )
-
-
-#ifdef __cplusplus
-} // end of extern "C"
-#endif
-
-#endif // AI_POSTPROCESS_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/quaternion.h b/src/3rdparty/assimp/include/assimp/quaternion.h
deleted file mode 100644
index a5cb67a9a..000000000
--- a/src/3rdparty/assimp/include/assimp/quaternion.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 quaternion.h
- * @brief Quaternion structure, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_QUATERNION_H_INC
-#define AI_QUATERNION_H_INC
-
-#ifdef __cplusplus
-
-#include "defs.h"
-
-template <typename TReal> class aiVector3t;
-template <typename TReal> class aiMatrix3x3t;
-
-// ---------------------------------------------------------------------------
-/** Represents a quaternion in a 4D vector. */
-template <typename TReal>
-class aiQuaterniont
-{
-public:
- aiQuaterniont() : w(1.0), x(), y(), 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. */
- explicit aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix);
-
- /** Construct from euler angles */
- aiQuaterniont( TReal rotx, TReal roty, TReal rotz);
-
- /** Construct from an axis-angle pair */
- aiQuaterniont( aiVector3t<TReal> axis, TReal angle);
-
- /** Construct from a normalized quaternion stored in a vec3 */
- explicit aiQuaterniont( aiVector3t<TReal> normalized);
-
- /** Returns a matrix representation of the quaternion */
- aiMatrix3x3t<TReal> GetMatrix() const;
-
-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 */
- aiQuaterniont& Normalize();
-
- /** Compute quaternion conjugate */
- aiQuaterniont& Conjugate ();
-
- /** Rotate a point by this quaternion */
- aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in);
-
- /** Multiply two quaternions */
- aiQuaterniont operator* (const aiQuaterniont& two) const;
-
-public:
-
- /** Performs a spherical interpolation between two quaternions and writes the result into the third.
- * @param pOut Target object to received the interpolated rotation.
- * @param pStart Start rotation of the interpolation at factor == 0.
- * @param pEnd End rotation, factor == 1.
- * @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results.
- */
- static void Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart,
- const aiQuaterniont& pEnd, TReal pFactor);
-
-public:
-
- //! w,x,y,z components of the quaternion
- TReal w, x, y, z;
-} ;
-
-typedef aiQuaterniont<ai_real> aiQuaternion;
-
-#else
-
-struct aiQuaternion {
- ai_real w, x, y, z;
-};
-
-#endif
-
-#endif // AI_QUATERNION_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/quaternion.inl b/src/3rdparty/assimp/include/assimp/quaternion.inl
deleted file mode 100644
index d0bf5831c..000000000
--- a/src/3rdparty/assimp/include/assimp/quaternion.inl
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 quaternion.inl
- * @brief Inline implementation of aiQuaterniont<TReal> operators
- */
-#pragma once
-#ifndef AI_QUATERNION_INL_INC
-#define AI_QUATERNION_INL_INC
-
-#ifdef __cplusplus
-#include "quaternion.h"
-
-#include <cmath>
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
-{
- return x == o.x && y == o.y && z == o.z && w == o.w;
-}
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-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 = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
-
- // large enough
- if( t > static_cast<TReal>(0))
- {
- TReal s = std::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;
- w = static_cast<TReal>(0.25) * s;
- } // else we have to check several cases
- else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )
- {
- // Column 0:
- TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * static_cast<TReal>(2.0);
- x = static_cast<TReal>(0.25) * s;
- y = (pRotMatrix.b1 + pRotMatrix.a2) / s;
- z = (pRotMatrix.a3 + pRotMatrix.c1) / s;
- w = (pRotMatrix.c2 - pRotMatrix.b3) / s;
- }
- else if( pRotMatrix.b2 > pRotMatrix.c3)
- {
- // Column 1:
- TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * static_cast<TReal>(2.0);
- x = (pRotMatrix.b1 + pRotMatrix.a2) / s;
- y = static_cast<TReal>(0.25) * s;
- z = (pRotMatrix.c2 + pRotMatrix.b3) / s;
- w = (pRotMatrix.a3 - pRotMatrix.c1) / s;
- } else
- {
- // Column 2:
- TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * static_cast<TReal>(2.0);
- x = (pRotMatrix.a3 + pRotMatrix.c1) / s;
- y = (pRotMatrix.c2 + pRotMatrix.b3) / s;
- z = static_cast<TReal>(0.25) * s;
- w = (pRotMatrix.b1 - pRotMatrix.a2) / s;
- }
-}
-
-// ---------------------------------------------------------------------------
-// Construction from euler angles
-template<typename TReal>
-inline aiQuaterniont<TReal>::aiQuaterniont( TReal fPitch, TReal fYaw, TReal fRoll )
-{
- const TReal fSinPitch(std::sin(fPitch*static_cast<TReal>(0.5)));
- const TReal fCosPitch(std::cos(fPitch*static_cast<TReal>(0.5)));
- const TReal fSinYaw(std::sin(fYaw*static_cast<TReal>(0.5)));
- const TReal fCosYaw(std::cos(fYaw*static_cast<TReal>(0.5)));
- const TReal fSinRoll(std::sin(fRoll*static_cast<TReal>(0.5)));
- const TReal fCosRoll(std::cos(fRoll*static_cast<TReal>(0.5)));
- const TReal fCosPitchCosYaw(fCosPitch*fCosYaw);
- const TReal fSinPitchSinYaw(fSinPitch*fSinYaw);
- x = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw;
- y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
- z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
- w = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw;
-}
-
-// ---------------------------------------------------------------------------
-// Returns a matrix representation of the quaternion
-template<typename TReal>
-inline aiMatrix3x3t<TReal> aiQuaterniont<TReal>::GetMatrix() const
-{
- aiMatrix3x3t<TReal> resMatrix;
- resMatrix.a1 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (y * y + z * z);
- resMatrix.a2 = static_cast<TReal>(2.0) * (x * y - z * w);
- resMatrix.a3 = static_cast<TReal>(2.0) * (x * z + y * w);
- resMatrix.b1 = static_cast<TReal>(2.0) * (x * y + z * w);
- resMatrix.b2 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + z * z);
- resMatrix.b3 = static_cast<TReal>(2.0) * (y * z - x * w);
- resMatrix.c1 = static_cast<TReal>(2.0) * (x * z - y * w);
- resMatrix.c2 = static_cast<TReal>(2.0) * (y * z + x * w);
- resMatrix.c3 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + y * y);
-
- return resMatrix;
-}
-
-// ---------------------------------------------------------------------------
-// Construction from an axis-angle pair
-template<typename TReal>
-inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> axis, TReal angle)
-{
- axis.Normalize();
-
- const TReal sin_a = std::sin( angle / 2 );
- const TReal cos_a = std::cos( angle / 2 );
- x = axis.x * sin_a;
- y = axis.y * sin_a;
- z = axis.z * sin_a;
- w = cos_a;
-}
-// ---------------------------------------------------------------------------
-// Construction from am existing, normalized quaternion
-template<typename TReal>
-inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> normalized)
-{
- x = normalized.x;
- y = normalized.y;
- z = normalized.z;
-
- const TReal t = static_cast<TReal>(1.0) - (x*x) - (y*y) - (z*z);
-
- if (t < static_cast<TReal>(0.0)) {
- w = static_cast<TReal>(0.0);
- }
- else w = std::sqrt (t);
-}
-
-// ---------------------------------------------------------------------------
-// Performs a spherical interpolation between two quaternions
-// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
-// Congrats, gmtl!
-template<typename TReal>
-inline void aiQuaterniont<TReal>::Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, const aiQuaterniont& pEnd, TReal pFactor)
-{
- // calc cosine theta
- TReal cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
-
- // adjust signs (if necessary)
- aiQuaterniont end = pEnd;
- if( cosom < static_cast<TReal>(0.0))
- {
- cosom = -cosom;
- end.x = -end.x; // Reverse all signs
- end.y = -end.y;
- end.z = -end.z;
- end.w = -end.w;
- }
-
- // Calculate coefficients
- TReal sclp, sclq;
- if( (static_cast<TReal>(1.0) - cosom) > static_cast<TReal>(0.0001)) // 0.0001 -> some epsillon
- {
- // Standard case (slerp)
- TReal omega, sinom;
- omega = std::acos( cosom); // extract theta from dot product's cos theta
- sinom = std::sin( omega);
- sclp = std::sin( (static_cast<TReal>(1.0) - pFactor) * omega) / sinom;
- sclq = std::sin( pFactor * omega) / sinom;
- } else
- {
- // Very close, do linear interp (because it's faster)
- sclp = static_cast<TReal>(1.0) - pFactor;
- sclq = pFactor;
- }
-
- pOut.x = sclp * pStart.x + sclq * end.x;
- pOut.y = sclp * pStart.y + sclq * end.y;
- pOut.z = sclp * pStart.z + sclq * end.z;
- pOut.w = sclp * pStart.w + sclq * end.w;
-}
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Normalize()
-{
- // compute the magnitude and divide through it
- const TReal mag = std::sqrt(x*x + y*y + z*z + w*w);
- if (mag)
- {
- const TReal invMag = static_cast<TReal>(1.0)/mag;
- x *= invMag;
- y *= invMag;
- z *= invMag;
- w *= invMag;
- }
- return *this;
-}
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-inline aiQuaterniont<TReal> aiQuaterniont<TReal>::operator* (const aiQuaterniont& t) const
-{
- return aiQuaterniont(w*t.w - x*t.x - y*t.y - z*t.z,
- w*t.x + x*t.w + y*t.z - z*t.y,
- w*t.y + y*t.w + z*t.x - x*t.z,
- w*t.z + z*t.w + x*t.y - y*t.x);
-}
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate ()
-{
- x = -x;
- y = -y;
- z = -z;
- return *this;
-}
-
-// ---------------------------------------------------------------------------
-template<typename TReal>
-inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
-{
- aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
- qinv.Conjugate();
-
- q = q*q2*qinv;
- return aiVector3t<TReal>(q.x,q.y,q.z);
-}
-
-#endif
-#endif // AI_QUATERNION_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/scene.h b/src/3rdparty/assimp/include/assimp/scene.h
deleted file mode 100644
index 342c316d6..000000000
--- a/src/3rdparty/assimp/include/assimp/scene.h
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 scene.h
- * @brief Defines the data structures in which the imported scene is returned.
- */
-#pragma once
-#ifndef AI_SCENE_H_INC
-#define AI_SCENE_H_INC
-
-#include "types.h"
-#include "texture.h"
-#include "mesh.h"
-#include "light.h"
-#include "camera.h"
-#include "material.h"
-#include "anim.h"
-#include "metadata.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wattributes"
-#endif
-
-// -------------------------------------------------------------------------------
-/**
- * A node in the imported hierarchy.
- *
- * Each node has name, a parent node (except for the root node),
- * a transformation relative to its parent and possibly several child nodes.
- * Simple file formats don't support hierarchical structures - for these formats
- * the imported scene does consist of only a single root node without children.
- */
-// -------------------------------------------------------------------------------
-struct ASSIMP_API aiNode
-{
- /** The name of the node.
- *
- * The name might be empty (length of zero) but all nodes which
- * 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 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 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;
-
- /** The transformation relative to the node's parent. */
- C_STRUCT aiMatrix4x4 mTransformation;
-
- /** Parent node. NULL if this node is the root node. */
- C_STRUCT aiNode* mParent;
-
- /** The number of child nodes of this node. */
- unsigned int mNumChildren;
-
- /** The child nodes of this node. NULL if mNumChildren is 0. */
- C_STRUCT aiNode** mChildren;
-
- /** The number of meshes of this node. */
- unsigned int mNumMeshes;
-
- /** The meshes of this node. Each entry is an index into the
- * mesh list of the #aiScene.
- */
- 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();
-
- /** Construction from a specific name */
- explicit aiNode(const std::string& name);
-
- /** Destructor */
- ~aiNode();
-
- /** 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.
- *
- * @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);
- }
-
- const aiNode* FindNode(const char* name) const;
-
- aiNode* FindNode(const char* name);
-
- /**
- * @brief Will add new children.
- * @param numChildren Number of children to add.
- * @param children The array with pointers showing to the children.
- */
- void addChildren(unsigned int numChildren, aiNode **children);
-#endif // __cplusplus
-};
-
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-// -------------------------------------------------------------------------------
-/**
- * Specifies that the scene data structure that was imported is not complete.
- * This flag bypasses some internal validations and allows the import
- * of animation skeletons, material libraries or camera animation paths
- * using Assimp. Most applications won't support such data.
- */
-#define AI_SCENE_FLAGS_INCOMPLETE 0x1
-
-/**
- * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
- * if the validation is successful. In a validated scene you can be sure that
- * any cross references in the data structure (e.g. vertex indices) are valid.
- */
-#define AI_SCENE_FLAGS_VALIDATED 0x2
-
-/**
- * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
- * if the validation is successful but some issues have been found.
- * This can for example mean that a texture that does not exist is referenced
- * by a material or that the bone weights for a vertex don't sum to 1.0 ... .
- * In most cases you should still be able to use the import. This flag could
- * be useful for applications which don't capture Assimp's log output.
- */
-#define AI_SCENE_FLAGS_VALIDATION_WARNING 0x4
-
-/**
- * This flag is currently only set by the aiProcess_JoinIdenticalVertices step.
- * It indicates that the vertices of the output meshes aren't in the internal
- * verbose format anymore. In the verbose format all vertices are unique,
- * no vertex is ever referenced by more than one face.
- */
-#define AI_SCENE_FLAGS_NON_VERBOSE_FORMAT 0x8
-
- /**
- * Denotes pure height-map terrain data. Pure terrains usually consist of quads,
- * sometimes triangles, in a regular grid. The x,y coordinates of all vertex
- * positions refer to the x,y coordinates on the terrain height map, the z-axis
- * stores the elevation at a specific point.
- *
- * TER (Terragen) and HMP (3D Game Studio) are height map formats.
- * @note Assimp is probably not the best choice for loading *huge* terrains -
- * fully triangulated data takes extremely much free store and should be avoided
- * as long as possible (typically you'll do the triangulation when you actually
- * need to render it).
- */
-#define AI_SCENE_FLAGS_TERRAIN 0x10
-
- /**
- * Specifies that the scene data can be shared between structures. For example:
- * one vertex in few faces. \ref AI_SCENE_FLAGS_NON_VERBOSE_FORMAT can not be
- * used for this because \ref AI_SCENE_FLAGS_NON_VERBOSE_FORMAT has internal
- * meaning about postprocessing steps.
- */
-#define AI_SCENE_FLAGS_ALLOW_SHARED 0x20
-
-// -------------------------------------------------------------------------------
-/** The root structure of the imported data.
- *
- * Everything that was imported from the given file can be accessed from here.
- * Objects of this class are generally maintained and owned by Assimp, not
- * by the caller. You shouldn't want to instance it, nor should you ever try to
- * delete a given scene on your own.
- */
-// -------------------------------------------------------------------------------
-struct aiScene
-{
- /** Any combination of the AI_SCENE_FLAGS_XXX flags. By default
- * this value is 0, no flags are set. Most applications will
- * want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE
- * bit set.
- */
- unsigned int mFlags;
-
- /** The root node of the hierarchy.
- *
- * There will always be at least the root node if the import
- * was successful (and no special flags have been set).
- * Presence of further nodes depends on the format and content
- * of the imported file.
- */
- C_STRUCT aiNode* mRootNode;
-
- /** The number of meshes in the scene. */
- unsigned int mNumMeshes;
-
- /** The array of meshes.
- *
- * Use the indices given in the aiNode structure to access
- * this array. The array is mNumMeshes in size. If the
- * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always
- * be at least ONE material.
- */
- C_STRUCT aiMesh** mMeshes;
-
- /** The number of materials in the scene. */
- unsigned int mNumMaterials;
-
- /** The array of materials.
- *
- * Use the index given in each aiMesh structure to access this
- * array. The array is mNumMaterials in size. If the
- * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always
- * be at least ONE material.
- */
- C_STRUCT aiMaterial** mMaterials;
-
- /** The number of animations in the scene. */
- unsigned int mNumAnimations;
-
- /** The array of animations.
- *
- * All animations imported from the given file are listed here.
- * The array is mNumAnimations in size.
- */
- C_STRUCT aiAnimation** mAnimations;
-
- /** The number of textures embedded into the file */
- unsigned int mNumTextures;
-
- /** The array of embedded textures.
- *
- * Not many file formats embed their textures into the file.
- * An example is Quake's MDL format (which is also used by
- * some GameStudio versions)
- */
- C_STRUCT aiTexture** mTextures;
-
- /** The number of light sources in the scene. Light sources
- * are fully optional, in most cases this attribute will be 0
- */
- unsigned int mNumLights;
-
- /** The array of light sources.
- *
- * All light sources imported from the given file are
- * listed here. The array is mNumLights in size.
- */
- C_STRUCT aiLight** mLights;
-
- /** The number of cameras in the scene. Cameras
- * are fully optional, in most cases this attribute will be 0
- */
- unsigned int mNumCameras;
-
- /** The array of cameras.
- *
- * All cameras imported from the given file are listed here.
- * The array is mNumCameras in size. The first camera in the
- * array (if existing) is the default camera view into
- * the scene.
- */
- C_STRUCT aiCamera** mCameras;
-
-#ifdef __cplusplus
-
- //! Default constructor - set everything to 0/NULL
- ASSIMP_API aiScene();
-
- //! Destructor
- ASSIMP_API ~aiScene();
-
- //! Check whether the scene contains meshes
- //! Unless no special scene flags are set this will always be true.
- inline bool HasMeshes() const {
- return mMeshes != NULL && mNumMeshes > 0;
- }
-
- //! Check whether the scene contains materials
- //! Unless no special scene flags are set this will always be true.
- inline bool HasMaterials() const {
- return mMaterials != NULL && mNumMaterials > 0;
- }
-
- //! Check whether the scene contains lights
- inline bool HasLights() const {
- return mLights != NULL && mNumLights > 0;
- }
-
- //! Check whether the scene contains textures
- inline bool HasTextures() const {
- return mTextures != NULL && mNumTextures > 0;
- }
-
- //! Check whether the scene contains cameras
- inline bool HasCameras() const {
- return mCameras != NULL && mNumCameras > 0;
- }
-
- //! Check whether the scene contains animations
- inline bool HasAnimations() const {
- return mAnimations != NULL && mNumAnimations > 0;
- }
-
-#endif // __cplusplus
-
- /** Internal data, do not touch */
-#ifdef __cplusplus
- void* mPrivate;
-#else
- char* mPrivate;
-#endif
-
-};
-
-#ifdef __cplusplus
-} //! namespace Assimp
-#endif
-
-#endif // AI_SCENE_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/texture.h b/src/3rdparty/assimp/include/assimp/texture.h
deleted file mode 100644
index c09ef2cbe..000000000
--- a/src/3rdparty/assimp/include/assimp/texture.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 texture.h
- * @brief Defines texture helper structures for the library
- *
- * Used for file formats which embed their textures into the model file.
- * Supported are both normal textures, which are stored as uncompressed
- * pixels, and "compressed" textures, which are stored in a file format
- * such as PNG or TGA.
- */
-#pragma once
-#ifndef AI_TEXTURE_H_INC
-#define AI_TEXTURE_H_INC
-
-#include "types.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-// --------------------------------------------------------------------------------
-
-/** \def AI_EMBEDDED_TEXNAME_PREFIX
- * \ref AI_MAKE_EMBEDDED_TEXNAME
- */
-#ifndef AI_EMBEDDED_TEXNAME_PREFIX
-# define AI_EMBEDDED_TEXNAME_PREFIX "*"
-#endif
-
-/** @def AI_MAKE_EMBEDDED_TEXNAME
- * Used to build the reserved path name used by the material system to
- * reference textures that are embedded into their corresponding
- * model files. The parameter specifies the index of the texture
- * (zero-based, in the aiScene::mTextures array)
- */
-#if (!defined AI_MAKE_EMBEDDED_TEXNAME)
-# define AI_MAKE_EMBEDDED_TEXNAME(_n_) AI_EMBEDDED_TEXNAME_PREFIX # _n_
-#endif
-
-
-#include "./Compiler/pushpack1.h"
-
-// --------------------------------------------------------------------------------
-/** @brief Helper structure to represent a texel in a ARGB8888 format
-*
-* Used by aiTexture.
-*/
-struct aiTexel
-{
- unsigned char b,g,r,a;
-
-#ifdef __cplusplus
- //! Comparison operator
- bool operator== (const aiTexel& other) const
- {
- return b == other.b && r == other.r &&
- g == other.g && a == other.a;
- }
-
- //! Inverse comparison operator
- bool operator!= (const aiTexel& other) const
- {
- return b != other.b || r != other.r ||
- g != other.g || a != other.a;
- }
-
- //! Conversion to a floating-point 4d color
- operator aiColor4D() const
- {
- return aiColor4D(r/255.f,g/255.f,b/255.f,a/255.f);
- }
-#endif // __cplusplus
-
-} PACK_STRUCT;
-
-#include "./Compiler/poppack1.h"
-
-// --------------------------------------------------------------------------------
-/** Helper structure to describe an embedded texture
- *
- * Normally textures are contained in external files but some file formats embed
- * them directly in the model file. There are two types of embedded textures:
- * 1. Uncompressed textures. The color data is given in an uncompressed format.
- * 2. Compressed textures stored in a file format like png or jpg. The raw file
- * bytes are given so the application must utilize an image decoder (e.g. DevIL) to
- * get access to the actual color data.
- *
- * Embedded textures are referenced from materials using strings like "*0", "*1", etc.
- * as the texture paths (a single asterisk character followed by the
- * zero-based index of the texture in the aiScene::mTextures array).
- */
-struct aiTexture
-{
- /** Width of the texture, in pixels
- *
- * If mHeight is zero the texture is compressed in a format
- * like JPEG. In this case mWidth specifies the size of the
- * memory area pcData is pointing to, in bytes.
- */
- unsigned int mWidth;
-
- /** Height of the texture, in pixels
- *
- * If this value is zero, pcData points to an compressed texture
- * in any format (e.g. JPEG).
- */
- unsigned int mHeight;
-
- /** A hint from the loader to make it easier for applications
- * to determine the type of embedded textures.
- *
- * If mHeight != 0 this member is show how data is packed. Hint will consist of
- * two parts: channel order and channel bitness (count of the bits for every
- * color channel). For simple parsing by the viewer it's better to not omit
- * absent color channel and just use 0 for bitness. For example:
- * 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888";
- * 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888";
- * 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650";
- * 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010";
- * If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional
- * information about the texture file format used OR the
- * file extension of the format without a trailing dot. If there
- * are multiple file extensions for a format, the shortest
- * extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
- * E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case.
- * The fourth character will always be '\\0'.
- */
- char achFormatHint[9];// 8 for string + 1 for terminator.
-
- /** Data of the texture.
- *
- * Points to an array of mWidth * mHeight aiTexel's.
- * The format of the texture data is always ARGB8888 to
- * make the implementation for user of the library as easy
- * as possible. If mHeight = 0 this is a pointer to a memory
- * buffer of size mWidth containing the compressed texture
- * data. Good luck, have fun!
- */
- C_STRUCT aiTexel* pcData;
-
-#ifdef __cplusplus
-
- //! For compressed textures (mHeight == 0): compare the
- //! format hint against a given string.
- //! @param s Input string. 3 characters are maximally processed.
- //! Example values: "jpg", "png"
- //! @return true if the given string matches the format hint
- bool CheckFormat(const char* s) const
- {
- return (0 == ::strncmp(achFormatHint, s, sizeof(achFormatHint)));
- }
-
- // Construction
- aiTexture ()
- : mWidth (0)
- , mHeight (0)
- , pcData (NULL)
- {
- achFormatHint[0] = achFormatHint[1] = 0;
- achFormatHint[2] = achFormatHint[3] = 0;
- }
-
- // Destruction
- ~aiTexture ()
- {
- delete[] pcData;
- }
-#endif
-};
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // AI_TEXTURE_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/types.h b/src/3rdparty/assimp/include/assimp/types.h
deleted file mode 100644
index 0012a0bba..000000000
--- a/src/3rdparty/assimp/include/assimp/types.h
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 types.h
- * Basic data types and primitives, such as vectors or colors.
- */
-#pragma once
-#ifndef AI_TYPES_H_INC
-#define AI_TYPES_H_INC
-
-// Some runtime headers
-#include <sys/types.h>
-#include <stddef.h>
-#include <string.h>
-#include <limits.h>
-
-// Our compile configuration
-#include "defs.h"
-
-// Some types moved to separate header due to size of operators
-#include "vector3.h"
-#include "vector2.h"
-#include "color4.h"
-#include "matrix3x3.h"
-#include "matrix4x4.h"
-#include "quaternion.h"
-
-#ifdef __cplusplus
-#include <cstring>
-#include <new> // for std::nothrow_t
-#include <string> // for aiString::Set(const std::string&)
-
-namespace Assimp {
- //! @cond never
-namespace Intern {
- // --------------------------------------------------------------------
- /** @brief Internal helper class to utilize our internal new/delete
- * routines for allocating object of this and derived classes.
- *
- * By doing this you can safely share class objects between Assimp
- * and the application - it works even over DLL boundaries. A good
- * example is the #IOSystem where the application allocates its custom
- * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer
- * destructs, Assimp calls operator delete on the stored #IOSystem.
- * If it lies on a different heap than Assimp is working with,
- * the application is determined to crash.
- */
- // --------------------------------------------------------------------
-#ifndef SWIG
- struct ASSIMP_API AllocateFromAssimpHeap {
- // http://www.gotw.ca/publications/mill15.htm
-
- // new/delete overload
- void *operator new ( size_t num_bytes) /* throw( std::bad_alloc ) */;
- void *operator new ( size_t num_bytes, const std::nothrow_t& ) throw();
- void operator delete ( void* data);
-
- // array new/delete overload
- void *operator new[] ( size_t num_bytes) /* throw( std::bad_alloc ) */;
- void *operator new[] ( size_t num_bytes, const std::nothrow_t& ) throw();
- void operator delete[] ( void* data);
-
- }; // struct AllocateFromAssimpHeap
-#endif
-} // namespace Intern
- //! @endcond
-} // namespace Assimp
-
-extern "C" {
-#endif
-
-/** Maximum dimension for strings, ASSIMP strings are zero terminated. */
-#ifdef __cplusplus
-static
-const size_t MAXLEN = 1024;
-#else
-# define MAXLEN 1024
-#endif
-
-// ----------------------------------------------------------------------------------
-/** Represents a plane in a three-dimensional, euclidean space
-*/
-struct aiPlane
-{
-#ifdef __cplusplus
- aiPlane () : a(0.f), b(0.f), c(0.f), d(0.f) {}
- aiPlane (ai_real _a, ai_real _b, ai_real _c, ai_real _d)
- : a(_a), b(_b), c(_c), d(_d) {}
-
- aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {}
-
-#endif // !__cplusplus
-
- //! Plane equation
- ai_real a,b,c,d;
-}; // !struct aiPlane
-
-// ----------------------------------------------------------------------------------
-/** Represents a ray
-*/
-struct aiRay
-{
-#ifdef __cplusplus
- aiRay () {}
- aiRay (const aiVector3D& _pos, const aiVector3D& _dir)
- : pos(_pos), dir(_dir) {}
-
- aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {}
-
-#endif // !__cplusplus
-
- //! Position and direction of the ray
- C_STRUCT aiVector3D pos, dir;
-}; // !struct aiRay
-
-// ----------------------------------------------------------------------------------
-/** Represents a color in Red-Green-Blue space.
-*/
-struct aiColor3D
-{
-#ifdef __cplusplus
- aiColor3D () : r(0.0f), g(0.0f), b(0.0f) {}
- aiColor3D (ai_real _r, ai_real _g, ai_real _b) : r(_r), g(_g), b(_b) {}
- explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {}
- aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {}
-
- /** Component-wise comparison */
- // TODO: add epsilon?
- bool operator == (const aiColor3D& other) const
- {return r == other.r && g == other.g && b == other.b;}
-
- /** Component-wise inverse comparison */
- // TODO: add epsilon?
- 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);
- }
-
- /** Component-wise subtraction */
- aiColor3D operator-(const aiColor3D& c) const {
- return aiColor3D(r-c.r,g-c.g,b-c.b);
- }
-
- /** Component-wise multiplication */
- aiColor3D operator*(const aiColor3D& c) const {
- return aiColor3D(r*c.r,g*c.g,b*c.b);
- }
-
- /** Multiply with a scalar */
- aiColor3D operator*(ai_real f) const {
- return aiColor3D(r*f,g*f,b*f);
- }
-
- /** Access a specific color component */
- ai_real operator[](unsigned int i) const {
- return *(&r + i);
- }
-
- /** Access a specific color component */
- ai_real& operator[](unsigned int i) {
- if ( 0 == i ) {
- return r;
- } else if ( 1 == i ) {
- return g;
- } else if ( 2 == i ) {
- return b;
- }
- return r;
- }
-
- /** Check whether a color is black */
- bool IsBlack() const {
- static const ai_real epsilon = ai_real(10e-3);
- return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
- }
-
-#endif // !__cplusplus
-
- //! Red, green and blue color values
- ai_real r, g, b;
-}; // !struct aiColor3D
-
-// ----------------------------------------------------------------------------------
-/** Represents an UTF-8 string, zero byte terminated.
- *
- * The character set of an aiString is explicitly defined to be UTF-8. This Unicode
- * transformation was chosen in the belief that most strings in 3d files are limited
- * to ASCII, thus the character set needed to be strictly ASCII compatible.
- *
- * Most text file loaders provide proper Unicode input file handling, special unicode
- * characters are correctly transcoded to UTF8 and are kept throughout the libraries'
- * import pipeline.
- *
- * For most applications, it will be absolutely sufficient to interpret the
- * aiString as ASCII data and work with it as one would work with a plain char*.
- * Windows users in need of proper support for i.e asian characters can use the
- * MultiByteToWideChar(), WideCharToMultiByte() WinAPI functionality to convert the
- * UTF-8 strings to their working character set (i.e. MBCS, WideChar).
- *
- * We use this representation instead of std::string to be C-compatible. The
- * (binary) length of such a string is limited to MAXLEN characters (including the
- * the terminating zero).
-*/
-struct aiString
-{
-#ifdef __cplusplus
- /** Default constructor, the string is set to have zero length */
- aiString() :
- length(0)
- {
- data[0] = '\0';
-
-#ifdef ASSIMP_BUILD_DEBUG
- // Debug build: overwrite the string on its full length with ESC (27)
- memset(data+1,27,MAXLEN-1);
-#endif
- }
-
- /** Copy constructor */
- aiString(const aiString& rOther) :
- length(rOther.length)
- {
- // Crop the string to the maximum length
- length = length>=MAXLEN?MAXLEN-1:length;
- memcpy( data, rOther.data, length);
- data[length] = '\0';
- }
-
- /** Constructor from std::string */
- explicit aiString(const std::string& pString) :
- length(pString.length())
- {
- length = length>=MAXLEN?MAXLEN-1:length;
- memcpy( data, pString.c_str(), length);
- data[length] = '\0';
- }
-
- /** Copy a std::string to the aiString */
- void Set( const std::string& pString) {
- if( pString.length() > MAXLEN - 1) {
- return;
- }
- length = pString.length();
- memcpy( data, pString.c_str(), length);
- data[length] = 0;
- }
-
- /** Copy a const char* to the aiString */
- void Set( const char* sz) {
- const size_t len = ::strlen(sz);
- if( len > MAXLEN - 1) {
- return;
- }
- length = len;
- memcpy( data, sz, len);
- data[len] = 0;
- }
-
- /** Assign a const char* to the string */
- aiString& operator = (const char* sz) {
- Set(sz);
- return *this;
- }
-
- /** Assign a cstd::string to the string */
- aiString& operator = ( const std::string& pString) {
- Set(pString);
- return *this;
- }
-
- /** Comparison operator */
- bool operator==(const aiString& other) const {
- return (length == other.length && 0 == memcmp(data,other.data,length));
- }
-
- /** Inverse comparison operator */
- bool operator!=(const aiString& other) const {
- return (length != other.length || 0 != memcmp(data,other.data,length));
- }
-
- /** Append a string to the string */
- void Append (const char* app) {
- const size_t len = ::strlen(app);
- if (!len) {
- return;
- }
- if (length + len >= MAXLEN) {
- return;
- }
-
- memcpy(&data[length],app,len+1);
- length += len;
- }
-
- /** Clear the string - reset its length to zero */
- void Clear () {
- length = 0;
- data[0] = '\0';
-
-#ifdef ASSIMP_BUILD_DEBUG
- // Debug build: overwrite the string on its full length with ESC (27)
- memset(data+1,27,MAXLEN-1);
-#endif
- }
-
- /** Returns a pointer to the underlying zero-terminated array of characters */
- const char* C_Str() const {
- return data;
- }
-
-#endif // !__cplusplus
-
- /** Binary length of the string excluding the terminal 0. This is NOT the
- * logical length of strings containing UTF-8 multibyte sequences! It's
- * the number of bytes from the beginning of the string to its end.*/
- size_t length;
-
- /** String buffer. Size limit is MAXLEN */
- char data[MAXLEN];
-} ; // !struct aiString
-
-
-// ----------------------------------------------------------------------------------
-/** Standard return type for some library functions.
- * Rarely used, and if, mostly in the C API.
- */
-typedef enum aiReturn
-{
- /** Indicates that a function was successful */
- aiReturn_SUCCESS = 0x0,
-
- /** Indicates that a function failed */
- aiReturn_FAILURE = -0x1,
-
- /** Indicates that not enough memory was available
- * to perform the requested operation
- */
- aiReturn_OUTOFMEMORY = -0x3,
-
- /** @cond never
- * Force 32-bit size enum
- */
- _AI_ENFORCE_ENUM_SIZE = 0x7fffffff
-
- /// @endcond
-} aiReturn; // !enum aiReturn
-
-// just for backwards compatibility, don't use these constants anymore
-#define AI_SUCCESS aiReturn_SUCCESS
-#define AI_FAILURE aiReturn_FAILURE
-#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY
-
-// ----------------------------------------------------------------------------------
-/** Seek origins (for the virtual file system API).
- * Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END.
- */
-enum aiOrigin
-{
- /** Beginning of the file */
- aiOrigin_SET = 0x0,
-
- /** Current position of the file pointer */
- aiOrigin_CUR = 0x1,
-
- /** End of the file, offsets must be negative */
- aiOrigin_END = 0x2,
-
- /** @cond never
- * Force 32-bit size enum
- */
- _AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff
-
- /// @endcond
-}; // !enum aiOrigin
-
-// ----------------------------------------------------------------------------------
-/** @brief Enumerates predefined log streaming destinations.
- * Logging to these streams can be enabled with a single call to
- * #LogStream::createDefaultStream.
- */
-enum aiDefaultLogStream
-{
- /** Stream the log to a file */
- aiDefaultLogStream_FILE = 0x1,
-
- /** Stream the log to std::cout */
- aiDefaultLogStream_STDOUT = 0x2,
-
- /** Stream the log to std::cerr */
- aiDefaultLogStream_STDERR = 0x4,
-
- /** MSVC only: Stream the log the the debugger
- * (this relies on OutputDebugString from the Win32 SDK)
- */
- aiDefaultLogStream_DEBUGGER = 0x8,
-
- /** @cond never
- * Force 32-bit size enum
- */
- _AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff
- /// @endcond
-}; // !enum aiDefaultLogStream
-
-// just for backwards compatibility, don't use these constants anymore
-#define DLS_FILE aiDefaultLogStream_FILE
-#define DLS_STDOUT aiDefaultLogStream_STDOUT
-#define DLS_STDERR aiDefaultLogStream_STDERR
-#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER
-
-// ----------------------------------------------------------------------------------
-/** Stores the memory requirements for different components (e.g. meshes, materials,
- * animations) of an import. All sizes are in bytes.
- * @see Importer::GetMemoryRequirements()
-*/
-struct aiMemoryInfo
-{
-#ifdef __cplusplus
-
- /** Default constructor */
- aiMemoryInfo()
- : textures (0)
- , materials (0)
- , meshes (0)
- , nodes (0)
- , animations (0)
- , cameras (0)
- , lights (0)
- , total (0)
- {}
-
-#endif
-
- /** Storage allocated for texture data */
- unsigned int textures;
-
- /** Storage allocated for material data */
- unsigned int materials;
-
- /** Storage allocated for mesh data */
- unsigned int meshes;
-
- /** Storage allocated for node data */
- unsigned int nodes;
-
- /** Storage allocated for animation data */
- unsigned int animations;
-
- /** Storage allocated for camera data */
- unsigned int cameras;
-
- /** Storage allocated for light data */
- unsigned int lights;
-
- /** Total storage allocated for the full import. */
- unsigned int total;
-}; // !struct aiMemoryInfo
-
-#ifdef __cplusplus
-}
-#endif //! __cplusplus
-
-// Include implementation files
-#include "vector2.inl"
-#include "vector3.inl"
-#include "color4.inl"
-#include "quaternion.inl"
-#include "matrix3x3.inl"
-#include "matrix4x4.inl"
-
-#endif // AI_TYPES_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/vector2.h b/src/3rdparty/assimp/include/assimp/vector2.h
deleted file mode 100644
index 564d1f8b5..000000000
--- a/src/3rdparty/assimp/include/assimp/vector2.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 vector2.h
- * @brief 2D vector structure, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_VECTOR2D_H_INC
-#define AI_VECTOR2D_H_INC
-
-#ifdef __cplusplus
-# include <cmath>
-#else
-# include <math.h>
-#endif
-
-#include "./Compiler/pushpack1.h"
-#include "defs.h"
-
-// ----------------------------------------------------------------------------------
-/** Represents a two-dimensional vector.
- */
-
-#ifdef __cplusplus
-template <typename TReal>
-class aiVector2t
-{
-public:
-
- aiVector2t () : x(), y() {}
- aiVector2t (TReal _x, TReal _y) : x(_x), y(_y) {}
- explicit aiVector2t (TReal _xyz) : x(_xyz), y(_xyz) {}
- aiVector2t (const aiVector2t& o) : x(o.x), y(o.y) {}
-
-public:
-
- void Set( TReal pX, TReal pY);
- TReal SquareLength() const ;
- TReal Length() const ;
- aiVector2t& Normalize();
-
-public:
-
- const aiVector2t& operator += (const aiVector2t& o);
- const aiVector2t& operator -= (const aiVector2t& o);
- const aiVector2t& operator *= (TReal f);
- const aiVector2t& operator /= (TReal f);
-
- TReal operator[](unsigned int i) const;
- TReal& operator[](unsigned int i);
-
- 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);
-
- template <typename TOther>
- operator aiVector2t<TOther> () const;
-
- TReal x, y;
-} PACK_STRUCT;
-
-typedef aiVector2t<ai_real> aiVector2D;
-
-#else
-
-struct aiVector2D {
- ai_real x, y;
-};
-
-#endif // __cplusplus
-
-#include "./Compiler/poppack1.h"
-
-#endif // AI_VECTOR2D_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/vector2.inl b/src/3rdparty/assimp/include/assimp/vector2.inl
deleted file mode 100644
index 5ce13eece..000000000
--- a/src/3rdparty/assimp/include/assimp/vector2.inl
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 vector2.inl
- * @brief Inline implementation of aiVector2t<TReal> operators
- */
-#pragma once
-#ifndef AI_VECTOR2D_INL_INC
-#define AI_VECTOR2D_INL_INC
-
-#ifdef __cplusplus
-#include "vector2.h"
-
-#include <cmath>
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-template <typename TOther>
-aiVector2t<TReal>::operator aiVector2t<TOther> () const {
- return aiVector2t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y));
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-void aiVector2t<TReal>::Set( TReal pX, TReal pY) {
- x = pX; y = pY;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-TReal aiVector2t<TReal>::SquareLength() const {
- return x*x + y*y;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-TReal aiVector2t<TReal>::Length() const {
- return std::sqrt( SquareLength());
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-aiVector2t<TReal>& aiVector2t<TReal>::Normalize() {
- *this /= Length();
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-const aiVector2t<TReal>& aiVector2t<TReal>::operator += (const aiVector2t& o) {
- x += o.x; y += o.y;
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-const aiVector2t<TReal>& aiVector2t<TReal>::operator -= (const aiVector2t& o) {
- x -= o.x; y -= o.y;
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-const aiVector2t<TReal>& aiVector2t<TReal>::operator *= (TReal f) {
- x *= f; y *= f;
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-const aiVector2t<TReal>& aiVector2t<TReal>::operator /= (TReal f) {
- x /= f; y /= f;
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-TReal aiVector2t<TReal>::operator[](unsigned int i) const {
- return *(&x + i);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-TReal& aiVector2t<TReal>::operator[](unsigned int i) {
- return *(&x + i);
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-bool aiVector2t<TReal>::operator== (const aiVector2t& other) const {
- return x == other.x && y == other.y;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-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) {
- x = y = f;
- return *this;
-}
-
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-const aiVector2t<TReal> aiVector2t<TReal>::SymMul(const aiVector2t& o) {
- return aiVector2t(x*o.x,y*o.y);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// symmetric addition
-template <typename TReal>
-inline aiVector2t<TReal> operator + (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
-{
- return aiVector2t<TReal>( v1.x + v2.x, v1.y + v2.y);
-}
-
-// ------------------------------------------------------------------------------------------------
-// symmetric subtraction
-template <typename TReal>
-inline aiVector2t<TReal> operator - (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
-{
- return aiVector2t<TReal>( v1.x - v2.x, v1.y - v2.y);
-}
-
-// ------------------------------------------------------------------------------------------------
-// scalar product
-template <typename TReal>
-inline TReal operator * (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
-{
- return v1.x*v2.x + v1.y*v2.y;
-}
-
-// ------------------------------------------------------------------------------------------------
-// scalar multiplication
-template <typename TReal>
-inline aiVector2t<TReal> operator * ( TReal f, const aiVector2t<TReal>& v)
-{
- return aiVector2t<TReal>( f*v.x, f*v.y);
-}
-
-// ------------------------------------------------------------------------------------------------
-// and the other way around
-template <typename TReal>
-inline aiVector2t<TReal> operator * ( const aiVector2t<TReal>& v, TReal f)
-{
- return aiVector2t<TReal>( f*v.x, f*v.y);
-}
-
-// ------------------------------------------------------------------------------------------------
-// scalar division
-template <typename TReal>
-inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, TReal f)
-{
-
- return v * (1/f);
-}
-
-// ------------------------------------------------------------------------------------------------
-// vector division
-template <typename TReal>
-inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, const aiVector2t<TReal>& v2)
-{
- return aiVector2t<TReal>(v.x / v2.x,v.y / v2.y);
-}
-
-// ------------------------------------------------------------------------------------------------
-// vector negation
-template <typename TReal>
-inline aiVector2t<TReal> operator - ( const aiVector2t<TReal>& v)
-{
- return aiVector2t<TReal>( -v.x, -v.y);
-}
-
-#endif
-
-#endif // AI_VECTOR2D_INL_INC
diff --git a/src/3rdparty/assimp/include/assimp/vector3.h b/src/3rdparty/assimp/include/assimp/vector3.h
deleted file mode 100644
index 641dab795..000000000
--- a/src/3rdparty/assimp/include/assimp/vector3.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 vector3.h
- * @brief 3D vector structure, including operators when compiling in C++
- */
-#pragma once
-#ifndef AI_VECTOR3D_H_INC
-#define AI_VECTOR3D_H_INC
-
-#ifdef __cplusplus
-# include <cmath>
-#else
-# include <math.h>
-#endif
-
-#include "defs.h"
-
-#ifdef __cplusplus
-
-template<typename TReal> class aiMatrix3x3t;
-template<typename TReal> class aiMatrix4x4t;
-
-// ---------------------------------------------------------------------------
-/** Represents a three-dimensional vector. */
-template <typename TReal>
-class aiVector3t
-{
-public:
- aiVector3t() : x(), y(), z() {}
- aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
- explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {}
- aiVector3t( const aiVector3t& o ) : x(o.x), y(o.y), z(o.z) {}
-
-public:
-
- // combined operators
- const aiVector3t& operator += (const aiVector3t& o);
- const aiVector3t& operator -= (const aiVector3t& o);
- const aiVector3t& operator *= (TReal f);
- const aiVector3t& operator /= (TReal f);
-
- // transform vector by matrix
- aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat);
- aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat);
-
- // access a single element
- TReal operator[](unsigned int i) const;
- TReal& operator[](unsigned int i);
-
- // comparison
- bool operator== (const aiVector3t& other) const;
- 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;
-
-public:
- /** @brief Set the components of a vector
- * @param pX X component
- * @param pY Y component
- * @param pZ Z component */
- void Set( TReal pX, TReal pY, TReal pZ);
-
- /** @brief Get the squared length of the vector
- * @return Square length */
- TReal SquareLength() const;
-
- /** @brief Get the length of the vector
- * @return length */
- TReal Length() const;
-
-
- /** @brief Normalize the vector */
- aiVector3t& Normalize();
-
- /** @brief Normalize the vector with extra check for zero vectors */
- aiVector3t& NormalizeSafe();
-
- /** @brief Componentwise multiplication of two vectors
- *
- * Note that vec*vec yields the dot product.
- * @param o Second factor */
- const aiVector3t SymMul(const aiVector3t& o);
-
- TReal x, y, z;
-};
-
-
-typedef aiVector3t<ai_real> aiVector3D;
-
-#else
-
-struct aiVector3D {
- ai_real x, y, z;
-};
-
-#endif // __cplusplus
-
-#ifdef __cplusplus
-
-#endif // __cplusplus
-
-#endif // AI_VECTOR3D_H_INC
diff --git a/src/3rdparty/assimp/include/assimp/vector3.inl b/src/3rdparty/assimp/include/assimp/vector3.inl
deleted file mode 100644
index a074bb23a..000000000
--- a/src/3rdparty/assimp/include/assimp/vector3.inl
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 vector3.inl
- * @brief Inline implementation of aiVector3t<TReal> operators
- */
-#pragma once
-#ifndef AI_VECTOR3D_INL_INC
-#define AI_VECTOR3D_INL_INC
-
-#ifdef __cplusplus
-#include "vector3.h"
-
-#include <cmath>
-
-// ------------------------------------------------------------------------------------------------
-/** Transformation of a vector by a 3x3 matrix */
-template <typename TReal>
-inline aiVector3t<TReal> operator * (const aiMatrix3x3t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
-{
- aiVector3t<TReal> res;
- res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z;
- res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z;
- res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z;
- return res;
-}
-
-// ------------------------------------------------------------------------------------------------
-/** Transformation of a vector by a 4x4 matrix */
-template <typename TReal>
-inline aiVector3t<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
-{
- aiVector3t<TReal> res;
- res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z + pMatrix.a4;
- res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z + pMatrix.b4;
- res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z + pMatrix.c4;
- return res;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-template <typename TOther>
-aiVector3t<TReal>::operator aiVector3t<TOther> () const {
- return aiVector3t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y),static_cast<TOther>(z));
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE void aiVector3t<TReal>::Set( TReal pX, TReal pY, TReal pZ) {
- x = pX; y = pY; z = pZ;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal aiVector3t<TReal>::SquareLength() const {
- return x*x + y*y + z*z;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal aiVector3t<TReal>::Length() const {
- return std::sqrt( SquareLength());
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::Normalize() {
- *this /= Length(); return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::NormalizeSafe() {
- TReal len = Length();
- if (len > static_cast<TReal>(0))
- *this /= len;
- return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator += (const aiVector3t<TReal>& o) {
- x += o.x; y += o.y; z += o.z; return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator -= (const aiVector3t<TReal>& o) {
- x -= o.x; y -= o.y; z -= o.z; return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator *= (TReal f) {
- x *= f; y *= f; z *= f; return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator /= (TReal f) {
- x /= f; y /= f; z /= f; return *this;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& mat){
- return(*this = mat * (*this));
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){
- return(*this = mat * (*this));
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal aiVector3t<TReal>::operator[](unsigned int i) const {
-// return *(&x + i);
- switch (i) {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- default:
- break;
- }
- return x;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE TReal& aiVector3t<TReal>::operator[](unsigned int i) {
-// return *(&x + i);
- switch (i) {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- default:
- break;
- }
- return x;
-}
-// ------------------------------------------------------------------------------------------------
-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>::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 bool aiVector3t<TReal>::operator < (const aiVector3t<TReal>& other) const {
- return x != other.x ? x < other.x : y != other.y ? y < other.y : z < other.z;
-}
-// ------------------------------------------------------------------------------------------------
-template <typename TReal>
-AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
- return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
-}
-// ------------------------------------------------------------------------------------------------
-// symmetric addition
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator + (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
- return aiVector3t<TReal>( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
-}
-// ------------------------------------------------------------------------------------------------
-// symmetric subtraction
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator - (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
- return aiVector3t<TReal>( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
-}
-// ------------------------------------------------------------------------------------------------
-// scalar product
-template <typename TReal>
-AI_FORCE_INLINE TReal operator * (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
- return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
-}
-// ------------------------------------------------------------------------------------------------
-// scalar multiplication
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator * ( TReal f, const aiVector3t<TReal>& v) {
- return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
-}
-// ------------------------------------------------------------------------------------------------
-// and the other way around
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator * ( const aiVector3t<TReal>& v, TReal f) {
- return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
-}
-// ------------------------------------------------------------------------------------------------
-// scalar division
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, TReal f) {
- return v * (1/f);
-}
-// ------------------------------------------------------------------------------------------------
-// vector division
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, const aiVector3t<TReal>& v2) {
- return aiVector3t<TReal>(v.x / v2.x,v.y / v2.y,v.z / v2.z);
-}
-// ------------------------------------------------------------------------------------------------
-// cross product
-template <typename TReal>
-AI_FORCE_INLINE aiVector3t<TReal> operator ^ ( const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
- return aiVector3t<TReal>( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
-}
-// ------------------------------------------------------------------------------------------------
-// vector negation
-template <typename TReal>
-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
deleted file mode 100644
index d1821fa2b..000000000
--- a/src/3rdparty/assimp/include/assimp/version.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2017, 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 version.h
- * @brief Functions to query the version of the Assimp runtime, check
- * compile flags, ...
- */
-#pragma once
-#ifndef AI_VERSION_H_INC
-#define AI_VERSION_H_INC
-
-#include "defs.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// ---------------------------------------------------------------------------
-/** @brief Returns a string with legal copyright and licensing information
- * about Assimp. The string may include multiple lines.
- * @return Pointer to static string.
- */
-ASSIMP_API const char* aiGetLegalString (void);
-
-// ---------------------------------------------------------------------------
-/** @brief Returns the current minor version number of Assimp.
- * @return Minor version of the Assimp runtime the application was
- * linked/built against
- */
-ASSIMP_API unsigned int aiGetVersionMinor (void);
-
-// ---------------------------------------------------------------------------
-/** @brief Returns the current major version number of Assimp.
- * @return Major version of the Assimp runtime the application was
- * linked/built against
- */
-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.
- */
-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
-#define ASSIMP_CFLAGS_STLPORT 0x2
-//! Assimp was compiled as a debug build
-#define ASSIMP_CFLAGS_DEBUG 0x4
-
-//! Assimp was compiled with ASSIMP_BUILD_BOOST_WORKAROUND defined
-#define ASSIMP_CFLAGS_NOBOOST 0x8
-//! Assimp was compiled with ASSIMP_BUILD_SINGLETHREADED defined
-#define ASSIMP_CFLAGS_SINGLETHREADED 0x10
-
-// ---------------------------------------------------------------------------
-/** @brief Returns assimp's compile flags
- * @return Any bitwise combination of the ASSIMP_CFLAGS_xxx constants.
- */
-ASSIMP_API unsigned int aiGetCompileFlags (void);
-
-#ifdef __cplusplus
-} // end extern "C"
-#endif
-
-#endif // !! #ifndef AI_VERSION_H_INC
-
diff --git a/src/3rdparty/assimp/qt_attribution.json b/src/3rdparty/assimp/qt_attribution.json
index e9a47c184..ccb148095 100644
--- a/src/3rdparty/assimp/qt_attribution.json
+++ b/src/3rdparty/assimp/qt_attribution.json
@@ -1,139 +1,14 @@
-[
- {
- "Id": "assimp",
- "Name": "Assimp - Open Asset Import Library",
- "QDocModule": "qt3d",
- "Description": "assimp (Open Asset Import Library) is a portable open source library to import various well-known 3D model formats in a uniform manner.",
- "QtUsage": "Used in Qt 3D.",
-
- "Homepage": "http://www.assimp.org/",
- "Version": "4.1.0",
- "License": "BSD 3-Clause \"New\" or \"Revised\" License",
- "LicenseId": "BSD-3-Clause",
- "LicenseFile": "LICENSE",
- "Copyright": "Copyright (c) 2006-2018, assimp team"
- },
- {
- "Id": "assimp-clipper",
- "Name": "Assimp - Clipper",
- "QDocModule": "qt3d",
- "Description": "",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/clipper",
-
- "Homepage": "http://www.angusj.com/delphi/clipper.php",
- "Version": "4.8.8",
- "License": "Boost Software License 1.0",
- "LicenseId": "BSL-1.0",
- "LicenseFile": "contrib/clipper/License.txt",
- "Copyright": "Copyright Angus Johnson 2010-2012"
- },
- {
- "Id": "assimp-irrXML",
- "Name": "Assimp - irrXML",
- "QDocModule": "qt3d",
- "Description": "Simple and fast open source xml parser for C++",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/irrXML",
-
- "Homepage": "https://www.ambiera.com/irrxml/",
- "License": "zlib License",
- "LicenseId": "Zlib",
- "LicenseFile": "contrib/clipper/License.txt",
- "Copyright": "Copyright (C) 2002-2005 Nikolaus Gebhardt"
- },
- {
- "Id": "assimp-Open3DGC",
- "Name": "Assimp - Open3DGC",
- "QDocModule": "qt3d",
- "Description": "Open 3D Graphics Compression",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/Open3DGC",
-
- "License": "MIT License and BSD 2-Clause \"Simplified\" License",
- "LicenseId": "MIT AND BSD-2-Clause",
- "LicenseFile": "LICENSE_Open3DGC.txt",
- "Copyright": "Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc\nCopyright (c) 2004 Amir Said (said@ieee.org) & William A. Pearlman (pearlw@ecse.rpi.edu)"
- },
- {
- "Id": "assimp-openddlparser",
- "Name": "Assimp - The OpenDDL-Parser",
- "QDocModule": "qt3d",
- "Description": "The OpenDDL-Parser is a small and easy to use library for OpenDDL-file-format-parsing.",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/openddlparser",
-
- "License": "MIT License",
- "LicenseId": "MIT",
- "LicenseFile": "contrib/openddlparser/LICENSE",
- "Copyright": "Copyright (c) 2014-2015 Kim Kulling"
- },
- {
- "Id": "assimp-poly2tri",
- "Name": "Assimp - Poly2Tri Polygon Triangulation Library",
- "QDocModule": "qt3d",
- "Description": "Poly2Tri is a sweepline constrained Delaunay Polygon Triangulation Library.",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/poly2tri",
-
- "Homepage": "https://github.com/greenm01/poly2tri",
- "LicenseId": "BSD-3-Clause",
- "License": "BSD 3-clause \"New\" or \"Revised\" License",
- "LicenseFile": "contrib/poly2tri/LICENSE",
- "Copyright": "Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors"
- },
- {
- "Id": "assimp-rapidjson",
- "Name": "Assimp - RapidJSON",
- "QDocModule": "qt3d",
- "Description": "RapidJSON is a JSON parser and generator for C++. Note that the bin/jsonchecker/ directory mentioned in the license is not included.",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/openddlparser",
-
- "License": "MIT License and BSD 3-Clause \"New\" or \"Revised\" License",
- "LicenseId": "MIT AND BSD-3-Clause",
- "LicenseFile": "contrib/rapidjson/license.txt",
- "Copyright": "Copyright (c) 2006-2013 Alexander Chemeris\nCopyright (C) 2015 THL A29 Limited\nCopyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip"
- },
- {
- "Id": "assimp-unzip",
- "Name": "Assimp - Unzip",
- "QDocModule": "qt3d",
- "Description": "IO for uncompress .zip files using zlib",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/unzip",
-
- "Homepage": "http://www.winimage.com/zLibDll/",
- "Version": "1.01e",
- "License": "zlib License",
- "LicenseId": "Zlib",
- "LicenseFile": "LICENSE_unzip.txt",
- "Copyright": "Copyright 1998-2004 Gilles Vollant"
- },
- {
- "Id": "assimp-utf8cpp",
- "Name": "Assimp - Utf8Cpp",
- "QDocModule": "qt3d",
- "Description": "UTF-8 with C++ in a Portable Way",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/utf8cpp",
-
- "Homepage": "https://sourceforge.net/projects/utfcpp/",
- "License": "Boost Software License 1.0",
- "LicenseId": "BSL-1.0",
- "LicenseFile": "LICENSE_utf8cpp.txt",
- "Copyright": "Copyright 2006 Nemanja Trifunovic"
- },
- {
- "Id": "assimp-zip",
- "Name": "Assimp - Zip",
- "QDocModule": "qt3d",
- "Description": "A portable (OSX/Linux/Windows), simple zip library written in C",
- "QtUsage": "Used in Qt 3D.",
- "Files": "contrib/zip",
-
- "License": "Public Domain",
- "LicenseFile": "LICENSE_zip.txt",
- "Copyright": ""
- }
-]
+{
+ "Id": "assimp",
+ "Name": "Open Asset Import Library",
+ "QDocModule": "qt3d",
+ "Description": "assimp (Open Asset Import Library) is a portable open source library to import various well-known 3D model formats in a uniform manner.",
+ "QtUsage": "Used for importing assets for use with Qt 3D",
+
+ "Homepage": "http://www.assimp.org/",
+ "Version": "5.0.1",
+ "License": "BSD 3-clause \"New\" or \"Revised\" Licensee",
+ "LicenseId": "BSD-3-Clause",
+ "LicenseFile": "LICENSE",
+ "Copyright": "Copyright (c) 2006-2018, assimp team"
+}
diff --git a/src/3rdparty/assimp/revision.h b/src/3rdparty/assimp/revision.h
index af5dc3ab0..137aa186b 100644
--- a/src/3rdparty/assimp/revision.h
+++ b/src/3rdparty/assimp/revision.h
@@ -1,7 +1,7 @@
#ifndef ASSIMP_REVISION_H_INC
#define ASSIMP_REVISION_H_INC
-#define GitVersion 0x80799bd
-#define GitBranch "master"
+#define GitVersion 0x8f0c6b0
+#define GitBranch "HEAD"
#endif // ASSIMP_REVISION_H_INC
diff --git a/src/3rdparty/assimp/src b/src/3rdparty/assimp/src
new file mode 160000
+Subproject 8f0c6b04b2257a520aaab38421b2e090204b69d
diff --git a/src/3rdparty/assimp/contrib/unzip/unzip.h b/src/3rdparty/assimp/unzip/unzip.h
index b247937c8..a4e7ca8ed 100644
--- a/src/3rdparty/assimp/contrib/unzip/unzip.h
+++ b/src/3rdparty/assimp/unzip/unzip.h
@@ -45,16 +45,17 @@
#ifndef _unz_H
#define _unz_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
+// This needs to be outside of the extern "C" when using Qt's zlib
#ifndef _ZLIB_H
#include "zlib.h"
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifndef _ZLIBIOAPI_H
-#include "ioapi.h"
+#include <contrib/unzip/ioapi.h>
#endif
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
diff --git a/src/animation/backend/animationclip.cpp b/src/animation/backend/animationclip.cpp
index 2c7e4fffb..78152c5bc 100644
--- a/src/animation/backend/animationclip.cpp
+++ b/src/animation/backend/animationclip.cpp
@@ -354,7 +354,7 @@ void AnimationClip::clearData()
float AnimationClip::findDuration()
{
// Iterate over the contained fcurves and find the longest one
- double tMax = 0.0;
+ float tMax = 0.f;
for (const Channel &channel : qAsConst(m_channels)) {
for (const ChannelComponent &channelComponent : qAsConst(channel.channelComponents)) {
const float t = channelComponent.fcurve.endTime();
diff --git a/src/plugins/renderers/opengl/renderer/renderer.cpp b/src/plugins/renderers/opengl/renderer/renderer.cpp
index 5c55d3bb9..4de847bf3 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderer.cpp
@@ -594,38 +594,50 @@ void Renderer::releaseGraphicsResources()
QOpenGLContext *context = m_submissionContext->openGLContext();
Q_ASSERT(context);
- if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) {
-
- // Clean up the graphics context and any resources
- const std::vector<HGLTexture> &activeTexturesHandles = m_glResourceManagers->glTextureManager()->activeHandles();
- for (const HGLTexture &textureHandle : activeTexturesHandles) {
- GLTexture *tex = m_glResourceManagers->glTextureManager()->data(textureHandle);
- tex->destroy();
- }
+ if (context->thread() == QThread::currentThread()) {
+ QSurface *lastContextSurface = context->surface();
+
+ if (context->makeCurrent(offscreenSurface)) {
+ // Clean up the graphics context and any resources
+ const std::vector<HGLTexture> &activeTexturesHandles = m_glResourceManagers->glTextureManager()->activeHandles();
+ for (const HGLTexture &textureHandle : activeTexturesHandles) {
+ GLTexture *tex = m_glResourceManagers->glTextureManager()->data(textureHandle);
+ tex->destroy();
+ }
- // Do the same thing with buffers
- const std::vector<HGLBuffer> &activeBuffers = m_glResourceManagers->glBufferManager()->activeHandles();
- for (const HGLBuffer &bufferHandle : activeBuffers) {
- GLBuffer *buffer = m_glResourceManagers->glBufferManager()->data(bufferHandle);
- buffer->destroy(m_submissionContext.data());
- }
+ // Do the same thing with buffers
+ const std::vector<HGLBuffer> &activeBuffers = m_glResourceManagers->glBufferManager()->activeHandles();
+ for (const HGLBuffer &bufferHandle : activeBuffers) {
+ GLBuffer *buffer = m_glResourceManagers->glBufferManager()->data(bufferHandle);
+ buffer->destroy(m_submissionContext.data());
+ }
- // Do the same thing with shaders
- const QVector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources();
- qDeleteAll(shaders);
+ // Do the same thing with shaders
+ const QVector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources();
+ qDeleteAll(shaders);
- // Do the same thing with VAOs
- const std::vector<HVao> &activeVaos = m_glResourceManagers->vaoManager()->activeHandles();
- for (const HVao &vaoHandle : activeVaos) {
- OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle);
- vao->destroy();
- }
+ // Do the same thing with VAOs
+ const std::vector<HVao> &activeVaos = m_glResourceManagers->vaoManager()->activeHandles();
+ for (const HVao &vaoHandle : activeVaos) {
+ OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle);
+ vao->destroy();
+ }
- m_submissionContext->releaseRenderTargets();
+ m_submissionContext->releaseRenderTargets();
- m_frameProfiler.reset();
- if (m_ownedContext)
- context->doneCurrent();
+ m_frameProfiler.reset();
+ if (m_ownedContext) {
+ context->doneCurrent();
+ } else {
+ // Leave the context in the state we found it in by restoring
+ // its last used surface. This satisfies expectations when used
+ // with QQuickWidgets that surface on current context after
+ // QQuickRenderControl cleanup is the same as prior to the
+ // cleanup. Arguably this could also be checked for in
+ // QQuickWidgetPrivate::invalidateRenderControl.
+ context->makeCurrent(lastContextSurface);
+ }
+ }
} else {
qWarning() << "Failed to make context current: OpenGL resources will not be destroyed";
}
@@ -1872,6 +1884,7 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
// Remove previous dependencies
m_cleanupJob->removeDependency(QWeakPointer<QAspectJob>());
+ const bool dirtyParametersForCurrentFrame = m_dirtyBits.marked & AbstractRenderer::ParameterDirty;
const BackendNodeDirtySet dirtyBitsForFrame = m_dirtyBits.marked | m_dirtyBits.remaining;
m_dirtyBits.marked = {};
m_dirtyBits.remaining = {};
@@ -1995,6 +2008,10 @@ QVector<Qt3DCore::QAspectJobPtr> Renderer::renderBinJobs()
m_dirtyBits.remaining = dirtyBitsForFrame & notCleared;
+ // Dirty Parameters might need 2 frames to react if the parameter references a texture
+ if (dirtyParametersForCurrentFrame)
+ m_dirtyBits.remaining |= AbstractRenderer::ParameterDirty;
+
return renderBinJobs;
}
diff --git a/src/render/backend/computecommand.cpp b/src/render/backend/computecommand.cpp
index bc82291f0..b80f81eb2 100644
--- a/src/render/backend/computecommand.cpp
+++ b/src/render/backend/computecommand.cpp
@@ -81,7 +81,10 @@ void ComputeCommand::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firs
if (!node)
return;
+ const bool wasEnabled = isEnabled();
BackendNode::syncFromFrontEnd(frontEnd, firstTime);
+ if (wasEnabled != isEnabled())
+ markDirty(AbstractRenderer::ComputeDirty);
if (m_workGroups[0] != node->workGroupX()) {
m_workGroups[0] = node->workGroupX();
diff --git a/src/render/geometry/qgeometryfactory.h b/src/render/geometry/qgeometryfactory.h
index 92acbc67d..2c8ada27e 100644
--- a/src/render/geometry/qgeometryfactory.h
+++ b/src/render/geometry/qgeometryfactory.h
@@ -55,7 +55,9 @@ class Q_3DRENDERSHARED_EXPORT QGeometryFactory : public QAbstractFunctor
public:
virtual ~QGeometryFactory();
virtual QGeometry *operator()() = 0;
- virtual bool operator ==(const QGeometryFactory &other) const = 0;
+ virtual bool equals(const QGeometryFactory &other) const = 0;
+ friend bool operator==(const QGeometryFactory &lhs, const QGeometryFactory &rhs)
+ { return lhs.equals(rhs); }
};
typedef QSharedPointer<QGeometryFactory> QGeometryFactoryPtr;
diff --git a/src/render/geometry/qmesh.cpp b/src/render/geometry/qmesh.cpp
index 1f05a71f6..c350a3891 100644
--- a/src/render/geometry/qmesh.cpp
+++ b/src/render/geometry/qmesh.cpp
@@ -391,7 +391,7 @@ QGeometry *MeshLoaderFunctor::operator()()
/*!
* \internal
*/
-bool MeshLoaderFunctor::operator ==(const QGeometryFactory &other) const
+bool MeshLoaderFunctor::equals(const QGeometryFactory &other) const
{
const MeshLoaderFunctor *otherFunctor = functor_cast<MeshLoaderFunctor>(&other);
if (otherFunctor != nullptr)
diff --git a/src/render/geometry/qmesh_p.h b/src/render/geometry/qmesh_p.h
index c80c930c5..d202e798b 100644
--- a/src/render/geometry/qmesh_p.h
+++ b/src/render/geometry/qmesh_p.h
@@ -119,7 +119,7 @@ public :
QMesh::Status status() const { return m_status; }
QGeometry *operator()() override;
- bool operator ==(const QGeometryFactory &other) const override;
+ bool equals(const QGeometryFactory &other) const override;
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
QT3D_FUNCTOR(MeshLoaderFunctor)
diff --git a/src/render/picking/objectpicker.cpp b/src/render/picking/objectpicker.cpp
index 182e1af55..cc2ebbf15 100644
--- a/src/render/picking/objectpicker.cpp
+++ b/src/render/picking/objectpicker.cpp
@@ -81,13 +81,16 @@ void ObjectPicker::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT
if (!node)
return;
- BackendNode::syncFromFrontEnd(frontEnd, firstTime);
-
if (firstTime) {
markDirty(AbstractRenderer::AllDirty);
notifyJob();
}
+ if (isEnabled() != node->isEnabled()) {
+ markDirty(AbstractRenderer::AllDirty);
+ // We let QBackendNode::syncFromFrontEnd change the enabled property
+ }
+
if (node->isHoverEnabled() != m_hoverEnabled) {
m_hoverEnabled = node->isHoverEnabled();
markDirty(AbstractRenderer::AllDirty);
@@ -105,6 +108,8 @@ void ObjectPicker::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstT
markDirty(AbstractRenderer::AllDirty);
notifyJob();
}
+
+ BackendNode::syncFromFrontEnd(frontEnd, firstTime);
}
void ObjectPicker::notifyJob()
diff --git a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
index 3e9b24408..4837ac87b 100644
--- a/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
+++ b/tests/auto/core/qchangearbiter/tst_qchangearbiter.cpp
@@ -831,7 +831,7 @@ void tst_QChangeArbiter::distributeBackendChanges()
// backend observer receives event from frontend node "root"
QCOMPARE(root->lastChanges().count(), 0);
QCOMPARE(postman->lastChanges().count(), 0);
- QCOMPARE(backenObserverObservable->lastChanges().count(), 1);
+ QTRY_COMPARE(backenObserverObservable->lastChanges().count(), 1);
backenObserverObservable->clear();
@@ -854,7 +854,7 @@ void tst_QChangeArbiter::distributeBackendChanges()
// THEN
// the repliers should receive it's reply
- QCOMPARE(backenObserverObservable->lastChanges().count(), 1);
+ QTRY_COMPARE(backenObserverObservable->lastChanges().count(), 1);
// verify that postMan has received the change
QCOMPARE(postman->lastChanges().count(), 0);
answer->exit();
@@ -880,7 +880,7 @@ void tst_QChangeArbiter::distributeBackendChanges()
// THEN
// the repliers should receive it's reply
- QCOMPARE(backenObserverObservable->lastChanges().count(), 1);
+ QTRY_COMPARE(backenObserverObservable->lastChanges().count(), 1);
// verify that postMan has received the change
QCOMPARE(postman->lastChanges().count(), 1);
diff --git a/tests/auto/render/computecommand/tst_computecommand.cpp b/tests/auto/render/computecommand/tst_computecommand.cpp
index d6fa1d579..e583a9c61 100644
--- a/tests/auto/render/computecommand/tst_computecommand.cpp
+++ b/tests/auto/render/computecommand/tst_computecommand.cpp
@@ -141,6 +141,10 @@ private Q_SLOTS:
backendComputeCommand.setRenderer(&renderer);
simulateInitializationSync(&computeCommand, &backendComputeCommand);
+ // THEN
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
+
{
// WHEN
const bool newValue = false;
@@ -149,6 +153,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.isEnabled(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -158,6 +164,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.x(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -167,6 +175,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.y(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -176,6 +186,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.z(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -185,6 +197,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.runType(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
{
// WHEN
@@ -194,6 +208,8 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendComputeCommand.frameCount(), newValue);
+ QVERIFY(renderer.dirtyBits() & Qt3DRender::Render::AbstractRenderer::ComputeDirty);
+ renderer.clearDirtyBits(Qt3DRender::Render::AbstractRenderer::AllDirty);
}
}
diff --git a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
index 19df24680..6026a3ff2 100644
--- a/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
+++ b/tests/auto/render/geometryrenderer/tst_geometryrenderer.cpp
@@ -50,7 +50,7 @@ public:
return nullptr;
}
- bool operator ==(const Qt3DRender::QGeometryFactory &other) const final
+ bool equals(const Qt3DRender::QGeometryFactory &other) const final
{
const TestFactory *otherFactory = Qt3DRender::functor_cast<TestFactory>(&other);
if (otherFactory != nullptr)
diff --git a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
index f8110085b..f845f39c8 100644
--- a/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
+++ b/tests/auto/render/meshfunctors/tst_meshfunctors.cpp
@@ -52,7 +52,7 @@ public:
return nullptr;
}
- bool operator ==(const Qt3DRender::QGeometryFactory &other) const override
+ bool equals(const Qt3DRender::QGeometryFactory &other) const override
{
return Qt3DRender::functor_cast<MeshFunctorA>(&other);
}
@@ -74,7 +74,7 @@ public:
return nullptr;
}
- bool operator ==(const Qt3DRender::QGeometryFactory &other) const override
+ bool equals(const Qt3DRender::QGeometryFactory &other) const override
{
return Qt3DRender::functor_cast<MeshFunctorB>(&other);
}
@@ -91,7 +91,7 @@ public:
~MeshFunctorASub()
{}
- bool operator ==(const Qt3DRender::QGeometryFactory &other) const override
+ bool equals(const Qt3DRender::QGeometryFactory &other) const override
{
return Qt3DRender::functor_cast<MeshFunctorASub>(&other);
}
diff --git a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
index 8cfbc0d23..8addfe9ad 100644
--- a/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
+++ b/tests/auto/render/qgeometryrenderer/tst_qgeometryrenderer.cpp
@@ -56,7 +56,7 @@ public:
return nullptr;
}
- bool operator ==(const Qt3DRender::QGeometryFactory &other) const final
+ bool equals(const Qt3DRender::QGeometryFactory &other) const final
{
const TestFactory *otherFactory = Qt3DRender::functor_cast<TestFactory>(&other);
if (otherFactory != nullptr)