Compare commits

..
Author SHA1 Message Date
Kim Kulling 676ef9637b glFT2: Fix texture size in export. 2025-03-11 13:04:10 +01:00
UnionTech-Software 70459b4d1f Fix memory leak in OpenGEXImporter (#6036) 2025-03-10 16:24:26 +01:00
Kim Kulling 45898eee55 Refactorings: glTF cleanups (#6028) 2025-03-05 21:37:47 +01:00
Kim Kulling f52fcb6052 Obj: remove smooth-normals postprocessing (#6031)
- closes https://github.com/assimp/assimp/issues/5514
2025-03-03 09:44:35 +01:00
Kim Kulling 2bce77f909 IFC: Remove redundand check (#6006)
- closes https://github.com/assimp/assimp/issues/5798
2025-02-22 21:34:51 +01:00
Kim Kulling 5d716b8fe0 Bugfix/fix mingw issue 5975 (#6005)
* MDL: Ensure alignment of bool vector
2025-02-20 21:20:11 +01:00
fishguy6564 b58afb7b83 Fixing PyAssimp misalignment errors with certain structures (#6001)
* Fixed misaligned structures in PyAssimp

* Added documentation on missing aiBone fields
2025-02-17 20:41:07 +01:00
StefanandKim Kulling 7945359a5c Use ear-cutting library for triangulation (#5977)
* Use ear-cutting library for triangulation

Fixes #3609
Fixes #3019
Fixes #1136

* Fix typo

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-02-13 11:24:59 +01:00
Kim Kulling 9bb6f2e1b8 Use correct data type for animation key (#5998) 2025-02-12 00:26:01 +01:00
Kim Kulling 7efb98db27 Doc: Separate viewer (#5995) 2025-02-07 21:17:59 +01:00
Kim Kulling f967e76493 Update Readme.md: Add new viewer (#5991)
- Add the Qt5 Modelviewer to the readme
2025-02-05 13:49:17 +01:00
mosfet80andKim Kulling d41511bf8a Update STEPFileReader.cpp (#5973)
Clean code

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-02-03 11:27:31 +01:00
Kim Kulling 53b5dba4df Doc: Make hint clearer (#5988)
-closes https://github.com/assimp/assimp/issues/5981
2025-01-31 09:53:13 +01:00
Spencer EvansandKim Kulling 9f3cd51a87 corrected postprocess FlipUVs flag documentation x coord (#5978)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-26 21:08:46 +01:00
bc47836a8f fix: reduce gltf2 export time (#5972)
* fix: reduce gltf2 export time

* fix: use std::less<> in std::map

---------

Co-authored-by: huangxinchuang <huangxinchuang@pointcode.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-25 21:50:33 +01:00
Steve MandSteve M 2aac984fa3 Add gltf metallic-roughness texture type (#5968)
* Introduce gltf metallic-roughness texture type

* Add to unit test, add doc citation

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2025-01-24 21:08:29 +01:00
PichasandKim Kulling 31f0dcb4d1 add EXCLUDE_FROM_ALL (#5959)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-22 16:28:43 +01:00
tyler92andKim Kulling f13197921b Fix heap buffer overflow in PLY parser (#5956)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-22 15:18:56 +01:00
Mike Chemistruck d91e0e4f42 Add POST_BUILD option to ADD_CUSTOM_COMMAND (#5962)
This commit fixes a set of warnings from the latest version of CMake:

(ADD_CUSTOM_COMMAND):
  Exactly one of PRE_BUILD, PRE_LINK, or POST_BUILD must be given.  Assuming
  POST_BUILD to preserve backward compatibility.

  Policy CMP0175 is not set: add_custom_command() rejects invalid arguments.
  Run "cmake --help-policy CMP0175" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.
This warning is for project developers.  Use -Wno-dev to suppress it.
2025-01-22 11:41:11 +01:00
ba4455c9c0 Added GLTF Extension KHR_materials_anisotropy (#5950)
* added gltf extension KHR_materials_anisotropy

* Update glTF2Importer.cpp

---------

Co-authored-by: lutz.hoeren <lutz.hoeren@redplant.de>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-21 00:02:46 +01:00
Kim Kulling 79d451bf4b Avoid exporting all primitives, which are not triangles. (#5964) 2025-01-17 19:28:12 +01:00
BurntRanchandKim Kulling 2a0969d4d9 Add customExtension support to the scene (#5954)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-17 16:09:23 +01:00
David Campos RodríguezandKim Kulling 1e44036c36 Prefix MTL textures with the MTL directory path (#5928)
* Prefix MTL textures with the MTL directory path.

Path to textures defined in MTL files are relative to the MTL
file rather than to the OBJ, so we need to prefix them with the
MTL file directory path.

* Adding test issue 2355

* Trying to fix for Windows when file has Linux path

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-15 10:03:32 +01:00
Engin ManapandKim Kulling 2f6dcdfd72 Assimp master head fixes for failure to compile (#5899)
* Fix unknown pragma error on msys2 mingw

* Fix missing assignment operator on msys2 mingw

Default is omitted by compiler because custom copy constructor

* Fix redefinition of _1 and _2 error on msys2 mingw

fix is converting it to lambda as clang is claiming that is
preferred

* Fix strncpy warnings about truncation

* Fix missing assignment operator error on clang

* Update glTFImporter.cpp

* Update glTF2Importer.cpp

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-14 14:23:02 +01:00
Julian KnodtandKim Kulling e722420907 [FBX] Allow export multi materials per node (#5888)
* [FBX] Allow export multi materials per node

Previously it was assumed that each node would export a single material. This removes that
assumption, and also allows for exporting multiple meshes with a single node. Previously they
would each be seprated into their own node.

* Support for animations with multiple meshes too

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-14 11:37:16 +01:00
8e44b40df4 [AMF] Fix texture mapping (#5949)
* Fix texture mapping

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-12 23:04:10 +01:00
Kim Kulling 5aa38fe3cd Update OpenDDLParser.cpp (#5953) 2025-01-10 18:28:22 +01:00
tyler92 0834fed661 Add aiProcess_ValidateDataStructure flag to the fuzzer (#5951) 2025-01-10 13:07:11 +01:00
f2c6aa15ed Add arm64-simulator support to iOS build script (#5920)
Co-authored-by: Dwayne Coussement <dwayne.coussement@showpad.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-08 14:34:05 +01:00
Kim KullingandKim Kulling 5fa7b8ceb9 Bugfix/cosmetic code cleanup (#5947)
* Refactorings: Code cleanups

* More cosmetic changes

---------

Co-authored-by: Kim Kulling <kim.kulling@draeger.com>
2025-01-07 23:32:50 +01:00
Kim KullingandKim Kulling d386309af9 Fix unittest path (#5948)
Co-authored-by: Kim Kulling <kim.kulling@draeger.com>
2025-01-06 23:03:59 +01:00
Jackson Levitt 2f40a77ae1 Updated Material.cpp to add missing cases (#5945) 2025-01-06 13:02:55 +01:00
David Campos RodríguezandKim Kulling a4d8a5fec3 AssbinImporter::ReadInternFile now closes stream before throwing (#5927)
While one of the throws in the function did indeed close the open stream,
several didn't.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-03 21:38:27 +01:00
stekap000 bbeb515421 pragma warning bug fix when using g++ on windows (#5943) 2025-01-03 19:50:18 +01:00
tyler92 437b484070 Fix heap buffer overflow in HMP loader (#5939) 2025-01-01 17:40:18 +01:00
tyler92andKim Kulling d70606bfb6 Verify negative values in Quake1 MDL header (#5940)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2025-01-01 01:55:05 +01:00
69558d8889 Introduce VRML format (.wrl and .x3dv) 3D model support (#5857)
- Introduce VRML format (.wrl and .x3dv) 3D model support
- Add samples
---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-30 11:56:18 +01:00
tyler92andKim Kulling 5e091572d5 Fix stack overflow in LWS loader (#5941)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-30 11:15:50 +01:00
David Campos RodríguezandKim Kulling ab5b32ecc7 Fix docs for aiImportFileExWithProperties. (#5925)
The docs talked about the importer, but no importer exists in the
context of calling this function. It seems like the docs may have been
accidentally copied from somewhere else.
I copied the docs from another import function within the same file.
This seems reasonable because the implementations of both functions
suggest they work the same way: the function creates the importer and
sets it into the scene private data so that the later release call can
release the importer.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-29 20:23:02 +01:00
tyler92andKim Kulling 7bd54e3604 Disable logs for fuzzer by default (#5938)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-25 20:19:42 +01:00
Julian KnodtandKim Kulling 258cdfd2bc Export tangents in GLTF (#5900)
Previously tangents were not being exported. If they are present, they should also be properly
exported.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-23 21:57:13 +01:00
David Campos RodríguezandKim Kulling 016be03c3d glTF importers: Avoid strncpy truncating away the ' \0' character (#5931)
* Fixing building errors from job https://github.com/assimp/assimp/actions/runs/12403918024/job/34628244451?pr=5928

* Adding some asserts for future mantainability, although a bit paranoic maybe

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-23 16:55:17 +01:00
Kim Kulling 1ce3164bc2 Bug/evaluate matrix4x4 access (#5936)
* Add test for 3x3 matrices and 4x4 matrix access
2024-12-23 16:33:37 +01:00
Kim Kulling 9f3a7e95ab Fix: Fix name collision (#5937)
* Fix: Fix name collision

* Fix: Fix possible override

* Fix: Use reentrant providing time function

* Fix: Fix override

* Update AssbinFileWriter.cpp

Revert, not portable.

* Update AssxmlFileWriter.cpp

Revert asctime_r, not portable.
2024-12-23 12:23:42 +01:00
tyler92andKim Kulling ecc8a1c869 Fix buffer overflow in MD5Parser::SkipSpacesAndLineEnd (#5921)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-17 18:57:54 +01:00
Sebastian SchäferandKim Kulling 2090508c34 Fix parsing of comments at the end of lines for tokens with variable number of elements. (#5890) (#5891)
* Fix parsing of comments at the end of lines for tokens with variable number of elements. (#5890)

* Fixed Quality Gate issues.

Reduced nesting of the break statements.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-17 18:17:02 +01:00
tyler92andKim Kulling 2b773f0f5a Fix heap-buffer-overflow in OpenDDLParser (#5919)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-16 22:48:45 +01:00
Stefan 7a114059cd Replace C# port with maintained fork (#5922) 2024-12-16 13:02:15 +01:00
saceredaandKim Kulling 862abe410b Fixed warnings (#5903)
* Fixed conversion warning when compiling without ASSIMP_DOUBLE_PRECISION. Fixed size() <> unsigned warnings

* Fix: Review finding

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-12 20:58:08 +01:00
Gene Walters 76d22e5fbe USD updates: properly place meshes into nodes (instead of all meshes getting added to the rool node). Adding animation framerate. (#5915)
Signed-off-by: AMZN-Gene <genewalt@amazon.com>
2024-12-11 16:32:40 +01:00
tyler92andKim Kulling f12e521986 Fix use after free in the CallbackToLogRedirector (#5918)
The heap-use-after-free vulnerability occurs in the
CallbackToLogRedirector function. During the process of logging,
a previously freed memory region is accessed, leading to a
use-after-free condition. This vulnerability stems from incorrect
memory management, specifically, freeing a log stream and then
attempting to access it later on.

This patch sets NULL value for The DefaultStream global pointer.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-11 11:17:14 +01:00
Kim Kulling 28ebc8452b Fix: Fix build for mingw10 (#5916)
- closes https://github.com/assimp/assimp/issues/5827
2024-12-10 23:40:02 +01:00
Kursat AktasandKim Kulling 46c26eda5a Introducing assimp Guru on Gurubase.io (#5887)
Signed-off-by: Kursat Aktas <kursat.ce@gmail.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-05 22:54:43 +01:00
Elijah NicolandKim Kulling bddc374b5a Validate mesh in WriteMesh before AttributeBegin call (#5884)
If mesh is validated after AttributeBegin call, then
the AttributeBegin is never closed with an
AttributeEnd, causing problems in pbrt.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-05 11:10:46 +01:00
HandsomeXiandKim Kulling 164a5ae8cf bugfix: Fixed the issue that draco compressed gltf files cannot be loaded normally (#5882) (#5883)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-04 22:03:57 +01:00
Julian KnodtandKim Kulling ff61095928 Blendshape export float & same # verts (#5775)
Previously it was possible that the number of vertices between the mesh and morph mesh varied.
This may have caused problems in tools like Blender, and this ensures there's a 1-1
correspondence between vertices.

In addition, exporting doubles broke meshlab on import, so now it exports floats.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-02 23:04:44 +01:00
Julian KnodtandKim Kulling ca17cdc1f9 Do not create GLTF Mesh if no faces (#5878)
Previously GLTF meshes were created even if there were no faces, which lead to GLTFs which were not technically valid.

I believe this fixes the problem I was encountering, but I've not been able to test it because of some Mac compile errors. Will test on a windows machine at some point.

Fixes #5868

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-01 21:21:08 +01:00
StefanandKim Kulling 739ebfd207 Synchronize DefaultLogger (#5898)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-12-01 20:35:24 +01:00
72c51a9997 Convert float to ai_real, (#5902)
Co-authored-by: ali turan <ali.turan@simsoft.com.tr>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-29 20:54:24 +01:00
2493deff37 USD Keyframe Animations (#5856)
USD Keyframe Animations

Signed-off-by: AMZN-Gene <genewalt@amazon.com>
Signed-off-by: Gene Walters <genewalt@amazon.com>
Co-authored-by: Kazuki Y <6259214+kazu0617@users.noreply.github.com>
Co-authored-by: kazu0617 <kazu0617@protonmail.com>
Co-authored-by: Kim Kulling <kim.kulling@googlemail.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-28 21:29:58 +01:00
12f3309996 Simplify JoinVerticesProcess (#5895)
Previously JoinVertices had a lot of extra complexity, simplify it greatly.

Co-authored-by: Julian Knodt <julianknodt@Julians-Air-2.attlocal.net>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-27 22:53:27 +01:00
StefanandKim Kulling 02d3887e9a Add CI to automatically build and attach binaries to releases (#5892)
* Add CI to automatically build and attach binaries to releases

* Correctly label arm64 MacOS and add x64 variation

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-26 22:57:44 +01:00
mosfet80andKim Kulling 09f6a5e136 Update cpp-pm / hunter (#5885)
OpenCV and dependencies update to v4.10.0-p0

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-25 21:58:33 +01:00
Kim Kulling 5f100a0984 Obj: fix nullptr access. (#5894) 2024-11-25 19:58:58 +01:00
Kim Kulling 795d4897db Readme.md: Add sonarcube q batch (#5893)
- Add sonarcube quality badge
2024-11-25 14:48:12 +01:00
Kim Kulling 6fad13c82b Cleanup: Delete code/.editorconfig (#5889) 2024-11-22 11:38:51 +01:00
Julian KnodtandKim Kulling 48bd7c3e22 Check that mMaterials not null before access (#5874)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-20 23:26:07 +01:00
Matt IselinandKim Kulling c867ddbc04 Fix potential uninitialized variable in clipper (#5881)
* Fix potential uninitialized variable in clipper

* Clipper: Fix second parameter as well.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-19 23:31:47 +01:00
Kim Kulling 41cc2f66a4 Remove strcpy. (#5802)
* Remove strcpy.

* Sonarcube: Add more strcpy replacements

* BlenderLoader: Replace strncpy by memcpy
2024-11-18 16:54:58 +01:00
Kim Kulling f5fb8ff842 Material: Fix sonarcube finding (#5880)
* Material: Fix sonarcube finding

- Use nullptr instead of 0x0 to simulate NULL.

* Material: Use NULL for c-code
2024-11-18 14:31:35 +01:00
Kim Kulling c9bbbcf633 Material: Fix the build for c compiler (#5879)
- Mark inlined functions as static inline to fix the linkage for c compilers
- closes https://github.com/assimp/assimp/issues/5875
2024-11-18 09:36:32 +01:00
David Campos RodríguezandKim Kulling e7a6d33365 Try to resolve image paths by replacing backslashes or forward slashes in EmbedTexturesProcess (#5844)
* Try to resolve image paths by replacing backslashes.

* Some changes suggested by CI

* Removed usage of <filesystem>.

* Removing usage of C++20/C++23 features

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-14 21:10:03 +01:00
Kim Kulling 9723b3554b Obj: Fix Sonarcube findings (#5873)
* Obj: Fix Sonarcube findings
2024-11-11 13:06:51 +01:00
f7bb1bc170 Add reference screenshots for complex bundled test 3D model files (#5822)
Feature: Add reference screenshots for complex bundled test 3D model files

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-08 16:09:00 +01:00
jwblaandKim Kulling 9694f7e8e4 Update CMakeLists.txt to fix gcc/clang++ issue (#5863)
This resolves an issue where using GCC as your C compiler but, say, clang++ as your CXX compiler produces
`error: unknown warning option '-Wno-dangling-reference' [-Werror,-Wunknown-warning-option]`

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-06 11:34:21 +01:00
Marco Feuerstein 6520354a58 Fix use of uninitialized value. (#5867)
If the stat command fails, statbuf is uninitialized.
2024-11-06 10:54:14 +01:00
Tobias Rittig, Ph.D.andKim Kulling e06b80f6b0 +Add vertex duplication during face normal generation (#5805)
* +Add vertex duplication during face normal generation
`aiProcess_GenNormals` PostProcess now duplicates vertices if they are referenced by more than one polygon which results in the correct faceted appearance.

* Update GenFaceNormalsProcess.cpp

- Fix old spellings
- Use static_cast instead of c-style casts

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-11-02 09:03:59 +01:00
Steve MandSteve M 401279e2f9 Update tinyusdz (#5849)
* Update tinyusdz to latest git commit

* Update patch file

* Bump to latest tinyusdz version

* Remove unused var (fix broken build for clients treating warnings-as-errors)

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-11-01 11:33:50 +01:00
Gene Walters 7634cf84ca USD Skinned Mesh (#5812)
USD: Skinned Mesh support
2024-10-31 21:48:28 +01:00
Gene WaltersandKim Kulling ec563823b6 Cleanup unit tests that export files by making sure those files are deleted once the unit test is complete. Moved logging from a .txt to a .log file so that git ignores the files (#5852)
Signed-off-by: AMZN-Gene <genewalt@amazon.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-30 10:39:44 +01:00
Kim Kulling 287d7ec213 Readme: Add project activity view item (#5854)
- Experimental view to mak the current activity in the project more visible and transparent
- Will create a more easy to get view onto the base activities like issues, PR and contributors
2024-10-30 10:26:48 +01:00
8d5cc3c5d5 Fix issue 5816 (cone.nff load failure): repair faulty line in 3D model file (#5817)
* Add missing numeric value

* Remove superfluous intermediate folder

* Add reference image

* Update path to match superfluous "NFF" removal

* Move reference screenshot to subfolder

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-30 00:13:17 +01:00
e699d23559 Store current exception when caught in ASSIMP_CATCH_GLOBAL_EXCEPTIONS (#5810)
In all other instances where we set mErrorString inside a catch block
we also set mException. I think that this was an oversight.

Co-authored-by: Michael Schmitt <michael.schmitt@visometry.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-29 10:59:37 +01:00
mosfet80andKim Kulling 53d4663f29 Update hunter (#5831)
changelog:
https://github.com/cpp-pm/hunter/releases

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-24 11:04:49 +02:00
Steve MandSteve M f6c62605c7 Simplify re-enabling M3D build support (#5835)
* Use CMake options to control M3D source compilation

* Revert .cpp file changes (better to treat them as external 3rd party code)

* Improve documentation

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-23 19:46:23 +02:00
mosfet80andKim Kulling 720eae1396 Update inno_setup-actions (#5833)
changelog:
https://github.com/Minionguyjpro/Inno-Setup-Action/releases

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-22 16:15:28 +02:00
Steve MandSteve M e4ef89182d Add unit tests for X3D models which were broken at 5 Oct 2020 commit 3b9d4cf (#5828)
* Add nascent tests against models broken by 5 Oct 2020 commit 3b9d4cf

* Temporarily disable chevy unit test (CI failing)

* Fix unit test assert value

* Swap actual/expected values and add correct value NE asserts

* Fix correct mesh count (indices 0-99 = 100 meshes)

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-20 23:14:26 +02:00
Steve MandSteve M fffce70fce Fix issue 2889 (molecule_ascii.cob load failure): change integers to floating point values in color triplets (#5819)
* Convert integer values to floating point

* Add reference screenshot

* Restore assert to expect pass instead of fail

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-19 19:20:49 +02:00
Qingyou ZhaoandKim Kulling a383cb1ff7 Fix a bug in the assbin loader that reads uninitialized memory (#5801)
* Fix a bug in the assbin loader that reads uninitialized memory

* Address review comment

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-10-18 20:41:47 +02:00
chefrolle695 4b9ac76815 Fixed bug in DefaultLogger::set: (#5826)
assigning s_pNullLogger to the parameter "logger" is definitely wrong.
However, custom logger previously set from user must not be deleted.
The user itself must handle allocation / deallocation.
2024-10-17 21:14:14 +02:00
Steve MandSteve M 2591d0e490 Fix broken normals: restore lines removed in commit cb22d53 of 4 May 2023 (#5824)
Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-15 23:42:07 +02:00
Steve MandSteve M ce0a50ec21 Fix FBX animation bug introduced with 24 Mar 2020 commit 14b8d12 (revert conditional to prior state) (#5815)
Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-14 11:24:27 +02:00
Pichas 811bf2df15 Fix issue 5767: Can't load USD from memory (#5818)
* initial commit

* fix element size
2024-10-13 21:11:45 +02:00
Steve MandSteve M cb4e663138 Restore 4x4 matrix functionn param and assignment prior to change in commit 168ae22 of 27 Oct 2019 (#5813)
Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-10-12 12:49:10 +02:00
Kim Kulling 9934a8d1cc Bugfix/installer add missing images (#5803)
* Installer: fix images for installer

* Installer: Add missing image
2024-10-08 08:29:08 +02:00
Kim Kulling 56ea25f9eb Installer: fix images for installer (#5800) 2024-10-07 23:14:11 +02:00
Kim Kulling ecdf8d24b8 SplitLargeMeshes: Fix crash (#5799)
- Fix nullptr access when rootnode of the scene is a nullptr. This can happen even if the scene stores any kind of meshes. closes https://github.com/assimp/assimp/issues/5791
2024-10-07 10:30:45 +02:00
Kim Kulling 1d99895e91 Update Readme.md (#5797)
Remove deprecated chat service
2024-10-02 10:47:55 +02:00
Kim Kulling 97257a3bcc Update Build.md (#5796)
- Update build from scratch with tools enabled
- Add itchi.io links
2024-09-25 09:05:37 +02:00
Julian KnodtandKim Kulling 17399d198f FBX Blendshapes: Do not require normals (#5776)
Some blendshapes don't have normal transformations, but Assimp currently requires that normals
be present. This removes that, and won't populate the normal field.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-24 08:07:18 +02:00
Kim Kulling f63625256c Update CMakeLists.txt (#5782)
- Disable function without a prototype for clang
2024-09-17 09:41:37 +02:00
PichasandKim Kulling f4c7606faf fix no_valid_proc (#5774)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-16 09:17:22 +02:00
Kim Kulling 66187a77cf Update dll_symbol.h (#5781)
- fix compile switch
- closes https://github.com/assimp/assimp/issues/5777
2024-09-15 20:44:32 +02:00
PatrickD 5c7acc968b Fix naming in aiMaterial comment (#5780) 2024-09-13 14:24:09 +02:00
Lux f81ea6986c Restored absolute transform calculation due to https://github.com/assimp/assimp/pull/5349 which requires this now. (#5751) 2024-09-11 10:11:15 +02:00
dataislandandKim Kulling ab12e8d8ba Fix stack overflow (#5764)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-10 23:15:31 +02:00
dataislandandKim Kulling 3bd98611d7 Fix buffer overflow in MD3Loader (#5763)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-10 22:10:36 +02:00
dataislandandKim Kulling d468e633b1 Fix invalid access (#5765)
* Fix invalid access

* Update SortByPTypeProcess.cpp

Some smaller refactorings.

* Update SortByPTypeProcess.cpp

Small refactorings.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-10 09:12:01 +02:00
Kim Kulling 4024726eca Fix leak (#5762)
* Fix leak

* Update utLogger.cpp
2024-09-07 21:02:34 +02:00
Kim KullingandKim Kulling cd0ef869e3 Kimkulling/mark blender versions as not supported (#5370)
* Cleanup defs + add deprecated macro

* Remove empty line

* Remove dead code

---------

Co-authored-by: Kim Kulling <kim.kulling@draeger.com>
2024-09-05 23:40:19 +02:00
RichardTeaandKim Kulling ed3fccd5db Add option to ignore FBX custom axes (#5754)
AI_CONFIG_IMPORT_FBX_IGNORE_UP_DIRECTION
Default false

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-05 21:03:26 +02:00
Matthias MöllerandKim Kulling ff2dc2fb2e Prevents PLY from parsing duplicate properties (#5743)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-09-04 11:54:24 +02:00
Tobias Rittig, Ph.D. f69e55058d Allow usage of pugixml from a superproject (#5752)
When using CMake subprojects with an existing build of pugixml
this prevents Assimp from using its own copy.
2024-09-03 21:45:30 +02:00
RichardTea c1ffbfec06 Zero-length mChildren arrays should be nullptr (#5749)
- Children: Don't allocate a zero-length array
- aiNode::mChildren should be left nullptr instead.
2024-09-03 10:26:27 +02:00
Kim Kulling c35200e38e prepare v5.4.3 (#5741)
* prepare v5.4.3

- Increase patch level

* Update utVersion.cpp

Fix version test
2024-08-30 20:35:01 +02:00
Kim Kulling 1e09642382 Ply-Importer: Fix vulnerability (#5739) 2024-08-30 19:43:39 +02:00
Kim Kulling edaf87f186 Update ccpp.yml (#5740)
- Add ccache to build
2024-08-30 19:29:32 +02:00
Olivier ChafikandKim Kulling 88340d0ce0 build: Add ccache support (#5686)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-30 13:22:54 +02:00
FavandKim Kulling 5e912e68da Update glTF2AssetWriter.inl (#5647)
The total length is incorrect when exporting gltf2

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 23:55:18 +02:00
Vincent FazioandKim Kulling ae0ff8a88a Update PyAssimp structs with Skeleton & SkeletonBone members (#5734)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 23:45:35 +02:00
Aliaksandr KasmachouandKim Kulling 924106188e feat: add option for creating XCFramework and configure minimum iOS target (#5648)
* feat: add option for creating XCFramework and configure minimum iOS target with a build parameter

* style: update indents for iOS bash script

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 23:05:32 +02:00
HaixiandKim Kulling 389bdedda7 FBX: add metadata as properties (#5675)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 21:38:34 +02:00
Olivier ChafikandKim Kulling f39f53e860 Fix casting typo in D3MFExporter::writeBaseMaterials (color channels < 1.0f were zeroed out) (#5681)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 21:27:13 +02:00
OGAWA KenIchiandKim Kulling 11daaf79a5 Fix to judge 'multi-configuration' correctly (#5720)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 21:09:17 +02:00
Matthias MöllerandKim Kulling 3e7e4c8c52 Fix potential memory leak in SceneCombiner for LWS/IRR/MD3 loader (#5721)
* fix potential memory leak in scenecombiner

* also cleansup srclist

* de-duplicates before deleting

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-29 11:21:59 +02:00
Vincent Fazio 4338817ca2 Fix copying private data when source pointer is NULL (#5733) 2024-08-29 00:13:40 +02:00
dependabot[bot]andKim Kulling fd7ad4a9d8 Bump softprops/action-gh-release from 1 to 2 (#5730)
Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2.
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](https://github.com/softprops/action-gh-release/compare/v1...v2)

---
updated-dependencies:
- dependency-name: softprops/action-gh-release
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-27 21:47:37 +02:00
dependabot[bot] a7a424e0a7 Bump actions/upload-artifact from 1 to 4 (#5731)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 1 to 4.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v1...v4)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-27 13:04:32 +02:00
dependabot[bot] f0ca4df704 Bump actions/download-artifact from 1 to 4 (#5732)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 1 to 4.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v1...v4)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-27 10:36:13 +02:00
imdongyeandKim Kulling d32370ff12 fix GetShortFilename function (#5728)
when blender export fbx then embedded texture path have slash and back slash.
so GetShortFilename have to check both types of slashes

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-25 17:11:19 +02:00
SanchikuuusandKim Kulling 12ed0286e4 Added more Maya materials (#5101)
* Added more Maya materials

Added Maya materials to list and add setting texture properties for getting lost textures to mesh

* Update utMaterialSystem.cpp

Now new enumerators are handled by a case label in utMaterialSystem.cpp

* Update material.h

- Fix tests: use the correct max material parameter

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-24 11:29:47 +02:00
bb9db8409f Sparky kitty studios master (#5727)
* upload contains "windows" in GH Actions

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* buildする方についてwindows-msvcのついている方にした

この二つ、何の違いがあるかいまいち理解してない…
clでビルドするかhunterでビルドするかの違い?

* upload/release対象のartifactを修正

追加当時のIssueを参考に修正(当時はHunterなかったっぽい)
https://github.com/assimp/assimp/commit/a9a0c3093226a23eb7558539bc6ebe5bcb98442b

* fix ccpp.yml -- fix matrix.name check for artifact

* fix ccpp.yml - build both hunter or not

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Update ccpp.yml

* Fix verbose string + refactorings

* Revert "Fix verbose string + refactorings"

This reverts commit 824db16a68.

* Fix verbose string + refactorings

---------

Co-authored-by: Kazuki Y <6259214+kazu0617@users.noreply.github.com>
Co-authored-by: kazu0617 <kazu0617@protonmail.com>
Co-authored-by: Kim Kulling <kim.kulling@draeger.com>
2024-08-22 11:09:14 +02:00
saceredaandKim Kulling d83904e3ee Expose aiGetEmbeddedTexture to C-API (#5382)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-21 21:15:57 +02:00
Kim Kulling bc6710a116 Fix leak in loader (#5718)
* Fix leak in loader

 Closes https://github.com/assimp/assimp/issues/5717

* Free generated mesh on importer destruction.
2024-08-17 13:49:09 +02:00
OGAWA KenIchi 10e97b2f4a Fix MSVC build error (#5716)
* add compile option /source-charset:utf-8
2024-08-16 19:33:09 +02:00
Steve MandSteve M d95a5c60ef Revert variable name (fix broken build on android) (#5715)
Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-08-14 12:13:49 +02:00
Matthias MöllerandKim Kulling 12cdbb712c Fixes possible out-of-bound read in findDegenerate (#5679)
This is possible, if the option "aiProcess_ValidateDataStructure" is deactivated as postprocessing step, but the option "aiProcess_FindDegenerates" is activated and the mesh contains invalid data structures

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 16:24:43 +02:00
Måns AndersenandKim Kulling b992ff278b Remove recursive include (#5705)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 16:14:31 +02:00
Måns AndersenandKim Kulling 9485d49e93 include Exceptional.h in 3DSExporter.cpp (#5707)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 11:17:45 +02:00
RichardTeaandKim Kulling f950f61a52 Use DRACO_GLTF_BITSTREAM (#5709)
Replaces deprecated DRACO_GLTF cmake option

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 10:09:28 +02:00
RichardTeaandKim Kulling afe06f2298 Fix MSVC PDBs and permit them to be disabled if required (#5710)
* Revert "Remove /Zi compiler flag for MSVC, release config"

This reverts commit 9e1de3ec6e.

* Allow MSVC PDB creation to be disabled

Turn off ASSIMP_INSTALL_PDB to disable PDB creation

* Whitespace cleanup

Assimp uses spaces in cmakelists, not tabs

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 09:53:33 +02:00
mkuritsuandKim Kulling d41b6b253d Added AND condition in poly2tri dll_symbol.h to only define macros fo… (#5693)
* Added ADD condition in poly2tri dll_symbol.h to only define macros for dynamic library linking if assimp is ordered to build as DLL

* Reverted last commit to handle this issue in a better way.

* added P2T_STATIC_EXPORTS to compile definitions when building assimp as DLL

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-13 09:39:53 +02:00
Nathan V. Morrical 09b981d943 fixing static build (#5713) 2024-08-13 09:23:14 +02:00
KimbattandKim Kulling 48c3a0ec46 FBX exporter - handle multiple vertex color channels (#5695)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-08-07 22:43:02 +02:00
Kim Kulling a37d748c17 Update DefaultIOSystem.cpp (#5697)
- closes https://github.com/assimp/assimp/issues/5678
2024-08-02 18:28:29 +02:00
Kim Kulling e63d3ed8e7 Make coord transfor for hs1 files optional (#5687)
* Make coord transfor for hs1 files optional

* Add config switch for HS1 transformation transformation
2024-07-31 18:39:39 +02:00
Kim Kulling 104a70f845 Return false instead of crash (#5685)
- Return false instead of crash
- closes https://github.com/assimp/assimp/issues/5684
2024-07-23 16:32:11 +02:00
Florian BornandKim Kulling 76de7cedf4 A fuzzed stride could cause the max count to become negative and hence wrap around uint (#5414)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-23 16:17:54 +02:00
JensEhrhardt-eOPUS c55158cd82 CalcTangents: zero vector is invalid for tangent/bitangent (#5432)
* CalcTangents: zero vector is invalid for tangent/bitangent
2024-07-23 13:13:12 +02:00
Kim Kulling 571ba09dc7 Mosfet80 updatedpoli2tri (#5682)
* updated poli2tri library to last version
2024-07-23 10:41:43 +02:00
Kim Kulling db19f62a0c Merge branch 'master' of https://github.com/assimp/assimp 2024-07-22 09:11:17 +02:00
Stoyan GaydarovandKim Kulling 5d5e0bad3c Fix a fuzz test heap buffer overflow in mdl material loader (#5658)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-19 21:48:10 +02:00
Kim Kulling 9cf03b4ddc Introduce interpolation mode to vectro and quaternion keys (#5674)
* Introduce interpolation mode to vectro and quaternion keys

* Update USDLoader.cpp

Fix review finding

* Update USDLoader.h

Fix review finding,
2024-07-18 23:54:31 +02:00
Vincent Fazio 91e93578c7 Update Python structs with missing fields (#5673) 2024-07-17 21:25:16 +02:00
Kim Kulling da281b7f48 Introduce interpolation mode to vectro and quaternion keys 2024-07-17 15:49:17 +02:00
Kim Kulling 35e4f1bf64 Kimkulling/fix double precision tests (#5660)
* Make color single precision

* Fix the unittests for double precision

* Fix merge issues

* Fix issues with Vertex + Color4

* Fix vertex operator, some tests are still red.
2024-07-12 14:37:49 +02:00
Steve MandSteve M 0cb1693689 [USD] Integrate "tinyusdz" project (#5628)
* Squash development commits for PR

* Fix failing build on armeabi-v7a via android NDK

* Update with blendshape support

* Migrate to auto-cloning and patching tinyusdz (instead of manually copying files)

* Update to latest rendermesh-refactor branch commit

* Remove tracked file

* Update to use recent commit to "dev" branch

"rendermesh-refactor" was merged to "dev" around 9 May 2024 but merge
was not obvious from commit messages

* Add UNUSED() macro

(cherry picked from commit d89fe8f034c353cc5cc5b3ac78cd8845e006de38)

* Update tinyusdz branch

* Prevent per-ABI (x86, x86_64 etc) clone on android

* Add verbose logging cmake option

* Fix macro and patch

* Address compiler warnings

* Address compiler warnings

* Address compiler warnings

* Attempt prevent re-clone/re-patch once downloaded by any ABI build

* Disable tinyusdz clone/build by default

assimp github PR auto-CI checks clone/build the tinyusdz code, and reject PR
due to compiler warnings in the 3rd party external tinyusdz project

---------

Co-authored-by: Steve M <praktique-tellypresence@yahoo.com>
2024-07-12 13:25:35 +02:00
Kim Kulling d3bec44990 Update Readme.md (#5665) 2024-07-11 14:19:09 +02:00
Kim Kulling b0aae04801 Update Readme.md (#5663)
- Add a discord invitation
2024-07-11 10:30:42 +02:00
Stepan HrbekandKim Kulling 206839d4f2 Allow empty slots in mTextureCoords (#5636)
* Allow empty slots in aiMesh::mTextureCoords.
1.Explicitly say in documentation that empty slots are allowed (it was unclear).
2.Change GetNumUVChannels() implementation to allow empty slots.
3.Revert fraction of 2da2835b29 where empty slots are detected and error logged.

* Fix #5632 by reverting fraction of d6aacefa1e where Collada texcoords are renumbered to avoid empty slots.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-10 09:01:53 +02:00
Kim Kulling 193f2c5d87 Fix compile warning (#5657) 2024-07-08 17:09:17 +02:00
Kim Kulling bff00b15f1 Replace raw pointers by std::string (#5656)
* Replace raw pointers by std::string
2024-07-06 13:59:02 +02:00
Matthias Möller d5cb1fe01f Fix potential heapbuffer overflow in md5 parsing (#5652) 2024-07-06 08:27:05 +02:00
Kim Kulling fe6e25080b Docker: Fix security finding (#5655)
- Use --no-install-recommends to avoid getting more deps than needed
2024-07-05 13:43:50 +02:00
Kim Kulling ddb74c2bbd Fix out of bound access (#5651) 2024-07-03 21:37:24 +02:00
Brad DandKim Kulling 625528d02c Fix: StackAllocator Undefined Reference fix (#5650)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-03 10:05:58 +02:00
Markus PrettnerandKim Kulling 7e053cc641 Fix names of enum values in docstring of aiProcess_FindDegenerates (#5640)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-02 22:11:52 +02:00
Matthias MöllerandKim Kulling 35976a4eb4 fixes some uninit bool loads (#5644)
This commit fixes some bool loads which are not initialized. With ubsan and the "option -fsanitize=bool", this results in a runtime error during test execution.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-02 21:54:18 +02:00
ThatOSDevandKim Kulling dd1474e280 Update zip.c (#5639)
Now works with GCC without failing the compilation.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-07-02 21:12:58 +02:00
Matthias Möller 0b19b7d73b fixes potential memory leak on malformed obj file (#5645) 2024-06-29 19:20:10 +02:00
Julian KnodtandKim Kulling d0703a5a3a Fix exporting incorrect bone order (#5435)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-28 12:58:09 +02:00
Kim Kulling cdf8394ccc Fix nullptr dereferencing (#5638)
- closes https://github.com/assimp/assimp/issues/5617
2024-06-25 00:05:31 +02:00
Garux dd10fb6ee4 remove ASE parsing break added in c1968823ad : original intent was to keep parsing (#5634)
crash case (iMaterialCount = 0) is handled by 47dbabadcd
2024-06-24 21:23:59 +02:00
Stepan HrbekandKim Kulling adff2f388a Fix collada uv channels - temporary was stored and then updated. So all information on uv channels was ignored. (#5630)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-21 13:49:19 +02:00
ycn2022andKim Kulling 0afd366dcb Update FBXMeshGeometry.cpp (#5624)
Some FBXs do not have "Materials" information, which can cause parsing errors

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-20 21:26:04 +02:00
michaelsctts 77f7706a97 fix PLY binary export color from float to uchar (#5608) 2024-06-19 15:45:15 +02:00
Kim Kulling 5c2a33f230 Make stepfile schema validation more robust. (#5627)
* Make stepfile schema validation more robust.

* Update STEPFile.h
2024-06-18 14:22:12 +02:00
mosfet80andKim Kulling 0cef794abd Update Readme.md (#5618)
link https://bitbucket.org/Starnick/assimpnet/src/master/  is deleted.
reverto to old link

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-18 09:30:35 +02:00
Kim Kulling 07ab05cc41 Fix init aistring issue 5622 inpython module (#5625)
* Draft: Update init of aiString

- closes https://github.com/assimp/assimp/issues/5622

* Update types.h

* Fix typo

* Fix another typo

* Adapt usage of AI_MAXLEN

* Fix compare operator

* Add missing renames

* Add missing renames
2024-06-17 23:52:23 +02:00
Kim Kulling a51500ba2b Draft: Update init of aiString (#5623)
* Draft: Update init of aiString

- closes https://github.com/assimp/assimp/issues/5622

* Update types.h

* Fix typo

* Fix another typo

* Adapt usage of AI_MAXLEN

* Fix compare operator

* Add missing renames
2024-06-17 13:12:54 +02:00
mosfet80andKim Kulling 75091d4529 clean HunterGate.cmake (#5619)
removing cmake version control check. The cmake version is always greater than 3.22

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-17 11:50:42 +02:00
Kim Kulling 907da122e9 Create inno_setup (#5621) 2024-06-15 12:41:43 +02:00
Kim Kulling 81858f9e62 Update MDLMaterialLoader.cpp (#5620)
* Update MDLMaterialLoader.cpp

- closes https://github.com/assimp/assimp/issues/5239

* Add missing declaration
2024-06-14 12:51:47 +02:00
Kim Kulling 97cbecb859 Move revision.h and revision.h.in to include folder (#5615) 2024-06-12 21:01:03 +02:00
Kim Kulling a722e33027 Move aiScene constructor (#5614) 2024-06-11 21:19:52 +02:00
Kim Kulling 75a10fedd0 Replace duplicated trim (#5613) 2024-06-11 16:30:49 +02:00
Kim Kulling e963a863ce Add trim to xml string parsing (#5611) 2024-06-10 22:25:28 +02:00
Bradly LanducciandKim Kulling 8231d99a85 Converted a size_t to mz_uint that was being treated as an error (#5600)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-06-10 11:19:57 +02:00
Kim Kulling 0d546b3d2e Build: Fix compilation for VS-2022 debug mode - warning (#5606)
- closes https://github.com/assimp/assimp/issues/5601
2024-05-31 13:08:51 +02:00
Kim Kulling 43634b8b27 Postprocessing: Fix endless loop (#5605)
- closes https://github.com/assimp/assimp/issues/5603
2024-05-31 09:36:14 +02:00
mosfet80andKim Kulling 83d7216726 updated zip (#5499)
* updated zip

udated zip from version 1.15 to version 3.0.2

* Check for double defined macro

* Update miniz.h

* Update zip.c

* Update zip.c

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-27 16:19:48 +02:00
Daniel SimonandKim Kulling 329fee2f0b Disabled maybe-uninitialized error for AssetLib/Obj/ObjFileParser.cpp as it seems to be spurious. Also fixed error message for previous GCC build issue modification (#5593)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-26 21:07:13 +02:00
Kim Kulling 4584719362 Update ObjFileParser.cpp (#5598)
Ensure not checking empty strings
2024-05-26 18:39:14 +02:00
Kim Kulling 30466aaf16 Fix possible nullptr dereferencing. (#5595) 2024-05-24 15:36:30 +02:00
ec5242a1a0 Fix a bug that could cause assertion failure. (#5575)
Co-authored-by: macmini <xhnsworks2@icloud.com>
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-22 21:20:22 +02:00
Daniel SimonandKim Kulling 6fa4f0ff5e Temporary fix for GCC 13+ build issue -Warray-bounds (#5577)
Added cmake code to remove warnings for array-bounds and stringop-overflow specifically for MDLLoader.cpp on GCC 13 and above.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-19 18:51:02 +02:00
Kim Kulling fd3f092d6e Optimize readability (#5578) 2024-05-18 22:06:04 +02:00
Jean-Louis BoudrandandKim Kulling 787c9afdf7 Assimp viewer fixes (#5582)
* AssimpViewer: Fix statistics reset + rename Time -> Loading time (more explicit)

* AssimpViewer: Fix bug where it was not possible to reload a closed asset

* AssimpViewer: Add a name in combobox for unnamed animations and disable anim UI when there is no animation

* AssimpViewer: Fixes the case where moving the anim cursor can break the animation

* AssimpViewer: Fixes the fact that when you press "play" on the animation after stopping it, there was a time jump in the animation

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-18 19:20:06 +02:00
Kim Kulling 2521909b8c Fix integer overflow (#5581)
- closes https://github.com/assimp/assimp/issues/5579
2024-05-18 19:05:10 +02:00
Kim Kulling 04afb63d34 fix ci by disabling tests (#5583)
* fix ci by disabling tests

* fix comment brackets
2024-05-18 12:04:50 +02:00
Kim Kulling 942518a4ff Remove deprecated c++11 warnings (#5576) 2024-05-15 10:22:03 +02:00
Kim Kulling 10df90ec14 Prepare v5.4.1 (#5573)
* [Draft] Prepare v5.4.1

* Update utVersion.cpp

Adapt test to v5.4.1
2024-05-13 13:45:14 +02:00
Julian UyandKim Kulling b6d53a0047 glTF2Importer: Support .vrm extension (#5569)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-13 13:24:41 +02:00
Kim Kulling 001bb01eb2 Make sure for releases revision will be zero (#5571) 2024-05-13 13:00:26 +02:00
Kim Kulling 325b0a543f Add checks for invalid buffer ans size (#5570) 2024-05-13 08:55:10 +02:00
GaruxandKim Kulling 47dbabadcd fix ASE loader crash when *MATERIAL_COUNT or *NUMSUBMTLS is not specified or is 0 (#5559)
code was doing vector[0u - 1] dereference in this case

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-08 10:43:43 +02:00
Kim Kulling c953739487 Kimkulling/fix pyassimp compatibility (#5563)
* Use correct exception message access

* Add missing docs
2024-05-06 21:38:29 +02:00
GaruxandKim Kulling 00b6db86ab mention IQM loader in Fileformats.md (#5560)
Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-05-02 16:34:47 +02:00
陈瑞锋 4621676424 fix a collada import bug (#5561) 2024-05-02 15:32:12 +02:00
Johannes UnterguggenbergerandKim Kulling 47ef79672e Reverts the changes introduced by commit ad766cb in February 2022. (#5542)
* Reverts the changes introduced by commit ad766cb in February 2022.
Explanation why the old code was just fine is given in Q&A #5512.

* Added that missing ;

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-04-29 21:03:57 +02:00
Kim Kulling c05895f3c7 Q3DLoader: Fix possible material string overflow (#5556)
- closes https://github.com/assimp/assimp/issues/5555
2024-04-26 11:11:19 +02:00
Succ3s 7bda0f88ca SplitByBoneCount had a minor typo that prevented updates to nodes indices (#5550) 2024-04-23 21:40:06 +02:00
Zeun b71b8f77ee add some ASSIMP_INSTALL checks (#5545) 2024-04-16 23:41:21 +02:00
Kim Kulling 85f084a4ce Update ComputeUVMappingProcess.cpp (#5541)
* Update ComputeUVMappingProcess.cpp

- closes https://github.com/assimp/assimp/issues/5540

* Update ComputeUVMappingProcess.cpp

Add missing token.
2024-04-11 11:30:36 +01:00
Stephen GoldandKim Kulling 08c1adc015 fix issue #5461 (segfault after removing redundant materials) (#5467)
* fix issue #5641 (segfault after removing redundant materials)

* Update RemoveRedundantMaterials.cpp

- Fix 2 possible memleaks.

---------

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-04-10 00:22:57 +02:00
mosfet80andKim Kulling 3ff7851ff9 updated STBIMAGElib (#5500)
2.29  (2023-05-xx) optimizations

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-04-09 23:31:10 +02:00
mosfet80andKim Kulling 64d88276ef updated minizip to last version (#5498)
Version 1.3.1 has these key changes:

Reject overflows of zip header fields in minizip
Fix bug in inflateSync() for data held in bit buffer
Add LIT_MEM define to use more memory for a small deflate speedup
Fix decision on the emission of Zip64 end records in minizip
Add bounds checking to ERR_MSG() macro, used by zError()
Neutralize zip file traversal attacks in miniunz
Fix a bug in ZLIB_DEBUG compiles in check_match()
Version 1.3 has these key changes:

Building using K&R (pre-ANSI) function definitions is no longer supported.
Fixed a bug in deflateBound() for level 0 and memLevel 9.
Fixed a bug when gzungetc() is used immediately after gzopen().
Fixed a bug when using gzflush() with a very small buffer.
Fixed a crash when gzsetparams() is attempted for a transparent write.
Fixed test/example.c to work with FORCE_STORED.
Fixed minizip to allow it to open an empty zip file.
Fixed reading disk number start on zip64 files in minizip.
Fixed a logic error in minizip argument processing.

Co-authored-by: Kim Kulling <kimkulling@users.noreply.github.com>
2024-04-09 00:08:38 +02:00
Alex Rønne Petersen b8aa68a080 CMake: Allow linking draco statically if ASSIMP_BUILD_DRACO_STATIC is set. (#5535)
* CMake: Mark draco as a private dependency since assimp does not publicly expose its interface.

* CMake: Allow linking draco statically if ASSIMP_BUILD_DRACO_STATIC is set.
2024-04-08 23:28:37 +02:00
887 changed files with 27423 additions and 9370 deletions
+94 -7
View File
@@ -7,10 +7,10 @@ on:
branches: [ master ]
permissions:
contents: read # to fetch code (actions/checkout)
contents: write # to fetch code (actions/checkout),and release
jobs:
job:
build:
name: ${{ matrix.name }}-build-and-test
runs-on: ${{ matrix.os }}
strategy:
@@ -37,6 +37,9 @@ jobs:
cc: gcc
steps:
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
- uses: actions/checkout@v4
with:
submodules: true
@@ -70,12 +73,12 @@ jobs:
- name: Set Windows specific CMake arguments
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 -DASSIMP_BUILD_ZLIB=1"
run: echo ":set-output name=args::=-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1" >> $GITHUB_OUTPUT
- 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"
run: echo "args=-DBUILD_SHARED_LIBS=OFF -DASSIMP_HUNTER_ENABLED=ON -DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/cmake/polly/${{ matrix.toolchain }}.cmake" >> $GITHUB_OUTPUT
- name: configure and build
uses: lukka/run-cmake@v3
@@ -92,7 +95,7 @@ jobs:
- 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"
run: echo "args=--gtest_filter=-utOpenGEXImportExport.Importissue1340_EmptyCameraObject:utColladaZaeImportExport.importBlenFromFileTest" >> $GITHUB_OUTPUT
- name: test
run: cd build/bin && ./unit ${{ steps.hunter_extra_test_args.outputs.args }}
@@ -101,5 +104,89 @@ jobs:
- uses: actions/upload-artifact@v4
if: matrix.name == 'windows-msvc'
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
path: build/bin
name: 'assimp-bins-${{ matrix.name }}'
path: build/bin/assimp*.exe
- uses: marvinpinto/action-automatic-releases@latest
if: contains(matrix.name, 'windows-msvc-hunter')
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "master"
prerelease: true
title: "AutoRelease"
files: |
build/bin/assimp*.exe
create-release:
needs: [build]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- id: create-release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: '${{secrets.GITHUB_TOKEN}}'
with:
tag_name: '${{github.ref}}'
release_name: 'Release ${{github.ref}}'
draft: false
prerelease: true
- run: |
echo '${{steps.create-release.outputs.upload_url}}' > release_upload_url.txt
- uses: actions/upload-artifact@v4
with:
name: create-release
path: release_upload_url.txt
upload-release:
strategy:
matrix:
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-latest-cl.exe
os: windows-latest
cxx: cl.exe
cc: cl.exe
- name: ubuntu-latest-clang++
os: ubuntu-latest
cxx: clang++
cc: clang
- name: macos-latest-clang++
os: macos-latest
cxx: clang++
cc: clang
- 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
needs: [create-release]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: softprops/action-gh-release@v2
with:
name: create-release
- id: upload-url
run: |
echo "url=$(cat create-release/release_upload_url.txt)" >> $GITHUB_OUTPUT
- uses: actions/download-artifact@v4
with:
name: 'assimp-bins-${{ matrix.name }}-${{ github.sha }}'
- uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: '${{secrets.GITHUB_TOKEN}}'
with:
files: |
*.zip
+52
View File
@@ -0,0 +1,52 @@
name: Build and Publish Prebuilt Binaries
on:
release:
types: [created]
jobs:
build:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: windows-x64
os: windows-latest
arch: x64
- name: windows-x86
os: windows-latest
arch: x86
cmake_args: -A Win32
- name: macos-x64
os: macos-13
- name: macos-arm64
os: macos-latest
- name: linux-x64
os: ubuntu-latest
steps:
- uses: actions/checkout@v4.2.2
- uses: lukka/get-cmake@latest
- uses: ilammy/msvc-dev-cmd@v1
with:
arch: ${{ matrix.arch }}
- name: Build
run: |
cmake -B build -S . ${{ matrix.cmake_args }} -DCMAKE_BUILD_TYPE=Release -DASSIMP_BUILD_TESTS=OFF
cmake --build build --config Release
- uses: TheDoctor0/zip-release@0.7.6
with:
filename: ${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
directory: build/bin/
- uses: softprops/action-gh-release@v2
with:
files: build/bin/${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
append_body: true
fail_on_unmatched_files: true
+51
View File
@@ -0,0 +1,51 @@
name: Build Windows Installer
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Build the Inno Setup Installer
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: lukka/get-cmake@latest
- uses: ilammy/msvc-dev-cmd@v1
- name: Cache DX SDK
id: dxcache
uses: actions/cache@v4
with:
path: '${{ github.workspace }}/DX_SDK'
key: ${{ runner.os }}-DX_SDK
restore-keys: |
${{ runner.os }}-DX_SDK
- name: Download DXSetup
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
id: windows_extra_cmake_args
run: echo "::set-output name=args::-DASSIMP_BUILD_ASSIMP_TOOLS=1 -DASSIMP_BUILD_ASSIMP_VIEW=1 -DASSIMP_BUILD_ZLIB=1"
- name: configure and build
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 }} ${{ steps.hunter_extra_cmake_args.outputs.args }}'
buildWithCMakeArgs: '--parallel 24 -v'
buildDirectory: '${{ github.workspace }}/build/'
- name: Compile .ISS to .EXE Installer
uses: Minionguyjpro/Inno-Setup-Action@v1.2.5
with:
path: packaging/windows-innosetup/script_x64.iss
options: /O+
+6
View File
@@ -120,3 +120,9 @@ tools/assimp_qt_viewer/ui_mainwindow.h
#Generated directory
generated/*
# 3rd party cloned repos/tarballs etc
# meshlab repo, automatically cloned via CMake (to gain 2 source files for VRML file format conversion)
contrib/meshlab/autoclone
# tinyusdz repo, automatically cloned via CMake
contrib/tinyusdz/autoclone
+41 -43
View File
@@ -1,36 +1,10 @@
# Build / Install Instructions
## Install on all platforms using vcpkg
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install assimp
```
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Install on Ubuntu
You can install the Asset-Importer-Lib via apt:
```
sudo apt-get update
sudo apt-get install libassimp-dev
```
## Install pyassimp
You need to have pip installed:
```
pip install pyassimp
```
## Manual build instructions
### Install CMake
Asset-Importer-Lib can be built for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
```bash
sudo apt-get install cmake
```
### Install prerequisites
You need to install
* cmake
* Your compiler
### Get the source
Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
@@ -38,15 +12,22 @@ Make sure you have a working git-installation. Open a command prompt and clone t
git clone https://github.com/assimp/assimp.git
```
### Build from source:
* For *assimp.lib* without any tools:
```bash
cd assimp
cmake CMakeLists.txt
cmake CMakeLists.txt
cmake --build .
```
* For assimp with the common tools like *assimp-cmd*
```bash
cd assimp
cmake CMakeLists.txt -DASSIMP_BUILD_ASSIMP_TOOLS=ON
cmake --build .
```
Note that by default this builds a shared library into the `bin` directory. If you want to build it as a static library see the build options at the bottom of this file.
### Build instructions for Windows with Visual-Studio
First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
```bash
@@ -57,17 +38,6 @@ This will generate the project files for the visual studio. All dependencies use
### Build instructions for Windows with UWP
See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
### Build instructions for Linux / Unix
Open a terminal and got to your repository. You can generate the makefiles and build the library via:
```bash
cmake CMakeLists.txt
make -j4
```
The option -j describes the number of parallel processes for the build. In this case make will try to use 4 cores for the build.
If you want to use an IDE for linux you can try QTCreator for instance.
### Build instructions for MinGW
Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag
required to compile some of assimp's files, especially for debug builds.
@@ -111,3 +81,31 @@ The cmake-build-environment provides options to configure the build. The followi
- **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
- **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
- **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
### Install prebuild binaries
## Install on all platforms using vcpkg
You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
```bash
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install assimp
```
The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
### Install on Ubuntu
You can install the Asset-Importer-Lib via apt:
```
sudo apt-get update
sudo apt-get install libassimp-dev
```
### Install pyassimp
You need to have pip installed:
```
pip install pyassimp
```
### Get the SDK from itchi.io
Just check [itchi.io](https://kimkulling.itch.io/the-asset-importer-lib)
+135 -65
View File
@@ -1,6 +1,6 @@
# Open Asset Import Library (assimp)
# ----------------------------------------------------------------------
# Copyright (c) 2006-2024, assimp team
# Copyright (c) 2006-2025, assimp team
#
# All rights reserved.
#
@@ -40,22 +40,70 @@ SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
# Disabled importers: m3d for 5.1 or later
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
#================================================================================#
# Model formats not enabled by default
#
# 3rd party projects may not adhere to strict standards enforced by assimp,
# in which case those formats must be opt-in; otherwise the 3rd party code
# would fail assimp CI checks
#================================================================================#
# M3D format import support (assimp integration no longer supported by M3D format author)
# User may override these in their CMake script to provide M3D import/export support
# (M3D importer/exporter was disabled for assimp release 5.1 or later)
option(ASSIMP_BUILD_M3D_IMPORTER "Enable M3D file import" off)
option(ASSIMP_BUILD_M3D_EXPORTER "Enable M3D file export" off)
# Experimental USD importer: disabled, need to opt-in
# Note: assimp github PR automatic checks will fail the PR due to compiler warnings in
# the external, 3rd party tinyusdz code which isn't technically part of the PR since it's
# auto-cloned during build; so MUST disable the feature or the PR will be rejected
option(ASSIMP_BUILD_USD_IMPORTER "Enable USD file import" off)
option(ASSIMP_BUILD_USD_VERBOSE_LOGS "Enable verbose USD import debug logging" off)
# VRML (.wrl/.x3dv) file import support by leveraging X3D importer and 3rd party file
# format converter to convert .wrl/.x3dv files to X3D-compatible .xml
# (Need to make this opt-in because 3rd party code triggers lots of CI code quality warnings)
option(ASSIMP_BUILD_VRML_IMPORTER "Enable VRML (.wrl/.x3dv) file import" off)
#--------------------------------------------------------------------------------#
# Internal impl for optional model formats
#--------------------------------------------------------------------------------#
# Internal/private M3D logic
if (NOT ASSIMP_BUILD_M3D_IMPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
endif () # if (not ASSIMP_BUILD_M3D_IMPORTER)
if (NOT ASSIMP_BUILD_M3D_EXPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
# Internal/private VRML logic
if (NOT ASSIMP_BUILD_VRML_IMPORTER)
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_VRML_IMPORTER)
endif () # if (not ASSIMP_BUILD_VRML_IMPORTER)
#================================================================================#
option(ASSIMP_BUILD_USE_CCACHE "Use ccache to speed up compilation." on)
if(ASSIMP_BUILD_USE_CCACHE)
find_program(CCACHE_PATH ccache)
if (CCACHE_PATH)
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PATH})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PATH})
endif()
endif()
# Toggles the use of the hunter package manager
option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
IF(ASSIMP_HUNTER_ENABLED)
include("cmake-modules/HunterGate.cmake")
HunterGate(
URL "https://github.com/cpp-pm/hunter/archive/v0.25.5.tar.gz"
SHA1 "a20151e4c0740ee7d0f9994476856d813cdead29"
URL "https://github.com/cpp-pm/hunter/archive/v0.25.8.tar.gz"
SHA1 "26c79d587883ec910bce168e25f6ac4595f97033"
)
add_definitions(-DASSIMP_USE_HUNTER)
ENDIF()
PROJECT(Assimp VERSION 5.4.0)
PROJECT(Assimp VERSION 5.4.3)
# All supported options ###############################################
@@ -147,7 +195,7 @@ IF (WIN32)
IF(MSVC)
OPTION( ASSIMP_INSTALL_PDB
"Install MSVC debug files."
"Create MSVC debug symbol files and add to Install target."
ON )
IF(NOT (MSVC_VERSION LESS 1900))
# Multibyte character set has been deprecated since at least MSVC2015 (possibly earlier)
@@ -262,8 +310,8 @@ IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW AND NOT HAIKU)
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
ENDIF()
IF(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 13)
IF(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 13 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
MESSAGE(STATUS "GCC13 detected disabling \"-Wdangling-reference\" in Cpp files as it appears to be a false positive")
ADD_COMPILE_OPTIONS("$<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>")
ENDIF()
@@ -284,16 +332,23 @@ ELSEIF(MSVC)
ELSE() # msvc
ADD_COMPILE_OPTIONS(/MP /bigobj)
ENDIF()
# disable "elements of array '' will be default initialized" warning on MSVC2013
IF(MSVC12)
ADD_COMPILE_OPTIONS(/wd4351)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
# supress warning for double to float conversion if Double precision is activated
ADD_COMPILE_OPTIONS(/wd4244)
ADD_COMPILE_OPTIONS(/wd4244)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
# Allow user to disable PDBs
if(ASSIMP_INSTALL_PDB)
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
elseif((GENERATOR_IS_MULTI_CONFIG) OR (CMAKE_BUILD_TYPE MATCHES Release))
message("-- MSVC PDB generation disabled. Release binary will not be debuggable.")
endif()
# Source code is encoded in UTF-8
ADD_COMPILE_OPTIONS(/source-charset:utf-8)
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
@@ -330,7 +385,7 @@ ENDIF()
IF (ASSIMP_COVERALLS)
MESSAGE(STATUS "Coveralls enabled")
INCLUDE(Coveralls)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
@@ -338,7 +393,7 @@ ENDIF()
IF (ASSIMP_ASAN)
MESSAGE(STATUS "AddressSanitizer enabled")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
ENDIF()
@@ -452,18 +507,20 @@ configure_package_config_file(
INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
)
install(
FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
DESTINATION "${CONFIG_INSTALL_DIR}"
COMPONENT ${LIBASSIMP-DEV_COMPONENT}
)
if(ASSIMP_INSTALL)
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}
)
install(
EXPORT "${TARGETS_EXPORT_NAME}"
NAMESPACE "${NAMESPACE}"
DESTINATION "${CONFIG_INSTALL_DIR}"
COMPONENT ${LIBASSIMP-DEV_COMPONENT}
)
endif()
IF( ASSIMP_BUILD_DOCS )
ADD_SUBDIRECTORY(doc)
@@ -481,7 +538,7 @@ IF(ASSIMP_HUNTER_ENABLED)
set(ASSIMP_BUILD_MINIZIP TRUE)
ELSE()
# If the zlib is already found outside, add an export in case assimpTargets can't find it.
IF( ZLIB_FOUND )
IF( ZLIB_FOUND AND ASSIMP_INSTALL)
INSTALL( TARGETS zlib zlibstatic
EXPORT "${TARGETS_EXPORT_NAME}")
ENDIF()
@@ -621,6 +678,10 @@ ELSE ()
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
ENDIF ()
if(ASSIMP_BUILD_DRACO_STATIC)
set(ASSIMP_BUILD_DRACO ON)
endif()
# Draco requires cmake 3.12
IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "3.12")
message(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
@@ -630,7 +691,7 @@ ELSE()
IF ( ASSIMP_BUILD_DRACO )
# Primarily for glTF v2
# Enable Draco glTF feature set
set(DRACO_GLTF ON CACHE BOOL "" FORCE)
set(DRACO_GLTF_BITSTREAM ON CACHE BOOL "" FORCE)
# Disable unnecessary or omitted components
set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
set(DRACO_WASM OFF CACHE BOOL "" FORCE)
@@ -656,22 +717,29 @@ ELSE()
"-Wno-sign-compare"
"-Wno-unused-local-typedefs"
)
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang
list(APPEND DRACO_CXX_FLAGS
"-fvisibility=default"
)
if(NOT ASSIMP_BUILD_DRACO_STATIC)
# Draco 1.4.1 does not explicitly export any symbols under GCC/clang
list(APPEND DRACO_CXX_FLAGS
"-fvisibility=default"
)
endif()
ENDIF()
# Don't build or install all of Draco by default
ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
if(ASSIMP_BUILD_DRACO_STATIC)
set_property(DIRECTORY "contrib/draco" PROPERTY BUILD_SHARED_LIBS OFF)
endif()
if(MSVC OR WIN32)
set(draco_LIBRARIES "draco")
else()
if(BUILD_SHARED_LIBS)
set(draco_LIBRARIES "draco_shared")
else()
if(ASSIMP_BUILD_DRACO_STATIC)
set(draco_LIBRARIES "draco_static")
else()
set(draco_LIBRARIES "draco_shared")
endif()
endif()
@@ -694,15 +762,17 @@ ELSE()
set(draco_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/draco/src")
# This is probably wrong
INSTALL( TARGETS ${draco_LIBRARIES}
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION include
)
if (ASSIMP_INSTALL)
INSTALL( TARGETS ${draco_LIBRARIES}
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION include
)
endif()
ENDIF()
ENDIF()
ENDIF()
@@ -746,8 +816,8 @@ IF ( ASSIMP_INSTALL )
ENDIF()
CONFIGURE_FILE(
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
${CMAKE_CURRENT_BINARY_DIR}/revision.h
${CMAKE_CURRENT_LIST_DIR}/include/assimp/revision.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/assimp/revision.h
)
CONFIGURE_FILE(
@@ -835,24 +905,24 @@ if(WIN32)
IF(MSVC12 OR MSVC14 OR MSVC15 )
ADD_CUSTOM_TARGET(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
IF(CMAKE_GENERATOR MATCHES "^Visual Studio")
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ELSE()
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ADD_CUSTOM_COMMAND(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
ENDIF()
ENDIF()
ENDIF ()
+7 -12
View File
@@ -1,22 +1,17 @@
FROM ubuntu:22.04
FROM gcc:latest
RUN apt-get update && apt-get install -y ninja-build \
git cmake build-essential software-properties-common
RUN apt-get update && apt-get install --no-install-recommends -y ninja-build cmake
RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update
WORKDIR /opt
WORKDIR /app
RUN apt install zlib1g-dev
# Build Assimp
RUN git clone https://github.com/assimp/assimp.git /opt/assimp
COPY . .
WORKDIR /opt/assimp
RUN git checkout master \
&& mkdir build && cd build && \
RUN mkdir build && cd build && \
cmake -G 'Ninja' \
-DCMAKE_BUILD_TYPE=Release \
-DASSIMP_BUILD_ASSIMP_TOOLS=ON \
.. && \
ninja -j4 && ninja install
CMD ["/app/build/bin/unit"]
+17 -17
View File
@@ -1,20 +1,24 @@
Open Asset Import Library (assimp)
==================================
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
### Current project status ###
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
### Current project status ###
![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=assimp_assimp&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
[![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20assimp%20Guru-006BFF)](https://gurubase.io/g/assimp)
[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
<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.
APIs are provided for C and C++. Various bindings exist to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
## Project activity ##
![Alt](https://repobeats.axiom.co/api/embed/997f84e5f9fcf772da1e687f3a4f3a8afdbf4cf0.svg "Repobeats analytics image")
### Documentation ###
Read [our latest documentation](https://assimp-docs.readthedocs.io/en/latest/).
@@ -26,11 +30,10 @@ Clone [our model database](https://github.com/assimp/assimp-mdb).
### Communities ###
- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2)
- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
- Nothing has worked? File a question or an issue-report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
#### Supported file formats ####
See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
@@ -41,18 +44,18 @@ Start by reading [our build instructions](https://github.com/assimp/assimp/blob/
### Ports ###
* [Android](port/AndroidJNI/README.md)
* [Python](port/PyAssimp/README.md)
* [.NET](https://bitbucket.org/Starnick/assimpnet/src/master/)
* [.NET](https://github.com/Saalvage/AssimpNetter)
* [Pascal](port/AssimpPascal/Readme.md)
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
* [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs)
* [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
* [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/)
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
* [JVM](https://github.com/kotlin-graphics/assimp) Full JVM port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
* [Rust](https://github.com/jkvargas/russimp)
### Other tools ###
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
[Qt5-ModelViewer](https://github.com/sharjith/ModelViewer-Qt5) is a powerful viewer based on Qt5 and Assimp's import and export abilities.<br>
[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
#### Repository structure ####
@@ -60,7 +63,7 @@ Open Asset Import Library is implemented in C++. The directory structure looks l
/code Source code
/contrib Third-party libraries
/doc Documentation (doxysource and pre-compiled docs)
/doc Documentation (Doxygen source and pre-compiled docs)
/fuzz Contains the test code for the Google Fuzzer project
/include Public header C and C++ header files
/scripts Scripts are used to generate the loading code for some formats
@@ -80,7 +83,7 @@ The source code is organized in the following way:
code/AssetLib/<FormatName> Implementation for import and export of the format
### Contributing ###
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
I would greatly appreciate contributing to assimp. The easiest way to get involved is to submit
a pull request with your changes against the main repository's `master` branch.
## Contributors
@@ -102,7 +105,7 @@ Become a financial contributor and help us sustain our community. [[Contribute](
#### Organizations
Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
You can support the project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
<a href="https://opencollective.com/assimp/organization/0/website"><img src="https://opencollective.com/assimp/organization/0/avatar.svg"></a>
@@ -112,6 +115,3 @@ Our license is based on the modified, __3-clause BSD__-License.
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
For the legal details, see the `LICENSE` file.
### Why this name ###
Sorry, we're germans :-), no English native speakers ...
-29
View File
@@ -22,38 +22,9 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is a gate file to Hunter package manager.
# Include this file using `include` command and add package you need, example:
#
# cmake_minimum_required(VERSION 3.2)
#
# include("cmake/HunterGate.cmake")
# HunterGate(
# URL "https://github.com/path/to/hunter/archive.tar.gz"
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
# )
#
# project(MyProject)
#
# hunter_add_package(Foo)
# hunter_add_package(Boo COMPONENTS Bar Baz)
#
# Projects:
# * https://github.com/hunter-packages/gate/
# * https://github.com/ruslo/hunter
option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
if(HUNTER_ENABLED)
if(CMAKE_VERSION VERSION_LESS "3.2")
message(
FATAL_ERROR
"At least CMake version 3.2 required for Hunter dependency management."
" Update CMake or set HUNTER_ENABLED to OFF."
)
endif()
endif()
include(CMakeParseArguments) # cmake_parse_arguments
option(HUNTER_STATUS_PRINT "Print working status" ON)
-8
View File
@@ -1,8 +0,0 @@
# See <http://EditorConfig.org> for details
[*.{h,hpp,c,cpp}]
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_size = 4
indent_style = space
+10 -4
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -643,11 +643,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
}
// Allocate storage for children
pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
pcOut->mNumChildren = size;
if (size == 0) {
return;
}
pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
// Recursively process all children
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
for (unsigned int i = 0; i < size; ++i) {
pcOut->mChildren[i] = new aiNode();
pcOut->mChildren[i]->mParent = pcOut;
@@ -709,7 +715,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
pcNode->mNumMeshes = 1;
// Build a name for the node
pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u", i);
pcNode->mName.length = ai_snprintf(pcNode->mName.data, AI_MAXLEN, "3DSMesh_%u", i);
}
// Build dummy nodes for all cameras
+3 -6
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/Exceptional.h>
#include <assimp/IOSystem.hpp>
#include <memory>
@@ -102,7 +102,7 @@ private:
// preserves the mesh's given name if it has one. |index| is the index
// of the mesh in |aiScene::mMeshes|.
std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) {
static const char underscore = '_';
static constexpr char underscore = '_';
char postfix[10] = { 0 };
ASSIMP_itoa10(postfix, index);
@@ -208,9 +208,6 @@ Discreet3DSExporter::Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, con
}
}
// ------------------------------------------------------------------------------------------------
Discreet3DSExporter::~Discreet3DSExporter() = default;
// ------------------------------------------------------------------------------------------------
int Discreet3DSExporter::WriteHierarchy(const aiNode &node, int seq, int sibling_level) {
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
+3 -4
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -63,10 +63,10 @@ namespace Assimp {
* @brief Helper class to export a given scene to a 3DS file.
*/
// ------------------------------------------------------------------------------------------------
class Discreet3DSExporter {
class Discreet3DSExporter final {
public:
Discreet3DSExporter(std::shared_ptr<IOStream> &outfile, const aiScene* pScene);
~Discreet3DSExporter();
~Discreet3DSExporter() = default;
private:
void WriteMeshes();
@@ -88,7 +88,6 @@ private:
using MeshesByNodeMap = std::multimap<const aiNode*, unsigned int>;
MeshesByNodeMap meshes;
};
} // Namespace Assimp
+3 -4
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -365,14 +365,13 @@ struct Texture {
#ifdef _MSC_VER
#pragma warning(pop)
#endif // _MSC_VER
// ---------------------------------------------------------------------------
/** Helper structure representing a 3ds material */
struct Material {
//! Default constructor has been deleted
Material() :
mName(),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mDiffuse(0.6f, 0.6f, 0.6f),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
@@ -385,7 +384,7 @@ struct Material {
//! Constructor with explicit name
explicit Material(const std::string &name) :
mName(name),
mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
mDiffuse(0.6f, 0.6f, 0.6f),
mSpecularExponent(ai_real(0.0)),
mShininessStrength(ai_real(1.0)),
mShading(Discreet3DS::Gouraud),
+1 -1
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+2 -3
View File
@@ -3,8 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -64,7 +63,7 @@ using namespace D3DS;
// ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files
*/
class Discreet3DSImporter : public BaseImporter {
class Discreet3DSImporter final : public BaseImporter {
public:
Discreet3DSImporter();
~Discreet3DSImporter() override = default;
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+5 -5
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -249,10 +249,10 @@ void D3MFExporter::writeBaseMaterials() {
if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
hexDiffuseColor = ai_rgba2hex(
(int)((ai_real)color.r) * 255,
(int)((ai_real)color.g) * 255,
(int)((ai_real)color.b) * 255,
(int)((ai_real)color.a) * 255,
(int)(((ai_real)color.r) * 255),
(int)(((ai_real)color.g) * 255),
(int)(((ai_real)color.b) * 255),
(int)(((ai_real)color.a) * 255),
true);
} else {
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+2 -2
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -107,7 +107,7 @@ void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene,
XmlParser xmlParser;
if (xmlParser.parse(opcPackage.RootStream())) {
XmlSerializer xmlSerializer(&xmlParser);
XmlSerializer xmlSerializer(xmlParser);
xmlSerializer.ImportXml(pScene);
const std::vector<aiTexture*> &tex = opcPackage.GetEmbeddedTextures();
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+9 -9
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -57,8 +57,8 @@ static constexpr size_t ColRGBA_Len = 9;
static constexpr size_t ColRGB_Len = 7;
// format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
bool validateColorString(const char *color) {
const size_t len = strlen(color);
bool validateColorString(const std::string color) {
const size_t len = color.size();
if (ColRGBA_Len != len && ColRGB_Len != len) {
return false;
}
@@ -157,8 +157,8 @@ aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
return transformMatrix;
}
bool parseColor(const char *color, aiColor4D &diffuse) {
if (nullptr == color) {
bool parseColor(const std::string &color, aiColor4D &diffuse) {
if (color.empty()) {
return false;
}
@@ -178,7 +178,7 @@ bool parseColor(const char *color, aiColor4D &diffuse) {
char b[3] = { color[5], color[6], '\0' };
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
const size_t len = strlen(color);
const size_t len = color.size();
if (ColRGB_Len == len) {
return true;
}
@@ -199,11 +199,11 @@ void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
} // namespace
XmlSerializer::XmlSerializer(XmlParser *xmlParser) :
XmlSerializer::XmlSerializer(XmlParser &xmlParser) :
mResourcesDictionnary(),
mMeshCount(0),
mXmlParser(xmlParser) {
ai_assert(nullptr != xmlParser);
// empty
}
XmlSerializer::~XmlSerializer() {
@@ -218,7 +218,7 @@ void XmlSerializer::ImportXml(aiScene *scene) {
}
scene->mRootNode = new aiNode(XmlTag::RootTag);
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
XmlNode node = mXmlParser.getRootNode().child(XmlTag::model);
if (node.empty()) {
return;
}
+4 -4
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -59,9 +59,9 @@ class Texture2DGroup;
class EmbeddedTexture;
class ColorGroup;
class XmlSerializer {
class XmlSerializer final {
public:
XmlSerializer(XmlParser *xmlParser);
XmlSerializer(XmlParser &xmlParser);
~XmlSerializer();
void ImportXml(aiScene *scene);
@@ -92,7 +92,7 @@ private:
std::vector<aiMaterial *> mMaterials;
std::map<unsigned int, Resource *> mResourcesDictionnary;
unsigned int mMeshCount;
XmlParser *mXmlParser;
XmlParser &mXmlParser;
};
} // namespace D3MF
+12 -13
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -144,10 +144,6 @@ AC3DImporter::AC3DImporter() :
// nothing to be done here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
AC3DImporter::~AC3DImporter() = default;
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool AC3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -171,8 +167,9 @@ bool AC3DImporter::GetNextLine() {
// ------------------------------------------------------------------------------------------------
// Parse an object section in an AC file
bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
if (!TokenMatch(mBuffer.data, "OBJECT", 6))
if (!TokenMatch(mBuffer.data, "OBJECT", 6)) {
return false;
}
SkipSpaces(&mBuffer.data, mBuffer.end);
@@ -192,8 +189,7 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
light->mAttenuationConstant = 1.f;
// Generate a default name for both the light source and the node
// FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
light->mName.length = ::ai_snprintf(light->mName.data, AI_MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
obj.name = std::string(light->mName.data);
ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
@@ -202,8 +198,10 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
obj.type = Object::Group;
} else if (!ASSIMP_strincmp(mBuffer.data, "world", 5)) {
obj.type = Object::World;
} else
} else {
obj.type = Object::Poly;
}
while (GetNextLine()) {
if (TokenMatch(mBuffer.data, "kids", 4)) {
SkipSpaces(&mBuffer.data, mBuffer.end);
@@ -344,6 +342,7 @@ bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
}
}
ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
return false;
}
@@ -696,18 +695,18 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
// generate a name depending on the type of the node
switch (object.type) {
case Object::Group:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++);
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACGroup_%i", mGroupsCounter++);
break;
case Object::Poly:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++);
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACPoly_%i", mPolysCounter++);
break;
case Object::Light:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++);
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACLight_%i", mLightsCounter++);
break;
// there shouldn't be more than one world, but we don't care
case Object::World:
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++);
node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACWorld_%i", mWorldsCounter++);
break;
}
}
+3 -3
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -63,7 +63,7 @@ namespace Assimp {
class AC3DImporter : public BaseImporter {
public:
AC3DImporter();
~AC3DImporter() override;
~AC3DImporter() override = default;
// Represents an AC3D material
struct Material {
@@ -103,7 +103,7 @@ public:
unsigned int mat, flags;
typedef std::pair<unsigned int, aiVector2D> SurfaceEntry;
using SurfaceEntry = std::pair<unsigned int, aiVector2D>;
std::vector<SurfaceEntry> entries;
// Type is low nibble of flags
+12 -31
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -178,28 +178,6 @@ bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
return nullptr != mXmlParser->findNode(nodeName);
}
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) {
size_t instr_len;
pOutString.clear();
instr_len = strlen(pInStr);
if (!instr_len) return;
pOutString.reserve(instr_len * 3 / 2);
// check and correct floats in format ".x". Must be "x.y".
if (pInStr[0] == '.') pOutString.push_back('0');
pOutString.push_back(pInStr[0]);
for (size_t ci = 1; ci < instr_len; ci++) {
if ((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) {
pOutString.push_back('0');
pOutString.push_back('.');
} else {
pOutString.push_back(pInStr[ci]);
}
}
}
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
}
@@ -213,7 +191,10 @@ void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std
uint8_t arr4[4], arr3[3];
// check input data
if (pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
if (pInputBase64.size() % 4) {
throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
}
// prepare output place
pOutputData.clear();
pOutputData.reserve(pInputBase64.size() / 4 * 3);
@@ -403,17 +384,17 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "deltax") {
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
XmlParser::getValueAsReal(currentNode, als.Delta.x);
} else if (currentName == "deltay") {
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
XmlParser::getValueAsReal(currentNode, als.Delta.y);
} else if (currentName == "deltaz") {
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
XmlParser::getValueAsReal(currentNode, als.Delta.z);
} else if (currentName == "rx") {
XmlParser::getValueAsFloat(currentNode, als.Delta.x);
XmlParser::getValueAsReal(currentNode, als.Delta.x);
} else if (currentName == "ry") {
XmlParser::getValueAsFloat(currentNode, als.Delta.y);
XmlParser::getValueAsReal(currentNode, als.Delta.y);
} else if (currentName == "rz") {
XmlParser::getValueAsFloat(currentNode, als.Delta.z);
XmlParser::getValueAsReal(currentNode, als.Delta.z);
}
}
ParseHelper_Node_Exit();
@@ -493,7 +474,7 @@ void AMFImporter::ParseNode_Metadata(XmlNode &node) {
// read attribute
ne = new AMFMetadata(mNodeElement_Cur);
((AMFMetadata *)ne)->Type = type;
((AMFMetadata *)ne)->MetaType = 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.
+1 -2
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -168,7 +168,6 @@ public:
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
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;
+5 -5
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -167,11 +167,11 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
const std::string &currentName = ai_tolower(currentNode.name());
if (currentName == "x") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
XmlParser::getValueAsReal(currentNode, als.Coordinate.x);
} else if (currentName == "y") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
XmlParser::getValueAsReal(currentNode, als.Coordinate.y);
} else if (currentName == "z") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
XmlParser::getValueAsReal(currentNode, als.Coordinate.z);
}
}
ParseHelper_Node_Exit();
@@ -202,7 +202,7 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
((AMFVolume *)ne)->MaterialID = node.attribute("materialid").as_string();
((AMFVolume *)ne)->Type = type;
((AMFVolume *)ne)->VolumeType = type;
// Check for child nodes
bool col_read = false;
if (!node.empty()) {
+7 -8
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -263,26 +263,25 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
const std::string &name = currentNode.name();
if (name == "utex1") {
read_flag[0] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[0].x);
} else if (name == "utex2") {
read_flag[1] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[1].x);
} else if (name == "utex3") {
read_flag[2] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[2].x);
} else if (name == "vtex1") {
read_flag[3] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[0].y);
} else if (name == "vtex2") {
read_flag[4] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[1].y);
} else if (name == "vtex3") {
read_flag[5] = true;
XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
XmlParser::getValueAsReal(currentNode, als.TextureCoordinate[2].y);
}
}
ParseHelper_Node_Exit();
} else {
for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name();
+9 -23
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -56,7 +56,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
#include <vector>
/// \class CAMFImporter_NodeElement
/// Base class for elements of nodes.
class AMFNodeElementBase {
public:
@@ -87,7 +86,8 @@ public:
AMFNodeElementBase *Parent; ///< Parent element. If nullptr then this node is root.
std::list<AMFNodeElementBase *> Child; ///< Child elements.
public: /// Destructor, virtual..
public:
/// Destructor, virtual..
virtual ~AMFNodeElementBase() = default;
/// Disabled copy constructor and co.
@@ -98,15 +98,14 @@ public: /// Destructor, virtual..
protected:
/// In constructor inheritor must set element type.
/// \param [in] pType - element type.
/// \param [in] type - element type.
/// \param [in] pParent - parent element.
AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
Type(pType), Parent(pParent) {
AMFNodeElementBase(EType type, AMFNodeElementBase *pParent) :
Type(type), Parent(pParent) {
// empty
}
}; // class IAMFImporter_NodeElement
/// \struct CAMFImporter_NodeElement_Constellation
/// A collection of objects or constellations with specific relative locations.
struct AMFConstellation : public AMFNodeElementBase {
/// Constructor.
@@ -116,7 +115,6 @@ struct AMFConstellation : public AMFNodeElementBase {
}; // struct CAMFImporter_NodeElement_Constellation
/// \struct CAMFImporter_NodeElement_Instance
/// Part of constellation.
struct AMFInstance : public AMFNodeElementBase {
@@ -135,12 +133,11 @@ struct AMFInstance : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Instance, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Metadata
/// Structure that define metadata node.
struct AMFMetadata : public AMFNodeElementBase {
std::string Type; ///< Type of "Value".
std::string Value; ///< Value.
std::string MetaType; ///< Type of "Value".
std::string Value; ///< Value.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
@@ -148,7 +145,6 @@ struct AMFMetadata : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Metadata, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Root
/// Structure that define root node.
struct AMFRoot : public AMFNodeElementBase {
@@ -161,7 +157,6 @@ struct AMFRoot : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Root, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Color
/// Structure that define object node.
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.
@@ -177,7 +172,6 @@ struct AMFColor : public AMFNodeElementBase {
}
};
/// \struct CAMFImporter_NodeElement_Material
/// Structure that define material node.
struct AMFMaterial : public AMFNodeElementBase {
@@ -187,7 +181,6 @@ struct AMFMaterial : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Material, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Object
/// Structure that define object node.
struct AMFObject : public AMFNodeElementBase {
@@ -206,7 +199,6 @@ struct AMFMesh : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Mesh, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Vertex
/// Structure that define vertex node.
struct AMFVertex : public AMFNodeElementBase {
/// Constructor.
@@ -215,7 +207,6 @@ struct AMFVertex : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Vertex, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Edge
/// Structure that define edge node.
struct AMFEdge : public AMFNodeElementBase {
/// Constructor.
@@ -224,7 +215,6 @@ struct AMFEdge : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Edge, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Vertices
/// Structure that define vertices node.
struct AMFVertices : public AMFNodeElementBase {
/// Constructor.
@@ -233,11 +223,10 @@ struct AMFVertices : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Vertices, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Volume
/// Structure that define volume node.
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.
std::string VolumeType; ///< What this volume describes can be "region" or "support". If none specified, "object" is assumed.
/// Constructor.
/// \param [in] pParent - pointer to parent node.
@@ -245,7 +234,6 @@ struct AMFVolume : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Volume, pParent) {}
};
/// \struct CAMFImporter_NodeElement_Coordinates
/// Structure that define coordinates node.
struct AMFCoordinates : public AMFNodeElementBase {
aiVector3D Coordinate; ///< Coordinate.
@@ -256,7 +244,6 @@ struct AMFCoordinates : public AMFNodeElementBase {
AMFNodeElementBase(ENET_Coordinates, pParent) {}
};
/// \struct CAMFImporter_NodeElement_TexMap
/// Structure that define texture coordinates node.
struct AMFTexMap : public AMFNodeElementBase {
aiVector3D TextureCoordinate[3]; ///< Texture coordinates.
@@ -273,7 +260,6 @@ struct AMFTexMap : public AMFNodeElementBase {
}
};
/// \struct CAMFImporter_NodeElement_Triangle
/// Structure that define triangle node.
struct AMFTriangle : public AMFNodeElementBase {
size_t V[3]; ///< Triangle vertices.
@@ -1,9 +1,9 @@
/*
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -224,7 +224,8 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
}
// Create format hint.
strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string.
constexpr char templateColor[] = "rgba0000";
memcpy(converted_texture.FormatHint, templateColor, 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';
@@ -332,7 +333,7 @@ void AMFImporter::Postprocess_AddMetadata(const AMFMetaDataArray &metadataList,
size_t meta_idx(0);
for (const AMFMetadata *metadata : metadataList) {
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata->Type, aiString(metadata->Value));
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata->MetaType, aiString(metadata->Value));
}
}
@@ -867,7 +868,7 @@ nl_clean_loop:
pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data;
// texture format description.
strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
strncpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint, HINTMAXTEXTURELEN);
idx++;
} // for(const SPP_Texture& tex_convd: mTexture_Converted)
+16 -15
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -124,7 +124,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
// Allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2;
TextFileToBuffer(file.get(), mBuffer2);
const size_t fileSize = mBuffer2.size();
this->mBuffer = &mBuffer2[0];
this->pcScene = pScene;
@@ -146,7 +146,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
};
// Construct an ASE parser and parse the file
ASE::Parser parser(mBuffer, defaultFormat);
ASE::Parser parser(mBuffer, fileSize, defaultFormat);
mParser = &parser;
mParser->Parse();
@@ -446,10 +446,9 @@ void ASEImporter::BuildLights() {
}
// ------------------------------------------------------------------------------------------------
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
aiNode *pcParent, const char *szName) {
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name) {
aiMatrix4x4 m;
AddNodes(nodes, pcParent, szName, m);
AddNodes(nodes, pcParent, name, m);
}
// ------------------------------------------------------------------------------------------------
@@ -506,10 +505,9 @@ void ASEImporter::AddMeshes(const ASE::BaseNode *snode, aiNode *node) {
// ------------------------------------------------------------------------------------------------
// Add child nodes to a given parent node
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
aiNode *pcParent, const char *szName,
void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name,
const aiMatrix4x4 &mat) {
const size_t len = szName ? ::strlen(szName) : 0;
const size_t len = name.size();
ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
// Receives child nodes for the pcParent node
@@ -519,16 +517,18 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
// which has *us* as parent.
for (std::vector<BaseNode *>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
const BaseNode *snode = *it;
if (szName) {
if (len != snode->mParent.length() || ::strcmp(szName, snode->mParent.c_str()))
if (!name.empty()) {
if (len != snode->mParent.length() || name != snode->mParent.c_str()) {
continue;
} else if (snode->mParent.length())
}
} else if (snode->mParent.length()) {
continue;
}
(*it)->mProcessed = true;
// Allocate a new node and add it to the output data structure
apcNodes.push_back(new aiNode());
apcNodes.push_back(new aiNode);
aiNode *node = apcNodes.back();
node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
@@ -541,7 +541,7 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
// Add sub nodes - prevent stack overflow due to recursive parenting
if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) {
AddNodes(nodes, node, node->mName.data, snode->mTransform);
AddNodes(nodes, node, node->mName.C_Str(), snode->mTransform);
}
// Further processing depends on the type of the node
@@ -619,7 +619,8 @@ void ASEImporter::BuildNodes(std::vector<BaseNode *> &nodes) {
}
// add all nodes
AddNodes(nodes, ch, nullptr);
static const std::string none = "";
AddNodes(nodes, ch, none);
// now iterate through al nodes and find those that have not yet
// been added to the nodegraph (= their parent could not be recognized)
+4 -5
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -153,13 +153,13 @@ private:
* \param matrix Current transform
*/
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent,const char* szName);
aiNode* pcParent, const std::string &name);
void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
aiNode* pcParent,const char* szName,
aiNode* pcParent, const std::string &name,
const aiMatrix4x4& matrix);
void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
void AddMeshes(const ASE::BaseNode* snode, aiNode* node);
// -------------------------------------------------------------------
/** Generate a default material and add it to the parser's list
@@ -188,5 +188,4 @@ protected:
} // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -391,11 +391,11 @@ public:
// -------------------------------------------------------------------
//! Construct a parser from a given input file which is
//! guaranteed to be terminated with zero.
//! @param szFile Input file
//! @param file The name of the input file.
//! @param fileFormatDefault Assumed file format version. If the
//! file format is specified in the file the new value replaces
//! the default value.
Parser(const char *szFile, unsigned int fileFormatDefault);
Parser(const char *file, size_t fileLen, unsigned int fileFormatDefault);
// -------------------------------------------------------------------
//! Parses the file into the parsers internal representation
@@ -553,13 +553,15 @@ private:
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats)
//! \param rIndexOut Output index
void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
void ParseLV4MeshRealTriple(ai_real *apOut, unsigned int &rIndexOut);
void ParseLV4MeshFloatTriple(float *apOut, unsigned int &rIndexOut);
// -------------------------------------------------------------------
//! Parse a *MESH_VERT block in a file
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
//! \param apOut Output buffer (3 floats)
void ParseLV4MeshFloatTriple(ai_real *apOut);
void ParseLV4MeshRealTriple(ai_real *apOut);
void ParseLV4MeshFloatTriple(float *apOut);
// -------------------------------------------------------------------
//! Parse a *MESH_TFACE block in a file
@@ -577,7 +579,8 @@ private:
// -------------------------------------------------------------------
//! Parse a single float element
//! \param fOut Output float
void ParseLV4MeshFloat(ai_real &fOut);
void ParseLV4MeshReal(ai_real &fOut);
void ParseLV4MeshFloat(float &fOut);
// -------------------------------------------------------------------
//! Parse a single int element
@@ -617,11 +620,8 @@ private:
bool ParseString(std::string &out, const char *szName);
public:
//! Pointer to current data
const char *filePtr;
/// The end pointer of the file data
const char *mEnd;
const char *mFilePtr; ////< Pointer to current data
const char *mEnd; ///< The end pointer of the file data
//! background color to be passed to the viewer
//! QNAN if none was found
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+10 -3
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -91,9 +91,13 @@ bool AssbinImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, boo
}
char s[32];
in->Read(s, sizeof(char), 32);
const size_t read = in->Read(s, sizeof(char), 32);
pIOHandler->Close(in);
if (read < 19) {
return false;
}
return strncmp(s, "ASSIMP.binary-dump.", 19) == 0;
}
@@ -684,6 +688,7 @@ void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, I
unsigned int versionMajor = Read<unsigned int>(stream);
unsigned int versionMinor = Read<unsigned int>(stream);
if (versionMinor != ASSBIN_VERSION_MINOR || versionMajor != ASSBIN_VERSION_MAJOR) {
pIOHandler->Close(stream);
throw DeadlyImportError("Invalid version, data format not compatible!");
}
@@ -693,8 +698,10 @@ void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, I
shortened = Read<uint16_t>(stream) > 0;
compressed = Read<uint16_t>(stream) > 0;
if (shortened)
if (shortened) {
pIOHandler->Close(stream);
throw DeadlyImportError("Shortened binaries are not supported!");
}
stream->Seek(256, aiOrigin_CUR); // original filename
stream->Seek(128, aiOrigin_CUR); // options
+1 -1
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+2 -4
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -36,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
@@ -223,7 +221,7 @@ static void WriteDump(const char *pFile, const char *cmd, const aiScene *scene,
const unsigned int majorVersion(aiGetVersionMajor());
const unsigned int minorVersion(aiGetVersionMinor());
const unsigned int rev(aiGetVersionRevision());
const char *curtime(asctime(p));
const char *curtime = asctime(p);
ioprintf(io, header.c_str(), majorVersion, minorVersion, rev, pFile, c.c_str(), curtime, scene->mFlags, 0u);
// write the node graph
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+4 -8
View File
@@ -4,9 +4,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -85,11 +83,9 @@ BVHLoader::BVHLoader() :
mLine(),
mAnimTickDuration(),
mAnimNumFrames(),
noSkeletonMesh() {}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
BVHLoader::~BVHLoader() = default;
noSkeletonMesh() {
// empty
}
// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
+8 -13
View File
@@ -4,7 +4,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -80,32 +80,27 @@ class BVHLoader : public BaseImporter {
std::vector<ChannelType> mChannels;
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
Node() :
mNode(nullptr) {}
explicit Node(const aiNode *pNode) :
mNode(pNode) {}
Node() : mNode(nullptr) {}
explicit Node(const aiNode *pNode) :mNode(pNode) {}
};
public:
BVHLoader();
~BVHLoader();
~BVHLoader() override = default;
public:
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool cs) const override;
void SetupProperties(const Importer *pImp);
const aiImporterDesc *GetInfo() const;
void SetupProperties(const Importer *pImp) override;
const aiImporterDesc *GetInfo() const override;
protected:
/** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
protected:
/** Reads the file */
void ReadStructure(aiScene *pScene);
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -2
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+4 -2
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -841,5 +841,7 @@ template <template <typename> class TOUT> template <typename T> void ObjectCache
#endif
}
}}
}
}
#endif
+1 -2
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+6 -7
View File
@@ -1,10 +1,8 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -359,7 +357,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
// check if the file contents are bundled with the BLEND file
if (img->packedfile) {
name.data[0] = '*';
name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size()));
name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(AI_MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size()));
conv_data.textures->push_back(new aiTexture());
aiTexture *curTex = conv_data.textures->back();
@@ -433,7 +431,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial *out, const Material *mat, c
(void)conv_data;
aiString name;
name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
name.length = ai_snprintf(name.data, AI_MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
GetTextureTypeDisplayString(tex->tex->type));
out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(
conv_data.next_texture[aiTextureType_DIFFUSE]++));
@@ -495,8 +493,9 @@ void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData &conv_data) {
if (index == static_cast<unsigned int>(-1)) {
// Setup a default material.
std::shared_ptr<Material> p(new Material());
ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name) - 2);
strcpy(p->id.name + 2, AI_DEFAULT_MATERIAL_NAME);
const size_t len = ::strlen(AI_DEFAULT_MATERIAL_NAME);
ai_assert(len < sizeof(p->id.name) - 2);
memcpy(p->id.name + 2, AI_DEFAULT_MATERIAL_NAME, len);
// Note: MSVC11 does not zero-initialize Material here, although it should.
// Thus all relevant fields should be explicitly initialized. We cannot add
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+2 -10
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@@ -86,7 +86,7 @@ namespace Assimp {
}
}
static const aiImporterDesc desc = {
static constexpr aiImporterDesc desc = {
"Cinema4D Importer",
"",
"",
@@ -99,13 +99,6 @@ static const aiImporterDesc desc = {
"c4d"
};
// ------------------------------------------------------------------------------------------------
C4DImporter::C4DImporter() = default;
// ------------------------------------------------------------------------------------------------
C4DImporter::~C4DImporter() = default;
// ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
const std::string& extension = GetExtension(pFile);
@@ -196,7 +189,6 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
std::copy(materials.begin(), materials.end(), pScene->mMaterials);
}
// ------------------------------------------------------------------------------------------------
bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) {
// based on Cineware sample code (C4DImportExport.cpp)
+2 -2
View File
@@ -78,8 +78,8 @@ namespace Assimp {
// -------------------------------------------------------------------------------------------
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
public:
C4DImporter();
~C4DImporter() override;
C4DImporter() = default;
~C4DImporter() override = default;
bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
protected:
+7 -5
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -228,7 +228,7 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
const Mesh &ndmesh = (const Mesh &)(root);
if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {
typedef std::pair<const unsigned int, Mesh::FaceRefList> Entry;
using Entry = std::pair<const unsigned int, Mesh::FaceRefList>;
for (const Entry &reflist : ndmesh.temp_map) {
{ // create mesh
size_t n = 0;
@@ -372,9 +372,11 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
}
// add children recursively
nd->mChildren = new aiNode *[root.temp_children.size()]();
for (const Node *n : root.temp_children) {
(nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
if (!root.temp_children.empty()) {
nd->mChildren = new aiNode *[root.temp_children.size()]();
for (const Node *n : root.temp_children) {
(nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
}
}
return nd;
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+5 -9
View File
@@ -3,9 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -73,10 +71,9 @@ static constexpr aiImporterDesc desc = {
"csm"
};
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
CSMImporter::CSMImporter() : noSkeletonMesh(){
CSMImporter::CSMImporter() : noSkeletonMesh() {
// empty
}
@@ -102,8 +99,7 @@ void CSMImporter::SetupProperties(const Importer* pImp) {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void CSMImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
aiScene* pScene, IOSystem* pIOHandler) {
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file
@@ -127,11 +123,11 @@ void CSMImporter::InternReadFile( const std::string& pFile,
if ('$' == *buffer) {
++buffer;
if (TokenMatchI(buffer,"firstframe",10)) {
if (TokenMatchI(buffer,"firstframe",10)) {
SkipSpaces(&buffer, end);
first = strtol10(buffer,&buffer);
}
else if (TokenMatchI(buffer,"lastframe",9)) {
else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer, end);
last = strtol10(buffer,&buffer);
}
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+326 -273
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -36,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
@@ -64,6 +62,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
static const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
std::set<const aiNode *> topParentBoneNodes;
if (mesh && mesh->mNumBones > 0) {
for (unsigned int i = 0; i < mesh->mNumBones; ++i) {
aiBone *bone = mesh->mBones[i];
const aiNode *node = scene->mRootNode->findBoneNode(bone);
if (node) {
while (node->mParent && scene->findBone(node->mParent->mName) != nullptr) {
node = node->mParent;
}
topParentBoneNodes.insert(node);
}
}
}
if (!topParentBoneNodes.empty()) {
const aiNode *parentBoneNode = *topParentBoneNodes.begin();
if (topParentBoneNodes.size() == 1) {
return parentBoneNode;
} else {
for (auto it : topParentBoneNodes) {
if (it->mParent) return it->mParent;
}
return parentBoneNode;
}
}
return nullptr;
}
// ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
void ExportSceneCollada(const char *pFile, IOSystem *pIOSystem, const aiScene *pScene, const ExportProperties * /*pProperties*/) {
@@ -152,10 +181,6 @@ ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, con
WriteFile();
}
// ------------------------------------------------------------------------------------------------
// Destructor
ColladaExporter::~ColladaExporter() = default;
// ------------------------------------------------------------------------------------------------
// Starts writing the contents
void ColladaExporter::WriteFile() {
@@ -331,60 +356,68 @@ void ColladaExporter::WriteHeader() {
// ------------------------------------------------------------------------------------------------
// Write the embedded textures
void ColladaExporter::WriteTextures() {
static const unsigned int buffer_size = 1024;
char str[buffer_size];
static constexpr unsigned int buffer_size = 1024;
char str[buffer_size] = {'\0'};
if (mScene->HasTextures()) {
for (unsigned int i = 0; i < mScene->mNumTextures; i++) {
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
// so we just write the textures in the current directory.
if (!mScene->HasTextures()) {
return;
}
aiTexture *texture = mScene->mTextures[i];
if (nullptr == texture) {
continue;
}
for (unsigned int i = 0; i < mScene->mNumTextures; i++) {
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
// so we just write the textures in the current directory.
ASSIMP_itoa10(str, buffer_size, i + 1);
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char *)texture->achFormatHint);
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
if (outfile == nullptr) {
throw DeadlyExportError("could not open output texture file: " + mPath + name);
}
if (texture->mHeight == 0) {
outfile->Write((void *)texture->pcData, texture->mWidth, 1);
} else {
Bitmap::Save(texture, outfile.get());
}
outfile->Flush();
textures.insert(std::make_pair(i, name));
aiTexture *texture = mScene->mTextures[i];
if (nullptr == texture) {
continue;
}
ASSIMP_itoa10(str, buffer_size, i + 1);
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char *)texture->achFormatHint);
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
if (outfile == nullptr) {
throw DeadlyExportError("could not open output texture file: " + mPath + name);
}
if (texture->mHeight == 0) {
outfile->Write((void *)texture->pcData, texture->mWidth, 1);
} else {
Bitmap::Save(texture, outfile.get());
}
outfile->Flush();
textures.insert(std::make_pair(i, name));
}
}
// ------------------------------------------------------------------------------------------------
// Write the embedded textures
void ColladaExporter::WriteCamerasLibrary() {
if (mScene->HasCameras()) {
mOutput << startstr << "<library_cameras>" << endstr;
PushTag();
for (size_t a = 0; a < mScene->mNumCameras; ++a)
WriteCamera(a);
PopTag();
mOutput << startstr << "</library_cameras>" << endstr;
if (!mScene->HasCameras()) {
return;
}
mOutput << startstr << "<library_cameras>" << endstr;
PushTag();
for (size_t a = 0; a < mScene->mNumCameras; ++a) {
WriteCamera(a);
}
PopTag();
mOutput << startstr << "</library_cameras>" << endstr;
}
void ColladaExporter::WriteCamera(size_t pIndex) {
const aiCamera *cam = mScene->mCameras[pIndex];
if (cam == nullptr) {
return;
}
const std::string cameraId = GetObjectUniqueId(AiObjectType::Camera, pIndex);
const std::string cameraName = GetObjectName(AiObjectType::Camera, pIndex);
@@ -422,22 +455,27 @@ void ColladaExporter::WriteCamera(size_t pIndex) {
// ------------------------------------------------------------------------------------------------
// Write the embedded textures
void ColladaExporter::WriteLightsLibrary() {
if (mScene->HasLights()) {
mOutput << startstr << "<library_lights>" << endstr;
PushTag();
for (size_t a = 0; a < mScene->mNumLights; ++a)
WriteLight(a);
PopTag();
mOutput << startstr << "</library_lights>" << endstr;
if (!mScene->HasLights()) {
return;
}
mOutput << startstr << "<library_lights>" << endstr;
PushTag();
for (size_t a = 0; a < mScene->mNumLights; ++a) {
WriteLight(a);
}
PopTag();
mOutput << startstr << "</library_lights>" << endstr;
}
void ColladaExporter::WriteLight(size_t pIndex) {
const aiLight *light = mScene->mLights[pIndex];
if (light == nullptr) {
return;
}
const std::string lightId = GetObjectUniqueId(AiObjectType::Light, pIndex);
const std::string lightName = GetObjectName(AiObjectType::Light, pIndex);
@@ -462,6 +500,7 @@ void ColladaExporter::WriteLight(size_t pIndex) {
case aiLightSource_AREA:
case aiLightSource_UNDEFINED:
case _aiLightSource_Force32Bit:
default:
break;
}
PopTag();
@@ -521,10 +560,6 @@ void ColladaExporter::WriteSpotLight(const aiLight *const light) {
mOutput << startstr << "<quadratic_attenuation>"
<< light->mAttenuationQuadratic
<< "</quadratic_attenuation>" << endstr;
/*
out->mAngleOuterCone = AI_DEG_TO_RAD (std::acos(std::pow(0.1f,1.f/srcLight->mFalloffExponent))+
srcLight->mFalloffAngle);
*/
const ai_real fallOffAngle = AI_RAD_TO_DEG(light->mAngleInnerCone);
mOutput << startstr << "<falloff_angle sid=\"fall_off_angle\">"
@@ -559,41 +594,43 @@ void ColladaExporter::WriteAmbientLight(const aiLight *const light) {
// ------------------------------------------------------------------------------------------------
// Reads a single surface entry from the given material keys
bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex) {
if (pSrcMat.GetTextureCount(pTexture) > 0) {
aiString texfile;
unsigned int uvChannel = 0;
pSrcMat.GetTexture(pTexture, 0, &texfile, nullptr, &uvChannel);
std::string index_str(texfile.C_Str());
if (index_str.size() != 0 && index_str[0] == '*') {
unsigned int index;
index_str = index_str.substr(1, std::string::npos);
try {
index = (unsigned int)strtoul10_64<DeadlyExportError>(index_str.c_str());
} catch (std::exception &error) {
throw DeadlyExportError(error.what());
}
std::map<unsigned int, std::string>::const_iterator name = textures.find(index);
if (name != textures.end()) {
poSurface.texture = name->second;
} else {
throw DeadlyExportError("could not find embedded texture at index " + index_str);
}
} else {
poSurface.texture = texfile.C_Str();
}
poSurface.channel = uvChannel;
poSurface.exist = true;
} else {
if (pSrcMat.GetTextureCount(pTexture) == 0) {
if (pKey)
poSurface.exist = pSrcMat.Get(pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
return poSurface.exist;
}
aiString texfile;
unsigned int uvChannel = 0;
pSrcMat.GetTexture(pTexture, 0, &texfile, nullptr, &uvChannel);
std::string index_str(texfile.C_Str());
if (index_str.size() != 0 && index_str[0] == '*') {
unsigned int index;
index_str = index_str.substr(1, std::string::npos);
try {
index = (unsigned int)strtoul10_64<DeadlyExportError>(index_str.c_str());
} catch (std::exception &error) {
throw DeadlyExportError(error.what());
}
std::map<unsigned int, std::string>::const_iterator name = textures.find(index);
if (name != textures.end()) {
poSurface.texture = name->second;
} else {
throw DeadlyExportError("could not find embedded texture at index " + index_str);
}
} else {
poSurface.texture = texfile.C_Str();
}
poSurface.channel = uvChannel;
poSurface.exist = true;
return poSurface.exist;
}
@@ -606,79 +643,87 @@ static bool isalnum_C(char c) {
// ------------------------------------------------------------------------------------------------
// Writes an image entry for the given surface
void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string &imageId) {
if (!pSurface.texture.empty()) {
mOutput << startstr << "<image id=\"" << imageId << "\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>";
// URL encode image file name first, then XML encode on top
std::stringstream imageUrlEncoded;
for (std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it) {
if (isalnum_C((unsigned char)*it) || *it == ':' || *it == '_' || *it == '-' || *it == '.' || *it == '/' || *it == '\\')
imageUrlEncoded << *it;
else
imageUrlEncoded << '%' << std::hex << size_t((unsigned char)*it) << std::dec;
}
mOutput << XMLEscape(imageUrlEncoded.str());
mOutput << "</init_from>" << endstr;
PopTag();
mOutput << startstr << "</image>" << endstr;
if (pSurface.texture.empty()) {
return;
}
mOutput << startstr << "<image id=\"" << imageId << "\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>";
// URL encode image file name first, then XML encode on top
std::stringstream imageUrlEncoded;
for (std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it) {
if (isalnum_C((unsigned char)*it) || *it == ':' || *it == '_' || *it == '-' || *it == '.' || *it == '/' || *it == '\\')
imageUrlEncoded << *it;
else
imageUrlEncoded << '%' << std::hex << size_t((unsigned char)*it) << std::dec;
}
mOutput << XMLEscape(imageUrlEncoded.str());
mOutput << "</init_from>" << endstr;
PopTag();
mOutput << startstr << "</image>" << endstr;
}
// ------------------------------------------------------------------------------------------------
// Writes a color-or-texture entry into an effect definition
void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId) {
if (pSurface.exist) {
mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag();
if (pSurface.texture.empty()) {
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
} else {
mOutput << startstr << "<texture texture=\"" << imageId << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
}
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
if (!pSurface.exist) {
return;
}
mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag();
if (pSurface.texture.empty()) {
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
} else {
mOutput << startstr << "<texture texture=\"" << imageId << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
}
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
}
// ------------------------------------------------------------------------------------------------
// Writes the two parameters necessary for referencing a texture in an effect entry
void ColladaExporter::WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId) {
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
if (!pSurface.texture.empty()) {
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-surface\">" << endstr;
PushTag();
mOutput << startstr << "<surface type=\"2D\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>" << materialId << "-" << pTypeName << "-image</init_from>" << endstr;
PopTag();
mOutput << startstr << "</surface>" << endstr;
PopTag();
mOutput << startstr << "</newparam>" << endstr;
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-sampler\">" << endstr;
PushTag();
mOutput << startstr << "<sampler2D>" << endstr;
PushTag();
mOutput << startstr << "<source>" << materialId << "-" << pTypeName << "-surface</source>" << endstr;
PopTag();
mOutput << startstr << "</sampler2D>" << endstr;
PopTag();
mOutput << startstr << "</newparam>" << endstr;
if (pSurface.texture.empty()) {
return;
}
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-surface\">" << endstr;
PushTag();
mOutput << startstr << "<surface type=\"2D\">" << endstr;
PushTag();
mOutput << startstr << "<init_from>" << materialId << "-" << pTypeName << "-image</init_from>" << endstr;
PopTag();
mOutput << startstr << "</surface>" << endstr;
PopTag();
mOutput << startstr << "</newparam>" << endstr;
mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-sampler\">" << endstr;
PushTag();
mOutput << startstr << "<sampler2D>" << endstr;
PushTag();
mOutput << startstr << "<source>" << materialId << "-" << pTypeName << "-surface</source>" << endstr;
PopTag();
mOutput << startstr << "</sampler2D>" << endstr;
PopTag();
mOutput << startstr << "</newparam>" << endstr;
}
// ------------------------------------------------------------------------------------------------
// Writes a scalar property
void ColladaExporter::WriteFloatEntry(const Property &pProperty, const std::string &pTypeName) {
if (pProperty.exist) {
mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag();
mOutput << startstr << "<float sid=\"" << pTypeName << "\">" << pProperty.value << "</float>" << endstr;
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
if (!pProperty.exist) {
return;
}
mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag();
mOutput << startstr << "<float sid=\"" << pTypeName << "\">" << pProperty.value << "</float>" << endstr;
PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr;
}
// ------------------------------------------------------------------------------------------------
@@ -832,8 +877,9 @@ void ColladaExporter::WriteControllerLibrary() {
void ColladaExporter::WriteController(size_t pIndex) {
const aiMesh *mesh = mScene->mMeshes[pIndex];
// Is there a skin controller?
if (mesh->mNumBones == 0 || mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
if (mesh->mNumBones == 0 || mesh->mNumFaces == 0 || mesh->mNumVertices == 0) {
return;
}
const std::string idstr = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
const std::string namestr = GetObjectName(AiObjectType::Mesh, pIndex);
@@ -864,8 +910,9 @@ void ColladaExporter::WriteController(size_t pIndex) {
mOutput << startstr << "<Name_array id=\"" << idstr << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
for (size_t i = 0; i < mesh->mNumBones; ++i)
for (size_t i = 0; i < mesh->mNumBones; ++i) {
mOutput << GetBoneUniqueId(mesh->mBones[i]) << ' ';
}
mOutput << "</Name_array>" << endstr;
@@ -888,9 +935,11 @@ void ColladaExporter::WriteController(size_t pIndex) {
std::vector<ai_real> bind_poses;
bind_poses.reserve(mesh->mNumBones * 16);
for (unsigned int i = 0; i < mesh->mNumBones; ++i)
for (unsigned int j = 0; j < 4; ++j)
for (unsigned int i = 0; i < mesh->mNumBones; ++i) {
for (unsigned int j = 0; j < 4; ++j) {
bind_poses.insert(bind_poses.end(), mesh->mBones[i]->mOffsetMatrix[j], mesh->mBones[i]->mOffsetMatrix[j] + 4);
}
}
WriteFloatArray(idstr + "-skin-bind_poses", FloatType_Mat4x4, (const ai_real *)bind_poses.data(), bind_poses.size() / 16);
@@ -898,9 +947,11 @@ void ColladaExporter::WriteController(size_t pIndex) {
std::vector<ai_real> skin_weights;
skin_weights.reserve(mesh->mNumVertices * mesh->mNumBones);
for (size_t i = 0; i < mesh->mNumBones; ++i)
for (size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
for (size_t i = 0; i < mesh->mNumBones; ++i) {
for (size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j) {
skin_weights.push_back(mesh->mBones[i]->mWeights[j].mWeight);
}
}
WriteFloatArray(idstr + "-skin-weights", FloatType_Weight, (const ai_real *)skin_weights.data(), skin_weights.size());
@@ -924,12 +975,15 @@ void ColladaExporter::WriteController(size_t pIndex) {
mOutput << startstr << "<vcount>";
std::vector<ai_uint> num_influences(mesh->mNumVertices, (ai_uint)0);
for (size_t i = 0; i < mesh->mNumBones; ++i)
for (size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j)
for (size_t i = 0; i < mesh->mNumBones; ++i) {
for (size_t j = 0; j < mesh->mBones[i]->mNumWeights; ++j) {
++num_influences[mesh->mBones[i]->mWeights[j].mVertexId];
}
}
for (size_t i = 0; i < mesh->mNumVertices; ++i)
for (size_t i = 0; i < mesh->mNumVertices; ++i) {
mOutput << num_influences[i] << " ";
}
mOutput << "</vcount>" << endstr;
@@ -945,7 +999,7 @@ void ColladaExporter::WriteController(size_t pIndex) {
ai_uint weight_index = 0;
std::vector<ai_int> joint_weight_indices(2 * joint_weight_indices_length, (ai_int)-1);
for (unsigned int i = 0; i < mesh->mNumBones; ++i)
for (unsigned int i = 0; i < mesh->mNumBones; ++i) {
for (unsigned j = 0; j < mesh->mBones[i]->mNumWeights; ++j) {
unsigned int vId = mesh->mBones[i]->mWeights[j].mVertexId;
for (ai_uint k = 0; k < num_influences[vId]; ++k) {
@@ -957,9 +1011,11 @@ void ColladaExporter::WriteController(size_t pIndex) {
}
++weight_index;
}
}
for (size_t i = 0; i < joint_weight_indices.size(); ++i)
for (size_t i = 0; i < joint_weight_indices.size(); ++i) {
mOutput << joint_weight_indices[i] << " ";
}
num_influences.clear();
accum_influences.clear();
@@ -983,8 +1039,9 @@ void ColladaExporter::WriteGeometryLibrary() {
mOutput << startstr << "<library_geometries>" << endstr;
PushTag();
for (size_t a = 0; a < mScene->mNumMeshes; ++a)
for (size_t a = 0; a < mScene->mNumMeshes; ++a) {
WriteGeometry(a);
}
PopTag();
mOutput << startstr << "</library_geometries>" << endstr;
@@ -997,8 +1054,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
const std::string geometryId = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
const std::string geometryName = GetObjectName(AiObjectType::Mesh, pIndex);
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0) {
return;
}
// opening tag
mOutput << startstr << "<geometry id=\"" << geometryId << "\" name=\"" << geometryName << "\" >" << endstr;
@@ -1010,8 +1068,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// Positions
WriteFloatArray(geometryId + "-positions", FloatType_Vector, (ai_real *)mesh->mVertices, mesh->mNumVertices);
// Normals, if any
if (mesh->HasNormals())
if (mesh->HasNormals()) {
WriteFloatArray(geometryId + "-normals", FloatType_Vector, (ai_real *)mesh->mNormals, mesh->mNumVertices);
}
// texture coords
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
@@ -1040,10 +1099,11 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
int countLines = 0;
int countPoly = 0;
for (size_t a = 0; a < mesh->mNumFaces; ++a) {
if (mesh->mFaces[a].mNumIndices == 2)
if (mesh->mFaces[a].mNumIndices == 2) {
countLines++;
else if (mesh->mFaces[a].mNumIndices >= 3)
} else if (mesh->mFaces[a].mNumIndices >= 3) {
countPoly++;
}
}
// lines
@@ -1051,13 +1111,18 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
mOutput << startstr << "<lines count=\"" << countLines << "\" material=\"defaultMaterial\">" << endstr;
PushTag();
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << geometryId << "-vertices\" />" << endstr;
if (mesh->HasNormals())
if (mesh->HasNormals()) {
mOutput << startstr << "<input semantic=\"NORMAL\" source=\"#" << geometryId << "-normals\" />" << endstr;
}
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(a)))
mOutput << startstr << "<input semantic=\"TEXCOORD\" source=\"#" << geometryId << "-tex" << a << "\" "
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
mOutput << startstr
<< "<input semantic=\"TEXCOORD\" source=\"#"
<< geometryId
<< "-tex" << a << "\" "
<< "set=\"" << a << "\""
<< " />" << endstr;
}
}
for (size_t a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) {
if (mesh->HasVertexColors(static_cast<unsigned int>(a)))
@@ -1070,8 +1135,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
for (size_t a = 0; a < mesh->mNumFaces; ++a) {
const aiFace &face = mesh->mFaces[a];
if (face.mNumIndices != 2) continue;
for (size_t b = 0; b < face.mNumIndices; ++b)
for (size_t b = 0; b < face.mNumIndices; ++b) {
mOutput << face.mIndices[b] << " ";
}
}
mOutput << "</p>" << endstr;
PopTag();
@@ -1085,8 +1151,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
PushTag();
mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << geometryId << "-vertices\" />" << endstr;
if (mesh->HasNormals())
if (mesh->HasNormals()) {
mOutput << startstr << "<input offset=\"0\" semantic=\"NORMAL\" source=\"#" << geometryId << "-normals\" />" << endstr;
}
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(a)))
mOutput << startstr << "<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#" << geometryId << "-tex" << a << "\" "
@@ -1111,8 +1178,9 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
for (size_t a = 0; a < mesh->mNumFaces; ++a) {
const aiFace &face = mesh->mFaces[a];
if (face.mNumIndices < 3) continue;
for (size_t b = 0; b < face.mNumIndices; ++b)
for (size_t b = 0; b < face.mNumIndices; ++b) {
mOutput << face.mIndices[b] << " ";
}
}
mOutput << "</p>" << endstr;
PopTag();
@@ -1131,13 +1199,27 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount) {
size_t floatsPerElement = 0;
switch (pType) {
case FloatType_Vector: floatsPerElement = 3; break;
case FloatType_TexCoord2: floatsPerElement = 2; break;
case FloatType_TexCoord3: floatsPerElement = 3; break;
case FloatType_Color: floatsPerElement = 3; break;
case FloatType_Mat4x4: floatsPerElement = 16; break;
case FloatType_Weight: floatsPerElement = 1; break;
case FloatType_Time: floatsPerElement = 1; break;
case FloatType_Vector:
floatsPerElement = 3;
break;
case FloatType_TexCoord2:
floatsPerElement = 2;
break;
case FloatType_TexCoord3:
floatsPerElement = 3;
break;
case FloatType_Color:
floatsPerElement = 3;
break;
case FloatType_Mat4x4:
floatsPerElement = 16;
break;
case FloatType_Weight:
floatsPerElement = 1;
break;
case FloatType_Time:
floatsPerElement = 1;
break;
default:
return;
}
@@ -1163,8 +1245,9 @@ void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataTyp
mOutput << pData[a * 4 + 2] << " ";
}
} else {
for (size_t a = 0; a < pElementCount * floatsPerElement; ++a)
for (size_t a = 0; a < pElementCount * floatsPerElement; ++a) {
mOutput << pData[a] << " ";
}
}
mOutput << "</float_array>" << endstr;
PopTag();
@@ -1256,9 +1339,13 @@ void ColladaExporter::WriteSceneLibrary() {
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
const aiAnimation *anim = mScene->mAnimations[pIndex];
if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0)
if (anim == nullptr) {
return;
}
if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0) {
return;
}
const std::string animationNameEscaped = GetObjectName(AiObjectType::Animation, pIndex);
const std::string idstrEscaped = GetObjectUniqueId(AiObjectType::Animation, pIndex);
@@ -1269,8 +1356,11 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
std::string cur_node_idstr;
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim *nodeAnim = anim->mChannels[a];
if (nodeAnim == nullptr) {
continue;
}
// sanity check
// sanity checks
if (nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys) {
continue;
}
@@ -1369,6 +1459,9 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim *nodeAnim = anim->mChannels[a];
if (nodeAnim == nullptr) {
continue;
}
{
// samplers
@@ -1387,97 +1480,42 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim *nodeAnim = anim->mChannels[a];
if (nodeAnim == nullptr) {
continue;
}
{
// channels
mOutput << startstr << "<channel source=\"#" << XMLIDEncode(nodeAnim->mNodeName.data + std::string("_matrix-sampler")) << "\" target=\"" << XMLIDEncode(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
mOutput << startstr
<< "<channel source=\"#"
<< XMLIDEncode(nodeAnim->mNodeName.data + std::string("_matrix-sampler"))
<< "\" target=\""
<< XMLIDEncode(nodeAnim->mNodeName.data)
<< "/matrix\"/>"
<< endstr;
}
}
PopTag();
mOutput << startstr << "</animation>" << endstr;
}
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationsLibrary() {
if (mScene->mNumAnimations > 0) {
mOutput << startstr << "<library_animations>" << endstr;
PushTag();
// start recursive write at the root node
for (size_t a = 0; a < mScene->mNumAnimations; ++a)
WriteAnimationLibrary(a);
PopTag();
mOutput << startstr << "</library_animations>" << endstr;
if (mScene->mNumAnimations == 0) {
return;
}
}
// ------------------------------------------------------------------------------------------------
// Helper to find a bone by name in the scene
aiBone *findBone(const aiScene *scene, const aiString &name) {
for (size_t m = 0; m < scene->mNumMeshes; m++) {
aiMesh *mesh = scene->mMeshes[m];
for (size_t b = 0; b < mesh->mNumBones; b++) {
aiBone *bone = mesh->mBones[b];
if (name == bone->mName) {
return bone;
}
}
}
return nullptr;
}
mOutput << startstr << "<library_animations>" << endstr;
PushTag();
// ------------------------------------------------------------------------------------------------
// Helper to find the node associated with a bone in the scene
const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) {
if (aNode && bone && aNode->mName == bone->mName) {
return aNode;
// start recursive write at the root node
for (size_t a = 0; a < mScene->mNumAnimations; ++a) {
WriteAnimationLibrary(a);
}
if (aNode && bone) {
for (unsigned int i = 0; i < aNode->mNumChildren; ++i) {
aiNode *aChild = aNode->mChildren[i];
const aiNode *foundFromChild = nullptr;
if (aChild) {
foundFromChild = findBoneNode(aChild, bone);
if (foundFromChild) {
return foundFromChild;
}
}
}
}
return nullptr;
}
const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
std::set<const aiNode *> topParentBoneNodes;
if (mesh && mesh->mNumBones > 0) {
for (unsigned int i = 0; i < mesh->mNumBones; ++i) {
aiBone *bone = mesh->mBones[i];
const aiNode *node = findBoneNode(scene->mRootNode, bone);
if (node) {
while (node->mParent && findBone(scene, node->mParent->mName) != nullptr) {
node = node->mParent;
}
topParentBoneNodes.insert(node);
}
}
}
if (!topParentBoneNodes.empty()) {
const aiNode *parentBoneNode = *topParentBoneNodes.begin();
if (topParentBoneNodes.size() == 1) {
return parentBoneNode;
} else {
for (auto it : topParentBoneNodes) {
if (it->mParent) return it->mParent;
}
return parentBoneNode;
}
}
return nullptr;
PopTag();
mOutput << startstr << "</library_animations>" << endstr;
}
// ------------------------------------------------------------------------------------------------
@@ -1488,13 +1526,13 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
// Assimp-specific: nodes with no name cannot be associated with bones
const char *node_type;
bool is_joint, is_skeleton_root = false;
if (pNode->mName.length == 0 || nullptr == findBone(mScene, pNode->mName)) {
if (pNode->mName.length == 0 || nullptr == mScene->findBone(pNode->mName)) {
node_type = "NODE";
is_joint = false;
} else {
node_type = "JOINT";
is_joint = true;
if (!pNode->mParent || nullptr == findBone(mScene, pNode->mParent->mName)) {
if (!pNode->mParent || nullptr == mScene->findBone(pNode->mParent->mName)) {
is_skeleton_root = true;
}
}
@@ -1532,7 +1570,6 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
}
// customized, sid should be 'matrix' to match with loader code.
//mOutput << startstr << "<matrix sid=\"transform\">";
mOutput << startstr << "<matrix sid=\"matrix\">";
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
@@ -1556,7 +1593,6 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
break;
}
}
} else
// instance every geometry
for (size_t a = 0; a < pNode->mNumMeshes; ++a) {
@@ -1612,8 +1648,9 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
}
// recurse into subnodes
for (size_t a = 0; a < pNode->mNumChildren; ++a)
for (size_t a = 0; a < pNode->mNumChildren; ++a) {
WriteNode(pNode->mChildren[a]);
}
PopTag();
mOutput << startstr << "</node>" << endstr;
@@ -1628,8 +1665,9 @@ void ColladaExporter::CreateNodeIds(const aiNode *node) {
std::string ColladaExporter::GetNodeUniqueId(const aiNode *node) {
// Use the pointer as the key. This is safe because the scene is immutable.
auto idIt = mNodeIdMap.find(node);
if (idIt != mNodeIdMap.cend())
if (idIt != mNodeIdMap.cend()) {
return idIt->second;
}
// Prefer the requested Collada Id if extant
std::string idStr;
@@ -1640,36 +1678,42 @@ std::string ColladaExporter::GetNodeUniqueId(const aiNode *node) {
idStr = node->mName.C_Str();
}
// Make sure the requested id is valid
if (idStr.empty())
if (idStr.empty()) {
idStr = "node";
else
} else {
idStr = XMLIDEncode(idStr);
}
// Ensure it's unique
idStr = MakeUniqueId(mUniqueIds, idStr, std::string());
mUniqueIds.insert(idStr);
mNodeIdMap.insert(std::make_pair(node, idStr));
return idStr;
}
std::string ColladaExporter::GetNodeName(const aiNode *node) {
if (node == nullptr) {
return std::string();
}
return XMLEscape(node->mName.C_Str());
}
std::string ColladaExporter::GetBoneUniqueId(const aiBone *bone) {
// Find the Node that is this Bone
const aiNode *boneNode = findBoneNode(mScene->mRootNode, bone);
if (boneNode == nullptr)
const aiNode *boneNode = mScene->mRootNode->findBoneNode(bone);
if (boneNode == nullptr) {
return std::string();
}
return GetNodeUniqueId(boneNode);
}
std::string ColladaExporter::GetObjectUniqueId(AiObjectType type, size_t pIndex) {
auto idIt = GetObjectIdMap(type).find(pIndex);
if (idIt != GetObjectIdMap(type).cend())
if (idIt != GetObjectIdMap(type).cend()) {
return idIt->second;
}
// Not seen this object before, create and add
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
@@ -1678,8 +1722,9 @@ std::string ColladaExporter::GetObjectUniqueId(AiObjectType type, size_t pIndex)
std::string ColladaExporter::GetObjectName(AiObjectType type, size_t pIndex) {
auto objectName = GetObjectNameMap(type).find(pIndex);
if (objectName != GetObjectNameMap(type).cend())
if (objectName != GetObjectNameMap(type).cend()) {
return objectName->second;
}
// Not seen this object before, create and add
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
@@ -1699,9 +1744,15 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
// Get the name and id postfix
switch (type) {
case AiObjectType::Mesh: name = mScene->mMeshes[index]->mName.C_Str(); break;
case AiObjectType::Material: name = mScene->mMaterials[index]->GetName().C_Str(); break;
case AiObjectType::Animation: name = mScene->mAnimations[index]->mName.C_Str(); break;
case AiObjectType::Mesh:
name = mScene->mMeshes[index]->mName.C_Str();
break;
case AiObjectType::Material:
name = mScene->mMaterials[index]->GetName().C_Str();
break;
case AiObjectType::Animation:
name = mScene->mAnimations[index]->mName.C_Str();
break;
case AiObjectType::Light:
name = mScene->mLights[index]->mName.C_Str();
idPostfix = "-light";
@@ -1710,7 +1761,8 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
name = mScene->mCameras[index]->mName.C_Str();
idPostfix = "-camera";
break;
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
case AiObjectType::Count:
throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
}
if (name.empty()) {
@@ -1728,8 +1780,9 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
idStr = XMLIDEncode(name);
}
if (!name.empty())
if (!name.empty()) {
name = XMLEscape(name);
}
idStr = MakeUniqueId(mUniqueIds, idStr, idPostfix);
@@ -1743,5 +1796,5 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
} // end of namespace Assimp
#endif
#endif
#endif // ASSIMP_BUILD_NO_COLLADA_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
+2 -3
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -72,7 +71,7 @@ public:
ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
/// Destructor
virtual ~ColladaExporter();
virtual ~ColladaExporter() = default;
protected:
/// Starts writing the contents
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+9 -8
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -247,7 +247,9 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
// add children. first the *real* ones
node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size() + instances.size());
node->mChildren = new aiNode *[node->mNumChildren];
if (node->mNumChildren != 0) {
node->mChildren = new aiNode * [node->mNumChildren];
}
for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
node->mChildren[a] = BuildHierarchy(pParser, pNode->mChildren[a]);
@@ -623,16 +625,14 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
}
// same for texture coords, as many as we have
// empty slots are not allowed, need to pack and adjust UV indexes accordingly
for (size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
dstMesh->mTextureCoords[a] = new aiVector3D[numVertices];
for (size_t b = 0; b < numVertices; ++b) {
dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
dstMesh->mTextureCoords[a][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
}
dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
++real;
dstMesh->mNumUVComponents[a] = pSrcMesh->mNumUVComponents[a];
}
}
@@ -1077,6 +1077,7 @@ static float getWeightAtKey(const std::vector<MorphTimeValues> &values, int key,
return mKey.mWeight;
}
}
// no value at key found, try to interpolate if present at other keys. if not, return zero
// TODO: interpolation
return 0.0f;
+22 -19
View File
@@ -4,8 +4,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -77,8 +76,11 @@ struct ColladaMeshIndex {
}
};
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
* more useless stuff, so I limited the data to what I think is useful for games.
/**
* @brief Loader class to read Collada scenes.
*
* Collada is over-engineered to death, with every new iteration bringing more useless stuff,
* so I limited the data to what I think is useful for games.
*/
class ColladaLoader : public BaseImporter {
public:
@@ -102,50 +104,51 @@ protected:
/// See #BaseImporter::InternReadFile for the details
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
/** Recursively constructs a scene node for the given parser node and returns it. */
/// Recursively constructs a scene node for the given parser node and returns it.
aiNode *BuildHierarchy(const ColladaParser &pParser, const Collada::Node *pNode);
/** Resolve node instances */
/// Resolve node instances
void ResolveNodeInstances(const ColladaParser &pParser, const Collada::Node *pNode,
std::vector<const Collada::Node *> &resolved);
/** Builds meshes for the given node and references them */
/// Builds meshes for the given node and references them
void BuildMeshesForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
/// Lookup for meshes by their name
aiMesh *findMesh(const std::string &meshid);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
/// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
aiMesh *CreateMesh(const ColladaParser &pParser, const Collada::Mesh *pSrcMesh, const Collada::SubMesh &pSubMesh,
const Collada::Controller *pSrcController, size_t pStartVertex, size_t pStartFace);
/** Builds cameras for the given node and references them */
/// Builds cameras for the given node and references them
void BuildCamerasForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
/** Builds lights for the given node and references them */
/// Builds lights for the given node and references them
void BuildLightsForNode(const ColladaParser &pParser, const Collada::Node *pNode,
aiNode *pTarget);
/** Stores all meshes in the given scene */
/// Stores all meshes in the given scene
void StoreSceneMeshes(aiScene *pScene);
/** Stores all materials in the given scene */
/// Stores all materials in the given scene
void StoreSceneMaterials(aiScene *pScene);
/** Stores all lights in the given scene */
/// Stores all lights in the given scene
void StoreSceneLights(aiScene *pScene);
/** Stores all cameras in the given scene */
/// Stores all cameras in the given scene
void StoreSceneCameras(aiScene *pScene);
/** Stores all textures in the given scene */
/// Stores all textures in the given scene
void StoreSceneTextures(aiScene *pScene);
/** Stores all animations
* @param pScene target scene to store the anims
*/
void StoreAnimations(aiScene *pScene, const ColladaParser &pParser);
/// Stores all animations
/// @param pScene Target scene to store the anims
/// @param parser The collada parser
void StoreAnimations(aiScene *pScene, const ColladaParser &parser);
/** Stores all animations for the given source anim and its nested child animations
* @param pScene target scene to store the anims
+31 -30
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -635,7 +635,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
const std::string &currentName = currentNode.name();
if (currentName == "morph") {
controller.mType = Morph;
controller.mMeshId = currentNode.attribute("source").as_string();
std::string id = currentNode.attribute("source").as_string();
controller.mMeshId = id.substr(1, id.size() - 1);
int methodIndex = currentNode.attribute("method").as_int();
if (methodIndex > 0) {
std::string method;
@@ -967,34 +968,34 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
SkipSpacesAndLineEnd(&content, end);
} else if (currentName == "constant_attenuation") {
XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
} else if (currentName == "linear_attenuation") {
XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
} else if (currentName == "quadratic_attenuation") {
XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
} else if (currentName == "falloff_angle") {
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
} else if (currentName == "falloff_exponent") {
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
}
// FCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "outer_cone") {
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
} else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
} else if (currentName == "intensity") {
XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
}
else if (currentName == "falloff") {
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
} else if (currentName == "hotspot_beam") {
XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
}
// OpenCOLLADA extensions
// -------------------------------------------------------
else if (currentName == "decay_falloff") {
XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
}
}
}
@@ -1009,15 +1010,15 @@ void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
if (currentName == "orthographic") {
camera.mOrtho = true;
} else if (currentName == "xfov" || currentName == "xmag") {
XmlParser::getValueAsFloat(currentNode, camera.mHorFov);
XmlParser::getValueAsReal(currentNode, camera.mHorFov);
} else if (currentName == "yfov" || currentName == "ymag") {
XmlParser::getValueAsFloat(currentNode, camera.mVerFov);
XmlParser::getValueAsReal(currentNode, camera.mVerFov);
} else if (currentName == "aspect_ratio") {
XmlParser::getValueAsFloat(currentNode, camera.mAspect);
XmlParser::getValueAsReal(currentNode, camera.mAspect);
} else if (currentName == "znear") {
XmlParser::getValueAsFloat(currentNode, camera.mZNear);
XmlParser::getValueAsReal(currentNode, camera.mZNear);
} else if (currentName == "zfar") {
XmlParser::getValueAsFloat(currentNode, camera.mZFar);
XmlParser::getValueAsReal(currentNode, camera.mZFar);
}
}
}
@@ -1169,15 +1170,15 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
} else if (currentName == "mirrorV") {
XmlParser::getValueAsBool(currentNode, out.mMirrorV);
} else if (currentName == "repeatU") {
XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.x);
XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.x);
} else if (currentName == "repeatV") {
XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.y);
XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.y);
} else if (currentName == "offsetU") {
XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.x);
XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.x);
} else if (currentName == "offsetV") {
XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.y);
XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.y);
} else if (currentName == "rotateUV") {
XmlParser::getValueAsFloat(currentNode, out.mTransform.mRotation);
XmlParser::getValueAsReal(currentNode, out.mTransform.mRotation);
} else if (currentName == "blend_mode") {
std::string v;
XmlParser::getValueAsString(currentNode, v);
@@ -1197,14 +1198,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
// OKINO extensions
// -------------------------------------------------------
else if (currentName == "weighting") {
XmlParser::getValueAsFloat(currentNode, out.mWeighting);
XmlParser::getValueAsReal(currentNode, out.mWeighting);
} else if (currentName == "mix_with_previous_layer") {
XmlParser::getValueAsFloat(currentNode, out.mMixWithPrevious);
XmlParser::getValueAsReal(currentNode, out.mMixWithPrevious);
}
// MAX3D extensions
// -------------------------------------------------------
else if (currentName == "amount") {
XmlParser::getValueAsFloat(currentNode, out.mWeighting);
XmlParser::getValueAsReal(currentNode, out.mWeighting);
}
}
}
@@ -1264,13 +1265,13 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
// ------------------------------------------------------------------------------------------------
// Reads an effect entry containing a float
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
pFloat = 0.f;
void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pReal) {
pReal = 0.f;
XmlNode floatNode = node.child("float");
if (floatNode.empty()) {
return;
}
XmlParser::getValueAsFloat(floatNode, pFloat);
XmlParser::getValueAsReal(floatNode, pReal);
}
// ------------------------------------------------------------------------------------------------
@@ -2292,9 +2293,9 @@ void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
urlMat++;
s.mMatName = urlMat;
ReadMaterialVertexInputBinding(instanceMatNode, s);
// store the association
instance.mMaterials[group] = s;
ReadMaterialVertexInputBinding(instanceMatNode, s);
}
}
}
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+9 -20
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -62,10 +61,7 @@ namespace DXF {
// do NOT skip empty lines. In DXF files, they count as valid data.
class LineReader {
public:
LineReader(StreamReaderLE& reader)
: splitter(reader,false,true)
, groupcode( 0 )
, end() {
LineReader(StreamReaderLE& reader) : splitter(reader,false,true), groupcode( 0 ), end() {
// empty
}
@@ -165,8 +161,7 @@ private:
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
struct PolyLine {
PolyLine()
: flags() {
PolyLine() : flags() {
// empty
}
@@ -182,10 +177,7 @@ struct PolyLine {
// reference to a BLOCK. Specifies its own coordinate system.
struct InsertBlock {
InsertBlock()
: pos()
, scale(1.f,1.f,1.f)
, angle() {
InsertBlock() : pos(0.f, 0.f, 0.f), scale(1.f,1.f,1.f), angle(0.0f) {
// empty
}
@@ -198,8 +190,7 @@ struct InsertBlock {
// keeps track of all geometry in a single BLOCK.
struct Block
{
struct Block {
std::vector< std::shared_ptr<PolyLine> > lines;
std::vector<InsertBlock> insertions;
@@ -207,14 +198,12 @@ struct Block
aiVector3D base;
};
struct FileData
{
struct FileData {
// note: the LAST block always contains the stuff from ENTITIES.
std::vector<Block> blocks;
};
}
} // Namespace Assimp
} // namespace DXF
} // namespace Assimp
#endif
#endif // INCLUDED_DXFHELPER_H
+1 -1
View File
@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+25 -23
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -143,31 +143,33 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, cons
// ------------------------------------------------------------------------------------------------
const AnimationCurveMap &AnimationCurveNode::Curves() const {
if (curves.empty()) {
// resolve attached animation curves
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
if (!curves.empty()) {
return curves;
}
// resolve attached animation curves
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "AnimationCurve");
for (const Connection *con : conns) {
for (const Connection *con : conns) {
// link should go for a property
if (!con->PropertyName().length()) {
continue;
}
const Object *const ob = con->SourceObject();
if (nullptr == ob) {
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
continue;
}
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
if (nullptr == anim) {
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
continue;
}
curves[con->PropertyName()] = anim;
// link should go for a property
if (!con->PropertyName().length()) {
continue;
}
const Object *const ob = con->SourceObject();
if (nullptr == ob) {
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring", &element);
continue;
}
const AnimationCurve *const anim = dynamic_cast<const AnimationCurve *>(ob);
if (nullptr == anim) {
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve", &element);
continue;
}
curves[con->PropertyName()] = anim;
}
return curves;
+10 -53
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -60,58 +59,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace FBX {
//enum Flag
//{
// e_unknown_0 = 1 << 0,
// e_unknown_1 = 1 << 1,
// e_unknown_2 = 1 << 2,
// e_unknown_3 = 1 << 3,
// e_unknown_4 = 1 << 4,
// e_unknown_5 = 1 << 5,
// e_unknown_6 = 1 << 6,
// e_unknown_7 = 1 << 7,
// e_unknown_8 = 1 << 8,
// e_unknown_9 = 1 << 9,
// e_unknown_10 = 1 << 10,
// e_unknown_11 = 1 << 11,
// e_unknown_12 = 1 << 12,
// e_unknown_13 = 1 << 13,
// e_unknown_14 = 1 << 14,
// e_unknown_15 = 1 << 15,
// e_unknown_16 = 1 << 16,
// e_unknown_17 = 1 << 17,
// e_unknown_18 = 1 << 18,
// e_unknown_19 = 1 << 19,
// e_unknown_20 = 1 << 20,
// e_unknown_21 = 1 << 21,
// e_unknown_22 = 1 << 22,
// e_unknown_23 = 1 << 23,
// e_flag_field_size_64_bit = 1 << 24, // Not sure what is
// e_unknown_25 = 1 << 25,
// e_unknown_26 = 1 << 26,
// e_unknown_27 = 1 << 27,
// e_unknown_28 = 1 << 28,
// e_unknown_29 = 1 << 29,
// e_unknown_30 = 1 << 30,
// e_unknown_31 = 1 << 31
//};
//
//bool check_flag(uint32_t flags, Flag to_check)
//{
// return (flags & to_check) != 0;
//}
// ------------------------------------------------------------------------------------------------
Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset)
:
#ifdef DEBUG
contents(sbegin, static_cast<size_t>(send-sbegin)),
#endif
sbegin(sbegin)
, send(send)
, type(type)
, line(offset)
, column(BINARY_MARKER)
{
Token::Token(const char* sbegin, const char* send, TokenType type, size_t offset) :
#ifdef DEBUG
contents(sbegin, static_cast<size_t>(send-sbegin)),
#endif
sbegin(sbegin),
send(send),
type(type),
line(offset),
column(BINARY_MARKER) {
ai_assert(sbegin);
ai_assert(send);
+3 -2
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -51,7 +51,8 @@ namespace Assimp {
namespace FBX {
static constexpr size_t NumNullRecords = 25;
const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
constexpr char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
}; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+40 -31
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -181,7 +181,9 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
if (out->mNumMeshes == 0) {
out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
} else {
correctRootTransform(mSceneOut);
// Apply the FBX axis metadata unless requested not to
if (!doc.Settings().ignoreUpDirection)
correctRootTransform(mSceneOut);
}
}
@@ -245,7 +247,7 @@ struct FBXConverter::PotentialNode {
/// todo: get bone from stack
/// todo: make map of aiBone* to aiNode*
/// then update convert clusters to the new format
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4& parent_transform) {
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
std::vector<PotentialNode> nodes;
@@ -276,7 +278,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
if (nullptr != model) {
nodes_chain.clear();
post_nodes_chain.clear();
aiMatrix4x4 new_abs_transform = parent->mTransformation;
aiMatrix4x4 new_abs_transform = parent_transform;
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
@@ -310,6 +312,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
child->mParent = last_parent;
last_parent = child.mNode;
new_abs_transform *= child->mTransformation;
}
// attach geometry
@@ -332,6 +336,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
postnode->mParent = last_parent;
last_parent = postnode.mNode;
new_abs_transform *= postnode->mTransformation;
}
} else {
// free the nodes we allocated as we don't need them
@@ -339,7 +345,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
}
// recursion call - child nodes
ConvertNodes(model->ID(), last_parent, root_node);
ConvertNodes(model->ID(), last_parent, root_node, new_abs_transform);
if (doc.Settings().readLights) {
ConvertLights(*model, node_name);
@@ -357,12 +363,12 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
if (nodes.empty()) {
parent->mNumChildren = 0;
parent->mChildren = nullptr;
}
parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
for (unsigned int i = 0; i < nodes.size(); ++i) {
parent->mChildren[i] = nodes[i].mOwnership.release();
} else {
parent->mChildren = new aiNode *[nodes.size()]();
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
for (unsigned int i = 0; i < nodes.size(); ++i) {
parent->mChildren[i] = nodes[i].mOwnership.release();
}
}
}
@@ -432,7 +438,8 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
out_light->mType = aiLightSource_UNDEFINED;
break;
default:
ai_assert(false);
FBXImporter::LogError("Not handled light type: ", light.LightType());
break;
}
float decay = light.DecayStart();
@@ -457,7 +464,7 @@ void FBXConverter::ConvertLight(const Light &light, const std::string &orig_name
out_light->mAttenuationQuadratic = 1.0f;
break;
default:
ai_assert(false);
FBXImporter::LogError("Not handled light decay type: ", light.DecayType());
break;
}
}
@@ -595,7 +602,7 @@ const char *FBXConverter::NameTransformationCompProperty(TransformationComp comp
return "GeometricRotationInverse";
case TransformationComp_GeometricTranslationInverse:
return "GeometricTranslationInverse";
case TransformationComp_MAXIMUM: // this is to silence compiler warnings
case TransformationComp_MAXIMUM:
break;
}
@@ -711,8 +718,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast<TransformationComp>(i);
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ||
comp == TransformationComp_PreRotation || comp == TransformationComp_PostRotation) {
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation) {
continue;
}
@@ -1248,9 +1254,9 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
const auto &curVertices = shapeGeometry->GetVertices();
const auto &curNormals = shapeGeometry->GetNormals();
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh, true, !curNormals.empty());
const auto &curVertices = shapeGeometry->GetVertices();
const auto &curIndices = shapeGeometry->GetIndices();
//losing channel name if using shapeGeometry->Name()
// if blendShapeChannel Name is empty or doesn't have a ".", add geoMetryName;
@@ -1266,7 +1272,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
for (size_t j = 0; j < curIndices.size(); j++) {
const unsigned int curIndex = curIndices.at(j);
aiVector3D vertex = curVertices.at(j);
aiVector3D normal = curNormals.at(j);
aiVector3D normal = curNormals.empty() ? aiVector3D() : curNormals.at(j);
unsigned int count = 0;
const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
for (unsigned int k = 0; k < count; k++) {
@@ -1486,15 +1492,15 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
const auto& curVertices = shapeGeometry->GetVertices();
const auto& curNormals = shapeGeometry->GetNormals();
aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh, true, !curNormals.empty());
const auto& curVertices = shapeGeometry->GetVertices();
const auto& curIndices = shapeGeometry->GetIndices();
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
for (size_t j = 0; j < curIndices.size(); j++) {
unsigned int curIndex = curIndices.at(j);
aiVector3D vertex = curVertices.at(j);
aiVector3D normal = curNormals.at(j);
aiVector3D normal = curNormals.empty() ? aiVector3D() : curNormals.at(j);
unsigned int count = 0;
const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
for (unsigned int k = 0; k < count; k++) {
@@ -1670,14 +1676,14 @@ void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const
//bone->mOffsetMatrix = cluster->Transform();
// store local transform link for post processing
bone->mOffsetMatrix = cluster->TransformLink();
bone->mOffsetMatrix.Inverse();
const aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
//
// Now calculate the aiVertexWeights
//
@@ -1860,7 +1866,7 @@ aiString FBXConverter::GetTexturePath(const Texture *tex) {
// We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
// This may occur on this case too, it has to be studied
path.data[0] = '*';
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index);
}
}
}
@@ -2128,6 +2134,10 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|base", aiTextureType_MAYA_BASE, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specular", aiTextureType_MAYA_SPECULAR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specularColor", aiTextureType_MAYA_SPECULAR_COLOR, mesh);
TrySetTextureProperties(out_mat, _textures, "Maya|specularRoughness", aiTextureType_MAYA_SPECULAR_ROUGHNESS, mesh);
// Maya stingray
TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
@@ -2440,7 +2450,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
// setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
path.data[0] = '*';
path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index);
}
out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
@@ -2806,7 +2816,7 @@ void FBXConverter::ProcessMorphAnimDatas(std::map<std::string, morphAnimData *>
auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo);
auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt));
auto name = aiString(FixNodeName(model->Name() + "*"));
name.length = 1 + ASSIMP_itoa10(name.data + name.length, MAXLEN - 1, geoIndex);
name.length = 1 + ASSIMP_itoa10(name.data + name.length, AI_MAXLEN - 1, geoIndex);
morphAnimData *animData;
auto animIt = morphAnimDatas->find(name.C_Str());
if (animIt == morphAnimDatas->end()) {
@@ -3406,7 +3416,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
KeyFrameListList inputs;
inputs.reserve(nodes.size() * 3);
//give some breathing room for rounding errors
// give some breathing room for rounding errors
const int64_t adj_start = start - 10000;
const int64_t adj_stop = stop + 10000;
@@ -3432,7 +3442,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
ai_assert(curve->GetKeys().size() == curve->GetValues().size());
ai_assert(curve->GetKeys().size());
//get values within the start/stop time window
// get values within the start/stop time window
std::shared_ptr<KeyTimeList> Keys(new KeyTimeList());
std::shared_ptr<KeyValueList> Values(new KeyValueList());
const size_t count = curve->GetKeys().size();
@@ -3452,8 +3462,7 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
if (tnew >= adj_start && tnew <= adj_stop) {
Keys->push_back(tnew);
Values->push_back(vnew);
}
else {
} else {
// Something broke
break;
}
+3 -4
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -70,7 +69,7 @@ struct morphKeyData {
std::vector<unsigned int> values;
std::vector<float> weights;
};
typedef std::map<int64_t, morphKeyData*> morphAnimData;
using morphAnimData = std::map<int64_t, morphKeyData*> ;
namespace Assimp {
namespace FBX {
@@ -134,7 +133,7 @@ private:
// ------------------------------------------------------------------------------------------------
// collect and assign child nodes
void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4& parent_transform = aiMatrix4x4());
// ------------------------------------------------------------------------------------------------
void ConvertLights(const Model& model, const std::string &orig_name );
+6 -19
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -65,9 +65,6 @@ Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, con
props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
}
// ------------------------------------------------------------------------------------------------
Deformer::~Deformer() = default;
// ------------------------------------------------------------------------------------------------
Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Deformer(id,element,doc,name)
@@ -113,10 +110,6 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
}
}
// ------------------------------------------------------------------------------------------------
Cluster::~Cluster() = default;
// ------------------------------------------------------------------------------------------------
Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Deformer(id,element,doc,name)
@@ -142,9 +135,6 @@ Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::
}
}
// ------------------------------------------------------------------------------------------------
Skin::~Skin() = default;
// ------------------------------------------------------------------------------------------------
BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Deformer(id, element, doc, name)
@@ -161,8 +151,7 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
}
}
}
// ------------------------------------------------------------------------------------------------
BlendShape::~BlendShape() = default;
// ------------------------------------------------------------------------------------------------
BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name)
: Deformer(id, element, doc, name)
@@ -188,10 +177,8 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
}
}
}
// ------------------------------------------------------------------------------------------------
BlendShapeChannel::~BlendShapeChannel() = default;
// ------------------------------------------------------------------------------------------------
}
}
#endif
} // namespace FBX
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
+9 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -663,6 +663,10 @@ LazyObject& Connection::LazyDestinationObject() const {
const Object* Connection::SourceObject() const {
LazyObject* const lazy = doc.GetObject(src);
ai_assert(lazy);
if (lazy == nullptr) {
return nullptr;
}
return lazy->Get();
}
@@ -670,6 +674,10 @@ const Object* Connection::SourceObject() const {
const Object* Connection::DestinationObject() const {
LazyObject* const lazy = doc.GetObject(dest);
ai_assert(lazy);
if (lazy == nullptr) {
return nullptr;
}
return lazy->Get();
}
+8 -8
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -657,11 +657,11 @@ private:
};
/** DOM class for generic FBX materials */
class Material : public Object {
class Material final : public Object {
public:
Material(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Material();
~Material() override = default;
const std::string& GetShadingModel() const {
return shading;
@@ -835,7 +835,7 @@ private:
class Deformer : public Object {
public:
Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Deformer();
virtual ~Deformer() = default;
const PropertyTable& Props() const {
ai_assert(props.get());
@@ -855,7 +855,7 @@ class BlendShapeChannel : public Deformer {
public:
BlendShapeChannel(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~BlendShapeChannel();
virtual ~BlendShapeChannel() = default;
float DeformPercent() const {
return percent;
@@ -880,7 +880,7 @@ class BlendShape : public Deformer {
public:
BlendShape(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~BlendShape();
virtual ~BlendShape() = default;
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
return blendShapeChannels;
@@ -895,7 +895,7 @@ class Cluster : public Deformer {
public:
Cluster(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Cluster();
virtual ~Cluster() = default;
/** get the list of deformer weights associated with this cluster.
* Use #GetIndices() to get the associated vertices. Both arrays
@@ -939,7 +939,7 @@ class Skin : public Deformer {
public:
Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name);
virtual ~Skin();
virtual ~Skin() = default;
float DeformAccuracy() const {
return accuracy;
+11 -16
View File
@@ -2,8 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -36,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
@@ -81,8 +79,7 @@ void DOMWarning(const std::string& message, const Token& token) {
}
// ------------------------------------------------------------------------------------------------
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/)
{
void DOMWarning(const std::string& message, const Element* element /*= nullptr*/) {
if(element) {
DOMWarning(message,element->KeyToken());
return;
@@ -92,41 +89,39 @@ void DOMWarning(const std::string& message, const Element* element /*= nullptr*/
}
}
// ------------------------------------------------------------------------------------------------
// fetch a property table and the corresponding property template
std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
const std::string& templateName,
const Element &element,
const Scope& sc,
bool no_warn /*= false*/)
{
const std::string& templateName,
const Element &element,
const Scope& sc,
bool no_warn /*= false*/) {
const Element* const Properties70 = sc["Properties70"];
std::shared_ptr<const PropertyTable> templateProps = std::shared_ptr<const PropertyTable>(
static_cast<const PropertyTable *>(nullptr));
if(templateName.length()) {
if (templateName.length()) {
PropertyTemplateMap::const_iterator it = doc.Templates().find(templateName);
if(it != doc.Templates().end()) {
templateProps = (*it).second;
}
}
if(!Properties70 || !Properties70->Compound()) {
if (!Properties70 || !Properties70->Compound()) {
if(!no_warn) {
DOMWarning("property table (Properties70) not found",&element);
}
if(templateProps) {
return templateProps;
}
else {
} else {
return std::make_shared<const PropertyTable>();
}
}
return std::make_shared<const PropertyTable>(*Properties70,templateProps);
}
} // !Util
} // !FBX
} // !Assimp
#endif
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
+1 -1
View File
@@ -114,4 +114,4 @@ inline const T* ProcessSimpleConnection(const Connection& con,
} //!FBX
} //!Assimp
#endif
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
+14 -21
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -35,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_EXPORT
@@ -55,37 +54,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> // shared_ptr
namespace Assimp {
// AddP70<type> helpers... there's no usable pattern here,
// so all are defined as separate functions.
// Even "animatable" properties are often completely different
// from the standard (nonanimated) property definition,
// so they are specified with an 'A' suffix.
void FBX::Node::AddP70int(
const std::string& cur_name, int32_t value
) {
void FBX::Node::AddP70int(const std::string& cur_name, int32_t value) {
FBX::Node n("P");
n.AddProperties(cur_name, "int", "Integer", "", value);
AddChild(n);
}
void FBX::Node::AddP70bool(
const std::string& cur_name, bool value
) {
void FBX::Node::AddP70bool(const std::string& cur_name, bool value) {
FBX::Node n("P");
n.AddProperties(cur_name, "bool", "", "", int32_t(value));
AddChild(n);
}
void FBX::Node::AddP70double(
const std::string &cur_name, double value) {
FBX::Node n("P");
void FBX::Node::AddP70double(const std::string &cur_name, double value) { FBX::Node n("P");
n.AddProperties(cur_name, "double", "Number", "", value);
AddChild(n);
}
void FBX::Node::AddP70numberA(
const std::string &cur_name, double value) {
void FBX::Node::AddP70numberA(const std::string &cur_name, double value) {
FBX::Node n("P");
n.AddProperties(cur_name, "Number", "", "A", value);
AddChild(n);
@@ -405,8 +398,7 @@ void FBX::Node::DumpChildrenAscii(std::ostream& s, int indent)
}
}
void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children)
{
void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children) {
if (!has_children) { return; } // nothing to do
s << '\n';
for (int i = 0; i < indent; ++i) { s << '\t'; }
@@ -417,11 +409,10 @@ void FBX::Node::EndAscii(std::ostream& s, int indent, bool has_children)
// ascii property node from vector of doubles
void FBX::Node::WritePropertyNodeAscii(
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s,
int indent
){
const std::string& name,
const std::vector<double>& v,
Assimp::StreamWriterLE& s,
int indent){
char buffer[32];
FBX::Node node(name);
node.Begin(s, false, indent);
@@ -556,6 +547,8 @@ void FBX::Node::WritePropertyNode(
FBX::Node::WritePropertyNodeAscii(name, v, s, indent);
}
}
}
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
+27 -36
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -35,7 +35,6 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
@@ -70,7 +69,6 @@ public:
// some nodes always pretend they have children...
bool force_has_children = false;
public: // constructors
/// The default class constructor.
Node() = default;
@@ -89,7 +87,6 @@ public: // constructors
AddProperties(std::forward<More>(more)...);
}
public: // functions to add properties or children
// add a single property to the node
template <typename T>
void AddProperty(T&& value) {
@@ -118,8 +115,6 @@ public: // functions to add properties or children
children.push_back(std::move(c));
}
public: // support specifically for dealing with Properties70 nodes
// it really is simpler to make these all separate functions.
// the versions with 'A' suffixes are for animatable properties.
// those often follow a completely different format internally in FBX.
@@ -150,8 +145,6 @@ public: // support specifically for dealing with Properties70 nodes
AddChild(n);
}
public: // member functions for writing data to a file or stream
// write the full node to the given file or stream
void Dump(
const std::shared_ptr<Assimp::IOStream> &outfile,
@@ -175,31 +168,6 @@ public: // member functions for writing data to a file or stream
bool has_children
);
private: // internal functions used for writing
void DumpBinary(Assimp::StreamWriterLE &s);
void DumpAscii(Assimp::StreamWriterLE &s, int indent);
void DumpAscii(std::ostream &s, int indent);
void BeginBinary(Assimp::StreamWriterLE &s);
void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
void DumpChildrenBinary(Assimp::StreamWriterLE& s);
void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
void BeginAscii(std::ostream &s, int indent);
void DumpPropertiesAscii(std::ostream &s, int indent);
void BeginChildrenAscii(std::ostream &s, int indent);
void DumpChildrenAscii(std::ostream &s, int indent);
void EndAscii(std::ostream &s, int indent, bool has_children);
private: // data used for binary dumps
size_t start_pos; // starting position in stream
size_t end_pos; // ending position in stream
size_t property_start; // starting position of property section
public: // static member functions
// convenience function to create a node with a single property,
// and write it to the stream.
@@ -235,7 +203,26 @@ public: // static member functions
bool binary, int indent
);
private: // static helper functions
private: // internal functions used for writing
void DumpBinary(Assimp::StreamWriterLE &s);
void DumpAscii(Assimp::StreamWriterLE &s, int indent);
void DumpAscii(std::ostream &s, int indent);
void BeginBinary(Assimp::StreamWriterLE &s);
void DumpPropertiesBinary(Assimp::StreamWriterLE& s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s);
void EndPropertiesBinary(Assimp::StreamWriterLE &s, size_t num_properties);
void DumpChildrenBinary(Assimp::StreamWriterLE& s);
void EndBinary(Assimp::StreamWriterLE &s, bool has_children);
void BeginAscii(std::ostream &s, int indent);
void DumpPropertiesAscii(std::ostream &s, int indent);
void BeginChildrenAscii(std::ostream &s, int indent);
void DumpChildrenAscii(std::ostream &s, int indent);
void EndAscii(std::ostream &s, int indent, bool has_children);
// static helper functions
static void WritePropertyNodeAscii(
const std::string& name,
const std::vector<double>& v,
@@ -259,9 +246,13 @@ private: // static helper functions
Assimp::StreamWriterLE& s
);
private: // data used for binary dumps
size_t start_pos; // starting position in stream
size_t end_pos; // ending position in stream
size_t property_start; // starting position of property section
};
}
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXEXPORTNODE_H_INC
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+1 -1
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
+341 -323
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -370,12 +370,6 @@ void FBXExporter::WriteHeaderExtension ()
"Creator", creator.str(), outstream, binary, indent
);
//FBX::Node sceneinfo("SceneInfo");
//sceneinfo.AddProperty("GlobalInfo" + FBX::SEPARATOR + "SceneInfo");
// not sure if any of this is actually needed,
// so just write an empty node for now.
//sceneinfo.Dump(outstream, binary, indent);
indent = 0;
// finish node
@@ -459,11 +453,7 @@ void WritePropString(const aiScene* scene, FBX::Node& p, const std::string& key,
}
}
void FBXExporter::WriteGlobalSettings ()
{
if (!binary) {
// no title, follows directly from the header extension
}
void FBXExporter::WriteGlobalSettings () {
FBX::Node gs("GlobalSettings");
gs.AddChild("Version", int32_t(1000));
@@ -493,8 +483,7 @@ void FBXExporter::WriteGlobalSettings ()
gs.Dump(outfile, binary, 0);
}
void FBXExporter::WriteDocuments ()
{
void FBXExporter::WriteDocuments() {
if (!binary) {
WriteAsciiSectionHeader("Documents Description");
}
@@ -523,8 +512,7 @@ void FBXExporter::WriteDocuments ()
docs.Dump(outfile, binary, 0);
}
void FBXExporter::WriteReferences ()
{
void FBXExporter::WriteReferences() {
if (!binary) {
WriteAsciiSectionHeader("Document References");
}
@@ -540,7 +528,6 @@ void FBXExporter::WriteReferences ()
// some internal helper functions used for writing the definitions
// (before any actual data is written)
// ---------------------------------------------------------------
size_t count_nodes(const aiNode* n, const aiNode* root) {
size_t count;
if (n == root) {
@@ -556,8 +543,7 @@ size_t count_nodes(const aiNode* n, const aiNode* root) {
return count;
}
bool has_phong_mat(const aiScene* scene)
{
static bool has_phong_mat(const aiScene* scene) {
// just search for any material with a shininess exponent
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
aiMaterial* mat = scene->mMaterials[i];
@@ -570,16 +556,12 @@ bool has_phong_mat(const aiScene* scene)
return false;
}
size_t count_images(const aiScene* scene) {
static size_t count_images(const aiScene* scene) {
std::unordered_set<std::string> images;
aiString texpath;
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
aiMaterial* mat = scene->mMaterials[i];
for (
size_t tt = aiTextureType_DIFFUSE;
tt < aiTextureType_UNKNOWN;
++tt
){
aiMaterial *mat = scene->mMaterials[i];
for (size_t tt = aiTextureType_DIFFUSE; tt < aiTextureType_UNKNOWN; ++tt) {
const aiTextureType textype = static_cast<aiTextureType>(tt);
const size_t texcount = mat->GetTextureCount(textype);
for (unsigned int j = 0; j < texcount; ++j) {
@@ -588,10 +570,11 @@ size_t count_images(const aiScene* scene) {
}
}
}
return images.size();
}
size_t count_textures(const aiScene* scene) {
static size_t count_textures(const aiScene* scene) {
size_t count = 0;
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
aiMaterial* mat = scene->mMaterials[i];
@@ -609,7 +592,7 @@ size_t count_textures(const aiScene* scene) {
return count;
}
size_t count_deformers(const aiScene* scene) {
static size_t count_deformers(const aiScene* scene) {
size_t count = 0;
for (size_t i = 0; i < scene->mNumMeshes; ++i) {
const size_t n = scene->mMeshes[i]->mNumBones;
@@ -621,8 +604,7 @@ size_t count_deformers(const aiScene* scene) {
return count;
}
void FBXExporter::WriteDefinitions ()
{
void FBXExporter::WriteDefinitions () {
// basically this is just bookkeeping:
// determining how many of each type of object there are
// and specifying the base properties to use when otherwise unspecified.
@@ -1033,9 +1015,7 @@ void FBXExporter::WriteDefinitions ()
// some internal helper functions used for writing the objects section
// (which holds the actual data)
// -------------------------------------------------------------------
aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node)
{
static aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node) {
for (size_t i = 0; i < node->mNumMeshes; ++i) {
if (node->mMeshes[i] == meshIndex) {
return node;
@@ -1048,10 +1028,9 @@ aiNode* get_node_for_mesh(unsigned int meshIndex, aiNode* node)
return nullptr;
}
aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene)
{
aiMatrix4x4 get_world_transform(const aiNode* node, const aiScene* scene) {
std::vector<const aiNode*> node_chain;
while (node != scene->mRootNode) {
while (node != scene->mRootNode && node != nullptr) {
node_chain.push_back(node);
node = node->mParent;
}
@@ -1073,8 +1052,7 @@ inline int64_t to_ktime(double time) {
return (static_cast<int64_t>(time * FBX::SECOND));
}
void FBXExporter::WriteObjects ()
{
void FBXExporter::WriteObjects () {
if (!binary) {
WriteAsciiSectionHeader("Object properties");
}
@@ -1087,21 +1065,28 @@ void FBXExporter::WriteObjects ()
object_node.BeginChildren(outstream, binary, indent);
bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
// save vertex_indices as it is needed later
std::vector<std::vector<int32_t>> vVertexIndice(mScene->mNumMeshes);
std::vector<uint32_t> uniq_v_before_mi;
const auto bTransparencyFactorReferencedToOpacity = mProperties->GetPropertyBool(AI_CONFIG_EXPORT_FBX_TRANSPARENCY_FACTOR_REFER_TO_OPACITY, false);
// geometry (aiMesh)
mesh_uids.clear();
indent = 1;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
// it's all about this mesh
aiMesh* m = mScene->mMeshes[mi];
std::function<void(const aiNode*)> visit_node_geo = [&](const aiNode *node) {
if (node->mNumMeshes == 0) {
for (uint32_t ni = 0; ni < node->mNumChildren; ni++) {
visit_node_geo(node->mChildren[ni]);
}
return;
}
// start the node record
FBX::Node n("Geometry");
int64_t uid = generate_uid();
mesh_uids.push_back(uid);
mesh_uids[node] = uid;
n.AddProperty(uid);
n.AddProperty(FBX::SEPARATOR + "Geometry");
n.AddProperty("Mesh");
@@ -1109,160 +1094,112 @@ void FBXExporter::WriteObjects ()
n.DumpProperties(outstream, binary, indent);
n.EndProperties(outstream, binary, indent);
n.BeginChildren(outstream, binary, indent);
indent = 2;
// output vertex data - each vertex should be unique (probably)
std::vector<double> flattened_vertices;
// index of original vertex in vertex data vector
std::vector<int32_t> vertex_indices;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
if(bJoinIdenticalVertices){
int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi];
auto elem = index_by_vertex_value.find(vtx);
if (elem == index_by_vertex_value.end()) {
vertex_indices.push_back(index);
index_by_vertex_value[vtx] = index;
flattened_vertices.push_back(vtx[0]);
flattened_vertices.push_back(vtx[1]);
flattened_vertices.push_back(vtx[2]);
++index;
} else {
vertex_indices.push_back(int32_t(elem->second));
}
}
}
else { // do not join vertex, respect the export flag
vertex_indices.resize(m->mNumVertices);
std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
aiVector3D vtx = m->mVertices[v];
flattened_vertices.push_back(vtx.x);
flattened_vertices.push_back(vtx.y);
flattened_vertices.push_back(vtx.z);
}
}
vVertexIndice.push_back(vertex_indices);
FBX::Node::WritePropertyNode(
"Vertices", flattened_vertices, outstream, binary, indent
);
std::vector<double> normal_data;
std::vector<double> color_data;
std::vector<int32_t> polygon_data;
std::vector<std::vector<double>> uv_data;
std::vector<std::vector<int32_t>> uv_indices;
std::map<aiVector3D, int32_t> index_by_uv;
std::vector<int32_t> offsets = { 0 };
indent = 2;
for (uint32_t n_mi = 0; n_mi < node->mNumMeshes; n_mi++) {
const auto mi = node->mMeshes[n_mi];
const aiMesh *m = mScene->mMeshes[mi];
size_t v_offset = vertex_indices.size();
size_t uniq_v_before = flattened_vertices.size() / 3;
// map of vertex value to its index in the data vector
std::map<aiVector3D,size_t> index_by_vertex_value;
if(bJoinIdenticalVertices){
int32_t index = 0;
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
aiVector3D vtx = m->mVertices[vi];
auto elem = index_by_vertex_value.find(vtx);
if (elem == index_by_vertex_value.end()) {
vertex_indices.push_back(index);
index_by_vertex_value[vtx] = index;
flattened_vertices.insert(flattened_vertices.end(), { vtx.x, vtx.y, vtx.z });
++index;
} else {
vertex_indices.push_back(int32_t(elem->second));
}
}
} else { // do not join vertex, respect the export flag
vertex_indices.resize(v_offset + m->mNumVertices);
std::iota(vertex_indices.begin() + v_offset, vertex_indices.end(), (int)v_offset);
for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
aiVector3D vtx = m->mVertices[v];
flattened_vertices.insert(flattened_vertices.end(), {vtx.x, vtx.y, vtx.z});
}
}
vVertexIndice[mi].insert(
// TODO test whether this can be end or not
vVertexIndice[mi].begin(),
vertex_indices.begin(),
vertex_indices.end()
);
// here could be edges but they're insane.
// it's optional anyway, so let's ignore it.
// output polygon data as a flattened array of vertex indices.
// the last vertex index of each polygon is negated and - 1
std::vector<int32_t> polygon_data;
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices - 1; ++pvi) {
polygon_data.push_back(vertex_indices[f.mIndices[pvi]]);
size_t pvi = 0;
for (; pvi < f.mNumIndices - 1; pvi++) {
polygon_data.push_back(
static_cast<int32_t>(uniq_v_before + vertex_indices[v_offset + f.mIndices[pvi]])
);
}
polygon_data.push_back(
-1 - vertex_indices[f.mIndices[f.mNumIndices-1]]
static_cast<int32_t>(-1 - (uniq_v_before + vertex_indices[v_offset+f.mIndices[pvi]]))
);
}
FBX::Node::WritePropertyNode(
"PolygonVertexIndex", polygon_data, outstream, binary, indent
);
}
// here could be edges but they're insane.
// it's optional anyway, so let's ignore it.
uniq_v_before_mi.push_back(static_cast<uint32_t>(uniq_v_before));
FBX::Node::WritePropertyNode(
"GeometryVersion", int32_t(124), outstream, binary, indent
);
// normals, if any
if (m->HasNormals()) {
FBX::Node normals("LayerElementNormal", int32_t(0));
normals.Begin(outstream, binary, indent);
normals.DumpProperties(outstream, binary, indent);
normals.EndProperties(outstream, binary, indent);
normals.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode(
"Version", int32_t(101), outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"Name", "", outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"MappingInformationType", "ByPolygonVertex",
outstream, binary, indent
);
// TODO: vertex-normals or indexed normals when appropriate
FBX::Node::WritePropertyNode(
"ReferenceInformationType", "Direct",
outstream, binary, indent
);
std::vector<double> normal_data;
if (m->HasNormals()) {
normal_data.reserve(3 * polygon_data.size());
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
normal_data.push_back(curN.x);
normal_data.push_back(curN.y);
normal_data.push_back(curN.z);
}
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
const aiFace & f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
const aiVector3D &curN = m->mNormals[f.mIndices[pvi]];
normal_data.insert(normal_data.end(), { curN.x, curN.y, curN.z });
}
}
FBX::Node::WritePropertyNode(
"Normals", normal_data, outstream, binary, indent
);
// note: version 102 has a NormalsW also... not sure what it is,
// so we can stick with version 101 for now.
indent = 2;
normals.End(outstream, binary, indent, true);
}
}
// colors, if any
// TODO only one color channel currently
const int32_t colorChannelIndex = 0;
if (m->HasVertexColors(colorChannelIndex)) {
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
vertexcolors.Begin(outstream, binary, indent);
vertexcolors.DumpProperties(outstream, binary, indent);
vertexcolors.EndProperties(outstream, binary, indent);
vertexcolors.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode(
"Version", int32_t(101), outstream, binary, indent
);
char layerName[8];
snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
FBX::Node::WritePropertyNode(
"Name", (const char*)layerName, outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"MappingInformationType", "ByPolygonVertex",
outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"ReferenceInformationType", "Direct",
outstream, binary, indent
);
std::vector<double> color_data;
const int32_t colorChannelIndex = 0;
if (m->HasVertexColors(colorChannelIndex)) {
color_data.reserve(4 * polygon_data.size());
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
color_data.push_back(c.r);
color_data.push_back(c.g);
color_data.push_back(c.b);
color_data.push_back(c.a);
}
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
color_data.insert(color_data.end(), { c.r, c.g, c.b, c.a });
}
}
FBX::Node::WritePropertyNode(
"Colors", color_data, outstream, binary, indent
);
indent = 2;
vertexcolors.End(outstream, binary, indent, true);
}
}
// uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
const auto num_uv = static_cast<size_t>(m->GetNumUVChannels());
uv_indices.resize(std::max(num_uv, uv_indices.size()));
uv_data.resize(std::max(num_uv, uv_data.size()));
// uvs, if any
for (size_t uvi = 0; uvi < m->GetNumUVChannels(); uvi++) {
if (m->mNumUVComponents[uvi] > 2) {
// FBX only supports 2-channel UV maps...
// or at least i'm not sure how to indicate a different number
@@ -1278,71 +1215,111 @@ void FBXExporter::WriteObjects ()
err << " but may be incorrectly interpreted on load.";
ASSIMP_LOG_WARN(err.str());
}
FBX::Node uv("LayerElementUV", int32_t(uvi));
uv.Begin(outstream, binary, indent);
uv.DumpProperties(outstream, binary, indent);
uv.EndProperties(outstream, binary, indent);
uv.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode(
"Version", int32_t(101), outstream, binary, indent
);
// it doesn't seem like assimp keeps the uv map name,
// so just leave it blank.
FBX::Node::WritePropertyNode(
"Name", "", outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"MappingInformationType", "ByPolygonVertex",
outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"ReferenceInformationType", "IndexToDirect",
outstream, binary, indent
);
std::vector<double> uv_data;
std::vector<int32_t> uv_indices;
std::map<aiVector3D,int32_t> index_by_uv;
int32_t index = 0;
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
const aiVector3D &curUv =
m->mTextureCoords[uvi][f.mIndices[pvi]];
auto elem = index_by_uv.find(curUv);
if (elem == index_by_uv.end()) {
index_by_uv[curUv] = index;
uv_indices.push_back(index);
for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) {
uv_data.push_back(curUv[x]);
}
++index;
} else {
uv_indices.push_back(elem->second);
}
for (size_t fi = 0; fi < m->mNumFaces; fi++) {
const aiFace &f = m->mFaces[fi];
for (size_t pvi = 0; pvi < f.mNumIndices; pvi++) {
const aiVector3D &curUv = m->mTextureCoords[uvi][f.mIndices[pvi]];
auto elem = index_by_uv.find(curUv);
if (elem == index_by_uv.end()) {
index_by_uv[curUv] = index;
uv_indices[uvi].push_back(index);
for (uint32_t x = 0; x < m->mNumUVComponents[uvi]; ++x) {
uv_data[uvi].push_back(curUv[x]);
}
++index;
} else {
uv_indices[uvi].push_back(elem->second);
}
}
}
FBX::Node::WritePropertyNode(
"UV", uv_data, outstream, binary, indent
);
FBX::Node::WritePropertyNode(
"UVIndex", uv_indices, outstream, binary, indent
);
indent = 2;
uv.End(outstream, binary, indent, true);
}
offsets.push_back((int32_t)polygon_data.size());
}
// i'm not really sure why this material section exists,
// as the material is linked via "Connections".
// it seems to always have the same "0" value.
FBX::Node::WritePropertyNode("Vertices", flattened_vertices, outstream, binary, indent);
FBX::Node::WritePropertyNode("PolygonVertexIndex", polygon_data, outstream, binary, indent);
FBX::Node::WritePropertyNode("GeometryVersion", int32_t(124), outstream, binary, indent);
FBX::Node normals("LayerElementNormal", int32_t(0));
normals.Begin(outstream, binary, indent);
normals.DumpProperties(outstream, binary, indent);
normals.EndProperties(outstream, binary, indent);
normals.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode("Version", int32_t(101),outstream,binary,indent);
FBX::Node::WritePropertyNode("Name", "",outstream,binary,indent);
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex",outstream,binary,indent);
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct",outstream,binary,indent);
FBX::Node::WritePropertyNode("Normals", normal_data,outstream,binary,indent);
// note: version 102 has a NormalsW also... not sure what it is,
// so stick with version 101 for now.
indent = 2;
normals.End(outstream,binary,indent,true);
const auto colorChannelIndex = 0;
FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
vertexcolors.Begin(outstream, binary, indent);
vertexcolors.DumpProperties(outstream, binary, indent);
vertexcolors.EndProperties(outstream, binary, indent);
vertexcolors.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
char layerName[8];
snprintf(layerName, sizeof(layerName), "COLOR_%d", colorChannelIndex);
FBX::Node::WritePropertyNode("Name", (const char *)layerName, outstream, binary, indent);
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolygonVertex", outstream, binary, indent);
FBX::Node::WritePropertyNode("ReferenceInformationType", "Direct", outstream, binary, indent);
FBX::Node::WritePropertyNode("Colors", color_data, outstream, binary, indent);
indent = 2;
vertexcolors.End(outstream, binary, indent, true);
for (uint32_t uvi = 0; uvi < uv_data.size(); uvi++) {
FBX::Node uv("LayerElementUV", int32_t(uvi));
uv.Begin(outstream, binary, indent);
uv.DumpProperties(outstream, binary, indent);
uv.EndProperties(outstream, binary, indent);
uv.BeginChildren(outstream, binary, indent);
indent = 3;
FBX::Node::WritePropertyNode("Version", int32_t(101), outstream, binary, indent);
FBX::Node::WritePropertyNode("Name", "", outstream, binary, indent);
FBX::Node::WritePropertyNode("MappingInformationType", "ByPolgonVertex", outstream, binary, indent);
FBX::Node::WritePropertyNode("ReferenceInformationType", "IndexToDirect", outstream, binary, indent);
FBX::Node::WritePropertyNode("UV", uv_data[uvi], outstream, binary, indent);
FBX::Node::WritePropertyNode("UVIndex", uv_indices[uvi], outstream, binary, indent);
indent = 2;
uv.End(outstream, binary, indent, true);
}
// When merging multiple meshes, we instead use by polygon so the correct material is
// assigned to each face. Previously, this LayerElementMaterial always had 0 since it
// assumed there was 1 material for each node for all meshes.
FBX::Node mat("LayerElementMaterial", int32_t(0));
mat.AddChild("Version", int32_t(101));
mat.AddChild("Name", "");
mat.AddChild("MappingInformationType", "AllSame");
mat.AddChild("ReferenceInformationType", "IndexToDirect");
std::vector<int32_t> mat_indices = {0};
mat.AddChild("Materials", mat_indices);
if (node->mNumMeshes == 1) {
mat.AddChild("MappingInformationType", "AllSame");
mat.AddChild("ReferenceInformationType", "IndexToDirect");
std::vector<int32_t> mat_indices = {0};
mat.AddChild("Materials", mat_indices);
} else {
mat.AddChild("MappingInformationType", "ByPolygon");
mat.AddChild("ReferenceInformationType", "IndexToDirect");
std::vector<int32_t> mat_indices(polygon_data.size());
uint32_t curr_offset = 0;
for (uint32_t mi = 0; mi < node->mNumMeshes; mi++) {
uint32_t num_faces = mScene->mMeshes[node->mMeshes[mi]]->mNumFaces;
for (uint32_t fi = 0; fi < num_faces; fi++) {
mat_indices[curr_offset + fi] = mi;
}
curr_offset += num_faces;
}
mat.AddChild("Materials", mat_indices);
}
mat.Dump(outstream, binary, indent);
// finally we have the layer specifications,
@@ -1354,11 +1331,12 @@ void FBXExporter::WriteObjects ()
le.AddChild("Type", "LayerElementNormal");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
// TODO only 1 color channel currently
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementColor");
le.AddChild("TypedIndex", int32_t(0));
layer.AddChild(le);
le = FBX::Node("LayerElement");
le.AddChild("Type", "LayerElementMaterial");
le.AddChild("TypedIndex", int32_t(0));
@@ -1369,8 +1347,7 @@ void FBXExporter::WriteObjects ()
layer.AddChild(le);
layer.Dump(outstream, binary, indent);
for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
{
for(unsigned int lr = 1; lr < uv_data.size(); ++ lr) {
FBX::Node layerExtra("Layer", int32_t(lr));
layerExtra.AddChild("Version", int32_t(100));
FBX::Node leExtra("LayerElement");
@@ -1382,7 +1359,14 @@ void FBXExporter::WriteObjects ()
// finish the node record
indent = 1;
n.End(outstream, binary, indent, true);
}
for (uint32_t ni = 0; ni < node->mNumChildren; ni++) {
visit_node_geo(node->mChildren[ni]);
}
return;
};
visit_node_geo(mScene->mRootNode);
// aiMaterial
@@ -1747,7 +1731,8 @@ void FBXExporter::WriteObjects ()
dnode.AddChild("Version", int32_t(101));
dnode.Dump(outstream, binary, indent);
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
const auto node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode);
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[node]);
std::vector<int32_t> vertex_indices = vVertexIndice[mi];
for (unsigned int am = 0; am < m->mNumAnimMeshes; ++am) {
@@ -1757,7 +1742,7 @@ void FBXExporter::WriteObjects ()
// start the node record
FBX::Node bsnode("Geometry");
int64_t blendshape_uid = generate_uid();
mesh_uids.push_back(blendshape_uid);
blendshape_uids.push_back(blendshape_uid);
bsnode.AddProperty(blendshape_uid);
bsnode.AddProperty(blendshape_name + FBX::SEPARATOR + "Geometry");
bsnode.AddProperty("Shape");
@@ -1769,23 +1754,25 @@ void FBXExporter::WriteObjects ()
indent++;
if (pAnimMesh->HasPositions()) {
std::vector<int32_t>shape_indices;
std::vector<double>pPositionDiff;
std::vector<double>pNormalDiff;
std::vector<float>pPositionDiff;
std::vector<float>pNormalDiff;
for (unsigned int vt = 0; vt < vertex_indices.size(); ++vt) {
aiVector3D pDiff = (pAnimMesh->mVertices[vertex_indices[vt]] - m->mVertices[vertex_indices[vt]]);
if(pDiff.Length()>1e-8){
shape_indices.push_back(vertex_indices[vt]);
pPositionDiff.push_back(pDiff[0]);
pPositionDiff.push_back(pDiff[1]);
pPositionDiff.push_back(pDiff[2]);
shape_indices.push_back(vertex_indices[vt]);
pPositionDiff.push_back(pDiff[0]);
pPositionDiff.push_back(pDiff[1]);
pPositionDiff.push_back(pDiff[2]);
if (pAnimMesh->HasNormals()) {
aiVector3D nDiff = (pAnimMesh->mNormals[vertex_indices[vt]] - m->mNormals[vertex_indices[vt]]);
pNormalDiff.push_back(nDiff[0]);
pNormalDiff.push_back(nDiff[1]);
pNormalDiff.push_back(nDiff[2]);
}
if (pAnimMesh->HasNormals()) {
aiVector3D nDiff = (pAnimMesh->mNormals[vertex_indices[vt]] - m->mNormals[vertex_indices[vt]]);
pNormalDiff.push_back(nDiff[0]);
pNormalDiff.push_back(nDiff[1]);
pNormalDiff.push_back(nDiff[2]);
} else {
pNormalDiff.push_back(0.0);
pNormalDiff.push_back(0.0);
pNormalDiff.push_back(0.0);
}
}
@@ -1868,33 +1855,26 @@ void FBXExporter::WriteObjects ()
// one sticky point is that the number of vertices may not match,
// because assimp splits vertices by normal, uv, etc.
// functor for aiNode sorting
struct SortNodeByName
{
bool operator()(const aiNode *lhs, const aiNode *rhs) const
{
return strcmp(lhs->mName.C_Str(), rhs->mName.C_Str()) < 0;
}
};
// first we should mark the skeleton for each mesh.
// the skeleton must include not only the aiBones,
// but also all their parent nodes.
// anything that affects the position of any bone node must be included.
// Use SorNodeByName to make sure the exported result will be the same across all systems
// Otherwise the aiNodes of the skeleton would be sorted based on the pointer address, which isn't consistent
std::vector<std::set<const aiNode*, SortNodeByName>> skeleton_by_mesh(mScene->mNumMeshes);
// note that we want to preserve input order as much as possible here.
// previously, sorting by name lead to consistent output across systems, but was not
// suitable for downstream consumption by some applications.
std::vector<std::vector<const aiNode*>> skeleton_by_mesh(mScene->mNumMeshes);
// at the same time we can build a list of all the skeleton nodes,
// which will be used later to mark them as type "limbNode".
std::unordered_set<const aiNode*> limbnodes;
//actual bone nodes in fbx, without parenting-up
std::unordered_set<std::string> setAllBoneNamesInScene;
for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m)
{
std::vector<std::string> allBoneNames;
for(unsigned int m = 0; m < mScene->mNumMeshes; ++ m) {
aiMesh* pMesh = mScene->mMeshes[m];
for(unsigned int b = 0; b < pMesh->mNumBones; ++ b)
setAllBoneNamesInScene.insert(pMesh->mBones[b]->mName.data);
allBoneNames.push_back(pMesh->mBones[b]->mName.data);
}
aiMatrix4x4 mxTransIdentity;
@@ -1902,7 +1882,7 @@ void FBXExporter::WriteObjects ()
std::map<std::string,aiNode*> node_by_bone;
for (size_t mi = 0; mi < mScene->mNumMeshes; ++mi) {
const aiMesh* m = mScene->mMeshes[mi];
std::set<const aiNode*, SortNodeByName> skeleton;
std::vector<const aiNode*> skeleton;
for (size_t bi =0; bi < m->mNumBones; ++bi) {
const aiBone* b = m->mBones[bi];
const std::string name(b->mName.C_Str());
@@ -1921,7 +1901,7 @@ void FBXExporter::WriteObjects ()
node_by_bone[name] = n;
limbnodes.insert(n);
}
skeleton.insert(n);
skeleton.push_back(n);
// mark all parent nodes as skeleton as well,
// up until we find the root node,
// or else the node containing the mesh,
@@ -1932,7 +1912,7 @@ void FBXExporter::WriteObjects ()
parent = parent->mParent
) {
// if we've already done this node we can skip it all
if (skeleton.count(parent)) {
if (std::find(skeleton.begin(), skeleton.end(), parent) != skeleton.end()) {
break;
}
// ignore fbx transform nodes as these will be collapsed later
@@ -1942,29 +1922,22 @@ void FBXExporter::WriteObjects ()
continue;
}
//not a bone in scene && no effect in transform
if(setAllBoneNamesInScene.find(node_name)==setAllBoneNamesInScene.end()
if (std::find(allBoneNames.begin(), allBoneNames.end(), node_name) == allBoneNames.end()
&& parent->mTransformation == mxTransIdentity) {
continue;
}
// otherwise check if this is the root of the skeleton
bool end = false;
// is the mesh part of this node?
for (size_t i = 0; i < parent->mNumMeshes; ++i) {
if (parent->mMeshes[i] == mi) {
end = true;
break;
}
for (size_t i = 0; i < parent->mNumMeshes && !end; ++i) {
end |= parent->mMeshes[i] == mi;
}
// is the mesh in one of the children of this node?
for (size_t j = 0; j < parent->mNumChildren; ++j) {
for (size_t j = 0; j < parent->mNumChildren && !end; ++j) {
aiNode* child = parent->mChildren[j];
for (size_t i = 0; i < child->mNumMeshes; ++i) {
if (child->mMeshes[i] == mi) {
end = true;
break;
}
for (size_t i = 0; i < child->mNumMeshes && !end; ++i) {
end |= child->mMeshes[i] == mi;
}
if (end) { break; }
}
// if it was the skeleton root we can finish here
@@ -1978,8 +1951,7 @@ void FBXExporter::WriteObjects ()
for (size_t i = 0; i < mScene->mNumMeshes; ++i) {
auto &s = skeleton_by_mesh[i];
for (const aiNode* n : s) {
auto elem = node_uids.find(n);
if (elem == node_uids.end()) {
if (node_uids.find(n) == node_uids.end()) {
node_uids[n] = generate_uid();
}
}
@@ -1995,6 +1967,8 @@ void FBXExporter::WriteObjects ()
if (!m->HasBones()) {
continue;
}
const aiNode *mesh_node = get_node_for_mesh((uint32_t)mi, mScene->mRootNode);
// make a deformer for this mesh
int64_t deformer_uid = generate_uid();
FBX::Node dnode("Deformer");
@@ -2006,10 +1980,7 @@ void FBXExporter::WriteObjects ()
dnode.Dump(outstream, binary, indent);
// connect it
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
//computed before
std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mesh_node]);
// TODO, FIXME: this won't work if anything is not in the bind pose.
// for now if such a situation is detected, we throw an exception.
@@ -2023,11 +1994,10 @@ void FBXExporter::WriteObjects ()
// as it can be instanced to many nodes.
// All we can do is assume no instancing,
// and take the first node we find that contains the mesh.
aiNode* mesh_node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode);
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
// now make a subdeformer for each bone in the skeleton
const std::set<const aiNode*, SortNodeByName> skeleton= skeleton_by_mesh[mi];
const auto & skeleton= skeleton_by_mesh[mi];
for (const aiNode* bone_node : skeleton) {
// if there's a bone for this node, find it
const aiBone* b = nullptr;
@@ -2052,14 +2022,15 @@ void FBXExporter::WriteObjects ()
sdnode.AddChild("Version", int32_t(100));
sdnode.AddChild("UserData", "", "");
std::set<int32_t> setWeightedVertex;
// add indices and weights, if any
if (b) {
std::set<int32_t> setWeightedVertex;
std::vector<int32_t> subdef_indices;
std::vector<double> subdef_weights;
int32_t last_index = -1;
for (size_t wi = 0; wi < b->mNumWeights; ++wi) {
int32_t vi = vertex_indices[b->mWeights[wi].mVertexId];
int32_t vi = vVertexIndice[mi][b->mWeights[wi].mVertexId] \
+ uniq_v_before_mi[mi];
bool bIsWeightedAlready = (setWeightedVertex.find(vi) != setWeightedVertex.end());
if (vi == last_index || bIsWeightedAlready) {
// only for vertices we exported to fbx
@@ -2493,6 +2464,57 @@ const std::map<std::string,std::pair<std::string,char>> transform_types = {
{"GeometricScalingInverse", {"GeometricScalingInverse", 'i'}}
};
//add metadata to fbx property
void add_meta(FBX::Node& fbx_node, const aiNode* node){
if(node->mMetaData == nullptr) return;
aiMetadata* meta = node->mMetaData;
for (unsigned int i = 0; i < meta->mNumProperties; ++i) {
aiString key = meta->mKeys[i];
aiMetadataEntry* entry = &meta->mValues[i];
switch (entry->mType) {
case AI_BOOL:{
bool val = *static_cast<bool *>(entry->mData);
fbx_node.AddP70bool(key.C_Str(), val);
break;
}
case AI_INT32:{
int32_t val = *static_cast<int32_t *>(entry->mData);
fbx_node.AddP70int(key.C_Str(), val);
break;
}
case AI_UINT64:{
//use string to add uint64
uint64_t val = *static_cast<uint64_t *>(entry->mData);
fbx_node.AddP70string(key.C_Str(), std::to_string(val).c_str());
break;
}
case AI_FLOAT:{
float val = *static_cast<float *>(entry->mData);
fbx_node.AddP70double(key.C_Str(), val);
break;
}
case AI_DOUBLE:{
double val = *static_cast<double *>(entry->mData);
fbx_node.AddP70double(key.C_Str(), val);
break;
}
case AI_AISTRING:{
aiString val = *static_cast<aiString *>(entry->mData);
fbx_node.AddP70string(key.C_Str(), val.C_Str());
break;
}
case AI_AIMETADATA: {
//ignore
break;
}
default:
break;
}
}
}
// write a single model node to the stream
void FBXExporter::WriteModelNode(
StreamWriterLE& outstream,
@@ -2560,6 +2582,7 @@ void FBXExporter::WriteModelNode(
}
}
}
add_meta(p, node);
m.AddChild(p);
// not sure what these are for,
@@ -2654,9 +2677,8 @@ void FBXExporter::WriteModelNodes(
// handled later
} else if (node->mNumMeshes == 1) {
// connect to child mesh, which should have been written previously
connections.emplace_back(
"C", "OO", mesh_uids[node->mMeshes[0]], node_uid
);
// TODO double check this line
connections.emplace_back("C", "OO", mesh_uids[node], node_uid);
// also connect to the material for the child mesh
connections.emplace_back(
"C", "OO",
@@ -2681,6 +2703,16 @@ void FBXExporter::WriteModelNodes(
na.Dump(outstream, binary, 1);
// and connect them
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
} else if (node->mNumMeshes >= 1) {
connections.emplace_back("C", "OO", mesh_uids[node], node_uid);
for (size_t i = 0; i < node->mNumMeshes; i++) {
connections.emplace_back(
"C", "OO",
material_uids[mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex],
node_uid
);
}
WriteModelNode(outstream, binary, node, node_uid, "Mesh", transform_chain);
} else {
const auto& lightIt = lights_uids.find(node->mName.C_Str());
if(lightIt != lights_uids.end()) {
@@ -2697,34 +2729,20 @@ void FBXExporter::WriteModelNodes(
}
}
// if more than one child mesh, make nodes for each mesh
if (node->mNumMeshes > 1 || node == mScene->mRootNode) {
for (size_t i = 0; i < node->mNumMeshes; ++i) {
// make a new model node
int64_t new_node_uid = generate_uid();
// connect to parent node
connections.emplace_back("C", "OO", new_node_uid, node_uid);
// connect to child mesh, which should have been written previously
connections.emplace_back(
"C", "OO", mesh_uids[node->mMeshes[i]], new_node_uid
);
// also connect to the material for the child mesh
connections.emplace_back(
"C", "OO",
material_uids[
mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex
],
new_node_uid
);
aiNode new_node;
// take name from mesh name, if it exists
new_node.mName = mScene->mMeshes[node->mMeshes[i]]->mName;
// write model node
WriteModelNode(
outstream, binary, &new_node, new_node_uid, "Mesh", std::vector<std::pair<std::string,aiVector3D>>()
);
}
if (node == mScene->mRootNode && node->mNumMeshes > 0) {
int64_t new_node_uid = generate_uid();
connections.emplace_back("C", "OO", new_node_uid, node_uid);
connections.emplace_back("C", "OO", mesh_uids[node], new_node_uid);
for (size_t i = 0; i < node->mNumMeshes; ++i) {
connections.emplace_back(
"C", "OO",
material_uids[mScene->mMeshes[node->mMeshes[i]]->mMaterialIndex],
new_node_uid
);
}
aiNode new_node;
new_node.mName = mScene->mMeshes[0]->mName;
WriteModelNode(outstream, binary, &new_node, new_node_uid, "Mesh", {});
}
// now recurse into children
+3 -3
View File
@@ -2,7 +2,7 @@
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2024, assimp team
Copyright (c) 2006-2025, assimp team
All rights reserved.
@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "FBXCommon.h" // FBX::TransformInheritance
#include <assimp/types.h>
//#include <assimp/material.h>
#include <assimp/StreamWriter.h> // StreamWriterLE
#include <assimp/Exceptional.h> // DeadlyExportError
@@ -91,7 +90,8 @@ namespace Assimp {
std::vector<FBX::Node> connections; // connection storage
std::vector<int64_t> mesh_uids;
std::map<const aiNode*, int64_t> mesh_uids;
std::vector<int64_t> blendshape_uids;
std::vector<int64_t> material_uids;
std::map<const aiNode*,int64_t> node_uids;
std::map<std::string,int64_t> lights_uids;

Some files were not shown because too many files have changed in this diff Show More