Compare commits

...
405 Commits
Author SHA1 Message Date
Kim Kulling 3a78db66a5 fix some doc-strings. 2020-12-24 09:10:20 +01:00
Kim Kulling 88fa7a0611 fix fixes of docs + update doxygen config. 2020-12-14 19:33:37 +01:00
Kim Kulling 3d49d06bcc Merge pull request #3518 from Biswa96/add-msvc-check
Check _MSC_VER for MSVC specific pragma directives.
2020-12-11 14:30:25 +01:00
Kim Kulling a2adef8726 Merge branch 'master' into add-msvc-check 2020-12-11 14:11:10 +01:00
Kim Kulling 80bb8ab726 Merge pull request #3521 from huiji12321/master
Additional Compiler Options for mips64el
2020-12-11 14:07:49 +01:00
huiji12321 db475e7d4a Merge branch 'master' into master 2020-12-10 09:04:24 +08:00
Kim Kulling 10092cd1ec Merge pull request #3515 from LoicFr/master
glTF2Exporter: fix crash when exporting a scene with several meshes p…
2020-12-09 21:14:51 +01:00
Kim Kulling e4a1fb171e Merge branch 'master' into master 2020-12-09 17:58:18 +01:00
Kim Kulling c168c4689e Merge branch 'master' into master 2020-12-09 13:59:27 +01:00
Kim Kulling 99e4a10dc3 Merge pull request #3528 from tellypresence/issue-3525_use_option_for_rapidjson_no_member_iterator
Provide option for rapidjson no-member-iterator define
2020-12-09 13:58:52 +01:00
tellypresence 6db5b7046f Provide option for rapidjson no-member-iterator define
Originally added to fix warning on MSVC but breaks android build
2020-12-09 20:21:43 +09:00
Kim Kulling 816bbc852c Merge branch 'master' into master 2020-12-08 19:54:04 +01:00
Kim Kulling aee01e8345 Merge pull request #3514 from ms-maxvollmer/gltf_fixes
GLTF: Fix crash on invalid base64 data + improved error messages
2020-12-08 19:48:53 +01:00
Kim Kulling 233d834514 Merge branch 'master' into gltf_fixes 2020-12-07 20:36:53 +01:00
Kim Kulling 41904ad7ce Merge pull request #3516 from assimp/kimkulling-patch-8
Update Readme.md
2020-12-07 20:30:21 +01:00
Kim Kulling 1f8c75c871 Merge branch 'master' into kimkulling-patch-8 2020-12-07 16:55:07 +01:00
Kim Kulling c0d7ea981a Merge branch 'master' into gltf_fixes 2020-12-04 16:02:16 +01:00
Kim Kulling 63f1b66224 Merge pull request #3512 from boguscoder/master
Fix for 3489 | Preserve morph targets when splitting by bone count
2020-12-04 15:58:22 +01:00
Kim Kulling eccdc6dc96 Merge branch 'master' into master 2020-12-04 15:30:56 +01:00
Kim Kulling f87ab4b4d7 Merge pull request #3506 from MalcolmTyrrell/fbxExceptionSafety
Fbx exception safety
2020-12-04 15:30:27 +01:00
Kim Kulling 5020a0aa33 Merge branch 'master' into fbxExceptionSafety 2020-12-04 11:01:56 +01:00
Max Vollmer (Microsoft Havok) e737adde50 Merge branch 'master' into gltf_fixes 2020-12-04 08:58:52 +00:00
huiji12321 1910bbbdd9 Additional Compiler Options for mips64el 2020-12-04 16:47:43 +08:00
Kim Kulling 00b626c3c5 Merge pull request #3505 from Neil-Clifford-FB/scenepreprocessor-memoryleak
Sceneprecessor - potential memory leak
2020-12-03 20:41:50 +01:00
Kim Kulling c7aeb882e6 Update ScenePreprocessor.cpp 2020-12-03 17:28:51 +01:00
Max Vollmer (Microsoft Havok) a0ebad1698 Merge branch 'master' into gltf_fixes 2020-12-03 09:28:48 +00:00
Kim Kulling c5f45e26bd Merge branch 'master' into scenepreprocessor-memoryleak 2020-12-03 10:08:05 +01:00
Biswapriyo Nath 8d8ba521e2 Check _MSC_VER for MSVC specific pragma directives.
This fixes build issues when compiled with compiles like Clang or GCC.
2020-12-02 02:05:14 +05:30
Kim Kulling 542ca843be Update Readme.md 2020-12-01 16:38:18 +01:00
Kim Kulling 0458ead7a2 Merge pull request #3503 from natanaeljr/master
Update Android port README.md with ABI doc
2020-12-01 12:30:09 +01:00
Kim Kulling 75204dfe7f Update README.md 2020-12-01 08:58:45 +01:00
FRICOTEAUX b47c5c8c27 glTF2Exporter: fix crash when exporting a scene with several meshes per node (regression coming from commit e8d2b84 on 08/03/2020 "clean all warnings for vs-2019") 2020-11-30 20:11:41 +01:00
Kim Kulling 223372aaba Merge branch 'master' into master 2020-11-30 19:05:31 +01:00
Max Vollmer 53ff0702ce Fixed check for base64 char values 2020-11-30 16:21:29 +00:00
Max Vollmer 7d72c78c8e Some improvements 2020-11-30 15:20:51 +00:00
Max Vollmer 6ed1488e6e * Improved error messages
* Throw instead of asserts on invalid file input
2020-11-30 15:04:06 +00:00
Oleg Bogdanov 4d4a3c42f6 Fix for 3489 | Preserve morph targets when splitting by bone count 2020-11-28 10:01:50 -08:00
Kim Kulling 88be8ec698 Merge branch 'master' into fbxExceptionSafety 2020-11-27 21:49:58 +01:00
Kim Kulling 9ae112309f Merge pull request #3511 from MalcolmTyrrell/fbxVideoKeys
Simplification: textures_converted keys can just be pointers
2020-11-27 21:49:21 +01:00
Malcolm Tyrrell 149b8d1fd1 Don't need operator< either. 2020-11-27 14:26:51 +00:00
Malcolm Tyrrell 14f79caf41 textures_converted keys can just be pointers 2020-11-26 16:29:37 +00:00
Neil Clifford ea60563822 Merge branch 'master' into scenepreprocessor-memoryleak 2020-11-26 08:57:57 +00:00
Kim Kulling 11b4153949 Merge pull request #3487 from inhosens/master
Prevent to generate redundant morph targets for glTF2
2020-11-25 17:13:38 +01:00
Kim Kulling 4590f06756 Merge branch 'master' into master 2020-11-25 16:57:49 +01:00
Kim Kulling dc9db3eaf2 Merge pull request #3504 from Neil-Clifford-FB/fbxparser-overead
FBXParser.cpp - handle buffer over-read correctly
2020-11-25 11:30:52 +01:00
Kim Kulling c059e58c5e Merge branch 'master' into fbxparser-overead 2020-11-24 08:36:15 +01:00
Kim Kulling fe78310486 Merge branch 'master' into fbxExceptionSafety 2020-11-23 10:08:23 +01:00
Kim Kulling afd69bea8a Merge pull request #3510 from Evangel63/scene_name
Added mName to aiScene.
2020-11-23 10:07:58 +01:00
Evangel 98e42e22b8 Added check around setting pScene->mName from asset.scene. 2020-11-22 15:49:41 +10:00
Evangel 30584c1ec1 Replaced name with scene_name to avoid shadowing. 2020-11-22 15:36:08 +10:00
Evangel 67abcb10ba Added mName to aiScene. Primarily to provide access to the "name" member of glTF2 scenes. 2020-11-22 15:33:31 +10:00
Malcolm Tyrrell 885a196c74 Unsigned 2020-11-19 16:30:44 +00:00
Kim Kulling 8108338215 Merge branch 'master' into master 2020-11-19 16:34:15 +01:00
Kim Kulling b1f3c48551 Merge pull request #3484 from MalcolmTyrrell/findDegeneratesOptimization
Optimize FindDegenerates so it doesn't explode
2020-11-19 16:33:46 +01:00
Neil Clifford fc842a0f97 Sceneprecessor potential memory leak 2020-11-19 13:20:43 +00:00
Neil Clifford 7b59cc297e FBXParser.cpp - handle buffer over-read cases correctly 2020-11-19 12:20:06 +00:00
Kim Kulling d10bf9a0d3 Merge branch 'master' into master 2020-11-18 21:30:58 +01:00
Inho Lee e3083c21f0 glTF2: import correct animation values for CUBICSPLINE
CUBICSPLINE interpolation has tangent values with the animation data.
Current import don't care this interpolation type but it will help not
to fetch tangent values instead of animation data.

Note: Assimp cannot support interpolation types yet.
2020-11-17 17:21:07 +01:00
Malcolm Tyrrell c00153089a Neater construction 2020-11-17 10:45:10 +00:00
Malcolm Tyrrell 213a9f9d55 First pass at PotentialNode 2020-11-17 10:39:03 +00:00
Malcolm Tyrrell c4573a6d5c Merge branch 'master' into findDegeneratesOptimization 2020-11-17 09:44:13 +00:00
Natanael Rabello 813f171493 Update Android port README.md with ABI doc 2020-11-16 21:45:01 -03:00
Kim Kulling 749a4963a2 Merge pull request #3501 from Nodrev/issue_3500
Fixing issue 3500, invalid outer cone angle readed from gltf2 file on  machines which defines M_PI as a double value
2020-11-16 22:03:54 +01:00
Kim Kulling c4ba5eeeea Merge branch 'master' into issue_3500 2020-11-16 21:52:14 +01:00
Kim Kulling 25aaa333eb Merge pull request #3502 from MalcolmTyrrell/fbxTextureFix
Prevent crash with malformed texture reference
2020-11-16 21:51:41 +01:00
Malcolm Tyrrell 3221522f95 Prevent crash with malformed texture reference 2020-11-16 17:29:19 +00:00
Malcolm Tyrrell d9b90f714a Fix typo 2020-11-16 11:06:39 +00:00
Malcolm Tyrrell 3ce0958b98 Merge branch 'master' into findDegeneratesOptimization 2020-11-16 09:13:13 +00:00
Jean-François Verdon 09ca11d063 Fixing issue 3500, invalid outer cone angle readed from gltf2 file on machines which defines M_PI as a double value 2020-11-16 09:19:13 +01:00
Kim Kulling 5e7d6a0e41 Merge pull request #3490 from MalcolmTyrrell/nullBufferviewFix
GLTF2: Null bufferview crash fix
2020-11-16 00:15:37 +01:00
Kim Kulling 647cef8a8b Merge branch 'master' into nullBufferviewFix 2020-11-15 19:02:09 +01:00
Kim Kulling 0d5e5790cb Fix findings. 2020-11-14 12:44:49 +01:00
Kim Kulling db7e594221 Merge branch 'master' into findDegeneratesOptimization 2020-11-14 12:32:57 +01:00
Kim Kulling 21a55a34ea Merge pull request #3498 from assimp/kimkulling-patch-8
closes https://github.com/assimp/assimp/issues/3187
2020-11-12 08:54:23 +01:00
Kim Kulling e08690ac51 Merge branch 'master' into kimkulling-patch-8 2020-11-11 21:22:46 +01:00
Kim Kulling b433243daf Merge pull request #3497 from assimp/fix_lws_with_envelop
closes https://github.com/assimp/assimp/issues/1044
2020-11-11 21:16:11 +01:00
Kim Kulling 75818f26eb closes https://github.com/assimp/assimp/issues/3187
Do not use pthread for android
2020-11-11 21:13:17 +01:00
Inho Lee 8845d7eed3 Prevent to generate redundant morph targets for glTF2 2020-11-11 20:49:22 +01:00
Kim Kulling fa0951012f closes https://github.com/assimp/assimp/issues/1044: fix envelope handling in lightintensity. 2020-11-11 20:32:55 +01:00
Kim Kulling 707ad68fba Merge branch 'master' into findDegeneratesOptimization 2020-11-11 09:54:08 +01:00
Kim Kulling c394c6fdda Merge pull request #3486 from assimp/kimkulling-patch-8
Delete AMFImporter_Postprocess.cpp
2020-11-10 17:11:54 +01:00
Kim Kulling ab34b25a03 Merge branch 'master' into kimkulling-patch-8 2020-11-10 15:32:04 +01:00
Kim Kulling 5da3e633e3 Merge pull request #3494 from assimp/issue_3198
closes https://github.com/assimp/assimp/issues/3198: make aiMaterial:…
2020-11-10 13:21:16 +01:00
Kim Kulling 8c91d1a3cd closes https://github.com/assimp/assimp/issues/3198: make aiMaterial::GetName const. 2020-11-10 12:50:17 +01:00
Kim Kulling 957e468c8a Merge pull request #3493 from assimp/issue_3448
closes https://github.com/assimp/assimp/issues/3448
2020-11-10 12:03:57 +01:00
Kim Kulling a8381113eb Update ObjFileMtlImporter.cpp 2020-11-10 10:23:28 +01:00
Kim Kulling 856d4c016e closes https://github.com/assimp/assimp/issues/3448
Add transmission alpha value. if any.
2020-11-10 10:03:09 +01:00
Malcolm Tyrrell 0f246edb97 Prevent GetValue from corrupting memory 2020-11-06 13:43:16 +00:00
Malcolm Tyrrell 34e3e6293a Style 2020-11-06 09:57:48 +00:00
Malcolm Tyrrell 0af05e7a60 Better message 2020-11-05 15:10:52 +00:00
Malcolm Tyrrell 01b2088dd3 A missing bufferview was causing a crash. 2020-11-05 15:02:41 +00:00
Kim Kulling 6873d79505 Delete AMFImporter_Postprocess.cpp 2020-11-03 13:00:28 +01:00
Malcolm Tyrrell a68f78ab94 C++11 2020-11-02 15:03:17 +00:00
Malcolm Tyrrell 75570307d6 Remove unneeded line 2020-11-02 14:50:20 +00:00
Malcolm Tyrrell 3deae8760c Optimize FindDegenerates so it doesn't explode 2020-11-02 14:43:35 +00:00
Kim Kulling de610b8ce9 Merge pull request #3455 from traversaro/fix/3365
Fix CMake config generation problems
2020-10-29 15:47:53 +01:00
Kim Kulling 206f28b8ad Merge branch 'master' into fix/3365 2020-10-29 13:40:00 +01:00
Kim Kulling bff65f3827 Merge pull request #3463 from maiqingqiang/fix/xcode-compile-20201018
fix xcode compile bug
2020-10-29 13:39:13 +01:00
Kim Kulling 72bc41b50f Merge branch 'master' into fix/xcode-compile-20201018 2020-10-28 22:00:08 +01:00
Kim Kulling 18471a39ca Merge pull request #3460 from MalcolmTyrrell/readFbxWeightsInConfig
AI_CONFIG_IMPORT_FBX_READ_WEIGHTS
2020-10-28 21:59:39 +01:00
Kim Kulling 8c135f779e Merge branch 'master' into readFbxWeightsInConfig 2020-10-28 20:38:29 +01:00
Kim Kulling 3fd95aff4e Merge branch 'master' into fix/3365 2020-10-27 17:43:28 +01:00
Kim Kulling f0a0b5c85e Merge pull request #3471 from MomoDeve/patch-1
MSVC crash while importing fbx model workaround
2020-10-27 17:42:56 +01:00
Kim Kulling df768bdd99 Merge branch 'master' into patch-1 2020-10-27 16:20:33 +01:00
Kim Kulling 753503ad83 Merge pull request #3478 from assimp/new_openddl
openddl: latest greatest.
2020-10-27 10:03:50 +01:00
Kim Kulling 43f7224d0c Update CMakeLists.txt 2020-10-27 09:46:31 +01:00
Kim Kulling 22ad7028f0 Delete CMakeLists.txt 2020-10-27 09:42:46 +01:00
Kim Kulling 4bba338d92 Update CMakeLists.txt 2020-10-27 09:23:20 +01:00
Kim Kulling 7e1a8f09c5 more openddl-fixes 2020-10-26 21:35:44 +01:00
Kim Kulling aee2e9a87d Merge branch 'master' into patch-1 2020-10-25 20:35:06 +01:00
Kim Kulling 57e691e28e openddl: latest greatest. 2020-10-25 10:34:43 +01:00
Kim Kulling 55feb0cb78 Merge branch 'master' into fix/xcode-compile-20201018 2020-10-23 22:06:49 +02:00
Kim Kulling 831af12974 Merge pull request #3476 from ms-maxvollmer/gltf_crash_fixes
Fixes for crashes in GLTF2 Importer
2020-10-23 16:31:10 +02:00
Max Vollmer 4006bb71f4 Fixes for crashes in GLTF2 Importer 2020-10-23 12:01:43 +01:00
John Mai cea54d1ac5 Merge branch 'master' into fix/xcode-compile-20201018 2020-10-23 14:06:25 +08:00
Kim Kulling 6ee5e248ee Fix typo 2020-10-22 22:26:29 +02:00
Kim Kulling 8d7e5db98c Fix typo. 2020-10-22 22:26:03 +02:00
Kim Kulling a5a331847b Merge pull request #3412 from MalcolmTyrrell/fbxReportAssetIssuesProperly
Fbx report asset issues properly
2020-10-22 22:24:44 +02:00
#Momo b168d8f441 replaced data with taking address of first element
oops, seems like `data()` returns `char*` only since C++17. Replaced with taking address of first string element
2020-10-21 23:41:33 +03:00
#Momo 7781fe5781 MSVC crash workaround
I do not know why, but the following line causes crash if assimp was compiled using MSVC with RelWithDebInfo configuration:
`std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower<char>);`
replacing `shading.begin()` with `shading.data()` fixes this issue.
2020-10-21 23:21:50 +03:00
Kim Kulling b842b4a3c1 Merge branch 'master' into fbxReportAssetIssuesProperly 2020-10-21 20:02:48 +02:00
Kim Kulling f13a69a817 Merge pull request #3470 from assimp/kimkulling-patch-7
Update FUNDING.yml
2020-10-21 17:04:36 +02:00
Kim Kulling f96698a6d2 Update FUNDING.yml 2020-10-21 16:39:19 +02:00
Kim Kulling 7c5f04deed Merge pull request #3466 from assimp/collada_cleanup
Collada cleanup
2020-10-20 00:20:40 +02:00
Kim Kulling bbac168ced Merge branch 'master' into collada_cleanup 2020-10-19 23:56:52 +02:00
Kim Kulling 69143ed149 fix unittests. 2020-10-19 23:53:27 +02:00
Kim Kulling 080322b9e2 cleanup collada xml migration. 2020-10-19 19:06:11 +02:00
Malcolm Tyrrell a2cd5619b4 Merge branch 'master' into readFbxWeightsInConfig 2020-10-19 10:16:02 +01:00
Kim Kulling 376e468877 Merge pull request #3231 from xiaozhuai/master
optimize CMakeLists.txt
2020-10-18 18:29:45 +02:00
john d48ac9d0a4 fix xcode compile bug 2020-10-18 10:54:04 +08:00
Kim Kulling 37c09ecb69 Update CMakeLists.txt 2020-10-17 10:58:06 +02:00
Kim Kulling 56e1a80e24 Merge branch 'master' into master 2020-10-17 10:57:26 +02:00
Kim Kulling fc11ca2f5e Merge pull request #3461 from inhosens/dev_1016
glTF1's orthgraphic camera & glTF2's skinning
2020-10-17 10:56:38 +02:00
Inho Lee ad7f8910e9 Rollback the method to handle empty bones for GLTF2
A patch made the assimp to ignore empty bones.
However, some assets can have bones which don't have weights
but are connected to other bones.
2020-10-16 17:09:17 +02:00
Inho Lee 9f880e2214 Fix glTF1 orthographic camera 2020-10-16 08:56:55 +02:00
Kim Kulling c035177847 Merge pull request #3451 from xantares/patch-1
CMake: Fix FindRT warning
2020-10-15 20:08:35 +02:00
Malcolm Tyrrell 0363c18f1f Read weights 2020-10-15 10:07:24 +01:00
Silvio Traversaro 3b5212067c Fix CMake config generation
Use standard CMake function to generate the CMake config files.
2020-10-14 23:55:28 +02:00
Kim Kulling 76d370b054 Merge branch 'master' into patch-1 2020-10-14 22:05:56 +02:00
Kim Kulling dbd99bf700 Merge pull request #3456 from rbsheth/rbsheth_hunter_hotfix
Hotfix for Hunter builds
2020-10-14 22:05:34 +02:00
Kim Kulling 828068d224 Merge branch 'master' into rbsheth_hunter_hotfix 2020-10-14 21:14:42 +02:00
Kim Kulling f713d30e9b Merge pull request #3454 from jsmaatta/master
Fix for issue #3445
2020-10-14 21:13:52 +02:00
Kim Kulling 7660070aa4 Merge branch 'master' into master 2020-10-14 21:01:35 +02:00
Kim Kulling b9f83c8db8 Merge pull request #3458 from assimp/issue_3449
Add handling for source for params
2020-10-14 20:57:08 +02:00
Kim Kulling 857f62cde0 closes pParam.mReference = source; 2020-10-14 20:34:46 +02:00
Rahul Sheth 4e57c1ee7f Hotfix for Hunter builds 2020-10-14 11:49:05 -04:00
Jukka Maatta 6848a18999 Fix for issue #3445
Add const to avoid creating a temporary copy.

This should fix the cmake compilation error on XGLLoader.cpp shown in bug #3445

The fix is similar to commit bbe6f7f213
2020-10-13 21:56:43 +03:00
Kim Kulling 84ef3dc0fc Merge branch 'master' into fbxReportAssetIssuesProperly 2020-10-13 18:37:03 +02:00
Kim Kulling ba1145885d Merge pull request #3452 from rbsheth/rbsheth_add_pugixml
Update Hunter for pugixml
2020-10-13 12:01:32 +02:00
Rahul Sheth b7c6719ed8 Fix test builds 2020-10-12 16:47:36 -04:00
Rahul Sheth f12e6eb6f4 Update Hunter for pugixml 2020-10-12 16:30:03 -04:00
xantares 22ea239049 CMake: Fix FindRT warning
This fixes the following warning:
The package name passed to `find_package_handle_standard_args` (rt) does                                                                                                                                                                   not match the name of the calling package (RT).
2020-10-12 10:42:41 +02:00
Kim Kulling 636f28965f Merge branch 'master' into fbxReportAssetIssuesProperly 2020-10-11 18:13:43 +02:00
Kim Kulling 1df00143f5 Merge pull request #3446 from stromaster/patch-1
fix for fbx files using stingray materials;
2020-10-11 18:05:57 +02:00
Sahin Serdar Kocdemir eb9928e029 fix for fbx files using stringray materials; 2020-10-09 07:28:15 +01:00
Malcolm Tyrrell 20733537d7 Merge branch 'master' into fbxReportAssetIssuesProperly 2020-10-08 09:54:04 +01:00
Kim Kulling c7ab7ff457 Merge pull request #3413 from Optimizer0/master
[Bug-Fix] Fixed Strict Aliasing Level 3 Warnings
2020-10-08 10:17:32 +02:00
Optimizer0 1d3f8bd871 Merge branch 'master' into master 2020-10-06 15:48:11 +05:30
Kim Kulling 95d0443a5d Merge pull request #3415 from assimp/issue_3379
closes https://github.com/assimp/assimp/issues/3379: reproduce error …
2020-10-06 10:38:09 +02:00
Optimizer0 152343b186 Merge branch 'master' into master 2020-10-06 08:35:26 +05:30
Kim Kulling d676e1a13f closes https://github.com/assimp/assimp/issues/3379: reproduce error of unresolved symbol with static lib 2020-10-05 21:37:18 +02:00
Kim Kulling 3b9d4cfd28 Merge pull request #2966 from assimp/pugi_xml
[WIP] Pugi xml
2020-10-05 20:02:51 +02:00
Kim Kulling 09a473ff02 fic tests. 2020-10-05 19:06:48 +02:00
Kim Kulling 52826a03f8 remove all hunter-dependencies for pugixml. 2020-10-05 18:53:42 +02:00
Kim Kulling 23f144a7b7 pugixml: use pugixml in headeronly mode. 2020-10-05 18:44:59 +02:00
Malcolm Tyrrell 4bdaf20b70 Add comment. 2020-10-05 14:23:42 +01:00
Isuru2000psn f2b3ec2e0c strict-aliasing level 3 warnings fix 2020-10-05 15:29:09 +05:30
Malcolm Tyrrell 585fb89154 Make an assert a DeadlyImportError. 2020-10-02 15:25:16 +01:00
Malcolm Tyrrell 57756750f6 Limit the output 2020-10-02 15:20:50 +01:00
Malcolm Tyrrell 17702605cf Limit the number of characters printed. 2020-10-02 14:41:36 +01:00
Malcolm Tyrrell 6b9c477763 The floar parsing routines are now DeadlyErrors. 2020-10-02 13:58:55 +01:00
Kim Kulling 9303fb31f6 Enable export only for windows 2020-10-02 11:30:37 +02:00
Kim Kulling 9d296f3943 export pugixml symbold in assimp 2020-10-01 22:02:03 +02:00
kimkulling b6dde74155 adaptions to support hunter 2020-10-01 16:35:34 +02:00
kimkulling d75fa2bb4b fix invalid path. 2020-10-01 10:43:48 +02:00
kimkulling c740f61f97 hunter integration: pugixml 2020-10-01 10:29:52 +02:00
Kim Kulling c7f7ed8901 Update ColladaLoader.cpp 2020-09-30 20:51:54 +02:00
Kim Kulling 0191c661b5 fix division by zero. 2020-09-30 20:39:26 +02:00
Kim Kulling 4affe21709 Update ccpp.yml 2020-09-30 19:28:04 +02:00
Kim Kulling 0f4ce80ff1 Update sanitizer.yml 2020-09-30 19:27:32 +02:00
Kim Kulling 177426185e Fix invalid cast 2020-09-30 16:38:13 +02:00
Kim Kulling 50d21e08f3 fix memoy leak. 2020-09-30 12:05:32 +02:00
Kim Kulling ea741fd8bd init readbuffer with 0-token. 2020-09-30 11:57:29 +02:00
Kim Kulling b4f79411aa Fix lowrcase names. 2020-09-30 11:24:41 +02:00
Kim Kulling 788099a223 Merge branch 'master' into pugi_xml 2020-09-29 21:29:37 +02:00
Kim Kulling 6a4c338625 Merge pull request #3405 from sherief/master
Fix for build break due to warnings-as-errors.
2020-09-29 21:10:38 +02:00
Kim Kulling c591f7de2f make xml parsing more verbose. 2020-09-29 21:01:10 +02:00
Kim Kulling 484d305987 pugi: enable static linkage explicitely. 2020-09-29 20:33:39 +02:00
Kim Kulling adcf84c41f Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml 2020-09-29 19:18:27 +02:00
Kim Kulling 880fe75671 add missing dep to assimp_cmd 2020-09-29 19:14:14 +02:00
Kim Kulling db49a541c3 remove unused attributes. 2020-09-28 20:35:30 +02:00
Kim Kulling ef9a78b49d remove unused attributes. 2020-09-28 20:34:44 +02:00
Kim Kulling 8f0888f7fc diable hunter fr pugi. 2020-09-28 20:03:51 +02:00
Kim Kulling effccfe2e6 Remove dead code. 2020-09-28 15:23:26 +02:00
Kim Kulling bf4ad2837f Remove dead code. 2020-09-28 15:20:59 +02:00
Kim Kulling 69822fd5e6 remove pugixml from hunter 2020-09-28 10:23:25 +02:00
Kim Kulling c598a12340 Remove unused variable. 2020-09-28 09:15:56 +02:00
Kim Kulling 89ac168014 ogre: fix warning: not inited variable. 2020-09-27 21:23:55 +02:00
Kim Kulling 1c85676a9c collada: fix warning: not inited variable. 2020-09-27 21:19:23 +02:00
Kim Kulling 052cc2e070 collada: fix warning: not inited variable. 2020-09-27 21:16:51 +02:00
Kim Kulling 5038f21d06 collada: fix warning: not inited variable. 2020-09-27 21:14:21 +02:00
Kim Kulling 202907d471 collada: fix warning: unused variable. 2020-09-27 21:11:42 +02:00
Kim Kulling 3f97a1df2c collada: fix warning: unused variable. 2020-09-27 21:09:06 +02:00
Kim Kulling bdd3c96eee amf: fix warning: unused variable. 2020-09-27 21:06:14 +02:00
Kim Kulling 5877f81419 amf: fix warning: unused variable. 2020-09-27 21:03:59 +02:00
Kim Kulling 5230b91611 amf: fix warning: unused variable. 2020-09-27 21:01:48 +02:00
Kim Kulling 8143ea5aec amf: fix warning: unused variable. 2020-09-27 20:58:08 +02:00
Kim Kulling 9a19a4723b amf: fix warning: unused variable. 2020-09-27 20:54:21 +02:00
Kim Kulling a6b90c354b fix pugi warnings 2020-09-27 20:38:09 +02:00
Kim Kulling 5653a82a87 fix the unittests. 2020-09-27 20:20:44 +02:00
Kim Kulling 9234fee35e Ogre: fix xml migration. 2020-09-27 09:36:38 +02:00
Sherief Farouk a3c8cfc0ff Fix for build break due to warnings-as-errors when not building M3D exporter. 2020-09-26 23:21:23 -07:00
Kim Kulling d6892b3f58 Merge branch 'master' into pugi_xml 2020-09-25 21:00:09 +02:00
Kim Kulling 557273818d collada: next iteration. 2020-09-23 21:23:12 +02:00
Kim Kulling 22dd53a4a2 Merge pull request #3394 from ms-maxvollmer/gltfBufferViewSizeFix
GLTF2: Throw instead of assert when input file is invalid.
2020-09-23 21:22:14 +02:00
Kim Kulling 34351b3cb9 fix collada material parsing. 2020-09-23 00:20:06 +02:00
Kim Kulling c0e58c1895 Merge branch 'master' into gltfBufferViewSizeFix 2020-09-22 20:02:16 +02:00
Kim Kulling 93ae409e74 Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml 2020-09-22 17:29:49 +02:00
Kim Kulling 6e91605268 reformat. 2020-09-22 17:29:46 +02:00
kimkulling 71f20eaa8a next fixes 2020-09-22 15:51:21 +02:00
kimkulling dee8e5bee1 Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml 2020-09-22 15:20:35 +02:00
Kim Kulling c4039d5cf0 fix collada data parsing. 2020-09-21 20:05:16 +02:00
kimkulling 8c88526da8 fix collada unittests. 2020-09-21 16:39:24 +02:00
Kim Kulling 11261671a3 Merge pull request #3400 from assimp/kimkulling-patch-7
Update Readme.md
2020-09-20 19:56:38 +02:00
Kim Kulling 3e025cdc8d Update Readme.md 2020-09-20 18:33:02 +02:00
Kim Kulling 64c1405dfd Merge pull request #3382 from rbsheth/rbsheth_hunter_rapidjson
Fix RapidJSON defines and add Hunter builds to CI
2020-09-19 21:37:16 +02:00
Max Vollmer (Microsoft Havok) c9fb21661f Merge branch 'master' into gltfBufferViewSizeFix 2020-09-18 08:01:24 +01:00
rahulshethsc 354e09e785 Merge branch 'master' into rbsheth_hunter_rapidjson 2020-09-17 14:39:04 -04:00
Rahul Sheth aa125c48ab Try fixing required action names 2020-09-17 14:38:49 -04:00
Kim Kulling fbc0914a21 Merge pull request #3383 from crocdialer/collada_animation_ticks_per_sec_issue_3162
collada: set aiAnimation->mTicksPerSecond to 1000.0
2020-09-17 14:37:55 +02:00
Fabian Schmidt 338c0b753c Merge branch 'master' into collada_animation_ticks_per_sec_issue_3162 2020-09-16 21:43:35 +02:00
Max Vollmer (Microsoft Havok) 9c1edaee96 Merge branch 'master' into gltfBufferViewSizeFix 2020-09-16 10:08:47 +01:00
Kim Kulling 14d6141f69 Collada: fix scenenode parsing. 2020-09-14 21:35:36 +02:00
Kim Kulling 9e2c4e0cf4 Merge branch 'master' into rbsheth_hunter_rapidjson 2020-09-14 09:00:11 +02:00
Kim Kulling 3e5feb4320 Merge pull request #3375 from MalcolmTyrrell/makeInternalErrorsAccessible
Make internal errors accessible
2020-09-14 08:59:09 +02:00
Kim Kulling 2901f68668 Adapt code style. 2020-09-14 08:45:18 +02:00
Kim Kulling 0e9621012c Adapt code style - finally :-). 2020-09-14 08:43:31 +02:00
Kim Kulling 1ff9e2b522 Adapt code style. 2020-09-14 08:40:21 +02:00
Kim Kulling 23defc275a Merge branch 'master' into makeInternalErrorsAccessible 2020-09-14 08:36:13 +02:00
kimkulling d0932c405f fix duplicated node parsing. 2020-09-11 15:46:46 +02:00
Kim Kulling c1f50e116a fix next unittests. 2020-09-11 00:46:29 +02:00
Kim Kulling 31f3812241 XGL: fix import of node values. 2020-09-10 21:03:02 +02:00
kimkulling 6ec07e4dc7 XGL: next steps. 2020-09-10 17:31:30 +02:00
kimkulling cca9eddb1c Fix material-base AMF-unittest. 2020-09-10 13:56:04 +02:00
Max Vollmer 615ffdf93f What: Throw instead of assert when input file is invalid.
Why: Assimp shouldn't crash on invalid files. Asserts are disabled on Release builds.
2020-09-10 10:47:58 +01:00
kkulling c2f0bf68af Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml 2020-09-10 11:02:51 +02:00
Kim Kulling d854f3b842 AMF: fix adding for child-nodes. 2020-09-10 00:05:53 +02:00
Kim Kulling bd91033172 Merge branch 'master' into collada_animation_ticks_per_sec_issue_3162 2020-09-08 20:53:00 +02:00
Kim Kulling 4f30b2aa5c Merge pull request #3391 from Naios/unref_param
Fix an unreferenced formal parameter warning on MSVC when no exporter…
2020-09-08 20:35:46 +02:00
Kim Kulling 0618db1f99 AMF: some smaller refactorings to improve readability. 2020-09-07 20:52:46 +02:00
Denis Blank f3b25b999b Fix an unreferenced formal parameter warning on MSVC when no exporter is built 2020-09-05 23:20:31 +02:00
Kim Kulling ef6b93a949 Merge branch 'master' into collada_animation_ticks_per_sec_issue_3162 2020-09-04 16:27:47 +02:00
Kim Kulling 689406fbda Fix Colladat import. 2020-09-04 07:33:10 +02:00
Rahul Sheth 78b30d1752 Merge branch 'master' into rbsheth_hunter_rapidjson 2020-09-03 09:51:32 -04:00
Rahul Sheth df56a97794 Dummy commit 2 to trigger Github Actions 2020-09-03 08:41:22 -04:00
Rahul Sheth 56a3759925 Dummy commit 1 2020-09-03 08:41:08 -04:00
kimkulling 1e6a1c63ec Remove irrxml search. 2020-09-03 11:45:43 +02:00
Kim Kulling 9ce0671134 Merge pull request #3387 from Gargaj/patch-1
add missing define to glTF importer
2020-09-03 08:42:18 +02:00
Kim Kulling be5089ae40 Collada: correct parsing of float data in xml nodes. 2020-09-02 22:38:19 +02:00
Kim Kulling 075540e15a AMF: fixes. 2020-09-02 22:37:57 +02:00
Kim Kulling 0b8ed5c03a fix crash when x3d is empty 2020-09-02 21:49:40 +02:00
Kim Kulling 34f343233e 3ml: fix xml parsing. 2020-09-02 21:49:20 +02:00
Kim Kulling 0c05398602 xml-parser: ensure that traverse-collectors are only collecting xmlnodes. 2020-09-02 21:48:58 +02:00
kkulling 87d2580aad fix 3mf rel-parsing 2020-09-02 17:45:37 +02:00
Gargaj 9053dfea05 add missing define to glTF importer 2020-09-02 16:28:12 +02:00
Kim Kulling 3081e83f43 Merge pull request #3385 from jnhyatt/smart-ptr-fix
Fix Bad Ownership Acquisition
2020-09-02 16:24:25 +02:00
Kim Kulling 4dad3eab3f Merge branch 'master' into smart-ptr-fix 2020-09-02 16:14:45 +02:00
Kim Kulling a7d3172dd8 Merge pull request #3386 from flowtsohg/master
Update Jassimp's AiTextureType.java
2020-09-02 16:14:08 +02:00
Chananya Freiman 542d784457 Update Jassimp's AiTextureType.java
The newer PBR enums are missing, making it impossible to import many models.
2020-09-02 02:52:56 +03:00
Kim Kulling 73fa2cbe88 Fix memory handling of xml-nodes in the parser. 2020-09-01 21:48:50 +02:00
Joshua Hyatt 638499a278 Replace unique_ptr and add custom deleter 2020-09-01 10:30:31 -06:00
Kim Kulling 3c2133a3b9 fix node collection for collada xml parsing 2020-09-01 07:51:17 +02:00
kimkulling e62b4e5cce next iteration. 2020-08-31 16:10:38 +02:00
Kim Kulling 6d5c388780 Introduce node iterator. 2020-08-30 21:10:04 +02:00
Joshua Hyatt dcf9a7b2d8 Conform variable names to code standards 2020-08-29 23:58:31 -06:00
Joshua Hyatt 953e976de6 Close stream when finished 2020-08-29 23:56:50 -06:00
Joshua Hyatt cc2613f264 Replace unique_ptr with raw pointer 2020-08-29 23:06:33 -06:00
Joshua Hyatt c769f8d4ad Replace unique_ptr with raw pointer to avoid destructing stream 2020-08-29 22:21:34 -06:00
kimkulling 30a4eae17f simplify some ttributes access in loaded xml. 2020-08-28 16:25:22 +02:00
kimkulling 0730eebe6f fix collada handling of xml nodes. 2020-08-28 16:17:56 +02:00
crocdialer 3c98197be0 set aiAnimation->mTicksPerSecond to 1000.0. this is analog to the behaviour of gltf2-importer 2020-08-28 16:09:15 +02:00
Kim Kulling b7e9595e54 fix loop of xml-files. 2020-08-28 00:09:51 +02:00
Rahul Sheth 6b32f34fc2 Try disabling C4389 for GTest only for MSVC 2020-08-27 17:02:42 -04:00
Rahul Sheth b15c111805 Try Hunter-based Github Actions 2020-08-27 16:55:39 -04:00
Rahul Sheth 5f19c8890b Update to the latest Hunter 2020-08-27 16:51:34 -04:00
Rahul Sheth 59c8b4ed84 Move RapidJSON definitions to CMake 2020-08-27 16:51:06 -04:00
kimkulling 582a8b1887 Fix xml-migration bild. 2020-08-27 17:05:09 +02:00
kimkulling 6f77d2e06d Prepare unittest for XmlParser. 2020-08-27 17:04:58 +02:00
Kim Kulling c359b973bb finish migration of collada. 2020-08-26 22:31:46 +02:00
Rahul Sheth 5087348a37 Build tests and tools with Hunter 2020-08-25 11:30:46 -04:00
Kim Kulling 904f17f29f next collada-iteration 2020-08-24 07:44:54 +02:00
Kim Kulling 7adfe1f2d8 Xml: introduce helper for attribute parsing. 2020-08-21 06:45:30 +02:00
Malcolm Tyrrell 962fe7cd4d Oops. Fix string to match restored error text. 2020-08-20 15:10:11 +01:00
Malcolm Tyrrell fa93ba76fe Do need to export base class. 2020-08-20 15:01:24 +01:00
Malcolm Tyrrell 16c227e27c Undo one other small change. 2020-08-20 14:53:00 +01:00
Malcolm Tyrrell 8f893e3653 Actually, just keep the old behaviour for now. 2020-08-20 14:32:15 +01:00
Kim Kulling cb631517a7 next iteration. 2020-08-19 22:44:13 +02:00
Malcolm Tyrrell 9b5e758bdd Even simpler DeadlyErrorBase 2020-08-19 17:59:13 +01:00
Malcolm Tyrrell 6f9c61e157 Use case which matches surrounding code. 2020-08-19 17:57:25 +01:00
Malcolm Tyrrell 6c2ceb55f8 Simplify some FBX error code. 2020-08-19 17:20:57 +01:00
kimkulling d393f677ce Collada: next methods migrated. 2020-08-19 17:10:30 +02:00
Malcolm Tyrrell d7c65c36cd Add unit test for formatting. 2020-08-19 11:31:46 +01:00
Malcolm Tyrrell 3ccf503d3e Forward template arguments. 2020-08-19 11:31:32 +01:00
Kim Kulling 56381241c5 move hasAttribute to XmlParser scope. 2020-08-19 00:19:56 +02:00
Kim Kulling 554ed1bf91 next step.s 2020-08-18 20:44:06 +02:00
Malcolm Tyrrell 0f6127e90e No need to build strings. 2020-08-18 18:21:20 +01:00
Malcolm Tyrrell e1a0163e7e Make all exceptions available. 2020-08-18 18:14:51 +01:00
Malcolm Tyrrell b7c789da67 Stop concatenating std::strings. Use formatter. 2020-08-18 17:35:08 +01:00
kimkulling 6a8edb21f8 fix merge issues 2020-08-18 17:41:37 +02:00
Malcolm Tyrrell 0ffcdf160e Build formatting into DeadlyImportError 2020-08-18 16:32:34 +01:00
kimkulling 7e93ae4428 3MF: Migration. 2020-08-18 16:54:29 +02:00
Malcolm Tyrrell 974252bd8f Fix two warnings that annoy clang. 2020-08-18 10:33:47 +01:00
Malcolm Tyrrell 4f1e904ec8 Fix typo. 2020-08-18 10:33:47 +01:00
Malcolm Tyrrell 829ff1adf0 Maybe this will help. 2020-08-18 10:33:47 +01:00
Malcolm Tyrrell a4110a59c5 Use runtime error. 2020-08-18 10:33:47 +01:00
Malcolm Tyrrell 19cdfd12df Unit test for internal failures. 2020-08-18 10:33:47 +01:00
Malcolm Tyrrell b1ed751b83 Provide an API for accessing internal errors. 2020-08-18 10:33:42 +01:00
Kim Kulling 48ec3ef458 Merge pull request #3374 from fuj1n/update_utf8cpp
Update utf8cpp to fix use of C++17 deprecated feature
2020-08-17 21:11:05 +02:00
Arthur (fuj1n) Uzulin 995ab805ff Update utf8cpp to fix use of C++17 deprecated feature 2020-08-17 17:54:48 +10:00
Kim Kulling 51a417ce6f Merge pull request #3372 from lsliegeo/nff_ai_real
NFF importer double precision support
2020-08-16 13:56:33 +02:00
lsliegeo 0d00ff7043 use ai_real instead of float 2020-08-15 14:57:49 +02:00
Kim Kulling 9fc00cbf74 Merge pull request #3369 from assimp/issue_3364
Fix incorrect index
2020-08-11 20:50:11 +02:00
Kim Kulling 1bbae19779 Fix leak 2020-08-11 20:28:12 +02:00
Kim Kulling b1b9fa94cf Update utStandardShapes.cpp 2020-08-11 20:21:35 +02:00
Kim Kulling 9bad20e99e Add test to CMakeLists 2020-08-11 20:03:30 +02:00
Kim Kulling 45f76f36f3 Add test to CMakeLists 2020-08-11 20:03:23 +02:00
Kim Kulling 153a6efecc Add test 2020-08-11 20:02:14 +02:00
Kim Kulling 729882debb Fix incorrect index
closes https://github.com/assimp/assimp/issues/3364
2020-08-11 19:57:36 +02:00
Kim Kulling 394651e640 x3d: migration of goups. 2020-08-10 22:13:45 +02:00
Kim Kulling f90bb2ca26 Merge pull request #3363 from malortie/fix-cmake-override-output-path3
Fixed runtime output directory overridden.
2020-08-08 10:54:31 +02:00
Kim Kulling b3f85613fc Merge branch 'master' into fix-cmake-override-output-path3 2020-08-08 10:42:36 +02:00
Kim Kulling 65265594ba Merge pull request #3362 from assimp/issue_3004
Fix nncorrectly named Assimp .dll
2020-08-08 09:19:53 +02:00
Kim Kulling fbd9c9651d fix clang detection 2020-08-08 09:06:41 +02:00
Marc-Antoine Lortie 11daed69d3 Fixed overwriting of CMake global output directory variables. 2020-08-07 16:04:39 -04:00
Kim Kulling 30d83d40c1 fix brackets for template in template 2020-08-07 19:15:28 +02:00
kimkulling 29b72fe6d4 fix cmake warning 2020-08-07 16:22:34 +02:00
kimkulling aaea564cbe closes https://github.com/assimp/assimp/issues/3004 : use prefix when ms_tools were found. 2020-08-07 16:14:44 +02:00
Kim Kulling 4c8b9fb96d Merge pull request #3360 from assimp/issue_2992
closes https://github.com/assimp/assimp/issues/2992: detect double support
2020-08-07 14:41:30 +02:00
kimkulling 13d7fad7f7 closes https://github.com/assimp/assimp/issues/2992: add single or double precision + missing compilers. 2020-08-07 14:23:07 +02:00
Kim Kulling 8504c191db Merge pull request #3356 from qarmin/more_ubsan_flags
Added more undefined sanitizer flags
2020-08-05 20:24:13 +02:00
Kim Kulling 919f730844 Merge branch 'master' into more_ubsan_flags 2020-08-05 19:59:18 +02:00
Kim Kulling 89eb7f889a Merge pull request #3355 from assimp/issue_3353
Fix wrong function defines
2020-08-05 19:56:46 +02:00
Kim Kulling 58bf23be55 Merge branch 'master' into issue_3353 2020-08-05 18:03:26 +02:00
Kim Kulling b94183376c Fix possible overflow in new. 2020-08-05 17:56:44 +02:00
Kim Kulling c238508706 Merge pull request #3357 from assimp/issue_3291
Export opacity is 3DS
2020-08-04 21:04:58 +02:00
Kim Kulling 1f348c5fc0 Remove redundant float f 2020-08-04 20:55:29 +02:00
Kim Kulling aabf12827b fix typo 2020-08-04 17:52:43 +02:00
Kim Kulling 855b47452e Export opacity is 3DS
closes https://github.com/assimp/assimp/issues/3291
2020-08-04 17:41:28 +02:00
Rafał Mikrut c60373c0ba Merge branch 'master' into more_ubsan_flags 2020-08-03 23:17:53 +02:00
Rafał Mikrut 447805f01a Added more undefined sanitizer flags 2020-08-03 23:12:08 +02:00
Kim Kulling aa6c35f683 Merge pull request #3350 from MalcolmTyrrell/fbxVersionCheck
FBX Version/Size Check
2020-08-03 21:30:03 +02:00
Kim Kulling e7ae576614 undo change 2020-08-03 15:54:19 +02:00
Kim Kulling 435bba30dd Move functions into the correct preprocessor branch 2020-08-03 09:30:02 +02:00
Kim Kulling 008e551f8e Merge branch 'master' into fbxVersionCheck 2020-07-31 14:33:21 +02:00
Kim Kulling ac8a8a5ad4 Merge pull request #3349 from rmstyrczula/fixFbxExportNullptr
FBXExport: Fix crash if scene->mMetaData is null
2020-07-31 14:32:32 +02:00
Malcolm Tyrrell 0282f358a4 Remove unneeded check. 2020-07-31 12:40:17 +01:00
Malcolm Tyrrell 301bae3967 Improve message 2020-07-30 16:37:41 +01:00
Malcolm Tyrrell eaf0587dd8 FBX Version/Size Check 2020-07-30 14:56:01 +01:00
Ryan Styrczula 3170c3d15c FBXExport: Fix crash if scene->mMetaData is null 2020-07-30 09:21:43 -04:00
Kim Kulling 58b81a2590 start migrating X3D. 2020-07-26 10:17:21 +02:00
Kim Kulling 575ce6136d Merge pull request #3347 from rbsheth/rbsheth_fix_warn
Fixing more build warnings
2020-07-25 19:06:21 +02:00
Rahul Sheth ad18e365e5 Fixing more warnings 2020-07-24 16:33:36 -04:00
Kim Kulling 6828cf2f03 Merge pull request #3328 from awr1/fix-mingw-priumax
Fix MinGW builds (issues related to pragmas and format strings)
2020-07-24 11:34:25 +02:00
Kim Kulling c7a9ef30cc Merge branch 'master' into fix-mingw-priumax 2020-07-24 11:14:15 +02:00
Kim Kulling e8cbc0928e Merge pull request #3346 from assimp/fix_compiler_warnings
Fix warning: comparison between unsigned and signed.
2020-07-24 11:11:39 +02:00
Kim Kulling 6886ea6c65 Fix warning: comparison between unsigned and signed. 2020-07-24 10:57:24 +02:00
Kim Kulling 59e15b7fd1 Merge pull request #3345 from assimp/fix_include
add missing include for logging.
2020-07-23 21:37:00 +02:00
Kim Kulling b2e53783de Merge branch 'master' into fix-mingw-priumax 2020-07-17 12:07:46 +02:00
Kim Kulling deddaf49df finish migrate ogrexmlserializer. 2020-07-16 11:33:28 +02:00
awr1 77cf6e3433 Ensure that zip.h warning disable is pushed 2020-07-14 22:07:24 -05:00
awr1 638369e995 Try to fix lexing issue with preproc w/r/t __has_warning 2020-07-14 21:58:36 -05:00
awr1 cc8cd88d7a Preproc conditional should be &&, not || 2020-07-14 21:50:22 -05:00
awr1 bad0df9a1a Remove unnecessary inversion in preproc 2020-07-14 21:48:46 -05:00
awr1 b3f61f8759 Fix error where -Wunused-but-set-variable might not be available 2020-07-14 21:44:33 -05:00
awr1 3bf6963d20 Use a better divider for import error 2020-07-14 21:34:30 -05:00
awr1 93d567e3b1 Fix sprintf format string 2020-07-14 21:32:22 -05:00
awr1 700d8e6614 Fix MinGW builds (issues related to pragmas and format strings) 2020-07-14 21:19:07 -05:00
Kim Kulling b19ebf5d54 Fix merge conflicts. 2020-07-14 09:02:14 +02:00
Kim Kulling 8cfd2a4cc1 Migrate OgreSerializer. 2020-07-14 09:00:06 +02:00
Kim Kulling c8d759de64 Merge branch 'master' into master 2020-07-12 19:11:02 +02:00
Kim Kulling 21678df589 ogre + collada migration. 2020-07-10 22:25:38 +02:00
Kim Kulling 77b705048b fix merge issues. 2020-07-04 13:42:23 +02:00
Kim Kulling 839986ca14 next step of AMF-Migration. 2020-07-04 09:04:06 +02:00
Kim Kulling d74c10dcb7 Merge branch 'master' into pugi_xml 2020-07-03 17:29:38 +02:00
Kim Kulling b1369d0912 next steps. 2020-07-02 15:18:59 +02:00
Kim Kulling fb20e15163 start to migrate colladat and amf 2020-06-27 15:57:06 +02:00
Kim Kulling f4dd5eafd0 Merge branch 'master' into master 2020-05-26 21:48:39 +02:00
Kim Kulling 2be731d1bf Merge branch 'master' into pugi_xml 2020-05-22 10:09:46 +02:00
xiaozhuai 80c88ffc73 optimize CMakeLists.txt 2020-05-18 15:40:12 +08:00
Kim Kulling 03182c21b8 xml-migration amf - next steps. 2020-02-26 22:19:42 +01:00
Kim Kulling 979153522c xml-migration: migration of XGLImporter. 2020-02-05 22:51:39 +01:00
Kim Kulling 1a8d5667b6 xml-migration: migrate shared code from irr-loader. 2020-02-04 20:47:20 +01:00
Kim Kulling bd2ffc8d58 Merge branch 'pugi_xml' of https://github.com/assimp/assimp into pugi_xml 2020-02-03 21:19:30 +01:00
Kim Kulling c1fcee9c5a XMl-Migration: Migration of IrrMesh. 2020-02-03 21:19:03 +01:00
Kim Kulling 02df65d541 Merge branch 'master' into pugi_xml 2020-01-28 13:13:47 +01:00
Kim Kulling 00ad892a49 xml: last changes. 2020-01-27 23:54:59 +01:00
Kim Kulling 0cb236bae3 next steps. 2020-01-27 22:18:48 +01:00
Kim Kulling 8ef106e185 xml-migration: introduce xmlnode. 2020-01-27 22:11:27 +01:00
Kim Kulling 6a471b4390 xml-migration: next steps. 2020-01-27 22:10:42 +01:00
Kim Kulling 02acb3f8c2 Merge branch 'master' into pugi_xml 2020-01-23 21:26:04 +01:00
Kim Kulling 11f49f85c4 try to migrate AMF 2020-01-23 21:25:25 +01:00
Kim Kulling a905303764 IrrXml: replaced irrXml by pugixml. 2020-01-23 21:16:10 +01:00
Kim Kulling d48b93cf34 Merge branch 'master' into pugi_xml 2020-01-18 08:28:19 +01:00
Kim Kulling 8761f3c67a add pugi to include. 2019-08-08 22:07:06 +02:00
Kim Kulling db3bb22933 Xml: Prepare replacement of irrXml. 2019-07-21 12:19:19 +02:00
262 changed files with 26841 additions and 27092 deletions

No files matched your search

-1
View File
@@ -1,3 +1,2 @@
patreon: assimp
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
open_collective: assimp
+48 -14
View File
@@ -8,30 +8,39 @@ on:
jobs:
job:
name: ${{ matrix.os }}-${{ matrix.cxx }}-build-and-test
name: ${{ matrix.name }}-build-and-test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
name: [ubuntu-gcc, macos-clang, windows-msvc, ubuntu-clang]
name: [ubuntu-latest-g++, macos-latest-clang++, windows-latest-cl.exe, ubuntu-latest-clang++, ubuntu-gcc-hunter, macos-clang-hunter, windows-msvc-hunter]
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
include:
- name: windows-msvc
- name: windows-latest-cl.exe
os: windows-latest
cxx: cl.exe
cc: cl.exe
- name: ubuntu-clang
- name: ubuntu-latest-clang++
os: ubuntu-latest
cxx: clang++
cc: clang
- name: macos-clang
- name: macos-latest-clang++
os: macos-latest
cxx: clang++
cc: clang
- name: ubuntu-gcc
- name: ubuntu-latest-g++
os: ubuntu-latest
cxx: g++
cc: gcc
- name: ubuntu-gcc-hunter
os: ubuntu-latest
toolchain: ninja-gcc-cxx17-fpic
- name: macos-clang-hunter
os: macos-latest
toolchain: ninja-clang-cxx17-fpic
- name: windows-msvc-hunter
os: windows-latest
toolchain: ninja-vs-win64-cxx17
steps:
- uses: actions/checkout@v2
@@ -40,14 +49,29 @@ jobs:
- uses: ilammy/msvc-dev-cmd@v1
- uses: lukka/set-shell-env@v1
- name: Set Compiler Environment
if: "!endsWith(matrix.name, 'hunter')"
uses: lukka/set-shell-env@v1
with:
CXX: ${{ matrix.cxx }}
CC: ${{ matrix.cc }}
- name: Set Compiler Environment for Hunter on Windows
if: startsWith(matrix.name, 'windows') && endsWith(matrix.name, 'hunter')
uses: lukka/set-shell-env@v1
with:
VS160COMNTOOLS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools
- name: Checkout Hunter toolchains
if: endsWith(matrix.name, 'hunter')
uses: actions/checkout@v2
with:
repository: cpp-pm/polly
path: cmake/polly
- name: Cache DX SDK
id: dxcache
if: matrix.name == 'windows-msvc'
if: contains(matrix.name, 'windows')
uses: actions/cache@v2
with:
path: '${{ github.workspace }}/DX_SDK'
@@ -56,30 +80,40 @@ jobs:
${{ runner.os }}-DX_SDK
- name: Download DXSetup
if: matrix.name == 'windows-msvc' && steps.dxcache.outputs.cache-hit != 'true'
if: contains(matrix.name, 'windows') && steps.dxcache.outputs.cache-hit != 'true'
run: |
curl -s -o DXSDK_Jun10.exe --location https://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
cmd.exe /c start /wait .\DXSDK_Jun10.exe /U /O /F /S /P "${{ github.workspace }}\DX_SDK"
- name: Set Windows specific CMake arguments
if: matrix.name == 'windows-msvc'
if: contains(matrix.name, 'windows')
id: windows_extra_cmake_args
run: echo "::set-output name=args::'-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1'"
run: echo "::set-output name=args::-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1"
- name: Set Hunter specific CMake arguments
if: contains(matrix.name, 'hunter')
id: hunter_extra_cmake_args
run: echo "::set-output name=args::-DBUILD_SHARED_LIBS=OFF -DASSIMP_HUNTER_ENABLED=ON -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/polly/${{ matrix.toolchain }}.cmake"
- name: configure and build
uses: lukka/run-cmake@v2
uses: lukka/run-cmake@v3
env:
DXSDK_DIR: '${{ github.workspace }}/DX_SDK'
with:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
cmakeAppendedArgs: '-GNinja -DCMAKE_BUILD_TYPE=Release ${{ steps.windows_extra_cmake_args.outputs.args }}'
cmakeAppendedArgs: '-GNinja -DCMAKE_BUILD_TYPE=Release ${{ steps.windows_extra_cmake_args.outputs.args }} ${{ steps.hunter_extra_cmake_args.outputs.args }}'
buildWithCMakeArgs: '-- -v'
buildDirectory: '${{ github.workspace }}/build/'
- name: Exclude certain tests in Hunter specific builds
if: contains(matrix.name, 'hunter')
id: hunter_extra_test_args
run: echo "::set-output name=args::--gtest_filter=-utOpenGEXImportExport.Importissue1340_EmptyCameraObject:utColladaZaeImportExport.importBlenFromFileTest"
- name: test
run: cd build/bin && ./unit
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
shell: bash
- uses: actions/upload-artifact@v2
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
CC: clang
- name: configure and build
uses: lukka/run-cmake@v2
uses: lukka/run-cmake@v3
with:
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
-3
View File
@@ -1,3 +0,0 @@
set(ASSIMP_INCLUDE_DIRS
"@PROJECT_SOURCE_DIR@"
"@PROJECT_BINARY_DIR@")
-11
View File
@@ -1,11 +0,0 @@
set(ASSIMP_PACKAGE_VERSION "@ASSIMP_SOVERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${ASSIMP_PACKAGE_VERSION}" VERSION_LESS "${ASSIMP_PACKAGE_FIND_VERSION}")
set(ASSIMP_PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(ASSIMP_PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${ASSIMP_PACKAGE_VERSION}" VERSION_EQUAL "${ASSIMP_PACKAGE_FIND_VERSION}")
set(ASSIMP_PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
+72 -92
View File
@@ -45,8 +45,8 @@ option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.23.261.tar.gz"
SHA1 "1540dad7b97c849784a09e8c452ba811c9f71ba2"
URL "https://github.com/cpp-pm/hunter/archive/v0.23.269.tar.gz"
SHA1 "64024b7b95b4c86d50ae05b926814448c93a70a0"
)
add_definitions(-DASSIMP_USE_HUNTER)
@@ -117,10 +117,6 @@ OPTION ( ASSIMP_UBSAN
"Enable Undefined Behavior sanitizer."
OFF
)
OPTION ( ASSIMP_SYSTEM_IRRXML
"Use system installed Irrlicht/IrrXML library."
OFF
)
OPTION ( ASSIMP_BUILD_DOCS
"Build documentation using Doxygen."
OFF
@@ -136,8 +132,8 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
)
IF ( WIN32 )
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OPTION ( ASSIMP_BUILD_ASSIMP_VIEW
"If the Assimp view tool is built. (requires DirectX)"
OFF )
ENDIF()
@@ -214,7 +210,7 @@ IF(NOT GIT_COMMIT_HASH)
ENDIF()
IF(ASSIMP_DOUBLE_PRECISION)
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
ENDIF()
CONFIGURE_FILE(
@@ -253,9 +249,15 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF()
# hide all not-exported symbols
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
SET(LIBSTDC++_LIBRARIES -lstdc++)
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
SET(LIBSTDC++_LIBRARIES -lstdc++)
ELSE()
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
SET(LIBSTDC++_LIBRARIES -lstdc++)
ENDIF()
ELSEIF(MSVC)
# enable multi-core compilation with MSVC
IF( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) # clang-cl
@@ -326,26 +328,27 @@ ENDIF()
IF (ASSIMP_UBSAN)
MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
ENDIF()
INCLUDE (FindPkgMacros)
INCLUDE (PrecompiledHeader)
# If this is an in-source build (CMAKE_SOURCE_DIR == CMAKE_BINARY_DIR),
# write the library/executable files to the respective directories in the
# source tree. During an out-of-source build, however, do not litter this
# directory, since that is probably what the user wanted to avoid.
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
ELSE()
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
ENDIF ()
# Set Assimp project output directory variables.
SET(ASSIMP_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
SET(ASSIMP_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/lib")
# Macro used to set the output directories of a target to the
# respective Assimp output directories.
MACRO(TARGET_USE_COMMON_OUTPUT_DIRECTORY target)
set_target_properties(${target} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${ASSIMP_RUNTIME_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${ASSIMP_LIBRARY_OUTPUT_DIRECTORY}
ARCHIVE_OUTPUT_DIRECTORY ${ASSIMP_ARCHIVE_OUTPUT_DIRECTORY}
)
ENDMACRO()
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
@@ -356,7 +359,7 @@ ELSE()
ENDIF()
# Only generate this target if no higher-level project already has
IF (NOT TARGET uninstall)
IF (NOT TARGET uninstall AND ASSIMP_INSTALL)
# add make uninstall capability
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
@@ -390,76 +393,56 @@ ELSE()
SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_BIN_INSTALL_DIR})
ENDIF()
set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
IF(ASSIMP_HUNTER_ENABLED)
set(CONFIG_INSTALL_DIR "lib/cmake/${PROJECT_NAME}")
set(INCLUDE_INSTALL_DIR "include")
set(GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
# Configuration
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-hunter-config.cmake.in")
set(NAMESPACE "${PROJECT_NAME}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME}Config.cmake")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME}Targets")
set(NAMESPACE "${PROJECT_NAME}::")
# Include module with fuction 'write_basic_package_version_file'
include(CMakePackageConfigHelpers)
# Note: PROJECT_VERSION is used as a VERSION
write_basic_package_version_file("${VERSION_CONFIG}" COMPATIBILITY SameMajorVersion)
# Use variables:
# * TARGETS_EXPORT_NAME
# * PROJECT_NAME
configure_package_config_file(
"cmake/assimp-hunter-config.cmake.in"
"${PROJECT_CONFIG}"
INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
)
install(
FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
DESTINATION "${CONFIG_INSTALL_DIR}"
)
install(
EXPORT "${TARGETS_EXPORT_NAME}"
NAMESPACE "${NAMESPACE}"
DESTINATION "${CONFIG_INSTALL_DIR}"
)
ELSE()
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
IF (is_multi_config)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake")
ELSEIF (CMAKE_BUILD_TYPE STREQUAL Debug)
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-debug.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake" @ONLY IMMEDIATE)
SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-debug.cmake")
ELSE()
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets-release.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake" @ONLY IMMEDIATE)
SET(PACKAGE_TARGETS_FILE "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets-release.cmake")
ENDIF()
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
#we should generated these scripts after CMake VERSION 3.0.2 using export(EXPORT ...) and write_basic_package_version_file(...)
INSTALL(FILES
"${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake"
${PACKAGE_TARGETS_FILE}
DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
set(CONFIG_INSTALL_DIR "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
set(CMAKE_CONFIG_TEMPLATE_FILE "cmake/assimp-plain-config.cmake.in")
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWERCASE)
set(NAMESPACE "${PROJECT_NAME_LOWERCASE}::")
set(TARGETS_EXPORT_NAME "${PROJECT_NAME_LOWERCASE}Targets")
set(VERSION_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}ConfigVersion.cmake")
set(PROJECT_CONFIG "${GENERATED_DIR}/${PROJECT_NAME_LOWERCASE}Config.cmake")
ENDIF()
set(INCLUDE_INSTALL_DIR "include")
# Include module with fuction 'write_basic_package_version_file'
include(CMakePackageConfigHelpers)
# Note: PROJECT_VERSION is used as a VERSION
write_basic_package_version_file("${VERSION_CONFIG}" COMPATIBILITY SameMajorVersion)
configure_package_config_file(
${CMAKE_CONFIG_TEMPLATE_FILE}
"${PROJECT_CONFIG}"
INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
)
install(
FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
DESTINATION "${CONFIG_INSTALL_DIR}"
COMPONENT ${LIBASSIMP-DEV_COMPONENT}
)
install(
EXPORT "${TARGETS_EXPORT_NAME}"
NAMESPACE "${NAMESPACE}"
DESTINATION "${CONFIG_INSTALL_DIR}"
COMPONENT ${LIBASSIMP-DEV_COMPONENT}
)
IF( ASSIMP_BUILD_DOCS )
ADD_SUBDIRECTORY(doc)
ENDIF()
# Look for system installed irrXML
IF ( ASSIMP_SYSTEM_IRRXML )
FIND_PACKAGE( IrrXML REQUIRED )
ENDIF()
# Search for external dependencies, and build them from source if not found
# Search for zlib
IF(ASSIMP_HUNTER_ENABLED)
@@ -586,10 +569,6 @@ ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF ()
IF(NOT ASSIMP_HUNTER_ENABLED)
ADD_SUBDIRECTORY(contrib)
ENDIF()
ADD_SUBDIRECTORY( code/ )
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
# The viewer for windows only
@@ -684,7 +663,8 @@ if(WIN32)
ENDIF()
IF(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
SET(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
SET(ASSIMP_MSVC_VERSION ${MCVS_PREFIX})
ELSE()
IF(MSVC12)
SET(ASSIMP_MSVC_VERSION "vc120")
+8 -5
View File
@@ -16,13 +16,16 @@ A library to import and export various 3d-model-formats including scene-post-pro
<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.
[Check the latest doc](https://assimp-docs.readthedocs.io/en/latest/).
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).
### Latest Doc's ###
Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/).
### Get involved ###
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).
<br>
You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
<br>
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
@@ -70,7 +73,7 @@ The source code is organized in the following way:
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.
If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](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)
-48
View File
@@ -1,48 +0,0 @@
# Open Asset Import Library (assimp)
# ----------------------------------------------------------------------
# Copyright (c) 2006-2020, assimp team
# All rights reserved.
#
# Redistribution and use of this software in source and binary forms,
# with or without modification, are permitted provided that the
# following conditions are met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the
# following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# * Neither the name of the assimp team, nor the names of its
# contributors may be used to endorse or promote products
# derived from this software without specific prior
# written permission of the assimp team.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#----------------------------------------------------------------------
set( PACKAGE_VERSION "@ASSIMP_VERSION@" )
if( "${PACKAGE_FIND_VERSION}" VERSION_EQUAL "@ASSIMP_VERSION@")
set(PACKAGE_VERSION_EXACT 1)
endif()
if( "${PACKAGE_FIND_VERSION_MAJOR}.${PACKAGE_FIND_VERSION_MINOR}" EQUAL "@ASSIMP_VERSION@" )
set(PACKAGE_VERSION_COMPATIBLE 1)
elseif( "${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "@ASSIMP_VERSION_MAJOR@" )
# for now backward compatible if minor version is less
if( ${PACKAGE_FIND_VERSION_MINOR} LESS @ASSIMP_VERSION_MINOR@ )
set(PACKAGE_VERSION_COMPATIBLE 1)
endif()
endif()
set( ASSIMP_STATIC_LIB "@ASSIMP_BUILD_STATIC_LIB@")
-1
View File
@@ -1 +0,0 @@
include(${CMAKE_CURRENT_LIST_DIR}/assimpTargets.cmake)
-126
View File
@@ -1,126 +0,0 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Debug".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if(MSVC)
if(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
else()
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( MSVC_VERSION LESS 1910)
set(MSVC_PREFIX "vc140")
elseif( MSVC_VERSION LESS 1920)
set(MSVC_PREFIX "vc141")
elseif( MSVC_VERSION LESS 1930)
set(MSVC_PREFIX "vc142")
else()
set(MSVC_PREFIX "vc150")
endif()
endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
if(ASSIMP_BUILD_SHARED_LIBS)
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Debug"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_IMPLIB_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}"
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}")
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}" )
else()
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Debug"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}")
endif()
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS)
if(WIN32)
# Handle MinGW compiler.
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
elseif(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else()
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
# Import target "assimp::assimp" for configuration "Debug"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
else()
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Debug"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
endif()
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
set( ASSIMP_CXX_FLAGS ) # dynamically linked library
set( ASSIMP_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
if(ASSIMP_BUILD_SHARED_LIBS)
set( ASSIMP_LIBRARIES ${sharedLibraryName})
else()
set( ASSIMP_LIBRARIES ${staticLibraryName})
endif()
# for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
MARK_AS_ADVANCED(
ASSIMP_ROOT_DIR
ASSIMP_CXX_FLAGS
ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES
ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX
ASSIMP_BUILD_SHARED_LIBS
)
-127
View File
@@ -1,127 +0,0 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
if(MSVC)
if(MSVC_TOOLSET_VERSION)
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
else()
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( MSVC_VERSION LESS 1910)
set(MSVC_PREFIX "vc140")
elseif( MSVC_VERSION LESS 1920)
set(MSVC_PREFIX "vc141")
elseif( MSVC_VERSION LESS 1930)
set(MSVC_PREFIX "vc142")
else()
set(MSVC_PREFIX "vc150")
endif()
endif()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
if(ASSIMP_BUILD_SHARED_LIBS)
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Release"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_IMPLIB_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}"
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}")
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}" )
else()
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Release"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}")
endif()
else()
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@" CACHE STRING "the suffix for the assimp libraries" )
if(ASSIMP_BUILD_SHARED_LIBS)
if(WIN32)
# Handle MinGW compiler.
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
elseif(APPLE)
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}.@ASSIMP_VERSION_MAJOR@@CMAKE_SHARED_LIBRARY_SUFFIX@")
else()
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
endif()
# Import target "assimp::assimp" for configuration "Release"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
else()
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
# Import target "assimp::assimp" for configuration "Release"
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(assimp::assimp PROPERTIES
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
)
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
endif()
endif()
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
get_filename_component(ASSIMP_ROOT_DIR "@CMAKE_INSTALL_PREFIX@" REALPATH)
set( ASSIMP_CXX_FLAGS ) # dynamically linked library
set( ASSIMP_LINK_FLAGS "" )
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
if(ASSIMP_BUILD_SHARED_LIBS)
set( ASSIMP_LIBRARIES ${sharedLibraryName})
else()
set( ASSIMP_LIBRARIES ${staticLibraryName})
endif()
# for compatibility with pkg-config
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
MARK_AS_ADVANCED(
ASSIMP_ROOT_DIR
ASSIMP_CXX_FLAGS
ASSIMP_LINK_FLAGS
ASSIMP_INCLUDE_DIRS
ASSIMP_LIBRARIES
ASSIMP_CFLAGS_OTHER
ASSIMP_LDFLAGS_OTHER
ASSIMP_LIBRARY_SUFFIX
ASSIMP_BUILD_SHARED_LIBS
)
-91
View File
@@ -1,91 +0,0 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
# Required for the evaluation of "if(@BUILD_SHARED_LIBS@)" below to function
cmake_policy(SET CMP0012 NEW)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget assimp::assimp)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Create imported target assimp::assimp
add_library(assimp::assimp @BUILD_LIB_TYPE@ IMPORTED)
set_target_properties(assimp::assimp PROPERTIES
COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"
INTERFACE_assimp_MAJOR_VERSION "1"
INTERFACE_INCLUDE_DIRECTORIES "@CMAKE_INSTALL_FULL_INCLUDEDIR@"
#INTERFACE_LINK_LIBRARIES "TxtUtils::TxtUtils;MealyMachine::MealyMachine"
)
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "This file relies on consumers using CMake 2.8.12 or greater.")
endif()
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/assimpTargets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
+1 -1
View File
@@ -16,5 +16,5 @@ set(RT_LIBRARIES ${RT_LIBRARY})
# handle the QUIETLY and REQUIRED arguments and set
# RT_FOUND to TRUE if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(rt DEFAULT_MSG RT_LIBRARY)
find_package_handle_standard_args(RT DEFAULT_MSG RT_LIBRARY)
mark_as_advanced(RT_LIBRARY)
+15 -16
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2013-2018, Ruslan Baratov
# Copyright (c) 2013-2019, Ruslan Baratov
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -60,7 +60,7 @@ option(HUNTER_STATUS_PRINT "Print working status" ON)
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF)
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON)
set(HUNTER_WIKI "https://github.com/ruslo/hunter/wiki")
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors")
function(hunter_gate_status_print)
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG)
@@ -79,9 +79,9 @@ function(hunter_gate_status_debug)
endif()
endfunction()
function(hunter_gate_wiki wiki_page)
message("------------------------------ WIKI -------------------------------")
message(" ${HUNTER_WIKI}/${wiki_page}")
function(hunter_gate_error_page error_page)
message("------------------------------ ERROR ------------------------------")
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html")
message("-------------------------------------------------------------------")
message("")
message(FATAL_ERROR "")
@@ -94,14 +94,13 @@ function(hunter_gate_internal_error)
endforeach()
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_wiki("error.internal")
hunter_gate_error_page("error.internal")
endfunction()
function(hunter_gate_fatal_error)
cmake_parse_arguments(hunter "" "WIKI" "" "${ARGV}")
string(COMPARE EQUAL "${hunter_WIKI}" "" have_no_wiki)
if(have_no_wiki)
hunter_gate_internal_error("Expected wiki")
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}")
if("${hunter_ERROR_PAGE}" STREQUAL "")
hunter_gate_internal_error("Expected ERROR_PAGE")
endif()
message("")
foreach(x ${hunter_UNPARSED_ARGUMENTS})
@@ -109,11 +108,11 @@ function(hunter_gate_fatal_error)
endforeach()
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]")
message("")
hunter_gate_wiki("${hunter_WIKI}")
hunter_gate_error_page("${hunter_ERROR_PAGE}")
endfunction()
function(hunter_gate_user_error)
hunter_gate_fatal_error(${ARGV} WIKI "error.incorrect.input.data")
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data")
endfunction()
function(hunter_gate_self root version sha1 result)
@@ -195,7 +194,7 @@ function(hunter_gate_detect_root)
hunter_gate_fatal_error(
"Can't detect HUNTER_ROOT"
WIKI "error.detect.hunter.root"
ERROR_PAGE "error.detect.hunter.root"
)
endfunction()
@@ -214,7 +213,7 @@ function(hunter_gate_download dir)
"Settings:"
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}"
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}"
WIKI "error.run.install"
ERROR_PAGE "error.run.install"
)
endif()
string(COMPARE EQUAL "${dir}" "" is_bad)
@@ -400,7 +399,7 @@ macro(HunterGate)
hunter_gate_fatal_error(
"Please set HunterGate *before* 'project' command. "
"Detected project: ${PROJECT_NAME}"
WIKI "error.huntergate.before.project"
ERROR_PAGE "error.huntergate.before.project"
)
endif()
@@ -470,7 +469,7 @@ macro(HunterGate)
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces."
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error"
"(Use at your own risk!)"
WIKI "error.spaces.in.hunter.root"
ERROR_PAGE "error.spaces.in.hunter.root"
)
endif()
endif()
+1 -1
View File
@@ -3,12 +3,12 @@
find_package(RapidJSON CONFIG REQUIRED)
find_package(ZLIB CONFIG REQUIRED)
find_package(utf8cpp CONFIG REQUIRED)
find_package(irrXML CONFIG REQUIRED)
find_package(minizip CONFIG REQUIRED)
find_package(openddlparser CONFIG REQUIRED)
find_package(poly2tri CONFIG REQUIRED)
find_package(polyclipping CONFIG REQUIRED)
find_package(zip CONFIG REQUIRED)
find_package(pugixml CONFIG REQUIRED)
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
check_required_components("@PROJECT_NAME@")
+9
View File
@@ -0,0 +1,9 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
set(ASSIMP_ROOT_DIR ${PACKAGE_PREFIX_DIR})
set(ASSIMP_LIBRARIES assimp::assimp)
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
get_property(ASSIMP_INCLUDE_DIRS TARGET assimp::assimp PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
set(ASSIMP_LIBRARY_DIRS "")
+7 -2
View File
@@ -290,12 +290,18 @@ void Discreet3DSExporter::WriteMaterials() {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color);
}
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color);
}
float f;
if (mat.Get(AI_MATKEY_OPACITY, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TRANSPARENCY);
WritePercentChunk(1.0f - f);
}
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter curChunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color);
@@ -333,7 +339,6 @@ void Discreet3DSExporter::WriteMaterials() {
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);
+2 -2
View File
@@ -147,7 +147,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
// We should have at least one chunk
if (theStream.GetRemainingSize() < 16) {
throw DeadlyImportError("3DS file is either empty or corrupt: " + pFile);
throw DeadlyImportError("3DS file is either empty or corrupt: ", pFile);
}
this->stream = &theStream;
@@ -178,7 +178,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
// file.
for (auto &mesh : mScene->mMeshes) {
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
throw DeadlyImportError("3DS file contains faces but no vertices: ", pFile);
}
CheckIndices(mesh);
MakeUnique(mesh);
-1
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
-1
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
-1
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
+84 -112
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -46,12 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h>
#include <assimp/StringUtils.h>
#include <assimp/XmlParser.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <cassert>
#include <map>
#include <memory>
@@ -61,7 +60,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "3MFXmlTags.h"
#include "D3MFOpcPackage.h"
#include <assimp/fast_atof.h>
#include <assimp/irrXMLWrapper.h>
#include <iomanip>
@@ -73,12 +71,12 @@ public:
using MatArray = std::vector<aiMaterial *>;
using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
XmlSerializer(XmlReader *xmlReader) :
XmlSerializer(XmlParser *xmlParser) :
mMeshes(),
mMatArray(),
mActiveMatGroup(99999999),
mMatId2MatArray(),
xmlReader(xmlReader) {
mXmlParser(xmlParser) {
// empty
}
@@ -95,16 +93,21 @@ public:
std::vector<aiNode *> children;
std::string nodeName;
while (ReadToEndElement(D3MF::XmlTag::model)) {
nodeName = xmlReader->getNodeName();
if (nodeName == D3MF::XmlTag::object) {
children.push_back(ReadObject(scene));
} else if (nodeName == D3MF::XmlTag::build) {
XmlNode node = mXmlParser->getRootNode().child("model");
if (node.empty()) {
return;
}
XmlNode resNode = node.child("resources");
for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentNodeName = currentNode.name();
if (currentNodeName == D3MF::XmlTag::object) {
children.push_back(ReadObject(currentNode, scene));
} else if (currentNodeName == D3MF::XmlTag::build) {
//
} else if (nodeName == D3MF::XmlTag::basematerials) {
ReadBaseMaterials();
} else if (nodeName == D3MF::XmlTag::meta) {
ReadMetadata();
} else if (currentNodeName == D3MF::XmlTag::basematerials) {
ReadBaseMaterials(currentNode);
} else if (currentNodeName == D3MF::XmlTag::meta) {
ReadMetadata(currentNode);
}
}
@@ -134,38 +137,37 @@ public:
std::copy(mMatArray.begin(), mMatArray.end(), scene->mMaterials);
}
// create the scenegraph
// create the scene-graph
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());
aiNode *ReadObject(XmlNode &node, aiScene *scene) {
std::unique_ptr<aiNode> nodePtr(new aiNode());
std::vector<unsigned long> meshIds;
const char *attrib(nullptr);
std::string name, type;
attrib = xmlReader->getAttributeValue(D3MF::XmlTag::id.c_str());
if (nullptr != attrib) {
name = attrib;
pugi::xml_attribute attr = node.attribute(D3MF::XmlTag::id.c_str());
if (!attr.empty()) {
name = attr.as_string();
}
attrib = xmlReader->getAttributeValue(D3MF::XmlTag::type.c_str());
if (nullptr != attrib) {
type = attrib;
attr = node.attribute(D3MF::XmlTag::type.c_str());
if (!attr.empty()) {
type = attr.as_string();
}
node->mParent = scene->mRootNode;
node->mName.Set(name);
nodePtr->mParent = scene->mRootNode;
nodePtr->mName.Set(name);
size_t meshIdx = mMeshes.size();
while (ReadToEndElement(D3MF::XmlTag::object)) {
if (xmlReader->getNodeName() == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh();
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::mesh) {
auto mesh = ReadMesh(currentNode);
mesh->mName.Set(name);
mMeshes.push_back(mesh);
meshIds.push_back(static_cast<unsigned long>(meshIdx));
@@ -173,33 +175,34 @@ private:
}
}
node->mNumMeshes = static_cast<unsigned int>(meshIds.size());
nodePtr->mNumMeshes = static_cast<unsigned int>(meshIds.size());
node->mMeshes = new unsigned int[node->mNumMeshes];
nodePtr->mMeshes = new unsigned int[nodePtr->mNumMeshes];
std::copy(meshIds.begin(), meshIds.end(), node->mMeshes);
std::copy(meshIds.begin(), meshIds.end(), nodePtr->mMeshes);
return node.release();
return nodePtr.release();
}
aiMesh *ReadMesh() {
aiMesh *ReadMesh(XmlNode &node) {
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);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::vertices) {
ImportVertices(currentNode, mesh);
} else if (currentName == D3MF::XmlTag::triangles) {
ImportTriangles(currentNode, mesh);
}
}
return mesh;
}
void ReadMetadata() {
const std::string name = xmlReader->getAttributeValue(D3MF::XmlTag::meta_name.c_str());
xmlReader->read();
const std::string value = xmlReader->getNodeData();
void ReadMetadata(XmlNode &node) {
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name.c_str());
const std::string name = attribute.as_string();
const std::string value = node.value();
if (name.empty()) {
return;
}
@@ -210,37 +213,36 @@ private:
mMetaData.push_back(entry);
}
void ImportVertices(aiMesh *mesh) {
void ImportVertices(XmlNode &node, aiMesh *mesh) {
std::vector<aiVector3D> vertices;
while (ReadToEndElement(D3MF::XmlTag::vertices)) {
if (xmlReader->getNodeName() == D3MF::XmlTag::vertex) {
vertices.push_back(ReadVertex());
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::vertex) {
vertices.push_back(ReadVertex(currentNode));
}
}
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 ReadVertex(XmlNode &node) {
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);
vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x.c_str()).as_string(), nullptr);
vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y.c_str()).as_string(), nullptr);
vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z.c_str()).as_string(), nullptr);
return vertex;
}
void ImportTriangles(aiMesh *mesh) {
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
std::vector<aiFace> faces;
while (ReadToEndElement(D3MF::XmlTag::triangles)) {
const std::string nodeName(xmlReader->getNodeName());
if (xmlReader->getNodeName() == D3MF::XmlTag::triangle) {
faces.push_back(ReadTriangle());
const char *pidToken(xmlReader->getAttributeValue(D3MF::XmlTag::p1.c_str()));
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == D3MF::XmlTag::triangle) {
faces.push_back(ReadTriangle(currentNode));
const char *pidToken = currentNode.attribute(D3MF::XmlTag::p1.c_str()).as_string();
if (nullptr != pidToken) {
int matIdx(std::atoi(pidToken));
mesh->mMaterialIndex = matIdx;
@@ -255,21 +257,21 @@ private:
std::copy(faces.begin(), faces.end(), mesh->mFaces);
}
aiFace ReadTriangle() {
aiFace ReadTriangle(XmlNode &node) {
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())));
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v1.c_str()).as_string()));
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v2.c_str()).as_string()));
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v3.c_str()).as_string()));
return face;
}
void ReadBaseMaterials() {
void ReadBaseMaterials(XmlNode &node) {
std::vector<unsigned int> MatIdArray;
const char *baseMaterialId(xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_id.c_str()));
const char *baseMaterialId = node.attribute(D3MF::XmlTag::basematerials_id.c_str()).as_string();
if (nullptr != baseMaterialId) {
unsigned int id = std::atoi(baseMaterialId);
const size_t newMatIdx(mMatArray.size());
@@ -287,9 +289,7 @@ private:
mMatId2MatArray[mActiveMatGroup] = MatIdArray;
}
while (ReadToEndElement(D3MF::XmlTag::basematerials)) {
mMatArray.push_back(readMaterialDef());
}
mMatArray.push_back(readMaterialDef(node));
}
bool parseColor(const char *color, aiColor4D &diffuse) {
@@ -339,19 +339,20 @@ private:
return true;
}
void assignDiffuseColor(aiMaterial *mat) {
const char *color = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_displaycolor.c_str());
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
const char *color = node.attribute(D3MF::XmlTag::basematerials_displaycolor.c_str()).as_string();
aiColor4D diffuse;
if (parseColor(color, diffuse)) {
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
}
}
aiMaterial *readMaterialDef() {
aiMaterial *readMaterialDef(XmlNode &node) {
aiMaterial *mat(nullptr);
const char *name(nullptr);
const std::string nodeName(xmlReader->getNodeName());
const std::string nodeName = node.name();
if (nodeName == D3MF::XmlTag::basematerials_base) {
name = xmlReader->getAttributeValue(D3MF::XmlTag::basematerials_name.c_str());
name = node.attribute(D3MF::XmlTag::basematerials_name.c_str()).as_string();
std::string stdMatName;
aiString matName;
std::string strId(to_string(mActiveMatGroup));
@@ -368,40 +369,12 @@ private:
mat = new aiMaterial;
mat->AddProperty(&matName, AI_MATKEY_NAME);
assignDiffuseColor(mat);
assignDiffuseColor(node, mat);
}
return mat;
}
private:
bool ReadToStartElement(const std::string &startTag) {
while (xmlReader->read()) {
const std::string &nodeName(xmlReader->getNodeName());
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT && nodeName == startTag) {
return true;
} else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == startTag) {
return false;
}
}
return false;
}
bool ReadToEndElement(const std::string &closeTag) {
while (xmlReader->read()) {
const std::string &nodeName(xmlReader->getNodeName());
if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT) {
return true;
} else if (xmlReader->getNodeType() == irr::io::EXN_ELEMENT_END && nodeName == closeTag) {
return false;
}
}
ASSIMP_LOG_ERROR("unexpected EOF, expected closing <" + closeTag + "> tag");
return false;
}
private:
struct MetaEntry {
std::string name;
@@ -412,7 +385,7 @@ private:
MatArray mMatArray;
unsigned int mActiveMatGroup;
MatId2MatArray mMatId2MatArray;
XmlReader *xmlReader;
XmlParser *mXmlParser;
};
} //namespace D3MF
@@ -468,12 +441,11 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
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);
XmlParser xmlParser;
if (xmlParser.parse(opcPackage.RootStream())) {
D3MF::XmlSerializer xmlSerializer(&xmlParser);
xmlSerializer.ImportXml(pScene);
}
}
} // Namespace Assimp
+37 -31
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -45,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "D3MFOpcPackage.h"
#include <assimp/Exceptional.h>
#include <assimp/XmlParser.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/ai_assert.h>
#include <assimp/DefaultLogger.hpp>
@@ -68,27 +68,22 @@ 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);
OpcPackageRelationshipReader(XmlParser &parser) {
XmlNode root = parser.getRootNode();
ParseRootNode(root);
}
void ParseRootNode(XmlNode &node) {
ParseAttributes(node);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string name = currentNode.name();
if (name == "Relationships") {
ParseRelationsNode(currentNode);
}
}
}
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 *) {
void ParseAttributes(XmlNode & /*node*/) {
// empty
}
@@ -99,14 +94,22 @@ public:
return true;
}
void ParseChildNode(XmlReader *xmlReader) {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
void ParseRelationsNode(XmlNode &node) {
if (node.empty()) {
return;
}
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);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string name = currentNode.name();
if (name == "Relationship") {
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID.c_str()).as_string();
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE.c_str()).as_string();
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET.c_str()).as_string();
if (validateRels(relPtr)) {
m_relationShips.push_back(relPtr);
}
}
}
}
@@ -115,10 +118,11 @@ public:
// ------------------------------------------------------------------------------------------------
D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
mRootStream(nullptr), mZipArchive() {
mRootStream(nullptr),
mZipArchive() {
mZipArchive.reset(new ZipArchiveIOSystem(pIOHandler, rFile));
if (!mZipArchive->isOpen()) {
throw DeadlyImportError("Failed to open file " + rFile + ".");
throw DeadlyImportError("Failed to open file ", rFile, ".");
}
std::vector<std::string> fileList;
@@ -182,17 +186,19 @@ bool D3MFOpcPackage::validate() {
}
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()));
XmlParser xmlParser;
if (!xmlParser.parse(stream)) {
return "";
}
OpcPackageRelationshipReader reader(xml.get());
OpcPackageRelationshipReader reader(xmlParser);
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);
throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
}
return (*itr)->target;
+2 -7
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -44,18 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define D3MFOPCPACKAGE_H
#include <memory>
#include <string>
#include <assimp/IOSystem.hpp>
#include <assimp/irrXMLWrapper.h>
namespace Assimp {
class ZipArchiveIOSystem;
namespace D3MF {
using XmlReader = irr::io::IrrXMLReader ;
using XmlReaderPtr = std::shared_ptr<XmlReader> ;
struct OpcPackageRelationship {
std::string id;
std::string type;
@@ -64,7 +59,7 @@ struct OpcPackageRelationship {
class D3MFOpcPackage {
public:
D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
D3MFOpcPackage( IOSystem* pIOHandler, const std::string& file );
~D3MFOpcPackage();
IOStream* RootStream() const;
bool validate();
+1 -1
View File
@@ -762,7 +762,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open AC3D file " + pFile + ".");
throw DeadlyImportError("Failed to open AC3D file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer
+166 -299
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -60,8 +58,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
/// \var aiImporterDesc AMFImporter::Description
/// Conastant which hold importer description
const aiImporterDesc AMFImporter::Description = {
"Additive manufacturing file format(AMF) Importer",
"smalcom",
@@ -82,7 +78,7 @@ void AMFImporter::Clear() {
mTexture_Converted.clear();
// Delete all elements
if (!mNodeElement_List.empty()) {
for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
for (AMFNodeElementBase *ne : mNodeElement_List) {
delete ne;
}
@@ -90,8 +86,18 @@ void AMFImporter::Clear() {
}
}
AMFImporter::AMFImporter() AI_NO_EXCEPT :
mNodeElement_Cur(nullptr),
mXmlParser(nullptr),
mUnit(),
mVersion(),
mMaterial_Converted(),
mTexture_Converted() {
// empty
}
AMFImporter::~AMFImporter() {
if (mReader != nullptr) delete mReader;
delete mXmlParser;
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
Clear();
}
@@ -100,10 +106,12 @@ AMFImporter::~AMFImporter() {
/************************************************************ 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) {
bool AMFImporter::Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const {
for (AMFNodeElementBase *ne : mNodeElement_List) {
if ((ne->ID == pID) && (ne->Type == pType)) {
if (pNodeElement != nullptr) *pNodeElement = ne;
if (pNodeElement != nullptr) {
*pNodeElement = ne;
}
return true;
}
@@ -112,12 +120,13 @@ bool AMFImporter::Find_NodeElement(const std::string &pID, const CAMFImporter_No
return false;
}
bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *> &pNodeList, aiNode **pNode) const {
bool AMFImporter::Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const {
aiString node_name(pID.c_str());
for (aiNode *node : pNodeList) {
for (aiNode *node : nodeArray) {
if (node->mName == node_name) {
if (pNode != nullptr) *pNode = node;
if (pNode != nullptr) {
*pNode = node;
}
return true;
}
@@ -129,7 +138,9 @@ bool AMFImporter::Find_ConvertedNode(const std::string &pID, std::list<aiNode *>
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;
if (pConvertedMaterial != nullptr) {
*pConvertedMaterial = &mat;
}
return true;
}
@@ -142,148 +153,38 @@ bool AMFImporter::Find_ConvertedMaterial(const std::string &pID, const SPP_Mater
/************************************************************ 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_CloseNotFound(const std::string &nodeName) {
throw DeadlyImportError("Close tag for node <" + nodeName + "> 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_IncorrectAttr(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Node <" + nodeName + "> has incorrect attribute \"" + attrName + "\".");
}
void AMFImporter::Throw_IncorrectAttrValue(const std::string &pAttrName) {
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
void AMFImporter::Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &attrName) {
throw DeadlyImportError("Attribute \"" + attrName + "\" in node <" + nodeName + "> 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_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) {
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + nodeName + ". Description: " + pDescription);
}
void AMFImporter::Throw_ID_NotFound(const std::string &pID) const {
throw DeadlyImportError("Not found node with name \"" + pID + "\".");
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;
ASSIMP_LOG_WARN_F("Skipping node \"", nn, "\" in ", pParentNodeName, ".");
void AMFImporter::XML_CheckNode_MustHaveChildren(pugi::xml_node &node) {
if (node.children().begin() == node.children().end()) {
throw DeadlyImportError(std::string("Node <") + node.name() + "> must have children.");
}
}
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;
bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
return nullptr != mXmlParser->findNode(nodeName);
}
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) {
@@ -362,29 +263,33 @@ void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std
}
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() == nullptr) {
throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
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.");
mXmlParser = new XmlParser();
if (!mXmlParser->parse(file.get())) {
delete mXmlParser;
throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
}
delete mReader;
// restore old XMLreader
mReader = OldReader;
// Start reading, search for root tag <amf>
if (!mXmlParser->hasNode("amf")) {
throw DeadlyImportError("Root node \"amf\" not found.");
}
ParseNode_Root();
} // namespace Assimp
void AMFImporter::ParseHelper_Node_Enter(AMFNodeElementBase *node) {
mNodeElement_Cur->Child.push_back(node); // add new element to current element child list.
mNodeElement_Cur = node;
}
void AMFImporter::ParseHelper_Node_Exit() {
if (mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
}
// <amf
@@ -395,54 +300,48 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
// Root XML element.
// Multi elements - No.
void AMFImporter::ParseNode_Root() {
std::string unit, version;
CAMFImporter_NodeElement *ne(nullptr);
AMFNodeElementBase *ne = nullptr;
XmlNode *root = mXmlParser->findNode("amf");
if (nullptr == root) {
throw DeadlyImportError("Root node \"amf\" not found.");
}
XmlNode node = *root;
mUnit = node.attribute("unit").as_string();
mVersion = node.attribute("version").as_string();
// 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");
if ((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
Throw_IncorrectAttrValue("unit", mUnit);
}
}
// create root node element.
ne = new CAMFImporter_NodeElement_Root(nullptr);
ne = new AMFRoot(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;
((AMFRoot *)ne)->Unit = mUnit;
((AMFRoot *)ne)->Version = mVersion;
// Check for child nodes
if (!mReader->isEmptyElement()) {
MACRO_NODECHECK_LOOPBEGIN("amf");
if (XML_CheckNode_NameEqual("object")) {
ParseNode_Object();
continue;
for (XmlNode &currentNode : node.children() ) {
const std::string currentName = currentNode.name();
if (currentName == "object") {
ParseNode_Object(currentNode);
} else if (currentName == "material") {
ParseNode_Material(currentNode);
} else if (currentName == "texture") {
ParseNode_Texture(currentNode);
} else if (currentName == "constellation") {
ParseNode_Constellation(currentNode);
} else if (currentName == "metadata") {
ParseNode_Metadata(currentNode);
}
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_Cur = ne;
}
mNodeElement_Cur = ne; // force restore "current" element
mNodeElement_List.push_back(ne); // add to node element list because its a new object in graph.
}
@@ -453,40 +352,34 @@ void AMFImporter::ParseNode_Root() {
// A collection of objects or constellations with specific relative locations.
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Constellation() {
void AMFImporter::ParseNode_Constellation(XmlNode &node) {
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;
id = node.attribute("id").as_string();
// create and if needed - define new grouping object.
ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
AMFNodeElementBase *ne = new AMFConstellation(mNodeElement_Cur);
CAMFImporter_NodeElement_Constellation &als = *((CAMFImporter_NodeElement_Constellation *)ne); // alias for convenience
AMFConstellation &als = *((AMFConstellation *)ne); // alias for convenience
if (!id.empty()) {
als.ID = id;
}
if (!id.empty()) als.ID = id;
// Check for child nodes
if (!mReader->isEmptyElement()) {
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
MACRO_NODECHECK_LOOPBEGIN("constellation");
if (XML_CheckNode_NameEqual("instance")) {
ParseNode_Instance();
continue;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
std::string name = currentNode.name();
if (name == "instance") {
ParseNode_Instance(currentNode);
} else if (name == "metadata") {
ParseNode_Metadata(currentNode);
}
}
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
} else {
mNodeElement_Cur->Child.push_back(ne);
}
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
@@ -497,47 +390,43 @@ void AMFImporter::ParseNode_Constellation() {
// 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);
void AMFImporter::ParseNode_Instance(XmlNode &node) {
AMFNodeElementBase *ne(nullptr);
// Read attributes for node <constellation>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
std::string objectid = node.attribute("objectid").as_string();
// used object id must be defined, check that.
if (objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
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
ne = new AMFInstance(mNodeElement_Cur);
AMFInstance &als = *((AMFInstance *)ne);
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);
if (!node.empty()) {
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");
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == "deltax") {
als.Delta.x = (ai_real)std::atof(currentNode.value());
} else if (currentName == "deltay") {
als.Delta.y = (ai_real)std::atof(currentNode.value());
} else if (currentName == "deltaz") {
als.Delta.z = (ai_real)std::atof(currentNode.value());
} else if (currentName == "rx") {
als.Delta.x = (ai_real)std::atof(currentNode.value());
} else if (currentName == "ry") {
als.Delta.y = (ai_real)std::atof(currentNode.value());
} else if (currentName == "rz") {
als.Delta.z = (ai_real)std::atof(currentNode.value());
}
}
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
} else {
mNodeElement_Cur->Child.push_back(ne);
}
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
@@ -549,51 +438,38 @@ void AMFImporter::ParseNode_Instance() {
// An object definition.
// Multi elements - Yes.
// Parent element - <amf>.
void AMFImporter::ParseNode_Object() {
std::string id;
CAMFImporter_NodeElement *ne(nullptr);
void AMFImporter::ParseNode_Object(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// Read attributes for node <object>.
MACRO_ATTRREAD_LOOPBEG;
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
MACRO_ATTRREAD_LOOPEND;
std::string id = node.attribute("id").as_string();
// create and if needed - define new geometry object.
ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
ne = new AMFObject(mNodeElement_Cur);
CAMFImporter_NodeElement_Object &als = *((CAMFImporter_NodeElement_Object *)ne); // alias for convenience
AMFObject &als = *((AMFObject *)ne); // alias for convenience
if (!id.empty()) {
als.ID = id;
}
if (!id.empty()) als.ID = id;
// Check for child nodes
if (!mReader->isEmptyElement()) {
bool col_read = false;
if (!node.empty()) {
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;
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string &currentName = currentNode.name();
if (currentName == "color") {
ParseNode_Color(currentNode);
} else if (currentName == "mesh") {
ParseNode_Mesh(currentNode);
} else if (currentName == "metadata") {
ParseNode_Metadata(currentNode);
}
}
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 {
} 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.
}
@@ -616,28 +492,20 @@ void AMFImporter::ParseNode_Object() {
// "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);
void AMFImporter::ParseNode_Metadata(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
std::string type = node.attribute("type").as_string(), value;
XmlParser::getValueAsString(node, value);
// 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;
ne = new AMFMetadata(mNodeElement_Cur);
((AMFMetadata *)ne)->Type = type;
((AMFMetadata *)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);
@@ -645,9 +513,8 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
return true;
}
if (!extension.length() || pCheckSig) {
if (extension.empty() || pCheckSig) {
const char *tokens[] = { "<amf" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
+148 -269
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -54,11 +52,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter_Node.hpp"
// Header files, Assimp.
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>
#include "assimp/types.h"
#include <assimp/BaseImporter.h>
#include <assimp/irrXMLWrapper.h>
#include <assimp/XmlParser.h>
#include <assimp/importerdesc.h>
#include <assimp/DefaultLogger.hpp>
// Header files, stdlib.
#include <set>
@@ -101,22 +99,21 @@ namespace Assimp {
///
class AMFImporter : public BaseImporter {
private:
struct SPP_Material;// forward declaration
struct SPP_Material; // forward declaration
/// \struct SPP_Composite
/// Data type for post-processing step. More suitable container for part of material's composition.
/// Data type for post-processing 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.
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 post-processing 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.
std::string ID; ///< Material ID.
std::list<AMFMetadata *> Metadata; ///< Metadata of material.
AMFColor *Color; ///< Color of material.
std::list<SPP_Composite> Composition; ///< List of child materials if current material is composition of few another.
/// Return color calculated for specified coordinate.
/// \param [in] pX - "x" coordinate.
@@ -129,304 +126,186 @@ private:
/// 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;
size_t Width, Height, Depth;
bool Tiled;
char FormatHint[9]; // 8 for string + 1 for terminator.
uint8_t *Data;
};
/// 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.
aiFace Face; ///< Face vertices.
const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face.
const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
};
/// Clear all temporary data.
void Clear();
using AMFMetaDataArray = std::vector<AMFMetadata*>;
using MeshArray = std::vector<aiMesh*>;
using NodeArray = std::vector<aiNode*>;
/***********************************************/
/************* Functions: find set *************/
/***********************************************/
/// Clear all temporary data.
void Clear();
/// 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;
/// 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 AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<AMFColor *> &pVertexColorArray) 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;
/// 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);
/// 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;
/// 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);
/// 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;
/// 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 AMFMetaDataArray &pMetadataList, aiNode &pSceneNode) const;
/// To create aiMesh and aiNode for it from <object>.
/// \param [in] pNodeElement - reference to node element which kept <object> data.
/// \param [out] meshList - 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 AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode);
/// 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;
/// 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 AMFMesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<AMFColor *> &pVertexColorArray, const AMFColor *pObjectColor,
MeshArray &pMeshList, aiNode &pSceneNode);
/// 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);
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
void Postprocess_BuildMaterial(const AMFMaterial &pMaterial);
/// 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);
/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
/// \param [in] pConstellation - reference to <constellation> node.
/// \param [out] nodeArray - reference to aiNode's list.
void Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) 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;
/// 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);
/// 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);
/// 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;
/// 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);
/// Parse <AMF> node of the file.
void ParseNode_Root();
/// 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);
/// Parse <constellation> node of the file.
void ParseNode_Constellation(XmlNode &node);
/// 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;
/// Parse <instance> node of the file.
void ParseNode_Instance(XmlNode &node);
/// 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);
/// Parse <material> node of the file.
void ParseNode_Material(XmlNode &node);
/// Parse <metadata> node.
void ParseNode_Metadata(XmlNode &node);
/// 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);
/// Parse <object> node of the file.
void ParseNode_Object(XmlNode &node);
/// 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);
/// Parse <texture> node of the file.
void ParseNode_Texture(XmlNode &node);
/// 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);
/// Parse <coordinates> node of the file.
void ParseNode_Coordinates(XmlNode &node);
/// 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);
/// Parse <edge> node of the file.
void ParseNode_Edge(XmlNode &node);
/// 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;
/// Parse <mesh> node of the file.
void ParseNode_Mesh(XmlNode &node);
/// Check if current node have children: <node>...</node>. If not then exception will throwed.
void XML_CheckNode_MustHaveChildren();
/// Parse <triangle> node of the file.
void ParseNode_Triangle(XmlNode &node);
/// 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; }
/// Parse <vertex> node of the file.
void ParseNode_Vertex(XmlNode &node);
/// 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);
/// Parse <vertices> node of the file.
void ParseNode_Vertices(XmlNode &node);
/// 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);
/// Parse <volume> node of the file.
void ParseNode_Volume(XmlNode &node);
/// Read attribute value.
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
/// \return read data.
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
/// Parse <color> node of the file.
void ParseNode_Color(XmlNode &node);
/// 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.
uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
/// Read node value.
/// \return read data.
float XML_ReadNode_GetVal_AsFloat();
/// Read node value.
/// \return read data.
uint32_t XML_ReadNode_GetVal_AsU32();
/// Read node value.
/// \return read data.
void XML_ReadNode_GetVal_AsString(std::string& pValue);
/// 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);
/// This function must be called when exiting from grouping node. \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);
/// 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;
/// Parse <AMF> node of the file.
void ParseNode_Root();
/// Parse <constellation> node of the file.
void ParseNode_Constellation();
/// Parse <instance> node of the file.
void ParseNode_Instance();
/// Parse <material> node of the file.
void ParseNode_Material();
/// Parse <metadata> node.
void ParseNode_Metadata();
/// Parse <object> node of the file.
void ParseNode_Object();
/// Parse <texture> node of the file.
void ParseNode_Texture();
/// Parse <coordinates> node of the file.
void ParseNode_Coordinates();
/// Parse <edge> node of the file.
void ParseNode_Edge();
/// Parse <mesh> node of the file.
void ParseNode_Mesh();
/// Parse <triangle> node of the file.
void ParseNode_Triangle();
/// Parse <vertex> node of the file.
void ParseNode_Vertex();
/// Parse <vertices> node of the file.
void ParseNode_Vertices();
/// Parse <volume> node of the file.
void ParseNode_Volume();
/// Parse <color> node of the file.
void ParseNode_Color();
/// 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);
/// 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(XmlNode &node, const bool pUseOldName = false);
public:
/// Default constructor.
AMFImporter() AI_NO_EXCEPT
: mNodeElement_Cur(nullptr)
, mReader(nullptr) {
// empty
}
/// Default constructor.
AMFImporter() AI_NO_EXCEPT;
/// Default destructor.
~AMFImporter();
/// Default destructor.
~AMFImporter();
/// 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 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);
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;
AMFImporter(const AMFImporter& pScene) = delete;
AMFImporter& operator=(const AMFImporter& pScene) = delete;
/// 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 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);
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
void ParseHelper_Node_Exit();
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;
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
void Throw_CloseNotFound(const std::string &nodeName);
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
void Throw_ID_NotFound(const std::string &pID) const;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
AMFImporter(const AMFImporter &pScene) = delete;
AMFImporter &operator=(const AMFImporter &pScene) = delete;
private:
static const aiImporterDesc Description;
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
AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
XmlParser *mXmlParser;
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.
std::string mVersion;
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.
};
}// namespace Assimp
} // namespace Assimp
#endif // INCLUDED_AI_AMF_IMPORTER_H
+159 -227
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -51,48 +49,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
namespace Assimp
{
#include <assimp/ParsingUtils.h>
namespace Assimp {
// <mesh>
// </mesh>
// A 3D mesh hull.
// Multi elements - Yes.
// Parent element - <object>.
void AMFImporter::ParseNode_Mesh()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Mesh(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new mesh object.
ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur);
// Check for child nodes
if(!mReader->isEmptyElement())
{
bool vert_read = false;
// create new mesh object.
ne = new AMFMesh(mNodeElement_Cur);
// Check for child nodes
if (0 != ASSIMP_stricmp(node.name(), "mesh")) {
return;
}
bool found_verts = false, found_volumes = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
pugi::xml_node vertNode = node.child("vertices");
if (!vertNode.empty()) {
ParseNode_Vertices(vertNode);
found_verts = true;
}
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;
pugi::xml_node volumeNode = node.child("volume");
if (!volumeNode.empty()) {
ParseNode_Volume(volumeNode);
found_volumes = true;
}
ParseHelper_Node_Exit();
}
continue;
}
if (!found_verts && !found_volumes) {
mNodeElement_Cur->Child.push_back(ne);
} // if(!mReader->isEmptyElement()) else
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.
// and to node element list because its a new object in graph.
mNodeElement_List.push_back(ne);
}
// <vertices>
@@ -100,27 +97,25 @@ CAMFImporter_NodeElement* ne;
// The list of vertices to be used in defining triangles.
// Multi elements - No.
// Parent element - <mesh>.
void AMFImporter::ParseNode_Vertices()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Vertices(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// 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
// create new mesh object.
ne = new AMFVertices(mNodeElement_Cur);
// Check for child nodes
pugi::xml_node vertexNode = node.child("vertex");
if (!vertexNode.empty()) {
ParseHelper_Node_Enter(ne);
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
ParseNode_Vertex(vertexNode);
ParseHelper_Node_Exit();
} 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>
@@ -128,52 +123,35 @@ CAMFImporter_NodeElement* ne;
// A vertex to be referenced in triangles.
// Multi elements - Yes.
// Parent element - <vertices>.
void AMFImporter::ParseNode_Vertex()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Vertex(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// 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;
// create new mesh object.
ne = new AMFVertex(mNodeElement_Cur);
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;
// Check for child nodes
pugi::xml_node colorNode = node.child("color");
bool col_read = false;
bool coord_read = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
if (!colorNode.empty()) {
ParseNode_Color(colorNode);
col_read = true;
}
pugi::xml_node coordNode = node.child("coordinates");
if (!coordNode.empty()) {
ParseNode_Coordinates(coordNode);
coord_read = true;
}
ParseHelper_Node_Exit();
}
continue;
}
if (!coord_read && !col_read) {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}
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.
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
// <coordinates>
@@ -186,37 +164,32 @@ CAMFImporter_NodeElement* ne;
// <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;
void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFNodeElementBase *ne = nullptr;
// create new color object.
ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur);
// create new color object.
ne = new AMFCoordinates(mNodeElement_Cur);
CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "X") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
} else if (currentName == "Y") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
} else if (currentName == "Z") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
}
}
// Check for child nodes
if(!mReader->isEmptyElement())
{
bool read_flag[3] = { false, false, false };
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne);
}
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.
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
// <volume
@@ -228,52 +201,41 @@ CAMFImporter_NodeElement* ne;
// 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;
void AMFImporter::ParseNode_Volume(XmlNode &node) {
std::string materialid;
std::string type;
AMFNodeElementBase *ne = new AMFVolume(mNodeElement_Cur);
// 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;
// Read attributes for node <color>.
// and assign read data
((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
((AMFVolume *)ne)->Type = type;
// Check for child nodes
bool col_read = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string currentName = currentNode.name();
if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
ParseNode_Color(currentNode);
col_read = true;
} else if (currentName == "triangle") {
ParseNode_Triangle(currentNode);
} else if (currentName == "metadata") {
ParseNode_Metadata(currentNode);
} else if (currentName == "volume") {
ParseNode_Metadata(currentNode);
}
}
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}
// 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.
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
// <triangle>
@@ -286,72 +248,42 @@ CAMFImporter_NodeElement* ne;
// <v1>, <v2>, <v3>
// Multi elements - No.
// Index of the desired vertices in a triangle or edge.
void AMFImporter::ParseNode_Triangle()
{
CAMFImporter_NodeElement* ne;
void AMFImporter::ParseNode_Triangle(XmlNode &node) {
AMFNodeElementBase *ne = new AMFTriangle(mNodeElement_Cur);
// create new color object.
ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur);
// create new triangle object.
CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience
AMFTriangle &als = *((AMFTriangle *)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 };
bool col_read = false;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
const std::string currentName = currentNode.name();
if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
ParseNode_Color(currentNode);
col_read = true;
} else if (currentName == "texmap") {
ParseNode_TexMap(currentNode);
} else if (currentName == "map") {
ParseNode_TexMap(currentNode, true);
} else if (currentName == "v1") {
als.V[0] = std::atoi(currentNode.value());
} else if (currentName == "v2") {
als.V[1] = std::atoi(currentNode.value());
} else if (currentName == "v3") {
als.V[2] = std::atoi(currentNode.value());
}
}
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
}
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.
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
}
}// namespace Assimp
} // namespace Assimp
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
-2
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
+147 -146
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -49,10 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
#include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
namespace Assimp
{
namespace Assimp {
// <color
// profile="" - The ICC color space used to interpret the three color channels <r>, <g> and <b>.
@@ -68,46 +64,44 @@ namespace Assimp
// 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;
void AMFImporter::ParseNode_Color(XmlNode &node) {
std::string profile = node.attribute("profile").as_string();
// create new color object.
ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur);
CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
AMFColor& als = *((AMFColor*)ne);// alias for convenience
als.Profile = profile;
// Check for child nodes
if(!mReader->isEmptyElement())
{
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
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();
for (pugi::xml_node &child : node.children()) {
std::string name = child.name();
if ( name == "r") {
read_flag[0] = true;
XmlParser::getValueAsFloat(child, als.Color.r);
} else if (name == "g") {
read_flag[1] = true;
XmlParser::getValueAsFloat(child, als.Color.g);
} else if (name == "b") {
read_flag[2] = true;
XmlParser::getValueAsFloat(child, als.Color.b);
} else if (name == "a") {
read_flag[3] = true;
XmlParser::getValueAsFloat(child, als.Color.a);
}
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.");
}
if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
throw DeadlyImportError("Not all color components are defined.");
}
// check if <a> is absent. Then manually add "a == 1".
if (!read_flag[3]) {
als.Color.a = 1;
}
}
else
{
// check if <a> is absent. Then manually add "a == 1".
if (!read_flag[3]) {
als.Color.a = 1;
}
} else {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}
@@ -122,45 +116,25 @@ void AMFImporter::ParseNode_Color() {
// 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;
void AMFImporter::ParseNode_Material(XmlNode &node) {
// create new object and assign read data
std::string id = node.attribute("id").as_string();
AMFNodeElementBase *ne = new AMFMaterial(mNodeElement_Cur);
((AMFMaterial*)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 (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (pugi::xml_node &child : node.children()) {
const std::string name = child.name();
if (name == "color") {
ParseNode_Color(child);
} else if (name == "metadata") {
ParseNode_Metadata(child);
}
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
MACRO_NODECHECK_LOOPEND("material");
ParseHelper_Node_Exit();
}
else
{
}
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
}
@@ -183,51 +157,41 @@ void AMFImporter::ParseNode_Material() {
// 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;
// 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;
void AMFImporter::ParseNode_Texture(XmlNode &node) {
std::string id = node.attribute("id").as_string();
uint32_t width = node.attribute("width").as_uint();
uint32_t height = node.attribute("height").as_uint();
uint32_t depth = node.attribute("depth").as_uint();
std::string type = node.attribute("type").as_string();
bool tiled = node.attribute("tiled").as_bool();
// create new texture object.
CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
AMFNodeElementBase *ne = new AMFTexture(mNodeElement_Cur);
CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
// Check for child nodes
if (!mReader->isEmptyElement()) {
XML_ReadNode_GetVal_AsString(enc64_data);
if (node.empty()) {
return;
}
std::string enc64_data = node.value();
// Check for child nodes
// check that all components was defined
if (id.empty()) {
throw DeadlyImportError("ID for texture must be defined.");
throw DeadlyImportError("ID for texture must be defined.");
}
if (width < 1) {
Throw_IncorrectAttrValue("width");
throw DeadlyImportError("INvalid width for texture.");
}
if (height < 1) {
Throw_IncorrectAttrValue("height");
}
throw DeadlyImportError("Invalid height for texture.");
}
if (depth < 1) {
Throw_IncorrectAttrValue("depth");
throw DeadlyImportError("Invalid depth for texture.");
}
if (type != "grayscale") {
Throw_IncorrectAttrValue("type");
throw DeadlyImportError("Invalid type for texture.");
}
if (enc64_data.empty()) {
throw DeadlyImportError("Texture data not defined.");
@@ -263,57 +227,94 @@ void AMFImporter::ParseNode_Texture()
// <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;
void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
// 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;
AMFNodeElementBase *ne = new AMFTexMap(mNodeElement_Cur);
AMFTexMap &als = *((AMFTexMap *)ne); //
std::string rtexid, gtexid, btexid, atexid;
if (!node.empty()) {
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "rtexid") {
XmlParser::getValueAsString(node, rtexid);
} else if (currentName == "gtexid") {
XmlParser::getValueAsString(node, gtexid);
} else if (currentName == "btexid") {
XmlParser::getValueAsString(node, btexid);
} else if (currentName == "atexid") {
XmlParser::getValueAsString(node, atexid);
}
}
ParseHelper_Node_Exit();
}
// create new texture coordinates object.
CAMFImporter_NodeElement *ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
// create new texture coordinates object, alias for convenience
// check data
if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");
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();
//XML_CheckNode_MustHaveChildren();
if (node.children().begin() == node.children().end()) {
throw DeadlyImportError("Invalid children definition.");
}
// 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");
if (!pUseOldName) {
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name();
if (name == "utex1") {
read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float();
} else if (name == "utex2") {
read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float();
} else if (name == "utex3") {
read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float();
} else if (name == "vtex1") {
read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float();
} else if (name == "vtex2") {
read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float();
} else if (name == "vtex3") {
read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float();
}
}
} else {
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name();
if (name == "u") {
read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float();
} else if (name == "u2") {
read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float();
} else if (name == "u3") {
read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float();
} else if (name == "v1") {
read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float();
} else if (name == "v2") {
read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float();
} else if (name == "v3") {
read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float();
}
}
}
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]))
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;
@@ -321,7 +322,7 @@ void AMFImporter::ParseNode_TexMap(const bool pUseOldName) {
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.
mNodeElement_List.push_back(ne);
}
}// namespace Assimp
+115 -149
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -56,80 +54,76 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <vector>
// Header files, Assimp.
#include "assimp/types.h"
#include "assimp/scene.h"
#include "assimp/types.h"
/// \class CAMFImporter_NodeElement
/// Base class for elements of nodes.
class CAMFImporter_NodeElement {
class AMFNodeElementBase {
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_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.
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.
const EType Type; ///< Type of element.
std::string ID; ///< ID of element.
AMFNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root.
std::list<AMFNodeElementBase *> Child; ///< Child elements.
public: /// Destructor, virtual..
virtual ~CAMFImporter_NodeElement() {
// empty
}
public: /// Destructor, virtual..
virtual ~AMFNodeElementBase() {
// empty
}
/// Disabled copy constructor and co.
CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement) = delete;
CAMFImporter_NodeElement(CAMFImporter_NodeElement&&) = delete;
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement) = delete;
CAMFImporter_NodeElement() = delete;
AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
AMFNodeElementBase(AMFNodeElementBase &&) = delete;
AMFNodeElementBase &operator=(const AMFNodeElementBase &pNodeElement) = delete;
AMFNodeElementBase() = delete;
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
AMFNodeElementBase(const EType pType, AMFNodeElementBase *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 {
struct AMFConstellation : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Constellation, pParent)
{}
AMFConstellation(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Constellation, pParent) {}
};// struct CAMFImporter_NodeElement_Constellation
}; // struct CAMFImporter_NodeElement_Constellation
/// \struct CAMFImporter_NodeElement_Instance
/// Part of constellation.
struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
struct AMFInstance : public AMFNodeElementBase {
std::string ObjectID;///< ID of object for instantiation.
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;
@@ -140,201 +134,173 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Instance, pParent)
{}
AMFInstance(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Instance, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Metadata
/// Structure that define metadata node.
struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement {
struct AMFMetadata : public AMFNodeElementBase {
std::string Type;///< Type of "Value".
std::string Value;///< Value.
std::string Type; ///< Type of "Value".
std::string Value; ///< Value.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Metadata, pParent)
{}
AMFMetadata(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Metadata, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Root
/// Structure that define root node.
struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement {
struct AMFRoot : public AMFNodeElementBase {
std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
std::string Version;///< Version of format.
std::string Unit; ///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
std::string Version; ///< Version of format.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Root, pParent)
{}
AMFRoot(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Root, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Color
/// Structure that define object node.
struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement {
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..
struct AMFColor : public AMFNodeElementBase {
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..
/// @brief Constructor.
/// @param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Color, pParent)
, Composed( false )
, Color()
, Profile() {
// empty
}
AMFColor(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color(), Profile() {
// empty
}
};
/// \struct CAMFImporter_NodeElement_Material
/// Structure that define material node.
struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement {
struct AMFMaterial : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Material, pParent)
{}
AMFMaterial(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Material, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Object
/// Structure that define object node.
struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement {
struct AMFObject : public AMFNodeElementBase {
/// Constructor.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Object, pParent)
{}
AMFObject(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Object, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Mesh
/// Structure that define mesh node.
struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement {
struct AMFMesh : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Mesh, pParent)
{}
AMFMesh(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Mesh, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Vertex
/// Structure that define vertex node.
struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement {
struct AMFVertex : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Vertex, pParent)
{}
AMFVertex(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertex, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Edge
/// Structure that define edge node.
struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement {
struct AMFEdge : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Edge, pParent)
{}
AMFEdge(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Edge, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Vertices
/// Structure that define vertices node.
struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement {
struct AMFVertices : public AMFNodeElementBase {
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Vertices, pParent)
{}
AMFVertices(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Vertices, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Volume
/// Structure that define volume node.
struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement {
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.
struct AMFVolume : public AMFNodeElementBase {
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.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Volume, pParent)
{}
AMFVolume(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Volume, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Coordinates
/// Structure that define coordinates node.
struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
{
aiVector3D Coordinate;///< Coordinate.
struct AMFCoordinates : public AMFNodeElementBase {
aiVector3D Coordinate; ///< Coordinate.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
{}
AMFCoordinates(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Coordinates, pParent) {}
};
/// \struct CAMFImporter_NodeElement_TexMap
/// Structure that define texture coordinates node.
struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement {
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.
struct AMFTexMap : public AMFNodeElementBase {
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.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_TexMap, pParent)
, TextureCoordinate{}
, TextureID_R()
, TextureID_G()
, TextureID_B()
, TextureID_A() {
// empty
}
AMFTexMap(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{}, TextureID_R(), TextureID_G(), TextureID_B(), TextureID_A() {
// empty
}
};
/// \struct CAMFImporter_NodeElement_Triangle
/// Structure that define triangle node.
struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement {
size_t V[3];///< Triangle vertices.
struct AMFTriangle : public AMFNodeElementBase {
size_t V[3]; ///< Triangle vertices.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
: CAMFImporter_NodeElement(ENET_Triangle, pParent) {
// empty
}
AMFTriangle(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Triangle, pParent) {
// empty
}
};
/// 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.
struct AMFTexture : public AMFNodeElementBase {
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
}
AMFTexture(AMFNodeElementBase *pParent) :
AMFNodeElementBase(ENET_Texture, pParent), Width(0), Height(0), Depth(0), Data(), Tiled(false) {
// empty
}
};
#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H
+176 -156
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -50,12 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AMFImporter.hpp"
// Header files, Assimp.
#include <assimp/SceneCombiner.h>
#include <assimp/StandardShapes.h>
#include <assimp/StringUtils.h>
// Header files, stdlib.
#include <iterator>
namespace Assimp {
@@ -83,61 +79,61 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
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;
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray,
std::vector<AMFColor *> &pVertexColorArray) const {
AMFVertices *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;
for (AMFNodeElementBase *ne_child : pNodeElement.Child) {
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
vn = (AMFVertices*)ne_child;
}
}
// If "vertices" not found then no work for us.
if (vn == nullptr) return;
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.
// all coordinates stored as child and we need to reserve space for future push_back's.
pVertexCoordinateArray.reserve(vn->Child.size());
// colors count equal vertices count.
pVertexColorArray.resize(vn->Child.size());
col_idx = 0;
// Inside vertices collect all data and place to arrays
for (CAMFImporter_NodeElement *vn_child : vn->Child) {
for (AMFNodeElementBase *vn_child : vn->Child) {
// vertices, colors
if (vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex) {
if (vn_child->Type == AMFNodeElementBase::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);
for (AMFNodeElementBase *vtx : vn_child->Child) {
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
continue;
}
if (vtx->Type == CAMFImporter_NodeElement::ENET_Color) {
pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color *)vtx;
if (vtx->Type == AMFNodeElementBase::ENET_Color) {
pVertexColorArray[col_idx] = (AMFColor *)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)
++col_idx;
}
}
}
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())
size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &r, const std::string &g, const std::string &b, const std::string &a) {
if (r.empty() && g.empty() && b.empty() && 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;
std::string TextureConverted_ID = r + "_" + g + "_" + b + "_" + a;
size_t TextureConverted_Index = 0;
for (const SPP_Texture &tex_convd : mTexture_Converted) {
if (tex_convd.ID == TextureConverted_ID) {
return TextureConverted_Index;
@@ -146,52 +142,60 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
}
}
//
// Converted texture not found, create it.
//
CAMFImporter_NodeElement_Texture *src_texture[4]{ nullptr };
std::vector<CAMFImporter_NodeElement_Texture *> src_texture_4check;
AMFTexture *src_texture[4] {
nullptr
};
std::vector<AMFTexture *> src_texture_4check;
SPP_Texture converted_texture;
{ // find all specified source textures
CAMFImporter_NodeElement *t_tex;
AMFNodeElementBase *t_tex = nullptr;
// R
if (!pID_R.empty()) {
if (!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
if (!r.empty()) {
if (!Find_NodeElement(r, AMFNodeElementBase::EType::ENET_Texture, &t_tex)) {
Throw_ID_NotFound(r);
}
src_texture[0] = (CAMFImporter_NodeElement_Texture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[0] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)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);
if (!g.empty()) {
if (!Find_NodeElement(g, AMFNodeElementBase::ENET_Texture, &t_tex)) {
Throw_ID_NotFound(g);
}
src_texture[1] = (CAMFImporter_NodeElement_Texture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[1] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)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);
if (!b.empty()) {
if (!Find_NodeElement(b, AMFNodeElementBase::ENET_Texture, &t_tex)) {
Throw_ID_NotFound(b);
}
src_texture[2] = (CAMFImporter_NodeElement_Texture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[2] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)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);
if (!a.empty()) {
if (!Find_NodeElement(a, AMFNodeElementBase::ENET_Texture, &t_tex)) {
Throw_ID_NotFound(a);
}
src_texture[3] = (CAMFImporter_NodeElement_Texture *)t_tex;
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture *)t_tex);
src_texture[3] = (AMFTexture *)t_tex;
src_texture_4check.push_back((AMFTexture *)t_tex);
} else {
src_texture[3] = nullptr;
}
@@ -213,38 +217,37 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
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++)
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';
if (!r.empty()) converted_texture.FormatHint[4] = '8';
if (!g.empty()) converted_texture.FormatHint[5] = '8';
if (!b.empty()) converted_texture.FormatHint[6] = '8';
if (!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]) {
if (!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]) {
if (!g.empty() && nullptr != src_texture[1]) {
tex_size += src_texture[1]->Data.size();
step++, off_b++;
}
if (!pID_B.empty() && nullptr != src_texture[2]) {
if (!b.empty() && nullptr != src_texture[2]) {
tex_size += src_texture[2]->Data.size();
step++;
}
if (!pID_A.empty() && nullptr != src_texture[3]) {
if (!a.empty() && nullptr != src_texture[3]) {
tex_size += src_texture[3]->Data.size();
step++;
}
@@ -255,17 +258,17 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
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];
AMFTexture *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);
CopyTextureData(r, 0, step, 0);
CopyTextureData(g, off_g, step, 1);
CopyTextureData(b, off_b, step, 2);
CopyTextureData(a, step - 1, step, 3);
// Store new converted texture ID
converted_texture.ID = TextureConverted_ID;
@@ -276,7 +279,7 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
}
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 {
auto texmap_is_equal = [](const AMFTexMap *pTexMap1, const AMFTexMap *pTexMap2) -> bool {
if ((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
if (pTexMap1 == nullptr) return false;
if (pTexMap2 == nullptr) return false;
@@ -313,73 +316,80 @@ void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace
} while (!pInputList.empty());
}
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.");
void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList, aiNode &sceneNode) const {
if (metadataList.empty()) {
return;
}
// copy collected metadata to output node.
sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size()));
size_t meta_idx(0);
if (sceneNode.mMetaData != nullptr) {
throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
}
for (const CAMFImporter_NodeElement_Metadata &metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
}
} // if(!metadataList.empty())
// copy collected metadata to output node.
sceneNode.mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(metadataList.size()));
size_t meta_idx(0);
for (const AMFMetadata &metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
}
}
void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object &pNodeElement, std::list<aiMesh *> &pMeshList, aiNode **pSceneNode) {
CAMFImporter_NodeElement_Color *object_color = nullptr;
void AMFImporter::Postprocess_BuildNodeAndObject(const AMFObject &pNodeElement, MeshArray &meshList, aiNode **pSceneNode) {
AMFColor *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) {
for (const AMFNodeElementBase *ne_child : pNodeElement.Child) {
std::vector<aiVector3D> vertex_arr;
std::vector<CAMFImporter_NodeElement_Color *> color_arr;
std::vector<AMFColor *> color_arr;
// color for object
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color *)ne_child;
if (ne_child->Type == AMFNodeElementBase::ENET_Color) {
object_color = (AMFColor *) ne_child;
}
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh) {
if (ne_child->Type == AMFNodeElementBase::ENET_Mesh) {
// Create arrays from children of mesh: vertices.
PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh *)ne_child), vertex_arr, color_arr);
PostprocessHelper_CreateMeshDataArray(*((AMFMesh *)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);
Postprocess_BuildMeshSet(*((AMFMesh *)ne_child), vertex_arr, color_arr, object_color, meshList, **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) {
void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const std::vector<aiVector3D> &pVertexCoordinateArray,
const std::vector<AMFColor *> &pVertexColorArray, const AMFColor *pObjectColor, MeshArray &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;
for (const AMFNodeElementBase *ne_child : pNodeElement.Child) {
const AMFColor *ne_volume_color = nullptr;
const SPP_Material *cur_mat = nullptr;
if (ne_child->Type == CAMFImporter_NodeElement::ENET_Volume) {
if (ne_child->Type == AMFNodeElementBase::ENET_Volume) {
/******************* Get faces *******************/
const CAMFImporter_NodeElement_Volume *ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume *>(ne_child);
const AMFVolume *ne_volume = reinterpret_cast<const AMFVolume *>(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);
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) {
for (const AMFNodeElementBase *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
if (ne_volume_child->Type == AMFNodeElementBase::ENET_Color) {
ne_volume_color = reinterpret_cast<const AMFColor *>(ne_volume_child);
} else if (ne_volume_child->Type == AMFNodeElementBase::ENET_Triangle) // triangles, triangles colors
{
const CAMFImporter_NodeElement_Triangle &tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle *>(ne_volume_child);
const AMFTriangle &tri_al = *reinterpret_cast<const AMFTriangle *>(ne_volume_child);
SComplexFace complex_face;
@@ -388,11 +398,11 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
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);
for (const AMFNodeElementBase *ne_triangle_child : tri_al.Child) {
if (ne_triangle_child->Type == AMFNodeElementBase::ENET_Color)
complex_face.Color = reinterpret_cast<const AMFColor *>(ne_triangle_child);
else if (ne_triangle_child->Type == AMFNodeElementBase::ENET_TexMap)
complex_face.TexMap = reinterpret_cast<const AMFTexMap *>(ne_triangle_child);
}
} // if(tri_al.Child.size())
@@ -422,15 +432,18 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
if (face.Face.mIndices[idx_vert] > *pBiggerThan) {
rv = face.Face.mIndices[idx_vert];
found = true;
break;
}
}
if (found) break;
if (found) {
break;
}
}
if (!found) return *pBiggerThan;
if (!found) {
return *pBiggerThan;
}
} else {
rv = pFaceList.front().Face.mIndices[0];
} // if(pBiggerThan != nullptr) else
@@ -505,9 +518,9 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
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
// Create vertices list and optimize indices. Optimization 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.
// Do you need all this thousands of garbage? Of course no. So, optimization step transform 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;
@@ -566,7 +579,7 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
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.
/// optimization.
bool *idx_vert_used;
idx_vert_used = new bool[VertexCount_Max * 2];
@@ -639,15 +652,15 @@ void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh &
} // if(mesh_idx.size() > 0)
}
void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material &pMaterial) {
void AMFImporter::Postprocess_BuildMaterial(const AMFMaterial &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 AMFNodeElementBase *mat_child : pMaterial.Child) {
if (mat_child->Type == AMFNodeElementBase::ENET_Color) {
new_mat.Color = (AMFColor*)mat_child;
} else if (mat_child->Type == AMFNodeElementBase::ENET_Metadata) {
new_mat.Metadata.push_back((AMFMetadata *)mat_child);
}
} // for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)
@@ -655,7 +668,7 @@ void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Mater
mMaterial_Converted.push_back(new_mat);
}
void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation &pConstellation, std::list<aiNode *> &pNodeList) const {
void AMFImporter::Postprocess_BuildConstellation(AMFConstellation &pConstellation, NodeArray &nodeArray) const {
aiNode *con_node;
std::list<aiNode *> ch_node;
@@ -667,18 +680,18 @@ void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Conste
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) {
for (const AMFNodeElementBase *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>.");
if (ne->Type == AMFNodeElementBase::ENET_Metadata) continue;
if (ne->Type != AMFNodeElementBase::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
// create alias for conveniance
CAMFImporter_NodeElement_Instance &als = *((CAMFImporter_NodeElement_Instance *)ne);
AMFInstance &als = *((AMFInstance *)ne);
// find referenced object
if (!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
if (!Find_ConvertedNode(als.ObjectID, nodeArray, &found_node)) Throw_ID_NotFound(als.ObjectID);
// create node for applying transformation
t_node = new aiNode;
@@ -707,13 +720,13 @@ void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Conste
con_node->mChildren[ch_idx++] = node;
// and place "root" of <constellation> node to node list
pNodeList.push_back(con_node);
nodeArray.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;
NodeArray nodeArray;
MeshArray mesh_list;
AMFMetaDataArray meta_list;
//
// Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
@@ -723,18 +736,21 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
pScene->mRootNode->mParent = nullptr;
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
// search for root(<amf>) element
CAMFImporter_NodeElement *root_el = nullptr;
AMFNodeElementBase *root_el = nullptr;
for (CAMFImporter_NodeElement *ne : mNodeElement_List) {
if (ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;
for (AMFNodeElementBase *ne : mNodeElement_List) {
if (ne->Type != AMFNodeElementBase::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.");
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
@@ -742,34 +758,38 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
//
// 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));
for (const AMFNodeElementBase *root_child : root_el->Child) {
if (root_child->Type == AMFNodeElementBase::ENET_Material) {
Postprocess_BuildMaterial(*((AMFMaterial *)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) {
for (const AMFNodeElementBase *root_child : root_el->Child) {
if (root_child->Type == AMFNodeElementBase::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);
Postprocess_BuildNodeAndObject(*((AMFObject *)root_child), mesh_list, &tnode);
if (tnode != nullptr) {
nodeArray.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) {
for (const AMFNodeElementBase *root_child : root_el->Child) {
// 4. <constellation>
if (root_child->Type == CAMFImporter_NodeElement::ENET_Constellation) {
if (root_child->Type == AMFNodeElementBase::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);
Postprocess_BuildConstellation(*((AMFConstellation *)root_child), nodeArray);
}
// 5, <metadata>
if (root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata *)root_child);
if (root_child->Type == AMFNodeElementBase::ENET_Metadata) meta_list.push_back((AMFMetadata *)root_child);
} // for(const CAMFImporter_NodeElement* root_child: root_el->Child)
// at now we can add collected metadata to root node
@@ -783,17 +803,17 @@ void AMFImporter::Postprocess_BuildScene(aiScene *pScene) {
// And at this step we are checking that relations.
nl_clean_loop:
if (node_list.size() > 1) {
if (nodeArray.size() > 1) {
// walk through all nodes
for (std::list<aiNode *>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); ++nl_it) {
for (NodeArray::iterator nl_it = nodeArray.begin(); nl_it != nodeArray.end(); ++nl_it) {
// and try to find them in another top nodes.
std::list<aiNode *>::const_iterator next_it = nl_it;
NodeArray::const_iterator next_it = nl_it;
++next_it;
for (; next_it != node_list.end(); ++next_it) {
for (; next_it != nodeArray.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);
nodeArray.erase(nl_it);
goto nl_clean_loop;
}
@@ -806,10 +826,10 @@ nl_clean_loop:
//
//
// Nodes
if (!node_list.empty()) {
std::list<aiNode *>::const_iterator nl_it = node_list.begin();
if (!nodeArray.empty()) {
NodeArray::const_iterator nl_it = nodeArray.begin();
pScene->mRootNode->mNumChildren = static_cast<unsigned int>(node_list.size());
pScene->mRootNode->mNumChildren = static_cast<unsigned int>(nodeArray.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
@@ -822,7 +842,7 @@ nl_clean_loop:
//
// Meshes
if (!mesh_list.empty()) {
std::list<aiMesh *>::const_iterator ml_it = mesh_list.begin();
MeshArray::const_iterator ml_it = mesh_list.begin();
pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
+6 -4
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -85,7 +83,11 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ASEImporter::ASEImporter() :
mParser(), mBuffer(), pcScene(), configRecomputeNormals(), noSkeletonMesh() {
mParser(),
mBuffer(),
pcScene(),
configRecomputeNormals(),
noSkeletonMesh() {
// empty
}
@@ -137,7 +139,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open ASE file " + pFile + ".");
throw DeadlyImportError("Failed to open ASE file ", pFile, ".");
}
// Allocate storage and copy the contents of the file to a memory buffer
+15 -26
View File
@@ -56,20 +56,20 @@ namespace Assimp {
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
// --------------------------------------------------------------------------------
/** Importer class for the 3DS ASE ASCII format.
*
*/
class ASEImporter : public BaseImporter {
/// @brief Importer class for the 3DS ASE ASCII format.
// --------------------------------------------------------------------------------
class ASEImporter final : public BaseImporter {
public:
/// @brief The default class constructor.
ASEImporter();
~ASEImporter();
/// @brief The class destructor.
~ASEImporter() override;
// -------------------------------------------------------------------
/** 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;
/// @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 override;
protected:
@@ -77,15 +77,14 @@ protected:
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
const aiImporterDesc* GetInfo () const override;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) override;
// -------------------------------------------------------------------
@@ -93,11 +92,10 @@ protected:
* 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);
void SetupProperties(const Importer* pImp) override;
private:
// -------------------------------------------------------------------
/** Generate normal vectors basing on smoothing groups
* (in some cases the normal are already contained in the file)
@@ -117,8 +115,8 @@ private:
/** Create one-material-per-mesh meshes ;-)
* \param mesh Mesh to work with
* \param Receives the list of all created meshes
* \param mesh Mesh to work with
* \param avOut Receives the list of all created meshes
*/
void ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOut);
@@ -183,18 +181,9 @@ private:
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;
};
+9 -5
View File
@@ -116,7 +116,7 @@ struct Material : public D3DS::Material {
return *this;
}
~Material() {}
~Material() = default;
//! Contains all sub materials of this material
std::vector<Material> avSubMaterials;
@@ -178,7 +178,7 @@ struct Bone {
/** Helper structure to represent an ASE file bone vertex */
struct BoneVertex {
//! Bone and corresponding vertex weight.
//! -1 for unrequired bones ....
//! -1 for not required bones ....
std::vector<std::pair<int, float>> mBoneWeights;
};
@@ -239,9 +239,13 @@ struct BaseNode {
Dummy
} mType;
//! Construction from an existing name
BaseNode(Type _mType, const std::string &name) :
mType(_mType), mName(name), mProcessed(false) {
/// Construction from an existing name
/// @param type The node type
/// @param name The node name
BaseNode(Type type, const std::string &name) :
mType(type),
mName(name),
mProcessed(false) {
// Set mTargetPosition to qnan
const ai_real qnan = get_qnan();
mTargetPosition.x = qnan;
+4 -4
View File
@@ -60,10 +60,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <time.h>
#ifdef _WIN32
#if _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4706)
#endif // _WIN32
#endif // _MSC_VER
namespace Assimp {
@@ -825,8 +825,8 @@ void DumpSceneToAssbin(
AssbinFileWriter fileWriter(shortened, compressed);
fileWriter.WriteBinaryDump(pFile, cmd, pIOSystem, pScene);
}
#ifdef _WIN32
#if _MSC_VER
#pragma warning(pop)
#endif // _WIN32
#endif // _MSC_VER
} // end of namespace Assimp
+9 -5
View File
@@ -9,8 +9,10 @@ For details, see http://sourceforge.net/projects/libb64
const int CHARS_PER_LINE = 72;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4244)
#endif // _MSC_VER
void base64_init_encodestate(base64_encodestate* state_in)
{
@@ -33,9 +35,9 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
char* codechar = code_out;
char result;
char fragment;
result = state_in->result;
switch (state_in->step)
{
while (1)
@@ -74,7 +76,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
*codechar++ = base64_encode_value(result);
result = (fragment & 0x03f) >> 0;
*codechar++ = base64_encode_value(result);
++(state_in->stepcount);
if (state_in->stepcount == CHARS_PER_LINE/4)
{
@@ -90,7 +92,7 @@ int base64_encode_block(const char* plaintext_in, int length_in, char* code_out,
int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
{
char* codechar = code_out;
switch (state_in->step)
{
case step_B:
@@ -106,8 +108,10 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
break;
}
*codechar++ = '\n';
return (int)(codechar - code_out);
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
+2 -2
View File
@@ -8,9 +8,9 @@ For details, see http://sourceforge.net/projects/libb64
#ifndef BASE64_CENCODE_H
#define BASE64_CENCODE_H
#ifdef _WIN32
#ifdef _MSC_VER
#pragma warning(disable : 4127 )
#endif // _WIN32
#endif // _MSC_VER
typedef enum
{
+2 -2
View File
@@ -119,7 +119,7 @@ void B3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open B3D file " + pFile + ".");
throw DeadlyImportError("Failed to open B3D file ", pFile, ".");
}
// check whether the .b3d file is large enough to contain
@@ -147,7 +147,7 @@ AI_WONT_RETURN void B3DImporter::Fail(string str) {
#ifdef DEBUG_B3D
ASSIMP_LOG_ERROR_F("Error in B3D file data: ", str);
#endif
throw DeadlyImportError("B3D Importer - error in B3D file data: " + str);
throw DeadlyImportError("B3D Importer - error in B3D file data: ", str);
}
// ------------------------------------------------------------------------------------------------
+19 -18
View File
@@ -71,6 +71,13 @@ static const aiImporterDesc desc = {
"bvh"
};
// ------------------------------------------------------------------------------------------------
// Aborts the file reading with an exception
template<typename... T>
AI_WONT_RETURN void BVHLoader::ThrowException(T&&... args) {
throw DeadlyImportError(mFileName, ":", mLine, " - ", args...);
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
BVHLoader::BVHLoader() :
@@ -118,7 +125,7 @@ void BVHLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSyst
// read file into memory
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open file " + pFile + ".");
throw DeadlyImportError("Failed to open file ", pFile, ".");
}
size_t fileSize = file->FileSize();
@@ -176,12 +183,12 @@ aiNode *BVHLoader::ReadNode() {
// first token is name
std::string nodeName = GetNextToken();
if (nodeName.empty() || nodeName == "{")
ThrowException(format() << "Expected node name, but found \"" << nodeName << "\".");
ThrowException("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 << "\".");
ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\".");
// Create a node
aiNode *node = new aiNode(nodeName);
@@ -211,7 +218,7 @@ aiNode *BVHLoader::ReadNode() {
siteToken.clear();
siteToken = GetNextToken();
if (siteToken != "Site")
ThrowException(format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\".");
ThrowException("Expected \"End Site\" keyword, but found \"", token, " ", siteToken, "\".");
aiNode *child = ReadEndSite(nodeName);
child->mParent = node;
@@ -221,7 +228,7 @@ aiNode *BVHLoader::ReadNode() {
break;
} else {
// everything else is a parse error
ThrowException(format() << "Unknown keyword \"" << token << "\".");
ThrowException("Unknown keyword \"", token, "\".");
}
}
@@ -242,7 +249,7 @@ aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) {
// check opening brace
std::string openBrace = GetNextToken();
if (openBrace != "{")
ThrowException(format() << "Expected opening brace \"{\", but found \"" << openBrace << "\".");
ThrowException("Expected opening brace \"{\", but found \"", openBrace, "\".");
// Create a node
aiNode *node = new aiNode("EndSite_" + pParentName);
@@ -261,7 +268,7 @@ aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) {
break;
} else {
// everything else is a parse error
ThrowException(format() << "Unknown keyword \"" << token << "\".");
ThrowException("Unknown keyword \"", token, "\".");
}
}
@@ -307,7 +314,7 @@ void BVHLoader::ReadNodeChannels(BVHLoader::Node &pNode) {
else if (channelToken == "Zrotation")
pNode.mChannels.push_back(Channel_RotationZ);
else
ThrowException(format() << "Invalid channel specifier \"" << channelToken << "\".");
ThrowException("Invalid channel specifier \"", channelToken, "\".");
}
}
@@ -317,7 +324,7 @@ 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 << "\".");
ThrowException("Expected frame count \"Frames:\", but found \"", tokenFrames, "\".");
float numFramesFloat = GetNextTokenAsFloat();
mAnimNumFrames = (unsigned int)numFramesFloat;
@@ -326,7 +333,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
std::string tokenDuration1 = GetNextToken();
std::string tokenDuration2 = GetNextToken();
if (tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
ThrowException(format() << "Expected frame duration \"Frame Time:\", but found \"" << tokenDuration1 << " " << tokenDuration2 << "\".");
ThrowException("Expected frame duration \"Frame Time:\", but found \"", tokenDuration1, " ", tokenDuration2, "\".");
mAnimTickDuration = GetNextTokenAsFloat();
@@ -393,17 +400,11 @@ float BVHLoader::GetNextTokenAsFloat() {
ctoken = fast_atoreal_move<float>(ctoken, result);
if (ctoken != token.c_str() + token.length())
ThrowException(format() << "Expected a floating point number, but found \"" << token << "\".");
ThrowException("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) {
@@ -453,7 +454,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
if (mapIter == channelMap.end())
throw DeadlyImportError("Missing position channel in node " + nodeName);
throw DeadlyImportError("Missing position channel in node ", nodeName);
else {
int channelIdx = mapIter->second;
switch (channel) {
+2 -1
View File
@@ -134,7 +134,8 @@ protected:
float GetNextTokenAsFloat();
/** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException(const std::string &pError) AI_WONT_RETURN_SUFFIX;
template<typename... T>
AI_WONT_RETURN void ThrowException(T&&... args) AI_WONT_RETURN_SUFFIX;
/** Constructs an animation for the motion data and stores it in the given scene */
void CreateAnimation(aiScene *pScene);
+1 -1
View File
@@ -149,7 +149,7 @@ bool isValidCustomDataType(const int cdtype) {
bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
if (!isValidCustomDataType(cdtype)) {
throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
throw Error("CustomData.type ", cdtype, " out of index");
}
const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
+4 -13
View File
@@ -130,9 +130,7 @@ void DNAParser::Parse() {
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)"));
throw DeadlyImportError("BlenderDNA: Invalid type index in structure name", n, " (there are only ", types.size(), " entries)");
}
// maintain separate indexes
@@ -141,7 +139,6 @@ void DNAParser::Parse() {
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);
@@ -151,9 +148,7 @@ void DNAParser::Parse() {
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)"));
throw DeadlyImportError("BlenderDNA: Invalid type index in structure field ", j, " (there are only ", types.size(), " entries)");
}
s.fields.push_back(Field());
Field &f = s.fields.back();
@@ -164,9 +159,7 @@ void DNAParser::Parse() {
j = stream.GetI2();
if (j >= names.size()) {
throw DeadlyImportError((format(),
"BlenderDNA: Invalid name index in structure field ", j,
" (there are only ", names.size(), " entries)"));
throw DeadlyImportError("BlenderDNA: Invalid name index in structure field ", j, " (there are only ", names.size(), " entries)");
}
f.name = names[j];
@@ -188,9 +181,7 @@ void DNAParser::Parse() {
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));
throw DeadlyImportError("BlenderDNA: Encountered invalid array declaration ", f.name);
}
f.flags |= FieldFlag_Array;
+6 -6
View File
@@ -83,9 +83,9 @@ class ObjectCache;
* ancestry. */
// -------------------------------------------------------------------------------
struct Error : DeadlyImportError {
Error(const std::string &s) :
DeadlyImportError(s) {
// empty
template <typename... T>
explicit Error(T &&...args) :
DeadlyImportError(args...) {
}
};
@@ -186,7 +186,7 @@ struct Field {
};
// -------------------------------------------------------------------------------
/** Range of possible behaviours for fields absend in the input file. Some are
/** Range of possible behaviors for fields absence in the input file. Some are
* mission critical so we need them, while others can silently be default
* initialized and no animations are harmed. */
// -------------------------------------------------------------------------------
@@ -394,7 +394,7 @@ private:
// --------------------------------------------------------
template <>
struct Structure ::_defaultInitializer<ErrorPolicy_Warn> {
struct Structure::_defaultInitializer<ErrorPolicy_Warn> {
template <typename T>
void operator()(T &out, const char *reason = "<add reason>") {
@@ -406,7 +406,7 @@ struct Structure ::_defaultInitializer<ErrorPolicy_Warn> {
};
template <>
struct Structure ::_defaultInitializer<ErrorPolicy_Fail> {
struct Structure::_defaultInitializer<ErrorPolicy_Fail> {
template <typename T>
void operator()(T & /*out*/, const char * = "") {
+22 -34
View File
@@ -57,9 +57,7 @@ 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,"`"
));
throw Error("BlendDNA: Did not find a field named `",ss,"` in structure `",name,"`");
}
return fields[(*it).second];
@@ -76,9 +74,7 @@ const Field* Structure :: Get (const std::string& ss) const
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,"`"
));
throw Error("BlendDNA: There is no field with index `",i,"` in structure `",name,"`");
}
return fields[i];
@@ -109,9 +105,7 @@ void Structure :: ReadFieldArray(T (& out)[M], const char* name, const FileDatab
// 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
));
throw Error("Field `",name,"` of structure `",this->name,"` ought to be an array of size ",M);
}
db.reader->IncPtr(f.offset);
@@ -148,9 +142,9 @@ void Structure :: ReadFieldArray2(T (& out)[M][N], const char* name, const FileD
// is the input actually an array?
if (!(f.flags & FieldFlag_Array)) {
throw Error((Formatter::format(),"Field `",name,"` of structure `",
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be an array of size ",M,"*",N
));
);
}
db.reader->IncPtr(f.offset);
@@ -195,8 +189,8 @@ bool Structure :: ReadFieldPtr(TOUT<T>& out, const char* name, const FileDatabas
// 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"));
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@@ -241,8 +235,8 @@ bool Structure :: ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
#ifdef _DEBUG
// 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"));
throw Error("Field `",name,"` of structure `",
this->name,"` ought to be a pointer AND an array");
}
#endif // _DEBUG
@@ -322,8 +316,8 @@ bool Structure::ReadCustomDataPtr(std::shared_ptr<ElemBase>&out, int cdtype, con
// 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"));
throw Error("Field `", name, "` of structure `",
this->name, "` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@@ -369,8 +363,8 @@ bool Structure::ReadFieldPtrVector(vector<TOUT<T>>&out, const char* name, const
// 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"));
throw Error("Field `", name, "` of structure `",
this->name, "` ought to be a pointer");
}
db.reader->IncPtr(f->offset);
@@ -428,9 +422,9 @@ bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
// 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,
throw Error("Expected target to be of type `",s.name,
"` but seemingly it is a `",ss.name,"` instead"
));
);
}
// try to retrieve the object from the cache
@@ -614,16 +608,14 @@ const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrv
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"
));
throw DeadlyImportError("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",
throw DeadlyImportError("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
));
(*it).address.val + (*it).size);
}
return &*it;
}
@@ -676,7 +668,7 @@ template <typename T> inline void ConvertDispatcher(T& out, const Structure& in,
out = static_cast<T>(db.reader->GetF8());
}
else {
throw DeadlyImportError("Unknown source for conversion to primitive data type: "+in.name);
throw DeadlyImportError("Unknown source for conversion to primitive data type: ", in.name);
}
}
@@ -784,9 +776,7 @@ 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,"`"
));
throw Error("BlendDNA: Did not find a structure named `",ss,"`");
}
return structures[(*it).second];
@@ -803,9 +793,7 @@ const Structure* DNA :: Get (const std::string& ss) const
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,"`"
));
throw Error("BlendDNA: There is no structure with index `",i,"`");
}
return structures[i];
+2 -3
View File
@@ -748,9 +748,8 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
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"));
ThrowException("Expected object at ", std::hex, dt, " to be of type `", check,
"`, but it claims to be a `", dt->dna_type, "`instead");
}
}
+5 -38
View File
@@ -106,51 +106,18 @@ class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter
public:
BlenderImporter();
~BlenderImporter();
public:
// --------------------
bool CanRead( const std::string& pFile,
IOSystem* pIOHandler,
bool checkSig
) const;
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
);
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,
+5 -2
View File
@@ -155,7 +155,7 @@ struct World : ElemBase {
// -------------------------------------------------------------------------------
struct MVert : ElemBase {
float co[3] FAIL;
float no[3] FAIL; // readed as short and divided through / 32767.f
float no[3] FAIL; // read as short and divided through / 32767.f
char flag;
int mat_nr WARN;
int bweight;
@@ -228,7 +228,10 @@ struct TFace : ElemBase {
// -------------------------------------------------------------------------------
struct MTFace : ElemBase {
MTFace() :
flag(0), mode(0), tile(0), unwrap(0) {
flag(0),
mode(0),
tile(0),
unwrap(0) {
}
float uv[4][2] FAIL;
+1 -1
View File
@@ -125,7 +125,7 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
// ------------------------------------------------------------------------------------------------
/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string &msg) {
throw DeadlyImportError("COB: " + msg);
throw DeadlyImportError("COB: ", msg);
}
// ------------------------------------------------------------------------------------------------
+1 -1
View File
@@ -128,7 +128,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
// Check whether we can read from the file
if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
throw DeadlyImportError( "Failed to open CSM file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer
+1 -1
View File
@@ -573,7 +573,7 @@ bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial &
index_str = index_str.substr(1, std::string::npos);
try {
index = (unsigned int)strtoul10_64(index_str.c_str());
index = (unsigned int)strtoul10_64<DeadlyExportError>(index_str.c_str());
} catch (std::exception &error) {
throw DeadlyExportError(error.what());
}
+1 -2
View File
@@ -1,5 +1,3 @@
/** Helper structures for the Collada loader */
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
@@ -40,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** Helper structures for the Collada loader */
#include "ColladaHelper.h"
+109 -119
View File
@@ -1,12 +1,9 @@
/** Helper structures for the Collada loader */
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -42,12 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** Helper structures for the Collada loader */
#ifndef AI_COLLADAHELPER_H_INC
#define AI_COLLADAHELPER_H_INC
#include <assimp/light.h>
#include <assimp/material.h>
#include <assimp/mesh.h>
#include <stdint.h>
#include <map>
#include <set>
@@ -58,14 +58,14 @@ struct aiMaterial;
namespace Assimp {
namespace Collada {
/** Collada file versions which evolved during the years ... */
/// 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 */
/// Transformation types that can be applied to a node
enum TransformType {
TF_LOOKAT,
TF_ROTATE,
@@ -75,7 +75,7 @@ enum TransformType {
TF_MATRIX
};
/** Different types of input data to a vertex or face */
/// 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.
@@ -87,38 +87,39 @@ enum InputType {
IT_Bitangent
};
/** Supported controller types */
/// Supported controller types
enum ControllerType {
Skin,
Morph
};
/** Supported morph methods */
/// Supported morph methods
enum MorphMethod {
Normalized,
Relative
};
/** Common metadata keys as <Collada, Assimp> */
typedef std::pair<std::string, std::string> MetaKeyPair;
typedef std::vector<MetaKeyPair> MetaKeyPairVector;
/// Common metadata keys as <Collada, Assimp>
using MetaKeyPair = std::pair<std::string, std::string>;
using MetaKeyPairVector = std::vector<MetaKeyPair>;
// Collada as lower_case (native)
/// Collada as lower_case (native)
const MetaKeyPairVector &GetColladaAssimpMetaKeys();
// Collada as CamelCase (used by Assimp for consistency)
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase();
/** Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" */
/// Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool"
void ToCamelCase(std::string &text);
/** Contains all data for one of the different transformation types */
/// 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. */
/// A collada camera.
struct Camera {
Camera() :
mOrtho(false),
@@ -128,22 +129,22 @@ struct Camera {
mZNear(0.1f),
mZFar(1000.f) {}
// Name of camera
/// Name of camera
std::string mName;
// True if it is an orthografic camera
/// True if it is an orthographic camera
bool mOrtho;
//! Horizontal field of view in degrees
/// Horizontal field of view in degrees
ai_real mHorFov;
//! Vertical field of view in degrees
/// Vertical field of view in degrees
ai_real mVerFov;
//! Screen aspect
/// Screen aspect
ai_real mAspect;
//! Near& far z
/// Near& far z
ai_real mZNear, mZFar;
};
@@ -162,27 +163,27 @@ struct Light {
mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
mIntensity(1.f) {}
//! Type of the light source aiLightSourceType + ambient
/// Type of the light source aiLightSourceType + ambient
unsigned int mType;
//! Color of the light
/// Color of the light
aiColor3D mColor;
//! Light attenuation
/// Light attenuation
ai_real mAttConstant, mAttLinear, mAttQuadratic;
//! Spot light falloff
/// Spot light falloff
ai_real mFalloffAngle;
ai_real mFalloffExponent;
// -----------------------------------------------------
// FCOLLADA extension from here
//! ... related stuff from maja and max extensions
/// ... related stuff from maja and max extensions
ai_real mPenumbraAngle;
ai_real mOuterAngle;
//! Common light intensity
/// Common light intensity
ai_real mIntensity;
};
@@ -192,30 +193,29 @@ struct InputSemanticMapEntry {
mSet(0),
mType(IT_Invalid) {}
//! Index of set, optional
/// Index of set, optional
unsigned int mSet;
//! Type of referenced vertex input
/// Type of referenced vertex input
InputType mType;
};
/** Table to map from effect to vertex input semantics */
/// Table to map from effect to vertex input semantics
struct SemanticMappingTable {
//! Name of material
/// Name of material
std::string mMatName;
//! List of semantic map commands, grouped by effect semantic name
/// List of semantic map commands, grouped by effect semantic name
std::map<std::string, InputSemanticMapEntry> mMap;
//! For std::find
/// 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
*/
/// 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;
@@ -224,25 +224,25 @@ struct MeshInstance {
std::map<std::string, SemanticMappingTable> mMaterials;
};
/** A reference to a camera inside a node*/
/// 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*/
/// 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*/
/// A reference to a node inside a node
struct NodeInstance {
///< ID of the node
std::string mNode;
};
/** A node in a scene hierarchy */
/// A node in a scene hierarchy
struct Node {
std::string mName;
std::string mID;
@@ -250,52 +250,53 @@ struct Node {
Node *mParent;
std::vector<Node *> mChildren;
/** Operations in order to calculate the resulting transformation to parent. */
/// Operations in order to calculate the resulting transformation to parent.
std::vector<Transform> mTransforms;
/** Meshes at this node */
/// Meshes at this node
std::vector<MeshInstance> mMeshes;
/** Lights at this node */
/// Lights at this node
std::vector<LightInstance> mLights;
/** Cameras at this node */
/// Cameras at this node
std::vector<CameraInstance> mCameras;
/** Node instances at this node */
/// Node instances at this node
std::vector<NodeInstance> mNodeInstances;
/** Root-nodes: Name of primary camera, if any */
/// Root-nodes: Name of primary camera, if any
std::string mPrimaryCamera;
//! Constructor. Begin with a zero parent
/// Constructor. Begin with a zero parent
Node() :
mParent(nullptr) {
// empty
}
//! Destructor: delete all children subsequently
/// Destructor: delete all children subsequently
~Node() {
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
delete *it;
}
}
};
/** Data source array: either floats or strings */
/// 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 */
/// 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.
size_t mSubOffset[4]; // Sub-offset 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. nullptr else
@@ -310,12 +311,12 @@ struct Accessor {
}
};
/** A single face in a mesh */
/// A single face in a mesh
struct Face {
std::vector<size_t> mIndices;
};
/** An input channel for mesh data, referring to a single accessor */
/// 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
@@ -331,18 +332,19 @@ struct InputChannel {
}
};
/** Subset of a mesh with a certain material */
/// Subset of a mesh with a certain material
struct SubMesh {
std::string mMaterial; ///< subgroup identifier
size_t mNumFaces; ///< number of faces in this submesh
size_t mNumFaces; ///< number of faces in this sub-mesh
};
/** Contains data for a single mesh */
/// Contains data for a single mesh
struct Mesh {
Mesh(const std::string &id) :
mId(id) {
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
mNumUVComponents[i] = 2;
}
}
const std::string mId;
@@ -373,11 +375,11 @@ struct Mesh {
// necessary for bone weight assignment
std::vector<size_t> mFacePosIndices;
// Submeshes in this mesh, each with a given material
// Sub-meshes in this mesh, each with a given material
std::vector<SubMesh> mSubMeshes;
};
/** Which type of primitives the ReadPrimitives() function is going to read */
/// Which type of primitives the ReadPrimitives() function is going to read
enum PrimitiveType {
Prim_Invalid,
Prim_Lines,
@@ -389,7 +391,7 @@ enum PrimitiveType {
Prim_Polygon
};
/** A skeleton controller to deform a mesh with the use of joints */
/// A skeleton controller to deform a mesh with the use of joints
struct Controller {
// controller type
ControllerType mType;
@@ -424,25 +426,25 @@ struct Controller {
std::string mMorphWeight;
};
/** A collada material. Pretty much the only member is a reference to an effect. */
/// 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 */
/// 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 */
/// 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 */
/// Shading type supported by the standard effect spec of Collada
enum ShadeType {
Shade_Invalid,
Shade_Constant,
@@ -451,7 +453,7 @@ enum ShadeType {
Shade_Blinn
};
/** Represents a texture sampler in collada */
/// Represents a texture sampler in collada
struct Sampler {
Sampler() :
mWrapU(true),
@@ -463,77 +465,66 @@ struct Sampler {
mWeighting(1.f),
mMixWithPrevious(1.f) {}
/** Name of image reference
*/
/// Name of image reference
std::string mName;
/** Wrap U?
*/
/// Wrap U?
bool mWrapU;
/** Wrap V?
*/
/// Wrap V?
bool mWrapV;
/** Mirror U?
*/
/// Mirror U?
bool mMirrorU;
/** Mirror V?
*/
/// Mirror V?
bool mMirrorV;
/** Blend mode
*/
/// Blend mode
aiTextureOp mOp;
/** UV transformation
*/
/// UV transformation
aiUVTransform mTransform;
/** Name of source UV channel
*/
/// Name of source UV channel
std::string mUVChannel;
/** Resolved UV channel index or UINT_MAX if not known
*/
/// Resolved UV channel index or UINT_MAX if not known
unsigned int mUVId;
// OKINO/MAX3D extensions from here
// -------------------------------------------------------
/** Weighting factor
*/
/// Weighting factor
ai_real mWeighting;
/** Mixing factor from OKINO
*/
/// 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. */
/// 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
/// Shading mode
ShadeType mShadeType;
// Colors
/// Colors
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
mTransparent, mReflective;
// Textures
/// Textures
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
mTexTransparent, mTexBump, mTexReflective;
// Scalar factory
/// 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;
/// local params referring to each other by their SID
using ParamLibrary = std::map<std::string, Collada::EffectParam>;
ParamLibrary mParams;
// MAX3D extensions
@@ -561,65 +552,64 @@ struct Effect {
}
};
/** An image, meaning texture */
/// An image, meaning texture
struct Image {
std::string mFileName;
/** Embedded image data */
/// Embedded image data
std::vector<uint8_t> mImageData;
/** File format hint of embedded image data */
/// File format hint of embedded image data
std::string mEmbeddedFormat;
};
/** An animation channel. */
/// An animation channel.
struct AnimationChannel {
/** URL of the data to animate. Could be about anything, but we support only the
* "NodeID/TransformID.SubElement" notation
*/
/// 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. */
/// Source URL of the time values. Collada calls them "input". Meh.
std::string mSourceTimes;
/** Source URL of the value values. Collada calls them "output". */
/// Source URL of the value values. Collada calls them "output".
std::string mSourceValues;
/** Source URL of the IN_TANGENT semantic values. */
/// Source URL of the IN_TANGENT semantic values.
std::string mInTanValues;
/** Source URL of the OUT_TANGENT semantic values. */
/// Source URL of the OUT_TANGENT semantic values.
std::string mOutTanValues;
/** Source URL of the INTERPOLATION semantic values. */
/// Source URL of the INTERPOLATION semantic values.
std::string mInterpolationValues;
};
/** An animation. Container for 0-x animation channels or 0-x animations */
/// An animation. Container for 0-x animation channels or 0-x animations
struct Animation {
/** Anim name */
/// Anim name
std::string mName;
/** the animation channels, if any */
/// the animation channels, if any
std::vector<AnimationChannel> mChannels;
/** the sub-animations, if any */
/// the sub-animations, if any
std::vector<Animation *> mSubAnims;
/** Destructor */
/// Destructor
~Animation() {
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
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. */
/// 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. */
/// Combine all single-channel animations' channel into the same (parent) animation channel list.
void CombineSingleChannelAnimations() {
CombineSingleChannelAnimationsRecursively(this);
}
@@ -658,9 +648,9 @@ struct Animation {
}
};
/** Description of a collada animation channel which has been determined to affect the current node */
/// Description of a collada animation channel which has been determined to affect the current node
struct ChannelEntry {
const Collada::AnimationChannel *mChannel; ///> the source channel
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
+50 -53
View File
@@ -45,25 +45,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaLoader.h"
#include "ColladaParser.h"
#include <assimp/ColladaMetaData.h>
#include <assimp/CreateAnimMesh.h>
#include <assimp/Defines.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/anim.h>
#include <assimp/fast_atof.h>
#include <assimp/importerdesc.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/CreateAnimMesh.h>
#include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <assimp/fast_atof.h>
#include "math.h"
#include "time.h"
#include <algorithm>
#include <memory>
#include <numeric>
namespace Assimp {
@@ -125,20 +119,17 @@ ColladaLoader::~ColladaLoader() {
bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
// check file extension
const std::string extension = GetExtension(pFile);
bool readSig = checkSig && (pIOHandler != nullptr);
const bool readSig = checkSig && (pIOHandler != nullptr);
if (!readSig) {
if (extension == "dae" || extension == "zae") {
return true;
}
}
if (readSig) {
} else {
// Look for a DAE file inside, but don't extract it
ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
if (zip_archive.isOpen())
if (zip_archive.isOpen()) {
return !ColladaParser::ReadZaeManifest(zip_archive).empty();
}
}
// XML - too generic, we need to open the file and search for typical keywords
@@ -337,13 +328,15 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
// 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) {
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
}
sampler.mUVId = it->second.mSet;
if (it == table.mMap.end()) {
return;
}
if (it->second.mType != Collada::IT_Texcoord) {
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
}
sampler.mUVId = it->second.mSet;
}
// ------------------------------------------------------------------------------------------------
@@ -390,7 +383,11 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Colla
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)) +
float f = 1.0f;
if ( 0.0f != srcLight->mFalloffExponent ) {
f = 1.f / srcLight->mFalloffExponent;
}
out->mAngleOuterCone = std::acos(std::pow(0.1f, f)) +
out->mAngleInnerCone;
} else {
out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD(srcLight->mPenumbraAngle);
@@ -585,10 +582,10 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Colla
// ------------------------------------------------------------------------------------------------
// Find mesh from either meshes or morph target meshes
aiMesh *ColladaLoader::findMesh(const std::string &meshid) {
if ( meshid.empty()) {
if (meshid.empty()) {
return nullptr;
}
for (unsigned int i = 0; i < mMeshes.size(); ++i) {
if (std::string(mMeshes[i]->mName.data) == meshid) {
return mMeshes[i];
@@ -1251,7 +1248,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
// 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 << "\".");
throw DeadlyImportError("Time count / value count mismatch in animation channel \"", e.mChannel->mTarget, "\".");
if (e.mTimeAccessor->mCount > 0) {
// find bounding times
@@ -1377,9 +1374,9 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
double time = double(mat.d4); // remember? time is stored in mat.d4
mat.d4 = 1.0f;
dstAnim->mPositionKeys[a].mTime = time * kMillisecondsFromSeconds ;
dstAnim->mRotationKeys[a].mTime = time * kMillisecondsFromSeconds ;
dstAnim->mScalingKeys[a].mTime = time * kMillisecondsFromSeconds ;
dstAnim->mPositionKeys[a].mTime = time * kMillisecondsFromSeconds;
dstAnim->mRotationKeys[a].mTime = time * kMillisecondsFromSeconds;
dstAnim->mScalingKeys[a].mTime = time * kMillisecondsFromSeconds;
mat.Decompose(dstAnim->mScalingKeys[a].mValue, dstAnim->mRotationKeys[a].mValue, dstAnim->mPositionKeys[a].mValue);
}
@@ -1400,7 +1397,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
if (e.mTargetId.find("morph-weights") != std::string::npos)
morphChannels.push_back(e);
}
if (!morphChannels.empty() ) {
if (!morphChannels.empty()) {
// either 1) morph weight animation count should contain morph target count channels
// or 2) one channel with morph target count arrays
// assume first
@@ -1434,8 +1431,8 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
morphAnim->mKeys[key].mValues = new unsigned int[morphChannels.size()];
morphAnim->mKeys[key].mWeights = new double[morphChannels.size()];
morphAnim->mKeys[key].mTime = morphTimeValues[key].mTime * kMillisecondsFromSeconds ;
for (unsigned int valueIndex = 0; valueIndex < morphChannels.size(); ++valueIndex ) {
morphAnim->mKeys[key].mTime = morphTimeValues[key].mTime * kMillisecondsFromSeconds;
for (unsigned int valueIndex = 0; valueIndex < morphChannels.size(); ++valueIndex) {
morphAnim->mKeys[key].mValues[valueIndex] = valueIndex;
morphAnim->mKeys[key].mWeights[valueIndex] = getWeightAtKey(morphTimeValues, key, valueIndex);
}
@@ -1468,7 +1465,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
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;
anim->mTicksPerSecond = 1000.0;
mAnims.push_back(anim);
}
}
@@ -1552,23 +1549,23 @@ void ColladaLoader::FillMaterials(const ColladaParser &pParser, aiScene * /*pSce
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;
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:
ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
shadeMode = aiShadingMode_Gouraud;
break;
default:
ASSIMP_LOG_WARN("Collada: Unrecognized shading mode, using gouraud shading");
shadeMode = aiShadingMode_Gouraud;
break;
}
}
mat.AddProperty<int>(&shadeMode, 1, AI_MATKEY_SHADING_MODEL);
@@ -1658,7 +1655,7 @@ void ColladaLoader::BuildMaterials(ColladaParser &pParser, aiScene * /*pScene*/)
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())
if (effIt == pParser.mEffectLibrary.end())
continue;
Collada::Effect &effect = effIt->second;
@@ -1734,7 +1731,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
// and add this texture to the list
mTextures.push_back(tex);
return result;
}
}
if (imIt->second.mFileName.empty()) {
throw DeadlyImportError("Collada: Invalid texture, no data or file reference given");
File diff suppressed because it is too large. Load diff
+66 -111
View File
@@ -4,7 +4,6 @@
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -50,9 +49,12 @@
#include "ColladaHelper.h"
#include <assimp/TinyFormatter.h>
#include <assimp/ai_assert.h>
#include <assimp/irrXMLWrapper.h>
#include <assimp/XmlParser.h>
#include <map>
namespace Assimp {
class ZipArchiveIOSystem;
// ------------------------------------------------------------------------------------------
@@ -81,25 +83,25 @@ protected:
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
/** Reads the contents of the file */
void ReadContents();
void ReadContents(XmlNode &node);
/** Reads the structure of the file */
void ReadStructure();
void ReadStructure(XmlNode &node);
/** Reads asset information such as coordinate system information and legal blah */
void ReadAssetInfo();
void ReadAssetInfo(XmlNode &node);
/** Reads contributor information such as author and legal blah */
void ReadContributorInfo();
void ReadContributorInfo(XmlNode &node);
/** Reads generic metadata into provided map and renames keys for Assimp */
void ReadMetaDataItem(StringMetaData &metadata);
void ReadMetaDataItem(XmlNode &node, StringMetaData &metadata);
/** Reads the animation library */
void ReadAnimationLibrary();
void ReadAnimationLibrary(XmlNode &node);
/** Reads the animation clip library */
void ReadAnimationClipLibrary();
void ReadAnimationClipLibrary(XmlNode &node);
/** Unwrap controllers dependency hierarchy */
void PostProcessControllers();
@@ -108,103 +110,103 @@ protected:
void PostProcessRootAnimations();
/** Reads an animation into the given parent structure */
void ReadAnimation(Collada::Animation *pParent);
void ReadAnimation(XmlNode &node, Collada::Animation *pParent);
/** Reads an animation sampler into the given anim channel */
void ReadAnimationSampler(Collada::AnimationChannel &pChannel);
void ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel);
/** Reads the skeleton controller library */
void ReadControllerLibrary();
void ReadControllerLibrary(XmlNode &node);
/** Reads a controller into the given mesh structure */
void ReadController(Collada::Controller &pController);
void ReadController(XmlNode &node, Collada::Controller &pController);
/** Reads the joint definitions for the given controller */
void ReadControllerJoints(Collada::Controller &pController);
void ReadControllerJoints(XmlNode &node, Collada::Controller &pController);
/** Reads the joint weights for the given controller */
void ReadControllerWeights(Collada::Controller &pController);
void ReadControllerWeights(XmlNode &node, Collada::Controller &pController);
/** Reads the image library contents */
void ReadImageLibrary();
void ReadImageLibrary(XmlNode &node);
/** Reads an image entry into the given image */
void ReadImage(Collada::Image &pImage);
void ReadImage(XmlNode &node, Collada::Image &pImage);
/** Reads the material library */
void ReadMaterialLibrary();
void ReadMaterialLibrary(XmlNode &node);
/** Reads a material entry into the given material */
void ReadMaterial(Collada::Material &pMaterial);
void ReadMaterial(XmlNode &node, Collada::Material &pMaterial);
/** Reads the camera library */
void ReadCameraLibrary();
void ReadCameraLibrary(XmlNode &node);
/** Reads a camera entry into the given camera */
void ReadCamera(Collada::Camera &pCamera);
void ReadCamera(XmlNode &node, Collada::Camera &pCamera);
/** Reads the light library */
void ReadLightLibrary();
void ReadLightLibrary(XmlNode &node);
/** Reads a light entry into the given light */
void ReadLight(Collada::Light &pLight);
void ReadLight(XmlNode &node, Collada::Light &pLight);
/** Reads the effect library */
void ReadEffectLibrary();
void ReadEffectLibrary(XmlNode &node);
/** Reads an effect entry into the given effect*/
void ReadEffect(Collada::Effect &pEffect);
void ReadEffect(XmlNode &node, Collada::Effect &pEffect);
/** Reads an COMMON effect profile */
void ReadEffectProfileCommon(Collada::Effect &pEffect);
void ReadEffectProfileCommon(XmlNode &node, Collada::Effect &pEffect);
/** Read sampler properties */
void ReadSamplerProperties(Collada::Sampler &pSampler);
void ReadSamplerProperties(XmlNode &node, Collada::Sampler &pSampler);
/** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler);
void ReadEffectColor(XmlNode &node, aiColor4D &pColor, Collada::Sampler &pSampler);
/** Reads an effect entry containing a float */
void ReadEffectFloat(ai_real &pFloat);
void ReadEffectFloat(XmlNode &node, ai_real &pFloat);
/** Reads an effect parameter specification of any kind */
void ReadEffectParam(Collada::EffectParam &pParam);
void ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam);
/** Reads the geometry library contents */
void ReadGeometryLibrary();
void ReadGeometryLibrary(XmlNode &node);
/** Reads a geometry from the geometry library. */
void ReadGeometry(Collada::Mesh &pMesh);
void ReadGeometry(XmlNode &node, Collada::Mesh &pMesh);
/** Reads a mesh from the geometry library */
void ReadMesh(Collada::Mesh &pMesh);
void ReadMesh(XmlNode &node, 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();
void ReadSource(XmlNode &node);
/** 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();
void ReadDataArray(XmlNode &node);
/** 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);
void ReadAccessor(XmlNode &node, const std::string &pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData(Collada::Mesh &pMesh);
void ReadVertexData(XmlNode &node, Collada::Mesh &pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData(Collada::Mesh &pMesh);
void ReadIndexData(XmlNode &node, 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);
void ReadInputChannel(XmlNode &node, 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 ReadPrimitives(XmlNode &node, 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 */
@@ -220,68 +222,27 @@ protected:
void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
/** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary();
void ReadSceneLibrary(XmlNode &node);
/** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode(Collada::Node *pNode);
void ReadSceneNode(XmlNode &node, 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);
void ReadNodeTransformation(XmlNode &node, 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);
void ReadNodeGeometry(XmlNode &node, Collada::Node *pNode);
/** Reads the collada scene */
void ReadScene();
void ReadScene(XmlNode &node);
// Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl);
void ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl);
/** Reads embedded textures from a ZAE archive*/
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
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 nullptr 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;
@@ -293,59 +254,59 @@ protected:
const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
protected:
/** Filename, for a verbose error message */
// Filename, for a verbose error message
std::string mFileName;
/** XML reader, member for everyday use */
irr::io::IrrXMLReader *mReader;
// XML reader, member for everyday use
XmlParser mXmlParser;
/** 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;
using DataLibrary = std::map<std::string, Collada::Data> ;
DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh *> MeshLibrary;
using MeshLibrary = std::map<std::string, Collada::Mesh *>;
MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node *> NodeLibrary;
using NodeLibrary = std::map<std::string, Collada::Node *>;
NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary;
using ImageLibrary = std::map<std::string, Collada::Image> ;
ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary;
using EffectLibrary = std::map<std::string, Collada::Effect> ;
EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary;
using MaterialLibrary = std::map<std::string, Collada::Material> ;
MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary;
using LightLibrary = std::map<std::string, Collada::Light> ;
LightLibrary mLightLibrary;
/** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary;
using CameraLibrary = std::map<std::string, Collada::Camera> ;
CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
using ControllerLibrary = std::map<std::string, Collada::Controller> ;
ControllerLibrary mControllerLibrary;
/** Animation library: animation references by ID */
typedef std::map<std::string, Collada::Animation *> AnimationLibrary;
using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
AnimationLibrary mAnimationLibrary;
/** Animation clip library: clip animation references by ID */
typedef std::vector<std::pair<std::string, std::vector<std::string>>> AnimationClipLibrary;
using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
AnimationClipLibrary mAnimationClipLibrary;
/** Pointer to the root node. Don't delete, it just points to one of
@@ -370,20 +331,14 @@ protected:
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 << "\".");
if (it == pLibrary.end()) {
throw DeadlyImportError("Unable to resolve library reference \"", pURL, "\".");
}
return it->second;
}
+1 -1
View File
@@ -152,7 +152,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
// Check whether we can read the file
if( file.get() == nullptr ) {
throw DeadlyImportError( "Failed to open DXF file " + filename + "");
throw DeadlyImportError( "Failed to open DXF file ", filename, "");
}
// Check whether this is a binary DXF file - we can't read binary DXF files :-(
+15 -4
View File
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exceptional.h>
#include <assimp/ByteSwapper.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/StringUtils.h>
namespace Assimp {
namespace FBX {
@@ -126,7 +127,7 @@ namespace {
AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void TokenizeError(const std::string& message, size_t offset)
{
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
throw DeadlyImportError("FBX-Tokenize", Util::GetOffsetText(offset), message);
}
@@ -456,11 +457,21 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
ASSIMP_LOG_DEBUG_F("FBX version: ", version);
const bool is64bits = version >= 7500;
const char *end = input + length;
while (cursor < end ) {
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break;
try
{
while (cursor < end ) {
if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
break;
}
}
}
catch (const DeadlyImportError& e)
{
if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", to_string(version), ") of the FBX format. (", e.what(), ")");
}
throw;
}
}
} // !FBX
+128 -124
View File
@@ -185,6 +185,17 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
return unique_name;
}
/// This struct manages nodes which may or may not end up in the node hierarchy.
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
struct FBXConverter::PotentialNode
{
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
aiNode* operator->() { return mNode; }
std::unique_ptr<aiNode> mOwnership;
aiNode* mNode;
};
/// todo: pre-build node hierarchy
/// todo: get bone from stack
/// todo: make map of aiBone* to aiNode*
@@ -192,137 +203,129 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector<aiNode *> nodes;
std::vector<PotentialNode> nodes;
nodes.reserve(conns.size());
std::vector<aiNode *> nodes_chain;
std::vector<aiNode *> post_nodes_chain;
std::vector<PotentialNode> nodes_chain;
std::vector<PotentialNode> post_nodes_chain;
try {
for (const Connection *con : conns) {
// ignore object-property links
if (con->PropertyName().length()) {
// really important we document why this is ignored.
FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
continue; //?
for (const Connection *con : conns) {
// ignore object-property links
if (con->PropertyName().length()) {
// really important we document why this is ignored.
FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
continue; //?
}
// convert connection source object into Object base class
const Object *const object = con->SourceObject();
if (nullptr == object) {
FBXImporter::LogError("failed to convert source object for Model link");
continue;
}
// FBX Model::Cube, Model::Bone001, etc elements
// This detects if we can cast the object into this model structure.
const Model *const model = dynamic_cast<const Model *>(object);
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent->mTransformation;
std::string node_name = FixNodeName(model->Name());
// 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.
// generate node transforms - this includes pivot data
// if need_additional_node is true then you t
const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
// assert that for the current node we must have at least a single transform
ai_assert(nodes_chain.size());
if (need_additional_node) {
nodes_chain.emplace_back(PotentialNode(node_name));
}
// convert connection source object into Object base class
const Object *const object = con->SourceObject();
if (nullptr == object) {
FBXImporter::LogError("failed to convert source object for Model link");
continue;
}
//setup metadata on newest node
SetupNodeMetadata(*model, *nodes_chain.back().mNode);
// FBX Model::Cube, Model::Bone001, etc elements
// This detects if we can cast the object into this model structure.
const Model *const model = dynamic_cast<const Model *>(object);
// link all nodes in a row
aiNode *last_parent = parent;
for (PotentialNode& child : nodes_chain) {
ai_assert(child.mNode);
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent->mTransformation;
std::string node_name = FixNodeName(model->Name());
// 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.
// generate node transforms - this includes pivot data
// if need_additional_node is true then you t
const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
// assert that for the current node we must have at least a single transform
ai_assert(nodes_chain.size());
if (need_additional_node) {
nodes_chain.push_back(new aiNode(node_name));
if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode *[1];
last_parent->mChildren[0] = child.mOwnership.release();
}
//setup metadata on newest node
SetupNodeMetadata(*model, *nodes_chain.back());
child->mParent = last_parent;
last_parent = child.mNode;
// link all nodes in a row
aiNode *last_parent = parent;
for (aiNode *child : nodes_chain) {
ai_assert(child);
new_abs_transform *= child->mTransformation;
}
// attach geometry
ConvertModel(*model, nodes_chain.back().mNode, root_node, new_abs_transform);
// check if there will be any child nodes
const std::vector<const Connection *> &child_conns = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model");
// if so, link the geometric transform inverse nodes
// before we attach any child nodes
if (child_conns.size()) {
for (PotentialNode& postnode : post_nodes_chain) {
ai_assert(postnode.mNode);
if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode *[1];
last_parent->mChildren[0] = child;
last_parent->mChildren[0] = postnode.mOwnership.release();
}
child->mParent = last_parent;
last_parent = child;
postnode->mParent = last_parent;
last_parent = postnode.mNode;
new_abs_transform *= child->mTransformation;
new_abs_transform *= postnode->mTransformation;
}
// attach geometry
ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
// check if there will be any child nodes
const std::vector<const Connection *> &child_conns = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model");
// if so, link the geometric transform inverse nodes
// before we attach any child nodes
if (child_conns.size()) {
for (aiNode *postnode : post_nodes_chain) {
ai_assert(postnode);
if (last_parent != parent) {
last_parent->mNumChildren = 1;
last_parent->mChildren = new aiNode *[1];
last_parent->mChildren[0] = postnode;
}
postnode->mParent = last_parent;
last_parent = postnode;
new_abs_transform *= postnode->mTransformation;
}
} else {
// free the nodes we allocated as we don't need them
Util::delete_fun<aiNode> deleter;
std::for_each(
post_nodes_chain.begin(),
post_nodes_chain.end(),
deleter);
}
// recursion call - child nodes
ConvertNodes(model->ID(), last_parent, root_node);
if (doc.Settings().readLights) {
ConvertLights(*model, node_name);
}
if (doc.Settings().readCameras) {
ConvertCameras(*model, node_name);
}
nodes.push_back(nodes_chain.front());
nodes_chain.clear();
} else {
// free the nodes we allocated as we don't need them
post_nodes_chain.clear();
}
// recursion call - child nodes
ConvertNodes(model->ID(), last_parent, root_node);
if (doc.Settings().readLights) {
ConvertLights(*model, node_name);
}
if (doc.Settings().readCameras) {
ConvertCameras(*model, node_name);
}
nodes.push_back(std::move(nodes_chain.front()));
nodes_chain.clear();
}
}
if (nodes.size()) {
parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
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);
} else {
parent->mNumChildren = 0;
parent->mChildren = nullptr;
for (unsigned int i = 0; i < nodes.size(); ++i)
{
parent->mChildren[i] = nodes[i].mOwnership.release();
}
} 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);
std::for_each(post_nodes_chain.begin(), post_nodes_chain.end(), deleter);
nodes.clear();
} else {
parent->mNumChildren = 0;
parent->mChildren = nullptr;
}
}
@@ -681,8 +684,8 @@ std::string FBXConverter::NameTransformationChainNode(const std::string &name, T
return name + std::string(MAGIC_NODE_TAG) + "_" + NameTransformationComp(comp);
}
bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std::string &name, std::vector<aiNode *> &output_nodes,
std::vector<aiNode *> &post_output_nodes) {
bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std::string &name, std::vector<PotentialNode> &output_nodes,
std::vector<PotentialNode> &post_output_nodes) {
const PropertyTable &props = model.Props();
const Model::RotOrder rot = model.RotationOrder();
@@ -828,7 +831,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
chain[i] = chain[i].Inverse();
}
aiNode *nd = new aiNode();
PotentialNode nd;
nd->mName.Set(NameTransformationChainNode(name, comp));
nd->mTransformation = chain[i];
@@ -836,9 +839,9 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
if (comp == TransformationComp_GeometricScalingInverse ||
comp == TransformationComp_GeometricRotationInverse ||
comp == TransformationComp_GeometricTranslationInverse) {
post_output_nodes.push_back(nd);
post_output_nodes.emplace_back(std::move(nd));
} else {
output_nodes.push_back(nd);
output_nodes.emplace_back(std::move(nd));
}
}
@@ -847,8 +850,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
}
// else, we can just multiply the matrices together
aiNode *nd = new aiNode();
output_nodes.push_back(nd);
PotentialNode nd;
// name passed to the method is already unique
nd->mName.Set(name);
@@ -857,6 +859,7 @@ bool FBXConverter::GenerateTransformationNodeChain(const Model &model, const std
for (unsigned int i = TransformationComp_Translation; i < TransformationComp_MAXIMUM; i++) {
nd->mTransformation = nd->mTransformation * chain[i];
}
output_nodes.push_back(std::move(nd));
return false;
}
@@ -1715,14 +1718,14 @@ aiString FBXConverter::GetTexturePath(const Texture *tex) {
bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
unsigned int index=0;
VideoMap::const_iterator it = textures_converted.find(*media);
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;
textures_converted[media] = index;
textureReady = true;
}
}
@@ -2221,12 +2224,12 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
if (media != nullptr && media->ContentLength() > 0) {
unsigned int index;
VideoMap::const_iterator videoIt = textures_converted.find(*media);
VideoMap::const_iterator videoIt = textures_converted.find(media);
if (videoIt != textures_converted.end()) {
index = videoIt->second;
} else {
index = ConvertVideo(*media);
textures_converted[*media] = index;
textures_converted[media] = index;
}
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
@@ -3481,10 +3484,11 @@ void FBXConverter::ConvertOrphanedEmbeddedTextures() {
const char *obtype = key.begin();
const size_t length = static_cast<size_t>(key.end() - key.begin());
if (strncmp(obtype, "Texture", length) == 0) {
const Texture *texture = static_cast<const Texture *>(object->Get());
if (texture->Media() && texture->Media()->ContentLength() > 0) {
realTexture = texture;
}
if (const Texture *texture = static_cast<const Texture *>(object->Get())) {
if (texture->Media() && texture->Media()->ContentLength() > 0) {
realTexture = texture;
}
}
}
} catch (...) {
// do nothing
@@ -3492,7 +3496,7 @@ void FBXConverter::ConvertOrphanedEmbeddedTextures() {
if (realTexture) {
const Video *media = realTexture->Media();
unsigned int index = ConvertVideo(*media);
textures_converted[*media] = index;
textures_converted[media] = index;
}
}
}
+4 -3
View File
@@ -171,9 +171,10 @@ private:
// ------------------------------------------------------------------------------------------------
/**
* note: memory for output_nodes will be managed by the caller
* note: memory for output_nodes is managed by the caller, via the PotentialNode struct.
*/
bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<aiNode*>& output_nodes, std::vector<aiNode*>& post_output_nodes);
struct PotentialNode;
bool GenerateTransformationNodeChain(const Model& model, const std::string& name, std::vector<PotentialNode>& output_nodes, std::vector<PotentialNode>& post_output_nodes);
// ------------------------------------------------------------------------------------------------
void SetupNodeMetadata(const Model& model, aiNode& nd);
@@ -428,7 +429,7 @@ private:
using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>;
MaterialMap materials_converted;
using VideoMap = std::fbx_unordered_map<const Video, unsigned int>;
using VideoMap = std::fbx_unordered_map<const Video*, unsigned int>;
VideoMap textures_converted;
using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >;
-35
View File
@@ -638,20 +638,6 @@ public:
return ptr;
}
bool operator==(const Video& other) const
{
return (
type == other.type
&& relativeFileName == other.relativeFileName
&& fileName == other.fileName
);
}
bool operator<(const Video& other) const
{
return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
}
private:
std::string type;
std::string relativeFileName;
@@ -1192,25 +1178,4 @@ private:
} // Namespace FBX
} // Namespace Assimp
namespace std
{
template <>
struct hash<const Assimp::FBX::Video>
{
std::size_t operator()(const Assimp::FBX::Video& video) const
{
using std::size_t;
using std::hash;
using std::string;
size_t res = 17;
res = res * 31 + hash<string>()(video.Name());
res = res * 31 + hash<string>()(video.RelativeFilename());
res = res * 31 + hash<string>()(video.Type());
return res;
}
};
}
#endif // INCLUDED_AI_FBX_DOCUMENT_H
+3 -3
View File
@@ -61,7 +61,7 @@ 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));
throw DeadlyImportError("FBX-DOM", Util::GetTokenText(&token), message);
}
// ------------------------------------------------------------------------------------------------
@@ -70,7 +70,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
if(element) {
DOMError(message,element->KeyToken());
}
throw DeadlyImportError("FBX-DOM " + message);
throw DeadlyImportError("FBX-DOM ", message);
}
@@ -79,7 +79,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
void DOMWarning(const std::string& message, const Token& token)
{
if(DefaultLogger::get()) {
ASSIMP_LOG_WARN(Util::AddTokenText("FBX-DOM",message,&token));
ASSIMP_LOG_WARN_F("FBX-DOM", Util::GetTokenText(&token), message);
}
}
+6 -6
View File
@@ -405,7 +405,7 @@ void FBXExporter::WriteHeaderExtension ()
void WritePropInt(const aiScene* scene, FBX::Node& p, const std::string& key, int defaultValue)
{
int value;
if (scene->mMetaData->Get(key, value)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70int(key, value);
} else {
p.AddP70int(key, defaultValue);
@@ -415,12 +415,12 @@ void WritePropInt(const aiScene* scene, FBX::Node& p, const std::string& key, in
void WritePropDouble(const aiScene* scene, FBX::Node& p, const std::string& key, double defaultValue)
{
double value;
if (scene->mMetaData->Get(key, value)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70double(key, value);
} else {
// fallback lookup float instead
float floatValue;
if (scene->mMetaData->Get(key, floatValue)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, floatValue)) {
p.AddP70double(key, (double)floatValue);
} else {
p.AddP70double(key, defaultValue);
@@ -431,7 +431,7 @@ void WritePropDouble(const aiScene* scene, FBX::Node& p, const std::string& key,
void WritePropEnum(const aiScene* scene, FBX::Node& p, const std::string& key, int defaultValue)
{
int value;
if (scene->mMetaData->Get(key, value)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70enum(key, value);
} else {
p.AddP70enum(key, defaultValue);
@@ -441,7 +441,7 @@ void WritePropEnum(const aiScene* scene, FBX::Node& p, const std::string& key, i
void WritePropColor(const aiScene* scene, FBX::Node& p, const std::string& key, const aiVector3D& defaultValue)
{
aiVector3D value;
if (scene->mMetaData->Get(key, value)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
// ai_real can be float or double, cast to avoid warnings
p.AddP70color(key, (double)value.x, (double)value.y, (double)value.z);
} else {
@@ -452,7 +452,7 @@ void WritePropColor(const aiScene* scene, FBX::Node& p, const std::string& key,
void WritePropString(const aiScene* scene, FBX::Node& p, const std::string& key, const std::string& defaultValue)
{
aiString value; // MetaData doesn't hold std::string
if (scene->mMetaData->Get(key, value)) {
if (scene->mMetaData != nullptr && scene->mMetaData->Get(key, value)) {
p.AddP70string(key, value.C_Str());
} else {
p.AddP70string(key, defaultValue);
+10 -1
View File
@@ -130,6 +130,7 @@ void FBXImporter::SetupProperties(const Importer *pImp) {
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.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, 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);
@@ -141,7 +142,10 @@ void FBXImporter::SetupProperties(const Importer *pImp) {
// ------------------------------------------------------------------------------------------------
// 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"));
auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream);
};
std::unique_ptr<IOStream, decltype(streamCloser)> stream(pIOHandler->Open(pFile, "rb"), streamCloser);
if (!stream) {
ThrowException("Could not open file for reading");
}
@@ -184,6 +188,11 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
if (size_relative_to_cm == 0.0)
{
// BaseImporter later asserts that fileScale is non-zero.
ThrowException("The UnitScaleFactor must be non-zero");
}
// Set FBX file scale is relative to CM must be converted to M for
// assimp universal format (M)
+1 -1
View File
@@ -86,7 +86,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
std::string templateName;
// lower-case shading because Blender (for example) writes "Phong"
std::transform(shading.begin(), shading.end(), shading.begin(), Assimp::ToLower<char>);
std::transform(shading.data(), shading.data() + shading.size(), std::addressof(shading[0]), Assimp::ToLower<char>);
if(shading == "phong") {
templateName = "Material.FbxSurfacePhong";
}
+42 -10
View File
@@ -73,7 +73,7 @@ namespace {
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));
throw DeadlyImportError("FBX-Parser", Util::GetTokenText(&token), message);
}
// ------------------------------------------------------------------------------------------------
@@ -83,7 +83,7 @@ namespace {
if(element) {
ParseError(message,element->KeyToken());
}
throw DeadlyImportError("FBX-Parser " + message);
throw DeadlyImportError("FBX-Parser ", message);
}
@@ -641,7 +641,11 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
const uint32_t count3 = count / 3;
out.reserve(count3);
@@ -728,7 +732,11 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
const uint32_t count4 = count / 4;
out.reserve(count4);
@@ -807,7 +815,11 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
const uint32_t count2 = count / 2;
out.reserve(count2);
@@ -879,7 +891,11 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * 4);
uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
out.reserve(count);
@@ -937,7 +953,11 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * (type == 'd' ? 8 : 4));
uint64_t dataToRead = static_cast<uint64_t>(count) * (type == 'd' ? 8 : 4);
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
if (type == 'd') {
const double* d = reinterpret_cast<const double*>(&buff[0]);
@@ -998,7 +1018,11 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * 4);
uint64_t dataToRead = static_cast<uint64_t>(count) * 4;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
out.reserve(count);
@@ -1063,7 +1087,11 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * 8);
uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
out.reserve(count);
@@ -1121,7 +1149,11 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
ReadBinaryDataArray(type, count, data, end, buff, el);
ai_assert(data == end);
ai_assert(buff.size() == count * 8);
uint64_t dataToRead = static_cast<uint64_t>(count) * 8;
ai_assert(buff.size() == dataToRead);
if (dataToRead > buff.size()) {
ParseError("Invalid read size (binary)",&el);
}
out.reserve(count);
+10 -1
View File
@@ -76,23 +76,30 @@ Property* ReadTypedProperty(const Element& element)
ai_assert(element.KeyToken().StringContents() == "P");
const TokenList& tok = element.Tokens();
ai_assert(tok.size() >= 5);
if (tok.size() < 2) {
return nullptr;
}
const std::string& s = ParseTokenAsString(*tok[1]);
const char* const cs = s.c_str();
if (!strcmp(cs,"KString")) {
ai_assert(tok.size() >= 5);
return new TypedProperty<std::string>(ParseTokenAsString(*tok[4]));
}
else if (!strcmp(cs,"bool") || !strcmp(cs,"Bool")) {
ai_assert(tok.size() >= 5);
return new TypedProperty<bool>(ParseTokenAsInt(*tok[4]) != 0);
}
else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) {
ai_assert(tok.size() >= 5);
return new TypedProperty<int>(ParseTokenAsInt(*tok[4]));
}
else if (!strcmp(cs, "ULongLong")) {
ai_assert(tok.size() >= 5);
return new TypedProperty<uint64_t>(ParseTokenAsID(*tok[4]));
}
else if (!strcmp(cs, "KTime")) {
ai_assert(tok.size() >= 5);
return new TypedProperty<int64_t>(ParseTokenAsInt64(*tok[4]));
}
else if (!strcmp(cs,"Vector3D") ||
@@ -103,6 +110,7 @@ Property* ReadTypedProperty(const Element& element)
!strcmp(cs,"Lcl Rotation") ||
!strcmp(cs,"Lcl Scaling")
) {
ai_assert(tok.size() >= 7);
return new TypedProperty<aiVector3D>(aiVector3D(
ParseTokenAsFloat(*tok[4]),
ParseTokenAsFloat(*tok[5]),
@@ -110,6 +118,7 @@ Property* ReadTypedProperty(const Element& element)
);
}
else if (!strcmp(cs,"double") || !strcmp(cs,"Number") || !strcmp(cs,"Float") || !strcmp(cs,"FieldOfView") || !strcmp( cs, "UnitScaleFactor" ) ) {
ai_assert(tok.size() >= 5);
return new TypedProperty<float>(ParseTokenAsFloat(*tok[4]));
}
return nullptr;
+1 -1
View File
@@ -90,7 +90,7 @@ namespace {
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));
throw DeadlyImportError("FBX-Tokenize", Util::GetLineAndColumnText(line,column), message);
}
+9 -11
View File
@@ -86,32 +86,30 @@ const char* TokenTypeString(TokenType t)
// ------------------------------------------------------------------------------------------------
std::string AddOffset(const std::string& prefix, const std::string& text, size_t offset)
std::string GetOffsetText(size_t offset)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (offset 0x" << std::hex << offset << ") " << text) );
return static_cast<std::string>( Formatter::format() << " (offset 0x" << std::hex << offset << ") " );
}
// ------------------------------------------------------------------------------------------------
std::string AddLineAndColumn(const std::string& prefix, const std::string& text, unsigned int line, unsigned int column)
std::string GetLineAndColumnText(unsigned int line, unsigned int column)
{
return static_cast<std::string>( (Formatter::format() << prefix << " (line " << line << " << col " << column << ") " << text) );
return static_cast<std::string>( Formatter::format() << " (line " << line << " << col " << column << ") " );
}
// ------------------------------------------------------------------------------------------------
std::string AddTokenText(const std::string& prefix, const std::string& text, const Token* tok)
std::string GetTokenText(const Token* tok)
{
if(tok->IsBinary()) {
return static_cast<std::string>( (Formatter::format() << prefix <<
return static_cast<std::string>( Formatter::format() <<
" (" << TokenTypeString(tok->Type()) <<
", offset 0x" << std::hex << tok->Offset() << ") " <<
text) );
", offset 0x" << std::hex << tok->Offset() << ") " );
}
return static_cast<std::string>( (Formatter::format() << prefix <<
return static_cast<std::string>( Formatter::format() <<
" (" << TokenTypeString(tok->Type()) <<
", line " << tok->Line() <<
", col " << tok->Column() << ") " <<
text) );
", col " << tok->Column() << ") " );
}
// Generated by this formula: T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
+7 -14
View File
@@ -73,31 +73,24 @@ 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, size_t offset);
* @param offset offset within the file
* @return A string of the following format: " (offset 0x{offset}) "*/
std::string GetOffsetText(size_t 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);
* @return A string of the following format: " (line {line}, col {column}) "*/
std::string GetLineAndColumnText(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);
* @return A string of the following format: " ({token-type}, line {line}, col {column}) "*/
std::string GetTokenText(const Token* tok);
/** Decode a single Base64-encoded character.
*
+3 -3
View File
@@ -115,7 +115,7 @@ void HMPImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open HMP file " + pFile + ".");
throw DeadlyImportError("Failed to open HMP file ", pFile, ".");
}
// Check whether the HMP file is large enough to contain
@@ -159,8 +159,8 @@ void HMPImporter::InternReadFile(const std::string &pFile,
szBuffer[4] = '\0';
// We're definitely unable to load this file
throw DeadlyImportError("Unknown HMP subformat " + pFile +
". Magic word (" + szBuffer + ") is not known");
throw DeadlyImportError("Unknown HMP subformat ", pFile,
". Magic word (", szBuffer, ") is not known");
}
// Set the AI_SCENE_FLAGS_TERRAIN bit
+9
View File
@@ -45,6 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IFCReaderGen_2x3.h"
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4702)
#endif // _MSC_VER
namespace Assimp {
using namespace ::Assimp::IFC;
@@ -3165,4 +3170,8 @@ template <> size_t GenericFill<IfcLightSourceDirectional>(const DB& db, const LI
} // ! STEP
} // ! Assimp
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#endif
+9
View File
@@ -43,6 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "IFCReaderGen_2x3.h"
#if _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4702)
#endif // _MSC_VER
namespace Assimp {
using namespace IFC;
using namespace ::Assimp::IFC::Schema_2x3;
@@ -1915,4 +1920,8 @@ template <> size_t GenericFill<IfcConditionCriterion>(const DB& db, const LIST&
} // ! STEP
} // ! Assimp
#if _MSC_VER
# pragma warning(pop)
#endif // _MSC_VER
#endif
File diff suppressed because it is too large. Load diff
+11 -22
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -40,7 +39,6 @@ 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.
@@ -83,7 +81,7 @@ protected:
private:
/** Data structure for a scenegraph node animator
/** Data structure for a scene-graph node animator
*/
struct Animator {
// Type of the animator
@@ -129,7 +127,7 @@ private:
int timeForWay;
};
/** Data structure for a scenegraph node in an IRR file
/** Data structure for a scene-graph node in an IRR file
*/
struct Node
{
@@ -227,8 +225,7 @@ private:
// -------------------------------------------------------------------
/** Fill the scenegraph recursively
*/
/// Fill the scene-graph recursively
void GenerateGraph(Node* root,aiNode* rootOut ,aiScene* scene,
BatchLoader& batch,
std::vector<aiMesh*>& meshes,
@@ -237,27 +234,22 @@ private:
std::vector<aiMaterial*>& materials,
unsigned int& defaultMatIdx);
// -------------------------------------------------------------------
/** Generate a mesh that consists of just a single quad
*/
/// 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.
*/
/// Build a sky-box
///
/// @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
*
@@ -271,7 +263,6 @@ private:
unsigned int& defMatIdx,
aiMesh* mesh);
// -------------------------------------------------------------------
/** Compute animations for a specific node
*
@@ -281,13 +272,11 @@ private:
void ComputeAnimations(Node* root, aiNode* real,
std::vector<aiNodeAnim*>& anims);
private:
/** Configuration option: desired output FPS */
/// Configuration option: desired output FPS
double fps;
/** Configuration option: speed flag was set? */
/// Configuration option: speed flag was set?
bool configSpeedFlag;
};
+426 -446
View File
@@ -43,494 +43,474 @@ 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 <assimp/ParsingUtils.h>
#include <assimp/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 <assimp/material.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <memory>
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"
"Irrlicht Mesh Reader",
"",
"",
"http://irrlicht.sourceforge.net/",
aiImporterFlags_SupportTextFlavour,
0,
0,
0,
0,
"xml irrmesh"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
IRRMeshImporter::IRRMeshImporter()
{}
IRRMeshImporter::IRRMeshImporter() :
BaseImporter(),
IrrlichtBase() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
IRRMeshImporter::~IRRMeshImporter()
{}
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
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);
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
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;
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;
const aiImporterDesc *IRRMeshImporter::GetInfo() const {
return &desc;
}
static void releaseMaterial( aiMaterial **mat ) {
if(*mat!= nullptr) {
delete *mat;
*mat = nullptr;
}
static void releaseMaterial(aiMaterial **mat) {
if (*mat != nullptr) {
delete *mat;
*mat = nullptr;
}
}
static void releaseMesh( aiMesh **mesh ) {
if (*mesh != nullptr){
delete *mesh;
*mesh = 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));
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() == nullptr) {
throw DeadlyImportError("Failed to open IRRMESH file " + 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
XmlParser parser;
if (!parser.parse( file.get() )) {
return;
}
// 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) {
ASSIMP_LOG_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) {
ASSIMP_LOG_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
ASSIMP_LOG_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 );
ASSIMP_LOG_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
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero indices");
// mesh - away
releaseMesh( &curMesh );
// material - away
releaseMaterial( &curMat );
textMeaning = 0;
continue;
}
if (curMesh->mNumVertices % 3) {
ASSIMP_LOG_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) {
ASSIMP_LOG_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()) {
ASSIMP_LOG_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)
ASSIMP_LOG_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) {
ASSIMP_LOG_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);
XmlNode root = parser.getRootNode();
// 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
for (pugi::xml_node child : root.children()) {
if (child.type() == pugi::node_element) {
if (!ASSIMP_stricmp(child.name(), "buffer") && (curMat || curMesh)) {
// end of previous buffer. A material and a mesh should be there
if (!curMat || !curMesh) {
ASSIMP_LOG_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(child.name(), "material")) {
if (curMat) {
ASSIMP_LOG_WARN("IRRMESH: Only one material description per buffer, please");
releaseMaterial(&curMat);
}
curMat = ParseMaterial(curMatFlags);
}
/* no else here! */ if (!ASSIMP_stricmp(child.name(), "vertices")) {
pugi::xml_attribute attr = child.attribute("vertexCount");
int num = attr.as_int();
//int num = reader->getAttributeValueAsInt("vertexCount");
if (!num) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_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");
pugi::xml_attribute t = child.attribute("type");
if (!ASSIMP_stricmp("2tcoords", t.name())) {
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.name())) {
curTangents.reserve(num);
curBitangents.reserve(num);
vertexFormat = 2;
} else if (ASSIMP_stricmp("standard", t.name())) {
releaseMaterial(&curMat);
ASSIMP_LOG_WARN("IRRMESH: Unknown vertex format");
} else
vertexFormat = 0;
textMeaning = 1;
} else if (!ASSIMP_stricmp(child.name(), "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
pugi::xml_attribute attr = child.attribute("indexCount");
curMesh->mNumVertices = attr.as_int();
if (!curMesh->mNumVertices) {
// This is possible ... remove the mesh from the list and skip further reading
ASSIMP_LOG_WARN("IRRMESH: Found mesh with zero indices");
// mesh - away
releaseMesh(&curMesh);
// material - away
releaseMaterial(&curMat);
textMeaning = 0;
continue;
}
if (curMesh->mNumVertices % 3) {
ASSIMP_LOG_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 = child.child_value();
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) {
ASSIMP_LOG_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()) {
ASSIMP_LOG_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)
ASSIMP_LOG_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);
}
}
}
}
// End of the last buffer. A material and a mesh should be there
if (curMat || curMesh) {
if (!curMat || !curMesh) {
ASSIMP_LOG_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;
}
}
#endif // !! ASSIMP_BUILD_NO_IRRMESH_IMPORTER
+8 -15
View File
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -47,12 +46,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_IRRMESHLOADER_H_INCLUDED
#define AI_IRRMESHLOADER_H_INCLUDED
#include <assimp/BaseImporter.h>
#include "IRRShared.h"
#include <assimp/BaseImporter.h>
#ifndef ASSIMP_BUILD_NO_IRRMESH_IMPORTER
namespace Assimp {
namespace Assimp {
// ---------------------------------------------------------------------------
/** IrrMesh importer class.
@@ -61,37 +60,31 @@ namespace Assimp {
* 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
{
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;
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;
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);
void InternReadFile(const std::string &pFile, aiScene *pScene,
IOSystem *pIOHandler);
};
} // end of namespace Assimp
+208 -322
View File
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -45,8 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @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))
@@ -56,10 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#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 (
@@ -70,125 +63,94 @@ const aiMatrix4x4 Assimp::AI_TO_IRR_MATRIX = aiMatrix4x4 (
// ------------------------------------------------------------------------------------------------
// 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"))
{
void IrrlichtBase::ReadHexProperty(HexProperty &out ) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string( attrib.value() );
} else if (!ASSIMP_stricmp(attrib.name(),"value")) {
// parse the hexadecimal value
out.value = strtoul16(reader->getAttributeValue(i));
out.value = strtoul16(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// 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));
void IrrlichtBase::ReadIntProperty(IntProperty & out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.value(),"value")) {
// parse the int value
out.value = strtol10(attrib.name());
}
}
}
// ------------------------------------------------------------------------------------------------
// 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"))
{
void IrrlichtBase::ReadStringProperty( StringProperty& out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// simple copy the string
out.value = std::string (reader->getAttributeValue(i));
out.value = std::string(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// 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"))
{
void IrrlichtBase::ReadBoolProperty(BoolProperty &out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")){
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// true or false, case insensitive
out.value = (ASSIMP_stricmp( reader->getAttributeValue(i),
"true") ? false : true);
out.value = (ASSIMP_stricmp(attrib.value(), "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"))
{
void IrrlichtBase::ReadFloatProperty(FloatProperty &out) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// just parse the float
out.value = fast_atof( reader->getAttributeValue(i) );
out.value = fast_atof(attrib.value());
}
}
}
// ------------------------------------------------------------------------------------------------
// 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"))
{
void IrrlichtBase::ReadVectorProperty( VectorProperty &out ) {
for (pugi::xml_attribute attrib : mNode->attributes()) {
if (!ASSIMP_stricmp(attrib.name(), "name")) {
out.name = std::string(attrib.value());
} else if (!ASSIMP_stricmp(attrib.name(), "value")) {
// three floats, separated with commas
const char* ptr = reader->getAttributeValue(i);
const char *ptr = attrib.value();
SkipSpaces(&ptr);
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.x );
SkipSpaces(&ptr);
if (',' != *ptr)
{
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
}
else SkipSpaces(ptr+1,&ptr);
} else {
SkipSpaces(ptr + 1, &ptr);
}
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.y );
SkipSpaces(&ptr);
if (',' != *ptr)
{
if (',' != *ptr) {
ASSIMP_LOG_ERROR("IRR(MESH): Expected comma in vector definition");
}
else SkipSpaces(ptr+1,&ptr);
} else {
SkipSpaces(ptr + 1, &ptr);
}
ptr = fast_atoreal_move<float>( ptr,(float&)out.value.z );
}
}
@@ -196,22 +158,19 @@ void IrrlichtBase::ReadVectorProperty (VectorProperty& out)
// ------------------------------------------------------------------------------------------------
// Convert a string to a proper aiMappingMode
int ConvertMappingMode(const std::string& mode)
{
if (mode == "texture_clamp_repeat")
{
int ConvertMappingMode(const std::string& mode) {
if (mode == "texture_clamp_repeat") {
return aiTextureMapMode_Wrap;
}
else if (mode == "texture_clamp_mirror")
return aiTextureMapMode_Mirror;
} 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* IrrlichtBase::ParseMaterial(unsigned int& matFlags) {
aiMaterial* mat = new aiMaterial();
aiColor4D clr;
aiString s;
@@ -220,244 +179,170 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
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:
for (pugi::xml_node child : mNode->children()) {
if (!ASSIMP_stricmp(child.name(), "color")) { // Hex properties
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);
}
// 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.
// 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);
}
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 {
ASSIMP_LOG_WARN("IRRMat: Unrecognized material type: " + prop.value);
}
}
} else if (!ASSIMP_stricmp(child.name(), "float")) { // Float properties
FloatProperty prop;
ReadFloatProperty(prop);
if (prop.name == "Shininess") {
mat->AddProperty(&prop.value, 1, AI_MATKEY_SHININESS);
}
} else if (!ASSIMP_stricmp(child.name(), "bool")) { // Bool properties
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);
}
} else if (!ASSIMP_stricmp(child.name(), "texture") ||
!ASSIMP_stricmp(child.name(), "enum")) { // String properties - textures and texture related properties
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;
} else if (prop.value == "normalmap_solid" ||
prop.value == "parallaxmap_solid") { // Normal and parallax maps are treated equally
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 {
ASSIMP_LOG_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));
// 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;
} else if (matFlags & AI_IRRMESH_MAT_normalmap_solid) { // alternatively: normal or parallax mapping
++cnt;
s.Set(prop.value);
mat->AddProperty(&s, AI_MATKEY_TEXTURE_NORMALS(0));
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else if (matFlags & AI_IRRMESH_MAT_solid_2layer) {// or just as second diffuse texture
++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 if (matFlags & AI_IRRMESH_MAT_solid_2layer) { // or just as second diffuse texture
++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 {
ASSIMP_LOG_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));
}
// set the corresponding material flag
matFlags |= AI_IRRMESH_EXTRA_2ND_TEXTURE;
} else {
ASSIMP_LOG_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:
// 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"))
// Assume there are no further nested nodes in <material> elements
if ( !ASSIMP_stricmp(reader->getNodeName(),"material") ||
!ASSIMP_stricmp(reader->getNodeName(),"attributes"))
{
// Now process lightmapping flags
// We should have at least one textur to do that ..
@@ -492,7 +377,8 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
// GCC complains here ...
break;
}
}
}*/
}
ASSIMP_LOG_ERROR("IRRMESH: Unexpected end of file. Material is not complete");
return mat;
+45 -44
View File
@@ -7,50 +7,48 @@
#ifndef INCLUDED_AI_IRRSHARED_H
#define INCLUDED_AI_IRRSHARED_H
#include <assimp/irrXMLWrapper.h>
#include <assimp/BaseImporter.h>
#include <assimp/XmlParser.h>
#include <stdint.h>
struct aiMaterial;
namespace Assimp {
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
#define AI_IRRMESH_MAT_solid_2layer 0x10000
// Transparency flags
#define AI_IRRMESH_MAT_trans_vertex_alpha 0x1
#define AI_IRRMESH_MAT_trans_add 0x2
#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)
#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)
#define AI_IRRMESH_MAT_normalmap_solid (0x100)
// Normal map combined with vertex alpha
#define AI_IRRMESH_MAT_normalmap_tva \
#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 \
#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
#define AI_IRRMESH_EXTRA_2ND_TEXTURE 0x100000
// ---------------------------------------------------------------------------
/** Base class for the Irr and IrrMesh importers.
@@ -58,61 +56,64 @@ extern const aiMatrix4x4 AI_TO_IRR_MATRIX;
* Declares some irrlight-related xml parsing utilities and provides tools
* to load materials from IRR and IRRMESH files.
*/
class IrrlichtBase
{
class IrrlichtBase {
protected:
IrrlichtBase() :
mNode(nullptr) {
// empty
}
~IrrlichtBase() {
// empty
}
/** @brief Data structure for a simple name-value property
*/
template <class T>
struct Property
{
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;
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;
/// XML reader instance
XmlParser mParser;
pugi::xml_node *mNode;
// -------------------------------------------------------------------
/** Parse a material description from the XML
* @return The created material
* @param matFlags Receives AI_IRRMESH_MAT_XX flags
*/
aiMaterial* ParseMaterial(unsigned int& matFlags);
aiMaterial *ParseMaterial(unsigned int &matFlags);
// -------------------------------------------------------------------
/** Read a property of the specified type from the current XML element.
* @param out Receives 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);
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)
{
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;
clr.g = ((in >> 8) & 0xff) / 255.f;
clr.b = ((in)&0xff) / 255.f;
}
} // end namespace Assimp
#endif // !! INCLUDED_AI_IRRSHARED_H
+3 -3
View File
@@ -145,7 +145,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWO file " + pFile + ".");
throw DeadlyImportError("Failed to open LWO file ", pFile, ".");
}
if ((this->fileSize = (unsigned int)file->FileSize()) < 12) {
@@ -212,7 +212,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
szBuff[2] = (char)(fileType >> 8u);
szBuff[3] = (char)(fileType);
szBuff[4] = '\0';
throw DeadlyImportError(std::string("Unknown LWO sub format: ") + szBuff);
throw DeadlyImportError("Unknown LWO sub format: ", szBuff);
}
if (AI_LWO_FOURCC_LWOB != fileType) {
@@ -232,7 +232,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
}
if (configLayerName.length() && !hasNamedLayer) {
throw DeadlyImportError("LWO2: Unable to find the requested layer: " + configLayerName);
throw DeadlyImportError("LWO2: Unable to find the requested layer: ", configLayerName);
}
}
+11 -6
View File
@@ -502,7 +502,7 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open LWS file " + pFile + ".");
throw DeadlyImportError("Failed to open LWS file ", pFile, ".");
}
// Allocate storage and copy the contents of the file to a memory buffer
@@ -750,12 +750,17 @@ void LWSImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
}
// '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)
if (nodes.empty() || nodes.back().type != LWS::NodeDesc::LIGHT) {
ASSIMP_LOG_ERROR("LWS: Unexpected keyword: \'LightIntensity\'");
else
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
} else {
const std::string env = "(envelope)";
if (0 == strncmp(c, env.c_str(), env.size())) {
ASSIMP_LOG_ERROR("LWS: envelopes for LightIntensity not supported, set to 1.0");
nodes.back().lightIntensity = (ai_real)1.0;
} else {
fast_atoreal_move<float>(c, nodes.back().lightIntensity);
}
}
}
// 'LightType': set type of currently active light
else if ((*it).tokens[0] == "LightType") {
+5 -2
View File
@@ -197,12 +197,15 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
break;
case m3dpf_float:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
aiProps[k].index, f) == AI_SUCCESS)
aiProps[k].index, f) == AI_SUCCESS) {
uint32_t f_uint32;
memcpy(&f_uint32, &f, sizeof(uint32_t));
addProp(&m3d->material[mi],
m3d_propertytypes[k].id,
/* not (uint32_t)f, because we don't want to convert
* it, we want to see it as 32 bits of memory */
*((uint32_t *)&f));
f_uint32);
}
break;
case m3dpf_uint8:
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
+5 -5
View File
@@ -160,21 +160,21 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
// Read file into memory
std::unique_ptr<IOStream> pStream(pIOHandler->Open(file, "rb"));
if (!pStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
// Get the file-size and validate it, throwing an exception when fails
size_t fileSize = pStream->FileSize();
if (fileSize < 8) {
throw DeadlyImportError("M3D-file " + file + " is too small.");
throw DeadlyImportError("M3D-file ", file, " is too small.");
}
std::vector<unsigned char> buffer(fileSize);
if (fileSize != pStream->Read(buffer.data(), 1, fileSize)) {
throw DeadlyImportError("Failed to read the file " + file + ".");
throw DeadlyImportError("Failed to read the file ", file, ".");
}
// extra check for binary format's first 8 bytes. Not done for the ASCII variant
if (!memcmp(buffer.data(), "3DMO", 4) && memcmp(buffer.data() + 4, &fileSize, 4)) {
throw DeadlyImportError("Bad binary header in file " + file + ".");
throw DeadlyImportError("Bad binary header in file ", file, ".");
}
#ifdef M3D_ASCII
// make sure there's a terminator zero character, as input must be ASCIIZ
@@ -200,7 +200,7 @@ void M3DImporter::InternReadFile(const std::string &file, aiScene *pScene, IOSys
M3DWrapper m3d(pIOHandler, buffer);
if (!m3d) {
throw DeadlyImportError("Unable to parse " + file + " as M3D.");
throw DeadlyImportError("Unable to parse ", file, " as M3D.");
}
// create the root node
+3
View File
@@ -133,6 +133,9 @@ unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
saved_output_ = m3d_save(m3d_, quality, flags, &size);
return saved_output_;
#else
(void)quality;
(void)flags;
(void)size;
return nullptr;
#endif
}
+11 -11
View File
@@ -686,7 +686,11 @@ typedef struct
} _m3dstbi__result_info;
#define STBI_ASSERT(v)
#define STBI_NOTUSED(v) (void)sizeof(v)
#ifdef _MSC_VER
#define STBI_NOTUSED(v) (void)(v)
#else
#define STBI_NOTUSED(v) (void)sizeof(v)
#endif
#define STBI__BYTECAST(x) ((unsigned char)((x)&255))
#define STBI_MALLOC(sz) M3D_MALLOC(sz)
#define STBI_REALLOC(p, newsz) M3D_REALLOC(p, newsz)
@@ -699,10 +703,6 @@ _inline static unsigned char _m3dstbi__get8(_m3dstbi__context *s) {
return 0;
}
_inline static int _m3dstbi__at_eof(_m3dstbi__context *s) {
return s->img_buffer >= s->img_buffer_end;
}
static void _m3dstbi__skip(_m3dstbi__context *s, int n) {
if (n < 0) {
s->img_buffer = s->img_buffer_end;
@@ -3590,7 +3590,7 @@ m3d_t *m3d_load(unsigned char *data, m3dread_t readfilecb, m3dfree_t freecb, m3d
case 4: f = (float)(*((float *)(data + 0))); break;
case 8: f = (float)(*((double *)(data + 0))); break;
}
h->cmd[i].arg[k] = *((uint32_t *)&f);
memcpy(&(h->cmd[i].arg[k]), &f, sizeof(uint32_t));
data += model->vc_s;
break;
case m3dcp_hi_t: data = _m3d_getidx(data, model->hi_s, &h->cmd[i].arg[k]); break;
@@ -4347,7 +4347,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
char vc_s, vi_s, si_s, ci_s, ti_s, bi_s, nb_s, sk_s, fc_s, hi_s, fi_s;
char *sn = NULL, *sl = NULL, *sa = NULL, *sd = NULL;
unsigned char *out = NULL, *z = NULL, weights[M3D_NUMBONE], *norm = NULL;
unsigned int i, j, k, l, n, len, chunklen, *length;
unsigned int i = 0, j = 0, k = 0, l = 0, n = 0, len = 0, chunklen = 0, *length = NULL;
M3D_FLOAT scale = (M3D_FLOAT)0.0, min_x, max_x, min_y, max_y, min_z, max_z;
M3D_INDEX last, *vrtxidx = NULL, *mtrlidx = NULL, *tmapidx = NULL, *skinidx = NULL;
uint32_t idx, numcmap = 0, *cmap = NULL, numvrtx = 0, maxvrtx = 0, numtmap = 0, maxtmap = 0, numproc = 0;
@@ -5578,9 +5578,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
} else
out--;
break;
case m3dpf_uint8: *out++ = m->prop[i].value.num; break;
case m3dpf_uint8: *out++ = (uint8_t)m->prop[i].value.num; break;
case m3dpf_uint16:
*((uint16_t *)out) = m->prop[i].value.num;
*((uint16_t *)out) = (uint16_t)m->prop[i].value.num;
out += 2;
break;
case m3dpf_uint32:
@@ -5655,7 +5655,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
face[i].data.normal[1] == M3D_UNDEF || face[i].data.normal[2] == M3D_UNDEF) ?
0 :
2);
*out++ = k;
*out++ = (uint8_t)k;
for (j = 0; j < 3; j++) {
out = _m3d_addidx(out, vi_s, vrtxidx[face[i].data.vertex[j]]);
if (k & 1)
@@ -6149,7 +6149,7 @@ public:
#endif /* M3D_CPPWRAPPER */
#ifdef _MSC_VER
#if _MSC_VER > 1920 && !defined(__clang__)
# pragma warning(pop)
#endif /* _MSC_VER */
+1 -1
View File
@@ -222,7 +222,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD2 file " + pFile + "");
throw DeadlyImportError("Failed to open MD2 file ", pFile, "");
}
// check whether the md3 file is large enough to contain
+1 -1
View File
@@ -715,7 +715,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MD3 file " + pFile + ".");
throw DeadlyImportError("Failed to open MD3 file ", pFile, ".");
}
// Check whether the md3 file is large enough to contain the header
+1 -1
View File
@@ -675,7 +675,7 @@ void MD5Importer::LoadMD5CameraFile() {
// Check whether we can read from the file
if (!file.get() || !file->FileSize()) {
throw DeadlyImportError("Failed to read MD5CAMERA file: " + pFile);
throw DeadlyImportError("Failed to read MD5CAMERA file: ", pFile);
}
mHadMD5Camera = true;
LoadFileIntoMemory(file.get());
+1 -1
View File
@@ -219,7 +219,7 @@ void MDCImporter::InternReadFile(
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDC file " + pFile + ".");
throw DeadlyImportError("Failed to open MDC file ", pFile, ".");
}
// check whether the mdc file is large enough to contain the file header
+2 -2
View File
@@ -218,12 +218,12 @@ private:
template <typename MDLFileHeader>
void HL1MDLLoader::load_file_into_buffer(const std::string &file_path, unsigned char *&buffer) {
if (!io_->Exists(file_path))
throw DeadlyImportError("Missing file " + DefaultIOSystem::fileName(file_path) + ".");
throw DeadlyImportError("Missing file ", DefaultIOSystem::fileName(file_path), ".");
std::unique_ptr<IOStream> file(io_->Open(file_path));
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + DefaultIOSystem::fileName(file_path) + ".");
throw DeadlyImportError("Failed to open MDL file ", DefaultIOSystem::fileName(file_path), ".");
}
const size_t file_size = file->FileSize();
+3 -3
View File
@@ -167,7 +167,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (file.get() == nullptr) {
throw DeadlyImportError("Failed to open MDL file " + pFile + ".");
throw DeadlyImportError("Failed to open MDL file ", pFile, ".");
}
// This should work for all other types of MDL files, too ...
@@ -251,8 +251,8 @@ void MDLImporter::InternReadFile(const std::string &pFile,
}
} 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");
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
+2 -2
View File
@@ -111,7 +111,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
// Read file by istream
std::filebuf fb;
if (!fb.open(file, std::ios::in | std::ios::binary)) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
std::istream fileStream(&fb);
@@ -122,7 +122,7 @@ void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
fileStream.seekg(0, fileStream.beg);
if (fileSize < sizeof(pmx::PmxModel)) {
throw DeadlyImportError(file + " is too small.");
throw DeadlyImportError(file, " is too small.");
}
pmx::PmxModel model;
+1 -1
View File
@@ -524,7 +524,7 @@ namespace pmx
if (version != 2.0f && version != 2.1f)
{
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", to_string(version));
}
this->setting.Read(stream);
+1 -1
View File
@@ -229,7 +229,7 @@ void MS3DImporter::InternReadFile( const std::string& pFile,
stream.CopyAndAdvance(head,10);
stream >> version;
if (strncmp(head,"MS3D000000",10)) {
throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: "+pFile);
throw DeadlyImportError("Not a MS3D file, magic string MS3D000000 not found: ", pFile);
}
if (version != 4) {
+7 -7
View File
@@ -96,7 +96,7 @@ const aiImporterDesc *NFFImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_FLOAT(f) \
SkipSpaces(&sz); \
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<float>(sz, (float &)f);
if (!::IsLineEnd(*sz)) sz = fast_atoreal_move<ai_real>(sz, (ai_real &)f);
// ------------------------------------------------------------------------------------------------
#define AI_NFF_PARSE_TRIPLE(v) \
@@ -214,7 +214,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// Check whether we can read from the file
if (!file.get())
throw DeadlyImportError("Failed to open NFF file " + pFile + ".");
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)
@@ -233,7 +233,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// camera parameters
aiVector3D camPos, camUp(0.f, 1.f, 0.f), camLookAt(0.f, 0.f, 1.f);
float angle = 45.f;
ai_real angle = 45.f;
aiVector2D resolution;
bool hasCam = false;
@@ -262,7 +262,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// check whether this is the NFF2 file format
if (TokenMatch(buffer, "nff", 3)) {
const float qnan = get_qnan();
const ai_real qnan = get_qnan();
const aiColor4D cQNAN = aiColor4D(qnan, 0.f, 0.f, 1.f);
const aiVector3D vQNAN = aiVector3D(qnan, 0.f, 0.f);
@@ -706,7 +706,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
}
// 'f' - shading information block
else if (TokenMatch(sz, "f", 1)) {
float d;
ai_real d;
// read the RGB colors
AI_NFF_PARSE_TRIPLE(s.color);
@@ -856,7 +856,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
// read the two center points and the respective radii
aiVector3D center1, center2;
float radius1 = 0.f, radius2 = 0.f;
ai_real radius1 = 0.f, radius2 = 0.f;
AI_NFF_PARSE_TRIPLE(center1);
AI_NFF_PARSE_FLOAT(radius1);
@@ -874,7 +874,7 @@ void NFFImporter::InternReadFile(const std::string &pFile,
curMesh.dir = center2 - center1;
curMesh.center = center1 + curMesh.dir / (ai_real)2.0;
float f;
ai_real f;
if ((f = curMesh.dir.Length()) < 10e-3f) {
ASSIMP_LOG_ERROR("NFF: Cone height is close to zero");
continue;
+3 -3
View File
@@ -113,14 +113,14 @@ private:
{}
aiColor3D color,diffuse,specular,ambient,emissive;
float refracti;
ai_real refracti;
std::string texFile;
// For NFF2
bool twoSided;
bool shaded;
float opacity, shininess;
ai_real opacity, shininess;
std::string name;
@@ -155,7 +155,7 @@ private:
{}
aiVector3D position;
float intensity;
ai_real intensity;
aiColor3D color;
};
+1 -1
View File
@@ -123,7 +123,7 @@ void OFFImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
// Check whether we can read from the file
if( file.get() == nullptr) {
throw DeadlyImportError( "Failed to open OFF file " + pFile + ".");
throw DeadlyImportError( "Failed to open OFF file ", pFile, ".");
}
// allocate storage and copy the contents of the file to a memory buffer
+20 -15
View File
@@ -75,7 +75,9 @@ using namespace std;
// ------------------------------------------------------------------------------------------------
// Default constructor
ObjFileImporter::ObjFileImporter() :
m_Buffer(), m_pRootObject(nullptr), m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
m_Buffer(),
m_pRootObject(nullptr),
m_strAbsPath(std::string(1, DefaultIOSystem().getOsSeparator())) {}
// ------------------------------------------------------------------------------------------------
// Destructor.
@@ -107,9 +109,12 @@ const aiImporterDesc *ObjFileImporter::GetInfo() const {
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));
auto streamCloser = [&](IOStream *pStream) {
pIOHandler->Close(pStream);
};
std::unique_ptr<IOStream, decltype(streamCloser)> fileStream(pIOHandler->Open(file, mode), streamCloser);
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
throw DeadlyImportError("Failed to open file ", file, ".");
}
// Get the file-size and validate it, throwing an exception when fails
@@ -589,18 +594,18 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
// 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;
ASSIMP_LOG_ERROR("OBJ: unexpected illumination model (0-2 recognized)");
case 0:
sm = aiShadingMode_NoShading;
break;
case 1:
sm = aiShadingMode_Gouraud;
break;
case 2:
sm = aiShadingMode_Phong;
break;
default:
sm = aiShadingMode_Gouraud;
ASSIMP_LOG_ERROR("OBJ: unexpected illumination model (0-2 recognized)");
}
mat->AddProperty<int>(&sm, 1, AI_MATKEY_SHADING_MODEL);
+6 -2
View File
@@ -137,10 +137,14 @@ void ObjFileMtlImporter::load() {
} break;
case 'T': {
++m_DataIt;
if (*m_DataIt == 'f') // Material transmission
{
// Material transmission color
if (*m_DataIt == 'f') {
++m_DataIt;
getColorRGBA(&m_pModel->m_pCurrentMaterial->transparent);
} else if (*m_DataIt == 'r') {
// Material transmission alpha value
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->alpha);
}
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
} break;
-29
View File
@@ -234,35 +234,6 @@ inline char_t getFloat(char_t it, char_t end, ai_real &value) {
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) {
Loaded 100 of 262 files, more files were not shown because too many files have changed in this diff. Show more